├── .gitignore ├── .gitmodules ├── .travis.yml ├── LICENSE ├── PROTOCOL.md ├── README.md ├── android ├── .gitignore ├── build.gradle ├── lint.xml └── src │ ├── androidTest │ └── scala │ │ └── com │ │ └── nutomic │ │ └── ensichat │ │ └── bluetooth │ │ └── BluetoothInterfaceTest.scala │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── nutomic │ │ └── ensichat │ │ └── util │ │ └── PRNGFixes.java │ ├── res │ ├── drawable-hdpi │ │ ├── ic_action_send_now.png │ │ ├── ic_add_white_24dp.png │ │ ├── ic_launcher.png │ │ ├── ic_person_add_white_24dp.png │ │ └── ic_qrcode_white_24dp.png │ ├── drawable-mdpi │ │ ├── ic_action_send_now.png │ │ ├── ic_add_white_24dp.png │ │ ├── ic_launcher.png │ │ ├── ic_person_add_white_24dp.png │ │ └── ic_qrcode_white_24dp.png │ ├── drawable-xhdpi │ │ ├── ic_action_send_now.png │ │ ├── ic_add_white_24dp.png │ │ ├── ic_launcher.png │ │ ├── ic_person_add_white_24dp.png │ │ └── ic_qrcode_white_24dp.png │ ├── drawable-xxhdpi │ │ ├── ic_action_send_now.png │ │ ├── ic_add_white_24dp.png │ │ ├── ic_launcher.png │ │ ├── ic_person_add_white_24dp.png │ │ └── ic_qrcode_white_24dp.png │ ├── drawable-xxxhdpi │ │ ├── ic_add_white_24dp.png │ │ ├── ic_launcher.png │ │ ├── ic_person_add_white_24dp.png │ │ └── ic_qrcode_white_24dp.png │ ├── drawable │ │ └── message_background.xml │ ├── layout │ │ ├── activity_connections.xml │ │ ├── activity_first_start.xml │ │ ├── activity_main.xml │ │ ├── fragment_chat.xml │ │ ├── fragment_contacts.xml │ │ ├── fragment_identicon.xml │ │ ├── item_date.xml │ │ ├── item_message.xml │ │ └── item_user.xml │ ├── menu │ │ ├── connections.xml │ │ └── main.xml │ ├── values │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── style.xml │ └── xml │ │ └── settings.xml │ └── scala │ └── com │ └── nutomic │ └── ensichat │ ├── App.scala │ ├── activities │ ├── ConnectionsActivity.scala │ ├── EnsichatActivity.scala │ ├── FirstStartActivity.scala │ ├── MainActivity.scala │ └── SettingsActivity.scala │ ├── bluetooth │ ├── BluetoothConnectThread.scala │ ├── BluetoothDevice.scala │ ├── BluetoothInterface.scala │ ├── BluetoothListenThread.scala │ └── BluetoothTransferThread.scala │ ├── fragments │ ├── ChatFragment.scala │ ├── ContactsFragment.scala │ ├── SettingsFragment.scala │ └── UserInfoFragment.scala │ ├── service │ ├── BootReceiver.scala │ ├── CallbackHandler.scala │ ├── ChatService.scala │ └── NotificationHandler.scala │ ├── util │ ├── IdenticonGenerator.scala │ ├── NetworkChangedReceiver.scala │ └── SettingsWrapper.scala │ └── views │ ├── DatesAdapter.scala │ ├── MessagesAdapter.scala │ └── UsersAdapter.scala ├── build.gradle ├── core ├── .gitignore ├── build.gradle └── src │ ├── main │ ├── resources │ │ └── logback.xml │ └── scala │ │ └── com │ │ └── nutomic │ │ └── ensichat │ │ └── core │ │ ├── ConnectionHandler.scala │ │ ├── interfaces │ │ ├── CallbackInterface.scala │ │ ├── SettingsInterface.scala │ │ └── TransmissionInterface.scala │ │ ├── internet │ │ ├── InternetConnectionThread.scala │ │ ├── InternetInterface.scala │ │ └── InternetServerThread.scala │ │ ├── messages │ │ ├── Message.scala │ │ ├── body │ │ │ ├── ConnectionInfo.scala │ │ │ ├── CryptoData.scala │ │ │ ├── EncryptedBody.scala │ │ │ ├── MessageBody.scala │ │ │ ├── MessageReceived.scala │ │ │ ├── PublicKeyReply.scala │ │ │ ├── PublicKeyRequest.scala │ │ │ ├── RouteError.scala │ │ │ ├── RouteReply.scala │ │ │ ├── RouteRequest.scala │ │ │ ├── Text.scala │ │ │ └── UserInfo.scala │ │ └── header │ │ │ ├── AbstractHeader.scala │ │ │ ├── ContentHeader.scala │ │ │ └── MessageHeader.scala │ │ ├── routing │ │ ├── Address.scala │ │ ├── LocalRoutesInfo.scala │ │ ├── MessageBuffer.scala │ │ ├── RouteMessageInfo.scala │ │ └── Router.scala │ │ └── util │ │ ├── BufferUtils.scala │ │ ├── Crypto.scala │ │ ├── Database.scala │ │ ├── FutureHelper.scala │ │ ├── SeqNumGenerator.scala │ │ └── User.scala │ └── test │ └── scala │ └── com │ └── nutomic │ └── ensichat │ └── core │ ├── messages │ ├── MessageTest.scala │ ├── body │ │ ├── ConnectionInfoTest.scala │ │ ├── RouteErrorTest.scala │ │ ├── RouteReplyTest.scala │ │ ├── RouteRequestTest.scala │ │ └── UserInfoTest.scala │ └── header │ │ ├── ContentHeaderTest.scala │ │ └── MessageHeaderTest.scala │ ├── routing │ ├── AddressTest.scala │ ├── LocalRoutesInfoTest.scala │ ├── MessageBufferTest.scala │ ├── RouteMessageInfoTest.scala │ └── RouterTest.scala │ └── util │ ├── CryptoTest.scala │ ├── DatabaseTest.scala │ └── UserTest.scala ├── docs └── bachelor-thesis.pdf ├── gradle ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── local.properties └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── graphics ├── ic_launcher.svg ├── screenshot_phone_1.png ├── screenshot_phone_2.png └── screenshot_phone_3.png ├── integration ├── .gitignore ├── build.gradle └── src │ └── main │ └── scala │ └── com.nutomic.ensichat.integration │ ├── LocalNode.scala │ └── Main.scala ├── server ├── .gitignore ├── build.gradle └── src │ ├── dist │ └── etc │ │ └── linux-systemd │ │ └── ensichat.service │ └── main │ └── scala │ └── com │ └── nutomic │ └── ensichat │ └── server │ ├── Config.scala │ ├── Main.scala │ └── Settings.scala └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | .gradle 2 | /local.properties 3 | /.idea 4 | /build 5 | *.iml 6 | *.iws 7 | *.ipr 8 | *.apk -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "buildSrc"] 2 | path = buildSrc 3 | url = https://github.com/xelnaga/gradle-android-scala-plugin.git 4 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: android 2 | jdk: oraclejdk8 3 | 4 | # Install Android SDK 5 | android: 6 | components: 7 | - tools 8 | - platform-tools 9 | - build-tools-24.0.2 10 | - android-24 11 | - extra-android-m2repository 12 | 13 | # Cache gradle dependencies 14 | # https://docs.travis-ci.com/user/languages/android/#Caching 15 | before_cache: 16 | - rm -f $HOME/.gradle/caches/modules-2/modules-2.lock 17 | cache: 18 | directories: 19 | - $HOME/.gradle/caches/ 20 | - $HOME/.gradle/wrapper/ 21 | 22 | env: 23 | - GRADLE_OPTS=-Xmx2048m 24 | 25 | script: 26 | # Lint fails because travis doesn't have platform-tools 24 27 | # https://github.com/travis-ci/travis-ci/issues/6699 28 | #- ./gradlew lint 29 | - ./gradlew core:test 30 | - ./gradlew server:release 31 | - ./gradlew integration:assemble 32 | - ./gradlew android:assembleRelRelease || ./gradlew android:assembleRelRelease 33 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | PROJECT DISCONTINUED 2 | ==================== 3 | 4 | Unfortunately, I won't be able to continue development on Ensichat, due to lack of time. I suggest 5 | you give [Briar](https://briarproject.org/) a try instead. 6 | 7 | If you wish to take over maintenance of the project, please contact me. 8 | 9 | Ensichat 10 | ======== 11 | 12 | [![Build Status](https://travis-ci.org/Nutomic/ensichat.svg?branch=master)](https://travis-ci.org/Nutomic/ensichat) 13 | [![License: MPLv2](https://img.shields.io/badge/License-MPLv2-blue.svg)](https://opensource.org/licenses/MPL-2.0) 14 | 15 | Instant messenger for Android that is fully decentralized, and uses strong end-to-end 16 | encryption. Messages are sent directly between devices via Bluetooth or Internet, without any 17 | central server. Relay nodes are used to ensure message delivery, even if the target node is 18 | offline. 19 | 20 | For details on how Ensichat works, you can check out my [bachelor thesis](docs/bachelor-thesis.pdf), and 21 | read the [protocol definition](PROTOCOL.md). 22 | 23 | screenshot 1 24 | screenshot 2 25 | screenshot 3 26 | 27 | [![Get it on Google Play](https://developer.android.com/images/brand/en_generic_rgb_wo_60.png)](https://play.google.com/store/apps/details?id=com.nutomic.ensichat) [![Get it on F-Droid](https://f-droid.org/wiki/images/0/06/F-Droid-button_get-it-on.png)](https://f-droid.org/repository/browse/?fdid=com.nutomic.ensichat) 28 | 29 | To set up a server, please follow the [instructions on the wiki](https://github.com/Nutomic/ensichat/wiki/Running-your-own-server). 30 | 31 | Building 32 | -------- 33 | 34 | To setup a development environment, just install [Android Studio](https://developer.android.com/sdk/) 35 | and import the project. 36 | 37 | Alternatively, you can use the command line. To create a debug apk, run `./gradlew assembleDevDebug`. 38 | This requires at least Android Lollipop on your development device. If you don't have 5.0 or higher, 39 | you have to use `./gradlew assembleRelDebug`. However, this results in considerably slower 40 | incremental builds. To create a release apk, run `./gradlew assembleRelRelease`. 41 | 42 | Testing 43 | ------- 44 | 45 | You can run the unit tests with `./gradlew test`. After connecting an Android device, you can run 46 | the Android tests with `./gradlew connectedDevDebugAndroidTest` (or 47 | `./gradlew connectedRelDebugAndroidTest` if your Android version is lower than 5.0). 48 | 49 | To run integration tests for the core module, use `./gradlew integration:run`. If this fails (or 50 | is very slow), try changing the value of Crypto#PublicKeySize to 512 (in the core module). 51 | 52 | License 53 | ------- 54 | The project is licensed under the [MPLv2](LICENSE). 55 | 56 | The launcher icon is based on the [Bubbles Icon](https://www.iconfinder.com/icons/285667/bubbles_icon) created by [Paomedia](https://www.iconfinder.com/paomedia) which is available under [CC BY 3.0](http://creativecommons.org/licenses/by/3.0/). 57 | -------------------------------------------------------------------------------- /android/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | apply plugin: 'jp.leafytree.android-scala' 3 | 4 | dependencies { 5 | compile 'com.android.support:design:24.2.1' 6 | compile 'com.android.support:multidex:1.0.1' 7 | compile 'org.scala-lang:scala-library:2.11.7' 8 | compile 'com.mobsandgeeks:adapter-kit:0.5.3' 9 | compile 'com.google.zxing:android-integration:3.3.0' 10 | compile 'com.google.zxing:core:3.3.0' 11 | compile 'org.slf4j:slf4j-android:1.7.21' 12 | compile project(path: ':core') 13 | androidTestCompile 'com.android.support:multidex-instrumentation:1.0.1', 14 | { exclude module: 'multidex' } 15 | } 16 | 17 | // RtlHardcoded behaviour differs between target API versions. We only care about API 15. 18 | preBuild.doFirst { 19 | android.applicationVariants.each { variant -> 20 | if (variant.name == 'devDebug' || variant.name == 'devRelease') { 21 | println variant.name 22 | android.lintOptions.disable 'RtlHardcoded' 23 | } 24 | } 25 | } 26 | 27 | android { 28 | compileSdkVersion 24 29 | buildToolsVersion "24.0.2" 30 | 31 | defaultConfig { 32 | applicationId "com.nutomic.ensichat" 33 | targetSdkVersion 24 34 | versionCode 17 35 | versionName "0.5.2" 36 | multiDexEnabled true 37 | testInstrumentationRunner "com.android.test.runner.MultiDexTestRunner" 38 | } 39 | 40 | buildTypes { 41 | debug { 42 | applicationIdSuffix ".debug" 43 | testCoverageEnabled true 44 | } 45 | } 46 | 47 | // Increasing minSdkVersion reduces compilation time for MultiDex. 48 | productFlavors { 49 | dev.minSdkVersion 21 50 | rel.minSdkVersion 15 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /android/lint.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /android/src/androidTest/scala/com/nutomic/ensichat/bluetooth/BluetoothInterfaceTest.scala: -------------------------------------------------------------------------------- 1 | package com.nutomic.ensichat.bluetooth 2 | 3 | import android.bluetooth.BluetoothAdapter 4 | import android.os.Handler 5 | import android.test.AndroidTestCase 6 | 7 | class BluetoothInterfaceTest extends AndroidTestCase { 8 | 9 | private lazy val btInterface = new BluetoothInterface(getContext, new Handler(), null) 10 | 11 | /** 12 | * Test for issue [[https://github.com/Nutomic/ensichat/issues/3 #3]]. 13 | */ 14 | def testStartBluetoothOff(): Unit = { 15 | val btAdapter = BluetoothAdapter.getDefaultAdapter 16 | if (btAdapter == null) 17 | return 18 | 19 | btAdapter.disable() 20 | btInterface.create() 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /android/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 23 | 24 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 39 | 40 | 44 | 47 | 48 | 49 | 53 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /android/src/main/res/drawable-hdpi/ic_action_send_now.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nutomic/ensichat/b9eddea5b903414af8c5ce38dd49d43d7a98a6a0/android/src/main/res/drawable-hdpi/ic_action_send_now.png -------------------------------------------------------------------------------- /android/src/main/res/drawable-hdpi/ic_add_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nutomic/ensichat/b9eddea5b903414af8c5ce38dd49d43d7a98a6a0/android/src/main/res/drawable-hdpi/ic_add_white_24dp.png -------------------------------------------------------------------------------- /android/src/main/res/drawable-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nutomic/ensichat/b9eddea5b903414af8c5ce38dd49d43d7a98a6a0/android/src/main/res/drawable-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/src/main/res/drawable-hdpi/ic_person_add_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nutomic/ensichat/b9eddea5b903414af8c5ce38dd49d43d7a98a6a0/android/src/main/res/drawable-hdpi/ic_person_add_white_24dp.png -------------------------------------------------------------------------------- /android/src/main/res/drawable-hdpi/ic_qrcode_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nutomic/ensichat/b9eddea5b903414af8c5ce38dd49d43d7a98a6a0/android/src/main/res/drawable-hdpi/ic_qrcode_white_24dp.png -------------------------------------------------------------------------------- /android/src/main/res/drawable-mdpi/ic_action_send_now.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nutomic/ensichat/b9eddea5b903414af8c5ce38dd49d43d7a98a6a0/android/src/main/res/drawable-mdpi/ic_action_send_now.png -------------------------------------------------------------------------------- /android/src/main/res/drawable-mdpi/ic_add_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nutomic/ensichat/b9eddea5b903414af8c5ce38dd49d43d7a98a6a0/android/src/main/res/drawable-mdpi/ic_add_white_24dp.png -------------------------------------------------------------------------------- /android/src/main/res/drawable-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nutomic/ensichat/b9eddea5b903414af8c5ce38dd49d43d7a98a6a0/android/src/main/res/drawable-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/src/main/res/drawable-mdpi/ic_person_add_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nutomic/ensichat/b9eddea5b903414af8c5ce38dd49d43d7a98a6a0/android/src/main/res/drawable-mdpi/ic_person_add_white_24dp.png -------------------------------------------------------------------------------- /android/src/main/res/drawable-mdpi/ic_qrcode_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nutomic/ensichat/b9eddea5b903414af8c5ce38dd49d43d7a98a6a0/android/src/main/res/drawable-mdpi/ic_qrcode_white_24dp.png -------------------------------------------------------------------------------- /android/src/main/res/drawable-xhdpi/ic_action_send_now.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nutomic/ensichat/b9eddea5b903414af8c5ce38dd49d43d7a98a6a0/android/src/main/res/drawable-xhdpi/ic_action_send_now.png -------------------------------------------------------------------------------- /android/src/main/res/drawable-xhdpi/ic_add_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nutomic/ensichat/b9eddea5b903414af8c5ce38dd49d43d7a98a6a0/android/src/main/res/drawable-xhdpi/ic_add_white_24dp.png -------------------------------------------------------------------------------- /android/src/main/res/drawable-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nutomic/ensichat/b9eddea5b903414af8c5ce38dd49d43d7a98a6a0/android/src/main/res/drawable-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/src/main/res/drawable-xhdpi/ic_person_add_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nutomic/ensichat/b9eddea5b903414af8c5ce38dd49d43d7a98a6a0/android/src/main/res/drawable-xhdpi/ic_person_add_white_24dp.png -------------------------------------------------------------------------------- /android/src/main/res/drawable-xhdpi/ic_qrcode_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nutomic/ensichat/b9eddea5b903414af8c5ce38dd49d43d7a98a6a0/android/src/main/res/drawable-xhdpi/ic_qrcode_white_24dp.png -------------------------------------------------------------------------------- /android/src/main/res/drawable-xxhdpi/ic_action_send_now.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nutomic/ensichat/b9eddea5b903414af8c5ce38dd49d43d7a98a6a0/android/src/main/res/drawable-xxhdpi/ic_action_send_now.png -------------------------------------------------------------------------------- /android/src/main/res/drawable-xxhdpi/ic_add_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nutomic/ensichat/b9eddea5b903414af8c5ce38dd49d43d7a98a6a0/android/src/main/res/drawable-xxhdpi/ic_add_white_24dp.png -------------------------------------------------------------------------------- /android/src/main/res/drawable-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nutomic/ensichat/b9eddea5b903414af8c5ce38dd49d43d7a98a6a0/android/src/main/res/drawable-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/src/main/res/drawable-xxhdpi/ic_person_add_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nutomic/ensichat/b9eddea5b903414af8c5ce38dd49d43d7a98a6a0/android/src/main/res/drawable-xxhdpi/ic_person_add_white_24dp.png -------------------------------------------------------------------------------- /android/src/main/res/drawable-xxhdpi/ic_qrcode_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nutomic/ensichat/b9eddea5b903414af8c5ce38dd49d43d7a98a6a0/android/src/main/res/drawable-xxhdpi/ic_qrcode_white_24dp.png -------------------------------------------------------------------------------- /android/src/main/res/drawable-xxxhdpi/ic_add_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nutomic/ensichat/b9eddea5b903414af8c5ce38dd49d43d7a98a6a0/android/src/main/res/drawable-xxxhdpi/ic_add_white_24dp.png -------------------------------------------------------------------------------- /android/src/main/res/drawable-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nutomic/ensichat/b9eddea5b903414af8c5ce38dd49d43d7a98a6a0/android/src/main/res/drawable-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/src/main/res/drawable-xxxhdpi/ic_person_add_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nutomic/ensichat/b9eddea5b903414af8c5ce38dd49d43d7a98a6a0/android/src/main/res/drawable-xxxhdpi/ic_person_add_white_24dp.png -------------------------------------------------------------------------------- /android/src/main/res/drawable-xxxhdpi/ic_qrcode_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nutomic/ensichat/b9eddea5b903414af8c5ce38dd49d43d7a98a6a0/android/src/main/res/drawable-xxxhdpi/ic_qrcode_white_24dp.png -------------------------------------------------------------------------------- /android/src/main/res/drawable/message_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /android/src/main/res/layout/activity_connections.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 11 | 12 | 20 | 21 | 25 | 26 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /android/src/main/res/layout/activity_first_start.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 14 | 15 | 24 | 25 |