├── settings.gradle
├── .gradle
├── 4.4
│ ├── fileChanges
│ │ └── last-build.bin
│ ├── fileHashes
│ │ ├── fileHashes.bin
│ │ ├── fileHashes.lock
│ │ └── resourceHashesCache.bin
│ ├── javaCompile
│ │ ├── taskJars.bin
│ │ ├── jarAnalysis.bin
│ │ ├── javaCompile.lock
│ │ ├── taskHistory.bin
│ │ └── classAnalysis.bin
│ ├── fileContent
│ │ └── fileContent.lock
│ └── taskHistory
│ │ ├── taskHistory.bin
│ │ └── taskHistory.lock
└── buildOutputCleanup
│ ├── cache.properties
│ ├── outputFiles.bin
│ └── buildOutputCleanup.lock
├── WhatsApp.apk
├── Screenshots
├── s1.png
└── s2.png
├── app
├── src
│ ├── main
│ │ ├── res
│ │ │ ├── drawable
│ │ │ │ ├── i1.jpg
│ │ │ │ ├── icon.png
│ │ │ │ ├── send.png
│ │ │ │ ├── attachment.png
│ │ │ │ ├── icon_round.png
│ │ │ │ ├── attach_camera.png
│ │ │ │ ├── input_emoji.png
│ │ │ │ ├── attach_gallery.png
│ │ │ │ ├── attach_location.png
│ │ │ │ ├── arrow_back_black.png
│ │ │ │ ├── arrow_back_white.png
│ │ │ │ ├── message_background.jpg
│ │ │ │ ├── rectangle_grey2.xml
│ │ │ │ ├── rectangle_green2.xml
│ │ │ │ ├── video.xml
│ │ │ │ ├── account.xml
│ │ │ │ ├── message.xml
│ │ │ │ ├── message_processing.xml
│ │ │ │ ├── plus.xml
│ │ │ │ ├── rectangle.xml
│ │ │ │ ├── rectangle_green.xml
│ │ │ │ ├── rectangle_grey.xml
│ │ │ │ ├── camera.xml
│ │ │ │ ├── dots_vertical.xml
│ │ │ │ ├── magnify.xml
│ │ │ │ ├── phone.xml
│ │ │ │ ├── attach.xml
│ │ │ │ └── ic_launcher_background.xml
│ │ │ ├── mipmap-hdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-mdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xhdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xxxhdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-anydpi-v26
│ │ │ │ ├── ic_launcher.xml
│ │ │ │ └── ic_launcher_round.xml
│ │ │ ├── layout
│ │ │ │ ├── user_details_tool_bar.xml
│ │ │ │ ├── activity_show_image.xml
│ │ │ │ ├── activity_contact.xml
│ │ │ │ ├── received_text.xml
│ │ │ │ ├── sent_text.xml
│ │ │ │ ├── tool_bar2.xml
│ │ │ │ ├── fragment_chat.xml
│ │ │ │ ├── fragment_contacts.xml
│ │ │ │ ├── search_contact.xml
│ │ │ │ ├── received_image.xml
│ │ │ │ ├── sent_image.xml
│ │ │ │ ├── editaccount.xml
│ │ │ │ ├── contact_cell.xml
│ │ │ │ ├── person_cell.xml
│ │ │ │ ├── tool_bar.xml
│ │ │ │ ├── activity_verify_phone_number.xml
│ │ │ │ ├── activity_set_profile_data.xml
│ │ │ │ ├── activity_register_phone_number.xml
│ │ │ │ ├── settings.xml
│ │ │ │ ├── activity_chat.xml
│ │ │ │ ├── activity_user_details_screen.xml
│ │ │ │ └── activity_message.xml
│ │ │ ├── values
│ │ │ │ ├── dimens.xml
│ │ │ │ ├── colors.xml
│ │ │ │ ├── styles.xml
│ │ │ │ └── strings.xml
│ │ │ ├── menu
│ │ │ │ ├── message_menu.xml
│ │ │ │ └── menu_chat.xml
│ │ │ ├── values-w820dp
│ │ │ │ └── dimens.xml
│ │ │ └── drawable-v24
│ │ │ │ └── ic_launcher_foreground.xml
│ │ ├── java
│ │ │ └── com
│ │ │ │ └── example
│ │ │ │ └── whatsapp
│ │ │ │ ├── AttachmentCell.java
│ │ │ │ ├── MyReceiver.java
│ │ │ │ ├── ShowImage.java
│ │ │ │ ├── PersonCell.java
│ │ │ │ ├── ContactCell.java
│ │ │ │ ├── Message.java
│ │ │ │ ├── DBHelper.java
│ │ │ │ ├── ContactActivity.java
│ │ │ │ ├── ContactAdapter.java
│ │ │ │ ├── ContactAdapter2.java
│ │ │ │ ├── VerifyPhoneNumberActivity.java
│ │ │ │ ├── UserDetailsScreen.java
│ │ │ │ ├── SetProfileData.java
│ │ │ │ ├── ChatAdapter.java
│ │ │ │ ├── RegisterPhoneNumber.java
│ │ │ │ ├── MessageAdapter.java
│ │ │ │ ├── Settings.java
│ │ │ │ ├── editaccount.java
│ │ │ │ ├── SyncMessagesService.java
│ │ │ │ └── ChatActivity.java
│ │ └── AndroidManifest.xml
│ ├── test
│ │ └── java
│ │ │ └── com
│ │ │ └── example
│ │ │ └── whatsapp
│ │ │ └── ExampleUnitTest.java
│ └── androidTest
│ │ └── java
│ │ └── com
│ │ └── example
│ │ └── whatsapp
│ │ └── ExampleInstrumentedTest.java
└── build.gradle
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── local.properties
├── gradle.properties
├── LICENSE
├── README.md
├── gradlew.bat
└── gradlew
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------
/.gradle/4.4/fileChanges/last-build.bin:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/WhatsApp.apk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FarhanShoukat/MessagingApp/HEAD/WhatsApp.apk
--------------------------------------------------------------------------------
/Screenshots/s1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FarhanShoukat/MessagingApp/HEAD/Screenshots/s1.png
--------------------------------------------------------------------------------
/Screenshots/s2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FarhanShoukat/MessagingApp/HEAD/Screenshots/s2.png
--------------------------------------------------------------------------------
/.gradle/buildOutputCleanup/cache.properties:
--------------------------------------------------------------------------------
1 | #Sun Sep 09 12:29:42 PKT 2018
2 | gradle.version=4.4
3 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/i1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FarhanShoukat/MessagingApp/HEAD/app/src/main/res/drawable/i1.jpg
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FarhanShoukat/MessagingApp/HEAD/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/app/src/main/res/drawable/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FarhanShoukat/MessagingApp/HEAD/app/src/main/res/drawable/icon.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/send.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FarhanShoukat/MessagingApp/HEAD/app/src/main/res/drawable/send.png
--------------------------------------------------------------------------------
/.gradle/4.4/fileHashes/fileHashes.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FarhanShoukat/MessagingApp/HEAD/.gradle/4.4/fileHashes/fileHashes.bin
--------------------------------------------------------------------------------
/.gradle/4.4/fileHashes/fileHashes.lock:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FarhanShoukat/MessagingApp/HEAD/.gradle/4.4/fileHashes/fileHashes.lock
--------------------------------------------------------------------------------
/.gradle/4.4/javaCompile/taskJars.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FarhanShoukat/MessagingApp/HEAD/.gradle/4.4/javaCompile/taskJars.bin
--------------------------------------------------------------------------------
/.gradle/4.4/fileContent/fileContent.lock:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FarhanShoukat/MessagingApp/HEAD/.gradle/4.4/fileContent/fileContent.lock
--------------------------------------------------------------------------------
/.gradle/4.4/javaCompile/jarAnalysis.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FarhanShoukat/MessagingApp/HEAD/.gradle/4.4/javaCompile/jarAnalysis.bin
--------------------------------------------------------------------------------
/.gradle/4.4/javaCompile/javaCompile.lock:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FarhanShoukat/MessagingApp/HEAD/.gradle/4.4/javaCompile/javaCompile.lock
--------------------------------------------------------------------------------
/.gradle/4.4/javaCompile/taskHistory.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FarhanShoukat/MessagingApp/HEAD/.gradle/4.4/javaCompile/taskHistory.bin
--------------------------------------------------------------------------------
/.gradle/4.4/taskHistory/taskHistory.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FarhanShoukat/MessagingApp/HEAD/.gradle/4.4/taskHistory/taskHistory.bin
--------------------------------------------------------------------------------
/.gradle/4.4/taskHistory/taskHistory.lock:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FarhanShoukat/MessagingApp/HEAD/.gradle/4.4/taskHistory/taskHistory.lock
--------------------------------------------------------------------------------
/app/src/main/res/drawable/attachment.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FarhanShoukat/MessagingApp/HEAD/app/src/main/res/drawable/attachment.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/icon_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FarhanShoukat/MessagingApp/HEAD/app/src/main/res/drawable/icon_round.png
--------------------------------------------------------------------------------
/.gradle/4.4/javaCompile/classAnalysis.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FarhanShoukat/MessagingApp/HEAD/.gradle/4.4/javaCompile/classAnalysis.bin
--------------------------------------------------------------------------------
/.gradle/buildOutputCleanup/outputFiles.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FarhanShoukat/MessagingApp/HEAD/.gradle/buildOutputCleanup/outputFiles.bin
--------------------------------------------------------------------------------
/app/src/main/res/drawable/attach_camera.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FarhanShoukat/MessagingApp/HEAD/app/src/main/res/drawable/attach_camera.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/input_emoji.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FarhanShoukat/MessagingApp/HEAD/app/src/main/res/drawable/input_emoji.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/attach_gallery.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FarhanShoukat/MessagingApp/HEAD/app/src/main/res/drawable/attach_gallery.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/attach_location.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FarhanShoukat/MessagingApp/HEAD/app/src/main/res/drawable/attach_location.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FarhanShoukat/MessagingApp/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FarhanShoukat/MessagingApp/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FarhanShoukat/MessagingApp/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/.gradle/4.4/fileHashes/resourceHashesCache.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FarhanShoukat/MessagingApp/HEAD/.gradle/4.4/fileHashes/resourceHashesCache.bin
--------------------------------------------------------------------------------
/app/src/main/res/drawable/arrow_back_black.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FarhanShoukat/MessagingApp/HEAD/app/src/main/res/drawable/arrow_back_black.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/arrow_back_white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FarhanShoukat/MessagingApp/HEAD/app/src/main/res/drawable/arrow_back_white.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/message_background.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FarhanShoukat/MessagingApp/HEAD/app/src/main/res/drawable/message_background.jpg
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FarhanShoukat/MessagingApp/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FarhanShoukat/MessagingApp/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/.gradle/buildOutputCleanup/buildOutputCleanup.lock:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FarhanShoukat/MessagingApp/HEAD/.gradle/buildOutputCleanup/buildOutputCleanup.lock
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FarhanShoukat/MessagingApp/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FarhanShoukat/MessagingApp/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FarhanShoukat/MessagingApp/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FarhanShoukat/MessagingApp/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FarhanShoukat/MessagingApp/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Thu Oct 26 19:06:53 PKT 2017
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip
7 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/rectangle_grey2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/rectangle_green2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/user_details_tool_bar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 | 16dp
6 | 8dp
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/message_menu.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
12 |
--------------------------------------------------------------------------------
/app/src/main/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 64dp
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/video.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
--------------------------------------------------------------------------------
/local.properties:
--------------------------------------------------------------------------------
1 | ## This file must *NOT* be checked into Version Control Systems,
2 | # as it contains information specific to your local configuration.
3 | #
4 | # Location of the SDK. This is only used by Gradle.
5 | # For customization when using a Version Control System, please read the
6 | # header note.
7 | #Sun Sep 09 12:27:37 PKT 2018
8 | ndk.dir=D\:\\Farhan\\Android\\SDK\\ndk-bundle
9 | sdk.dir=D\:\\Farhan\\Android\\SDK
10 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 | #FFFFFF
8 | #000000
9 | #128C7E
10 | #075E54
11 |
12 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/account.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/message.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/message_processing.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/menu_chat.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
15 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/plus.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/rectangle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/rectangle_green.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/rectangle_grey.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 |
11 |
--------------------------------------------------------------------------------
/app/src/test/java/com/example/whatsapp/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.example.whatsapp;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() throws Exception {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_show_image.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/whatsapp/AttachmentCell.java:
--------------------------------------------------------------------------------
1 | package com.example.whatsapp;
2 |
3 | /**
4 | * Created by farha on 03-Oct-17.
5 | */
6 |
7 | public class AttachmentCell {
8 | int imageId;
9 | String name;
10 |
11 | public AttachmentCell(int imageId, String name) {
12 | this.imageId = imageId;
13 | this.name = name;
14 | }
15 |
16 | public int getImageId() {
17 | return imageId;
18 | }
19 |
20 | public String getName() {
21 | return name;
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/camera.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/dots_vertical.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/magnify.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/phone.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_contact.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
12 |
13 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/whatsapp/MyReceiver.java:
--------------------------------------------------------------------------------
1 | package com.example.whatsapp;
2 |
3 | import android.content.BroadcastReceiver;
4 | import android.content.Context;
5 | import android.content.Intent;
6 |
7 | import com.google.firebase.auth.FirebaseAuth;
8 |
9 | /**
10 | * Created by farha on 30-Nov-17.
11 | */
12 |
13 | public class MyReceiver extends BroadcastReceiver {
14 | @Override
15 | public void onReceive(Context context, Intent intent) {
16 | if(FirebaseAuth.getInstance().getCurrentUser() != null) {
17 | context.startService(new Intent(context, SyncMessagesService.class));
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/attach.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 |
9 |
10 |
11 | -
12 |
15 |
16 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/whatsapp/ShowImage.java:
--------------------------------------------------------------------------------
1 | package com.example.whatsapp;
2 |
3 | import android.content.Intent;
4 | import android.net.Uri;
5 | import android.support.v7.app.AppCompatActivity;
6 | import android.os.Bundle;
7 |
8 | import com.github.chrisbanes.photoview.PhotoView;
9 |
10 | public class ShowImage extends AppCompatActivity {
11 |
12 | @Override
13 | protected void onCreate(Bundle savedInstanceState) {
14 | super.onCreate(savedInstanceState);
15 | setContentView(R.layout.activity_show_image);
16 |
17 | Intent intent = getIntent();
18 | String path = (String) intent.getSerializableExtra("image");
19 | PhotoView view = (PhotoView) findViewById(R.id.image);
20 | view.setImageURI(Uri.parse(path));
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | org.gradle.jvmargs=-Xmx1536m
13 |
14 | # When configured, Gradle will run in incubating parallel mode.
15 | # This option should only be used with decoupled projects. More details, visit
16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
17 | # org.gradle.parallel=true
18 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/received_text.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
21 |
22 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/com/example/whatsapp/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.example.whatsapp;
2 |
3 | import android.content.Context;
4 | import android.support.test.InstrumentationRegistry;
5 | import android.support.test.runner.AndroidJUnit4;
6 |
7 | import org.junit.Test;
8 | import org.junit.runner.RunWith;
9 |
10 | import static org.junit.Assert.*;
11 |
12 | /**
13 | * Instrumented test, which will execute on an Android device.
14 | *
15 | * @see Testing documentation
16 | */
17 | @RunWith(AndroidJUnit4.class)
18 | public class ExampleInstrumentedTest {
19 | @Test
20 | public void useAppContext() throws Exception {
21 | // Context of the app under test.
22 | Context appContext = InstrumentationRegistry.getTargetContext();
23 |
24 | assertEquals("com.example.whatsapp", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/sent_text.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
23 |
24 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/tool_bar2.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
13 |
14 |
22 |
23 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/whatsapp/PersonCell.java:
--------------------------------------------------------------------------------
1 | package com.example.whatsapp;
2 |
3 | import android.net.Uri;
4 |
5 | /**
6 | * Created by farha on 07-Nov-17.
7 | */
8 |
9 | public class PersonCell {
10 | private Uri photo;
11 | private String name;
12 | private String lastMessage;
13 | private String date;
14 | private String phone;
15 |
16 | public PersonCell(Uri photo, String name, String lastMessage, String date, String phone) {
17 | this.photo = photo;
18 | this.name = name;
19 | this.lastMessage = lastMessage;
20 | this.date = date;
21 | this.phone = phone;
22 | }
23 |
24 | public Uri getPhoto() {
25 | return photo;
26 | }
27 |
28 | public String getName() {
29 | return name;
30 | }
31 |
32 | public String getLastMessage() {
33 | return lastMessage;
34 | }
35 |
36 | public String getDate() {
37 | return date;
38 | }
39 |
40 | public String getPhone() {
41 | return phone;
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_chat.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
12 |
13 |
14 |
26 |
27 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_contacts.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
12 |
13 |
14 |
26 |
27 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/search_contact.xml:
--------------------------------------------------------------------------------
1 |
10 |
11 |
17 |
18 |
27 |
28 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/received_image.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
12 |
13 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 Farhan Shoukat
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/sent_image.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
14 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/whatsapp/ContactCell.java:
--------------------------------------------------------------------------------
1 | package com.example.whatsapp;
2 |
3 | import android.net.Uri;
4 |
5 | /**
6 | * Created by farha on 09-Nov-17.
7 | */
8 |
9 | public class ContactCell {
10 | private Uri photo;
11 | private String name;
12 | private String status;
13 | private String phone;
14 |
15 | public ContactCell(Uri photo, String name, String status, String phone) {
16 | this.photo = photo;
17 | this.name = name;
18 | this.status = status;
19 | this.phone = phone;
20 | }
21 |
22 | public Uri getPhoto() {
23 | return photo;
24 | }
25 |
26 | public String getName() {
27 | return name;
28 | }
29 |
30 | public String getStatus() {
31 | return status;
32 | }
33 |
34 | public String getPhone() {
35 | return phone;
36 | }
37 |
38 | public void setPhoto(Uri photo) {
39 | this.photo = photo;
40 | }
41 |
42 | public void setName(String name) {
43 | this.name = name;
44 | }
45 |
46 | public void setStatus(String status) {
47 | this.status = status;
48 | }
49 |
50 | public void setPhone(String phone) {
51 | this.phone = phone;
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
18 |
19 |
25 |
26 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/whatsapp/Message.java:
--------------------------------------------------------------------------------
1 | package com.example.whatsapp;
2 |
3 | import android.net.Uri;
4 |
5 | import java.util.Date;
6 |
7 | /**
8 | * Created by farha on 16-Nov-17.
9 | */
10 |
11 | public abstract class Message {
12 | private String date;
13 | private String sender;
14 |
15 | public Message(String sender) {
16 | this.sender = sender;
17 | }
18 |
19 | public String getDate() {
20 | return date;
21 | }
22 |
23 | public void setDate(String date) {
24 | this.date = date;
25 | }
26 |
27 | public String getSender() {
28 | return sender;
29 | }
30 |
31 | public void setSender(String sender) {
32 | this.sender = sender;
33 | }
34 | }
35 |
36 | class TextMessage extends Message {
37 | private String message;
38 |
39 | public TextMessage(String sender, String message) {
40 | super(sender);
41 | this.message = message;
42 | }
43 |
44 | public String getMessage() {
45 | return message;
46 | }
47 |
48 | public void setMessage(String message) {
49 | this.message = message;
50 | }
51 | }
52 |
53 | class ImageMessage extends Message {
54 | private Uri imageUri;
55 |
56 | public ImageMessage(String sender, Uri imageUri) {
57 | super(sender);
58 | this.imageUri = imageUri;
59 | }
60 |
61 | public Uri getImageUri() {
62 | return imageUri;
63 | }
64 |
65 | public void setImageUri(Uri imageUri) {
66 | this.imageUri = imageUri;
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/whatsapp/DBHelper.java:
--------------------------------------------------------------------------------
1 | package com.example.whatsapp;
2 |
3 | import android.content.Context;
4 | import android.database.sqlite.SQLiteDatabase;
5 | import android.database.sqlite.SQLiteOpenHelper;
6 |
7 | /**
8 | * Created by farha on 14-Nov-17.
9 | */
10 |
11 | public class DBHelper extends SQLiteOpenHelper {
12 | public static final int DATABASE_VERSION = 1;
13 | public static final String DATABASE_NAME = "mywhatsapp.db";
14 |
15 | public DBHelper(Context context) {
16 | super(context, DATABASE_NAME, null, DATABASE_VERSION);
17 | }
18 |
19 | @Override
20 | public void onCreate(SQLiteDatabase db) {
21 | db.execSQL("CREATE TABLE Friend (Number TEXT PRIMARY KEY, Status TEXT)");
22 |
23 | db.execSQL("CREATE TABLE Message (Friend TEXT PRIMARY KEY," +
24 | "Sender TEXT, " +
25 | "Date TEXT, " +
26 | "Type TEXT, " +
27 | "Message TEXT)");
28 |
29 | db.execSQL("CREATE TABLE MyMessage (Friend TEXT," +
30 | "Sender TEXT, " +
31 | "Date TEXT, " +
32 | "Type TEXT, " +
33 | "Message TEXT, " +
34 | "PRIMARY KEY(Sender, Date))");
35 | }
36 |
37 | @Override
38 | public void onUpgrade(SQLiteDatabase db, int i, int i1) {
39 | db.execSQL("DROP TABLE IF EXISTS User");
40 | db.execSQL("drop TABLE IF EXISTS Message");
41 | db.execSQL("drop TABLE IF EXISTS MyMessage");
42 | //db.execSQL("DROP TABLE IF EXISTS Image");
43 | onCreate(db);
44 | }
45 |
46 | @Override
47 | public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
48 | super.onDowngrade(db, oldVersion, newVersion);
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 28
5 | defaultConfig {
6 | applicationId "com.example.whatsapp"
7 | minSdkVersion 16
8 | targetSdkVersion 28
9 | versionCode 1
10 | versionName "1.0"
11 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
12 | }
13 | buildTypes {
14 | release {
15 | minifyEnabled false
16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
17 | }
18 | }
19 | }
20 |
21 | dependencies {
22 | implementation fileTree(dir: 'libs', include: ['*.jar'])
23 | implementation 'com.android.support:appcompat-v7:28.0.0-rc02'
24 | implementation 'com.android.support.constraint:constraint-layout:1.1.3'
25 | implementation 'com.android.support:design:28.0.0-rc02'
26 |
27 | implementation 'com.google.android.gms:play-services-location:15.0.1'
28 | implementation 'com.google.firebase:firebase-invites:16.0.3'
29 | testImplementation 'junit:junit:4.12'
30 | androidTestImplementation 'com.android.support.test:runner:1.0.2'
31 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
32 | implementation 'com.google.firebase:firebase-core:16.0.3'
33 | implementation 'com.google.firebase:firebase-auth:16.0.3'
34 | implementation 'com.google.firebase:firebase-database:16.0.2'
35 | implementation 'com.google.firebase:firebase-storage:16.0.2'
36 | implementation 'com.android.volley:volley:1.0.0'
37 | implementation 'de.hdodenhof:circleimageview:2.2.0'
38 | implementation 'com.github.chrisbanes:PhotoView:2.1.3'
39 | implementation "com.android.support:support-v4:28.0.0-rc02"
40 | }
41 |
42 | apply plugin: 'com.google.gms.google-services'
43 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/editaccount.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
17 |
18 |
22 |
23 |
24 |
34 |
35 |
39 |
40 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/contact_cell.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
17 |
18 |
25 |
26 |
34 |
40 |
41 |
42 |
51 |
52 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/person_cell.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
17 |
18 |
26 |
27 |
35 |
41 |
42 |
43 |
52 |
53 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
12 |
13 |
19 |
22 |
25 |
26 |
27 |
28 |
34 |
35 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Whatsapp
2 |
3 | ## Project Description
4 | This app is like WhatsApp. This is an **android app** that allows its users to send text messages, share images using camera or gallery and share their location with their friends. Users register with their **phone number** and their friends are made using their contact list (the same way as in WhatsApp).
5 |
6 | ## Tools and APIs Used
7 | * Android Studio
8 | * Firebase Authentication
9 | * Firebase Realtime Database
10 | * Firebase Storage
11 | * Firebase Invite
12 |
13 |
14 | ## Interfaces
15 |
16 | ### Chats/Conacts and Settings
17 |
18 |
19 |
20 |
21 | ### Messages
22 |
23 |
24 |
25 |
26 |
27 | ## Functionalities
28 |
29 | This app uses **Firebase Phone Number Authentication** which verifies a user’s phone number by sending a code to it. The user is then authenticated to use the app. Then the user is asked to provide a name and profile picture. Profile picture is stored in **Firebase Storage**.
30 |
31 | The app uses **Firebase Realtime Database** for text messaging and location sharing. In this way, user gets message instantaneously.
32 |
33 | The app uses **Firebase Realtime Database** and **Firebase Storage** for image sharing.
34 |
35 | The app also uses **Firebase Invites** to give user the facility to invite others to use this app using email or text message.
36 |
37 | User can also change his/her name or status. Status work the same way as in WhatsApp.
38 |
39 |
40 | ## How to Run
41 |
42 | An apk file [WhatsApp.apk](../master/WhatsApp.apk) is provided which can be installed on an Android Phone.
43 |
44 | In order to have a look at the code files and understand the working, simply download or clone this repository and open it in Android Studio.
45 |
46 |
47 | ## Contact
48 | You can get in touch with me on my LinkedIn Profile: [Farhan Shoukat](https://www.linkedin.com/in/farhan-shoukat/)
49 |
50 |
51 | ## License
52 | [MIT](../master/LICENSE)
53 | Copyright (c) 2018 Farhan Shoukat
54 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/tool_bar.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
16 |
17 |
22 |
23 |
28 |
29 |
34 |
35 |
46 |
47 |
48 |
49 |
55 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_verify_phone_number.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
18 |
19 |
25 |
26 |
30 |
31 |
38 |
39 |
45 |
46 |
47 |
48 |
60 |
61 |
66 |
67 |
68 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_set_profile_data.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
18 |
19 |
26 |
27 |
33 |
34 |
41 |
42 |
54 |
55 |
56 |
57 |
67 |
68 |
69 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
19 |
23 |
27 |
30 |
31 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
45 |
50 |
51 |
54 |
55 |
56 |
57 |
60 |
61 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/whatsapp/ContactActivity.java:
--------------------------------------------------------------------------------
1 | package com.example.whatsapp;
2 |
3 | import android.content.ContentResolver;
4 | import android.content.Context;
5 | import android.content.ContextWrapper;
6 | import android.database.Cursor;
7 | import android.database.sqlite.SQLiteDatabase;
8 | import android.net.Uri;
9 | import android.provider.ContactsContract;
10 | import android.support.v7.app.AppCompatActivity;
11 | import android.os.Bundle;
12 | import android.support.v7.widget.Toolbar;
13 | import android.text.Editable;
14 | import android.text.TextWatcher;
15 | import android.view.LayoutInflater;
16 | import android.view.Menu;
17 | import android.view.MenuInflater;
18 | import android.view.MenuItem;
19 | import android.widget.EditText;
20 | import android.widget.LinearLayout;
21 | import android.widget.ListView;
22 |
23 | import java.io.File;
24 | import java.util.ArrayList;
25 |
26 | public class ContactActivity extends AppCompatActivity {
27 |
28 | @Override
29 | protected void onCreate(Bundle savedInstanceState) {
30 | super.onCreate(savedInstanceState);
31 | setContentView(R.layout.activity_contact);
32 |
33 | setToolbar();
34 |
35 | ListView listView = (ListView) findViewById(R.id.list);
36 | DBHelper helper = new DBHelper(this);
37 | SQLiteDatabase db = helper.getReadableDatabase();
38 | Cursor cursor = db.rawQuery("SELECT * FROM Friend", null);
39 | ArrayList cells = new ArrayList<>();
40 | ContextWrapper wrapper = new ContextWrapper(getApplicationContext());
41 | File file = wrapper.getDir("profilePictures",MODE_PRIVATE);
42 | int i;
43 | while (cursor.moveToNext()) {
44 | String number = cursor.getString(cursor.getColumnIndex("Number"));
45 | if((i = ChatActivity.phones.indexOf(number)) != -1) {
46 | File file1 = new File(file, number + ".jpg");
47 | String status = cursor.getString(cursor.getColumnIndex("Status"));
48 | String name = ChatActivity.names.get(i);
49 | if(file1.exists())
50 | cells.add(new ContactCell(Uri.parse(file1.getAbsolutePath()), name, status, number));
51 | else
52 | cells.add(new ContactCell(null, name, status, number));
53 | }
54 | }
55 | final ContactAdapter2 contactAdapter = new ContactAdapter2(this, cells);
56 | listView.setAdapter(contactAdapter);
57 |
58 | EditText text = (EditText) findViewById(R.id.search);
59 | text.addTextChangedListener(new TextWatcher() {
60 | @Override
61 | public void beforeTextChanged(CharSequence s, int start, int count, int after) {
62 |
63 | }
64 |
65 | @Override
66 | public void onTextChanged(CharSequence s, int start, int before, int count) {
67 | contactAdapter.getFilter().filter(s.toString());
68 | }
69 |
70 | @Override
71 | public void afterTextChanged(Editable s) {
72 |
73 | }
74 | });
75 | }
76 |
77 | private void setToolbar() {
78 | Toolbar toolbar = (Toolbar) findViewById(R.id.tool_bar);
79 | setSupportActionBar(toolbar);
80 | getSupportActionBar().setDisplayShowTitleEnabled(false);
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_register_phone_number.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
19 |
20 |
29 |
30 |
37 |
38 |
44 |
45 |
51 |
52 |
62 |
63 |
64 |
65 |
75 |
76 |
84 |
85 |
86 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
18 |
19 |
27 |
28 |
32 |
33 |
39 |
40 |
45 |
46 |
47 |
48 |
49 |
50 |
54 |
55 |
65 |
66 |
70 |
71 |
72 |
82 |
83 |
87 |
88 |
97 |
98 |
99 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_chat.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
17 |
18 |
27 |
28 |
35 |
36 |
42 |
43 |
52 |
53 |
54 |
55 |
56 |
57 |
61 |
62 |
67 |
68 |
73 |
74 |
75 |
76 |
77 |
82 |
83 |
84 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/whatsapp/ContactAdapter.java:
--------------------------------------------------------------------------------
1 | package com.example.whatsapp;
2 |
3 | import android.content.Context;
4 | import android.content.Intent;
5 | import android.graphics.Bitmap;
6 | import android.support.annotation.NonNull;
7 | import android.support.annotation.Nullable;
8 | import android.view.LayoutInflater;
9 | import android.view.View;
10 | import android.view.ViewGroup;
11 | import android.widget.ArrayAdapter;
12 | import android.widget.Filter;
13 | import android.widget.LinearLayout;
14 | import android.widget.TextView;
15 |
16 | import java.io.File;
17 | import java.util.ArrayList;
18 |
19 | import de.hdodenhof.circleimageview.CircleImageView;
20 |
21 | /**
22 | * Created by farha on 09-Nov-17.
23 | */
24 |
25 | public class ContactAdapter extends ArrayAdapter {
26 | private ArrayList items;
27 | private ArrayList filteredItems;
28 | private LayoutInflater inflater;
29 | private Filter filter;
30 |
31 | public ContactAdapter(Context context, ArrayList items) {
32 | super(context, 0, items);
33 | this.items = items;
34 | this.filteredItems = items;
35 | inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
36 | }
37 |
38 | @Nullable
39 | @Override
40 | public ContactCell getItem(int position) {
41 | return filteredItems.get(position);
42 | }
43 |
44 | @Override
45 | public int getCount() {
46 | return filteredItems.size();
47 | }
48 |
49 | @NonNull
50 | @Override
51 | public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
52 | ContactCell cell = getItem(position);
53 |
54 | if (convertView == null) {
55 | convertView = inflater.inflate(R.layout.contact_cell, null);
56 | }
57 |
58 | CircleImageView photoImageView = (CircleImageView) convertView.findViewById(R.id.photo);
59 | LinearLayout layout = (LinearLayout) convertView.findViewById(R.id.layout);
60 | TextView nameTextView = (TextView) convertView.findViewById(R.id.person);
61 | TextView statusTextView = (TextView) convertView.findViewById(R.id.status);
62 |
63 | if(cell.getPhoto() == null) {
64 | photoImageView.setImageResource(R.drawable.account);
65 | } else {
66 | //photoImageView.setImageURI(cell.getPhoto());
67 | Bitmap bitmap = RegisterPhoneNumber.HelperClass.decodeBitmapFromFile(new File(cell.getPhoto().toString()), 100, 100);
68 | photoImageView.setImageBitmap(bitmap);
69 | }
70 | nameTextView.setText(cell.getName());
71 | statusTextView.setText(cell.getStatus());
72 |
73 | layout.setTag(cell);
74 |
75 | layout.setOnClickListener(new View.OnClickListener() {
76 | @Override
77 | public void onClick(View v) {
78 | ContactCell contactCell = (ContactCell) v.getTag();
79 | Intent intent = new Intent(getContext(), UserDetailsScreen.class);
80 | intent.putExtra("name", contactCell.getName());
81 | intent.putExtra("phone", contactCell.getPhone());
82 | getContext().startActivity(intent);
83 | }
84 | });
85 |
86 | return convertView;
87 | }
88 |
89 | @NonNull
90 | @Override
91 | public Filter getFilter() {
92 | if(filter == null) {
93 | filter = new ContactFilter();
94 | }
95 | return filter;
96 | }
97 |
98 | private class ContactFilter extends Filter {
99 | @Override
100 | protected FilterResults performFiltering(CharSequence constraint) {
101 | FilterResults results = new FilterResults();
102 | if(constraint != null && constraint.length() > 0) {
103 | ArrayList filteredList = new ArrayList<>();
104 | for(ContactCell cell : items) {
105 | if(cell.getName().toLowerCase().contains(constraint.toString().toLowerCase())) {
106 | filteredList.add(cell);
107 | }
108 | }
109 | results.count = filteredList.size();
110 | results.values = filteredList;
111 | }
112 | else {
113 | results.count = items.size();
114 | results.values = items;
115 | }
116 | return results;
117 | }
118 |
119 | @Override
120 | protected void publishResults(CharSequence constraint, FilterResults results) {
121 | filteredItems = (ArrayList) results.values;
122 | notifyDataSetChanged();
123 | }
124 | }
125 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/example/whatsapp/ContactAdapter2.java:
--------------------------------------------------------------------------------
1 | package com.example.whatsapp;
2 |
3 | import android.content.Context;
4 | import android.content.Intent;
5 | import android.graphics.Bitmap;
6 | import android.support.annotation.NonNull;
7 | import android.support.annotation.Nullable;
8 | import android.view.LayoutInflater;
9 | import android.view.View;
10 | import android.view.ViewGroup;
11 | import android.widget.ArrayAdapter;
12 | import android.widget.Filter;
13 | import android.widget.LinearLayout;
14 | import android.widget.TextView;
15 |
16 | import java.io.File;
17 | import java.util.ArrayList;
18 |
19 | import de.hdodenhof.circleimageview.CircleImageView;
20 |
21 | /**
22 | * Created by farha on 27-Nov-17.
23 | */
24 |
25 | public class ContactAdapter2 extends ArrayAdapter {
26 | private ArrayList items;
27 | private ArrayList filteredItems;
28 | private LayoutInflater inflater;
29 | private Filter filter;
30 |
31 | public ContactAdapter2(Context context, ArrayList items) {
32 | super(context, 0, items);
33 | this.items = items;
34 | this.filteredItems = items;
35 | inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
36 | }
37 |
38 | @Nullable
39 | @Override
40 | public ContactCell getItem(int position) {
41 | return filteredItems.get(position);
42 | }
43 |
44 | @Override
45 | public int getCount() {
46 | return filteredItems.size();
47 | }
48 |
49 | @NonNull
50 | @Override
51 | public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
52 | ContactCell cell = getItem(position);
53 |
54 | if (convertView == null) {
55 | convertView = inflater.inflate(R.layout.contact_cell, null);
56 | }
57 |
58 | CircleImageView photoImageView = (CircleImageView) convertView.findViewById(R.id.photo);
59 | LinearLayout layout = (LinearLayout) convertView.findViewById(R.id.layout);
60 | TextView nameTextView = (TextView) convertView.findViewById(R.id.person);
61 | TextView statusTextView = (TextView) convertView.findViewById(R.id.status);
62 |
63 | if(cell.getPhoto() == null) {
64 | photoImageView.setImageResource(R.drawable.account);
65 | } else {
66 | //photoImageView.setImageURI(cell.getPhoto());
67 | Bitmap bitmap = RegisterPhoneNumber.HelperClass.decodeBitmapFromFile(new File(cell.getPhoto().toString()), 100, 100);
68 | photoImageView.setImageBitmap(bitmap);
69 | }
70 | nameTextView.setText(cell.getName());
71 | statusTextView.setText(cell.getStatus());
72 |
73 | layout.setTag(cell);
74 |
75 | layout.setOnClickListener(new View.OnClickListener() {
76 | @Override
77 | public void onClick(View v) {
78 | ContactCell contactCell = (ContactCell) v.getTag();
79 | Intent intent = new Intent(getContext(), MessageActivity.class);
80 | intent.putExtra("name", contactCell.getName());
81 | intent.putExtra("phone", contactCell.getPhone());
82 | getContext().startActivity(intent);
83 | }
84 | });
85 |
86 | return convertView;
87 | }
88 |
89 | @NonNull
90 | @Override
91 | public Filter getFilter() {
92 | if(filter == null) {
93 | filter = new ContactFilter();
94 | }
95 | return filter;
96 | }
97 |
98 | private class ContactFilter extends Filter {
99 | @Override
100 | protected FilterResults performFiltering(CharSequence constraint) {
101 | FilterResults results = new FilterResults();
102 | if(constraint != null && constraint.length() > 0) {
103 | ArrayList filteredList = new ArrayList<>();
104 | for(ContactCell cell : items) {
105 | if(cell.getName().toLowerCase().contains(constraint.toString().toLowerCase())) {
106 | filteredList.add(cell);
107 | }
108 | }
109 | results.count = filteredList.size();
110 | results.values = filteredList;
111 | }
112 | else {
113 | results.count = items.size();
114 | results.values = items;
115 | }
116 | return results;
117 | }
118 |
119 | @Override
120 | protected void publishResults(CharSequence constraint, FilterResults results) {
121 | filteredItems = (ArrayList) results.values;
122 | notifyDataSetChanged();
123 | }
124 | }
125 | }
126 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/whatsapp/VerifyPhoneNumberActivity.java:
--------------------------------------------------------------------------------
1 | package com.example.whatsapp;
2 |
3 | import android.content.Intent;
4 | import android.support.annotation.NonNull;
5 | import android.support.v7.app.AppCompatActivity;
6 | import android.os.Bundle;
7 | import android.text.Editable;
8 | import android.text.TextWatcher;
9 | import android.view.View;
10 | import android.widget.EditText;
11 | import android.widget.TextView;
12 | import android.widget.Toast;
13 |
14 | import com.google.android.gms.tasks.OnCompleteListener;
15 | import com.google.android.gms.tasks.OnFailureListener;
16 | import com.google.android.gms.tasks.OnSuccessListener;
17 | import com.google.android.gms.tasks.Task;
18 | import com.google.firebase.FirebaseException;
19 | import com.google.firebase.auth.AuthResult;
20 | import com.google.firebase.auth.FirebaseAuth;
21 | import com.google.firebase.auth.PhoneAuthCredential;
22 | import com.google.firebase.auth.PhoneAuthProvider;
23 | import com.google.firebase.database.DatabaseReference;
24 | import com.google.firebase.database.FirebaseDatabase;
25 |
26 | import java.util.HashMap;
27 | import java.util.Map;
28 | import java.util.concurrent.TimeUnit;
29 |
30 | public class VerifyPhoneNumberActivity extends AppCompatActivity {
31 | private DatabaseReference mDatabase;
32 | FirebaseAuth mAuth;
33 | private static String code = "";
34 |
35 | @Override
36 | protected void onCreate(Bundle savedInstanceState) {
37 | super.onCreate(savedInstanceState);
38 | setContentView(R.layout.activity_verify_phone_number);
39 | mDatabase = FirebaseDatabase.getInstance().getReference();
40 | mAuth = FirebaseAuth.getInstance();
41 |
42 | Intent intent = getIntent();
43 | final String string = (String) intent.getSerializableExtra("phone");
44 | TextView verify = (TextView) findViewById(R.id.verify);
45 | verify.setText("Verify " + string);
46 | TextView phone = (TextView) findViewById(R.id.phone);
47 | phone.setText(string);
48 |
49 | EditText text = (EditText) findViewById(R.id.code);
50 | text.addTextChangedListener(new TextWatcher() {
51 | @Override
52 | public void beforeTextChanged(CharSequence s, int start, int count, int after) {
53 |
54 | }
55 |
56 | @Override
57 | public void onTextChanged(CharSequence s, int start, int before, int count) {
58 |
59 | }
60 |
61 | @Override
62 | public void afterTextChanged(Editable s) {
63 | if(s.length() == 6) {
64 | PhoneAuthCredential credential = PhoneAuthProvider.getCredential(code, s.toString());
65 | mAuth.signInWithCredential(credential).addOnSuccessListener(new OnSuccessListener() {
66 | @Override
67 | public void onSuccess(AuthResult authResult) {
68 | Intent intent = new Intent(VerifyPhoneNumberActivity.this, SetProfileData.class);
69 | intent.putExtra("phone", string);
70 | startActivity(intent);
71 | finish();
72 | }
73 | }).addOnFailureListener(new OnFailureListener() {
74 | @Override
75 | public void onFailure(@NonNull Exception e) {
76 | Toast.makeText(VerifyPhoneNumberActivity.this, e.getMessage(), Toast.LENGTH_SHORT).show();
77 | }
78 | });
79 | }
80 | }
81 | });
82 |
83 | PhoneAuthProvider.getInstance().verifyPhoneNumber(string, 60, TimeUnit.SECONDS, this,
84 | new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
85 | @Override
86 | public void onVerificationCompleted(PhoneAuthCredential credential) {
87 | mAuth.signInWithCredential(credential).addOnCompleteListener(VerifyPhoneNumberActivity.this,
88 | new OnCompleteListener() {
89 | @Override
90 | public void onComplete(@NonNull Task task) {
91 | Intent intent = new Intent(VerifyPhoneNumberActivity.this, SetProfileData.class);
92 | intent.putExtra("phone", string);
93 | startActivity(intent);
94 | finish();
95 | }
96 | });
97 | }
98 |
99 | @Override
100 | public void onVerificationFailed(FirebaseException e) {
101 | Toast.makeText(VerifyPhoneNumberActivity.this, e.getMessage(), Toast.LENGTH_SHORT).show();
102 | }
103 |
104 | @Override
105 | public void onCodeSent(String s, PhoneAuthProvider.ForceResendingToken forceResendingToken) {
106 | super.onCodeSent(s, forceResendingToken);
107 | code = s;
108 | }
109 | });
110 | }
111 |
112 | public void wrongNumber(View view) {
113 | onBackPressed();
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # Attempt to set APP_HOME
46 | # Resolve links: $0 may be a link
47 | PRG="$0"
48 | # Need this for relative symlinks.
49 | while [ -h "$PRG" ] ; do
50 | ls=`ls -ld "$PRG"`
51 | link=`expr "$ls" : '.*-> \(.*\)$'`
52 | if expr "$link" : '/.*' > /dev/null; then
53 | PRG="$link"
54 | else
55 | PRG=`dirname "$PRG"`"/$link"
56 | fi
57 | done
58 | SAVED="`pwd`"
59 | cd "`dirname \"$PRG\"`/" >/dev/null
60 | APP_HOME="`pwd -P`"
61 | cd "$SAVED" >/dev/null
62 |
63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
64 |
65 | # Determine the Java command to use to start the JVM.
66 | if [ -n "$JAVA_HOME" ] ; then
67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
68 | # IBM's JDK on AIX uses strange locations for the executables
69 | JAVACMD="$JAVA_HOME/jre/sh/java"
70 | else
71 | JAVACMD="$JAVA_HOME/bin/java"
72 | fi
73 | if [ ! -x "$JAVACMD" ] ; then
74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
75 |
76 | Please set the JAVA_HOME variable in your environment to match the
77 | location of your Java installation."
78 | fi
79 | else
80 | JAVACMD="java"
81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
82 |
83 | Please set the JAVA_HOME variable in your environment to match the
84 | location of your Java installation."
85 | fi
86 |
87 | # Increase the maximum file descriptors if we can.
88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
89 | MAX_FD_LIMIT=`ulimit -H -n`
90 | if [ $? -eq 0 ] ; then
91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
92 | MAX_FD="$MAX_FD_LIMIT"
93 | fi
94 | ulimit -n $MAX_FD
95 | if [ $? -ne 0 ] ; then
96 | warn "Could not set maximum file descriptor limit: $MAX_FD"
97 | fi
98 | else
99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
100 | fi
101 | fi
102 |
103 | # For Darwin, add options to specify how the application appears in the dock
104 | if $darwin; then
105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
106 | fi
107 |
108 | # For Cygwin, switch paths to Windows format before running java
109 | if $cygwin ; then
110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
112 | JAVACMD=`cygpath --unix "$JAVACMD"`
113 |
114 | # We build the pattern for arguments to be converted via cygpath
115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
116 | SEP=""
117 | for dir in $ROOTDIRSRAW ; do
118 | ROOTDIRS="$ROOTDIRS$SEP$dir"
119 | SEP="|"
120 | done
121 | OURCYGPATTERN="(^($ROOTDIRS))"
122 | # Add a user-defined pattern to the cygpath arguments
123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
125 | fi
126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
127 | i=0
128 | for arg in "$@" ; do
129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
131 |
132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
134 | else
135 | eval `echo args$i`="\"$arg\""
136 | fi
137 | i=$((i+1))
138 | done
139 | case $i in
140 | (0) set -- ;;
141 | (1) set -- "$args0" ;;
142 | (2) set -- "$args0" "$args1" ;;
143 | (3) set -- "$args0" "$args1" "$args2" ;;
144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
150 | esac
151 | fi
152 |
153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
154 | function splitJvmOpts() {
155 | JVM_OPTS=("$@")
156 | }
157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
159 |
160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
161 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_user_details_screen.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
13 |
14 |
17 |
18 |
27 |
28 |
42 |
43 |
44 |
45 |
52 |
53 |
62 |
63 |
71 |
72 |
80 |
81 |
89 |
90 |
96 |
97 |
101 |
102 |
103 |
104 |
105 |
106 |
116 |
117 |
123 |
124 |
127 |
128 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/whatsapp/UserDetailsScreen.java:
--------------------------------------------------------------------------------
1 | package com.example.whatsapp;
2 |
3 | import android.content.ContextWrapper;
4 | import android.content.Intent;
5 | import android.content.res.Resources;
6 | import android.graphics.Bitmap;
7 | import android.graphics.BitmapFactory;
8 | import android.graphics.BitmapRegionDecoder;
9 | import android.graphics.Rect;
10 | import android.net.Uri;
11 | import android.support.v7.app.AppCompatActivity;
12 | import android.os.Bundle;
13 | import android.support.v7.widget.Toolbar;
14 | import android.util.TypedValue;
15 | import android.view.View;
16 | import android.view.ViewGroup;
17 | import android.widget.AbsListView;
18 | import android.widget.ImageView;
19 | import android.widget.LinearLayout;
20 | import android.widget.TextView;
21 | import android.widget.Toast;
22 |
23 | import com.google.firebase.auth.FirebaseAuth;
24 | import com.google.firebase.database.DataSnapshot;
25 | import com.google.firebase.database.DatabaseError;
26 | import com.google.firebase.database.FirebaseDatabase;
27 | import com.google.firebase.database.ValueEventListener;
28 |
29 | import java.io.File;
30 |
31 | public class UserDetailsScreen extends AppCompatActivity {
32 |
33 | private String phone;
34 | private String name;
35 | private File image;
36 |
37 | @Override
38 | protected void onCreate(Bundle savedInstanceState) {
39 | super.onCreate(savedInstanceState);
40 | setContentView(R.layout.activity_user_details_screen);
41 |
42 | Intent intent = getIntent();
43 | name = (String) intent.getSerializableExtra("name");
44 | phone = (String)intent.getSerializableExtra("phone");
45 |
46 | TextView textView = (TextView) findViewById(R.id.name);
47 | textView.setText(name);
48 | textView = (TextView) findViewById(R.id.phone);
49 | textView.setText(phone);
50 |
51 | final TextView status = (TextView) findViewById(R.id.status);
52 | status.setText("");
53 |
54 | FirebaseDatabase.getInstance().getReference("users").child(phone).addValueEventListener(new ValueEventListener() {
55 | @Override
56 | public void onDataChange(DataSnapshot dataSnapshot) {
57 | try {
58 | status.setText(dataSnapshot.child("status").getValue(String.class));
59 | }
60 | catch (Exception ex) {}
61 | }
62 |
63 | @Override
64 | public void onCancelled(DatabaseError databaseError) {
65 |
66 | }
67 | });
68 |
69 | ImageView imageView = (ImageView) findViewById(R.id.contact_image);
70 | ContextWrapper wrapper = new ContextWrapper(getApplicationContext());
71 | File file = wrapper.getDir("profilePictures",MODE_PRIVATE);
72 | file = new File(file, phone + ".jpg");
73 | image = file;
74 | if(file.exists()) {
75 | imageView.setImageURI(Uri.parse(file.getAbsolutePath()));
76 | }
77 |
78 | setMedia();
79 | }
80 |
81 | private void setMedia() {
82 | FirebaseDatabase.getInstance().getReference("messages").child(FirebaseAuth.getInstance().getCurrentUser().getPhoneNumber() + " " + phone).addListenerForSingleValueEvent(new ValueEventListener() {
83 | @Override
84 | public void onDataChange(DataSnapshot dataSnapshot) {
85 | int i = 0;
86 | LinearLayout linearLayout = (LinearLayout) findViewById(R.id.media);
87 | ContextWrapper wrapper = new ContextWrapper(getApplicationContext());
88 | File file = wrapper.getDir(phone,MODE_PRIVATE);
89 | for(DataSnapshot ds : dataSnapshot.getChildren()) {
90 | if(ds.child("type").getValue(String.class).equals("image")) {
91 | String[] key = ds.getKey().split(" ");
92 | File file1 = new File(file, key[2] + " " + key[0] + " " + key[1] + ".jpg");
93 | if(file1.exists()) {
94 | i++;
95 | ImageView imageView = new ImageView(UserDetailsScreen.this);
96 | AbsListView.LayoutParams layoutParams = new AbsListView.LayoutParams(200, 200);
97 | imageView.setLayoutParams(layoutParams);
98 | imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
99 | imageView.setTag(file1.getAbsolutePath());
100 | imageView.setImageURI(Uri.parse(file1.getAbsolutePath()));
101 | imageView.setPadding(5, 5, 5, 5);
102 | imageView.setOnClickListener(new View.OnClickListener() {
103 | @Override
104 | public void onClick(View v) {
105 | String s = (String) v.getTag();
106 | if(s != null && new File(s).exists()) {
107 | Intent intent = new Intent(UserDetailsScreen.this, ShowImage.class);
108 | intent.putExtra("image", s);
109 | startActivity(intent);
110 | }
111 | }
112 | });
113 | linearLayout.addView(imageView);
114 | }
115 | }
116 | }
117 | if(i == 0) {
118 | ((LinearLayout) findViewById(R.id.media_parent)).setVisibility(View.GONE);
119 | }
120 | }
121 |
122 | @Override
123 | public void onCancelled(DatabaseError databaseError) {
124 |
125 | }
126 | });
127 | }
128 |
129 | public void imageClicked(View view) {
130 | if(image.exists()) {
131 | Intent intent = new Intent(this, ShowImage.class);
132 | intent.putExtra("image", image.getAbsolutePath());
133 | startActivity(intent);
134 | }
135 | }
136 | }
137 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
10 |
15 |
20 |
25 |
30 |
35 |
40 |
45 |
50 |
55 |
60 |
65 |
70 |
75 |
80 |
85 |
90 |
95 |
100 |
105 |
110 |
115 |
120 |
125 |
130 |
135 |
140 |
145 |
150 |
155 |
160 |
165 |
170 |
171 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/whatsapp/SetProfileData.java:
--------------------------------------------------------------------------------
1 | package com.example.whatsapp;
2 |
3 | import android.app.ProgressDialog;
4 | import android.content.ContextWrapper;
5 | import android.content.Intent;
6 | import android.graphics.Bitmap;
7 | import android.graphics.drawable.BitmapDrawable;
8 | import android.graphics.drawable.Drawable;
9 | import android.net.Uri;
10 | import android.support.annotation.NonNull;
11 | import android.support.v7.app.AppCompatActivity;
12 | import android.os.Bundle;
13 | import android.view.View;
14 | import android.widget.EditText;
15 | import android.widget.Toast;
16 |
17 | import com.google.android.gms.tasks.OnFailureListener;
18 | import com.google.android.gms.tasks.OnSuccessListener;
19 | import com.google.firebase.auth.FirebaseAuth;
20 | import com.google.firebase.auth.PhoneAuthCredential;
21 | import com.google.firebase.database.DatabaseReference;
22 | import com.google.firebase.database.FirebaseDatabase;
23 | import com.google.firebase.storage.FirebaseStorage;
24 | import com.google.firebase.storage.StorageReference;
25 | import com.google.firebase.storage.UploadTask;
26 |
27 | import java.io.ByteArrayOutputStream;
28 | import java.io.File;
29 | import java.io.FileOutputStream;
30 | import java.io.OutputStream;
31 | import java.util.HashMap;
32 | import java.util.Map;
33 |
34 | import de.hdodenhof.circleimageview.CircleImageView;
35 |
36 | public class SetProfileData extends AppCompatActivity {
37 | private EditText name;
38 | private CircleImageView imageView;
39 | private DatabaseReference mDatabase;
40 | String phone;
41 | private StorageReference storageRef;
42 |
43 | @Override
44 | protected void onCreate(Bundle savedInstanceState) {
45 | super.onCreate(savedInstanceState);
46 | setContentView(R.layout.activity_set_profile_data);
47 | mDatabase = FirebaseDatabase.getInstance().getReference();
48 | storageRef = FirebaseStorage.getInstance().getReference();
49 | Intent intent = getIntent();
50 | phone = (String) intent.getSerializableExtra("phone");
51 | name = (EditText) findViewById(R.id.name);
52 | imageView = (CircleImageView) findViewById(R.id.photo);
53 | imageView.setOnClickListener(new View.OnClickListener() {
54 | @Override
55 | public void onClick(View v) {
56 | Intent gallery = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.INTERNAL_CONTENT_URI);
57 | startActivityForResult(gallery, 1);
58 | }
59 | });
60 | }
61 |
62 | public void nextButton(View view) {
63 | BitmapDrawable drawable = (BitmapDrawable) imageView.getDrawable();
64 | if(drawable == null) {
65 | Toast.makeText(this, "Must attach a Profile Photo", Toast.LENGTH_SHORT).show();
66 | return;
67 | }
68 | final Bitmap photo = drawable.getBitmap();
69 | final String nam = name.getText().toString();
70 | if(nam.length() == 0) {
71 | Toast.makeText(this, "Must input Name", Toast.LENGTH_SHORT).show();
72 | return;
73 | }
74 |
75 | StorageReference reference = storageRef.child("profilePictures/" + phone + ".jpg");
76 | ByteArrayOutputStream baos = new ByteArrayOutputStream();
77 | try {
78 | photo.compress(Bitmap.CompressFormat.JPEG, 100, baos);
79 | byte[] data = baos.toByteArray();
80 |
81 | final ProgressDialog dialog = ProgressDialog.show(this, "Please wait", "Uploading Image...", true);
82 | UploadTask uploadTask = reference.putBytes(data);
83 | uploadTask.addOnFailureListener(new OnFailureListener() {
84 | @Override
85 | public void onFailure(@NonNull Exception exception) {
86 | Toast.makeText(SetProfileData.this, exception.getMessage(), Toast.LENGTH_SHORT).show();
87 | }
88 | }).addOnSuccessListener(new OnSuccessListener() {
89 | @Override
90 | public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
91 | ContextWrapper wrapper = new ContextWrapper(getApplicationContext());
92 | File file = wrapper.getDir("profilePictures",MODE_PRIVATE);
93 | file = new File(file, FirebaseAuth.getInstance().getCurrentUser().getPhoneNumber() + ".jpg");
94 | OutputStream stream = null;
95 | try {
96 | stream = new FileOutputStream(file);
97 | photo.compress(Bitmap.CompressFormat.JPEG,100,stream);
98 | }
99 | catch (Exception ex) {
100 | Toast.makeText(SetProfileData.this, ex.getMessage(), Toast.LENGTH_SHORT).show();
101 | }
102 | finally {
103 | try {
104 | dialog.dismiss();
105 | stream.flush();
106 | stream.close();
107 | }catch (Exception ex) {}
108 | }
109 | Map map = new HashMap<>();
110 | map.put("name", nam);
111 | map.put("status", "Available");
112 | DatabaseReference reference1 = mDatabase.child("users").child(phone);
113 |
114 | reference1.child("name").setValue(null);
115 | reference1.child("status").setValue(null);
116 | mDatabase.child("users").child(phone).setValue(map);
117 | startActivity(new Intent(SetProfileData.this, ChatActivity.class));
118 | finish();
119 | }
120 | });
121 | }
122 | catch (Exception ex) {
123 | Toast.makeText(SetProfileData.this, ex.getMessage(), Toast.LENGTH_SHORT).show();
124 | }
125 | }
126 |
127 | @Override
128 | protected void onActivityResult(int requestCode, int resultCode, Intent data) {
129 | super.onActivityResult(requestCode, resultCode, data);
130 |
131 | if(resultCode == RESULT_OK) {
132 | if(requestCode == 1) {
133 | Uri imageUri = data.getData();
134 | imageView.setImageURI(imageUri);
135 | }
136 | }
137 | }
138 | }
139 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/whatsapp/ChatAdapter.java:
--------------------------------------------------------------------------------
1 | package com.example.whatsapp;
2 |
3 | import android.content.Context;
4 | import android.content.Intent;
5 | import android.graphics.Bitmap;
6 | import android.support.annotation.NonNull;
7 | import android.support.annotation.Nullable;
8 | import android.view.LayoutInflater;
9 | import android.view.View;
10 | import android.view.ViewGroup;
11 | import android.widget.ArrayAdapter;
12 | import android.widget.Filter;
13 | import android.widget.Filterable;
14 | import android.widget.LinearLayout;
15 | import android.widget.TextView;
16 |
17 | import java.io.File;
18 | import java.util.ArrayList;
19 | import de.hdodenhof.circleimageview.CircleImageView;
20 |
21 | /**
22 | * Created by farha on 07-Nov-17.
23 | */
24 |
25 | public class ChatAdapter extends ArrayAdapter implements Filterable{
26 | private ArrayList items;
27 | private ArrayList filteredItems;
28 | private LayoutInflater inflater;
29 | private Filter filter;
30 |
31 | public ChatAdapter(Context context, ArrayList items) {
32 | super(context, 0, items);
33 | this.items = items;
34 | filteredItems = items;
35 | inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
36 | }
37 |
38 | @Nullable
39 | @Override
40 | public PersonCell getItem(int position) {
41 | return filteredItems.get(position);
42 | }
43 |
44 | @Override
45 | public int getCount() {
46 | return filteredItems.size();
47 | }
48 |
49 | @NonNull
50 | @Override
51 | public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
52 | final PersonCell cell = getItem(position);
53 | ChatActivity.ViewHolder holder;
54 |
55 | if (convertView == null) {
56 | convertView = inflater.inflate(R.layout.person_cell, null);
57 | holder = new ChatActivity.ViewHolder();
58 | holder.photoImageView = (CircleImageView) convertView.findViewById(R.id.photo);
59 | holder.layout = (LinearLayout) convertView.findViewById(R.id.layout);
60 | holder.nameTextView = (TextView) convertView.findViewById(R.id.person);
61 | holder.lastMessageTextView = (TextView) convertView.findViewById(R.id.lastmessage);
62 | holder.dateTextView = (TextView) convertView.findViewById(R.id.date);
63 | convertView.setTag(holder);
64 | }
65 | else {
66 | holder = (ChatActivity.ViewHolder) convertView.getTag();
67 | }
68 |
69 | if(cell.getPhoto() == null) {
70 | holder.photoImageView.setImageResource(R.drawable.account);
71 | }
72 | else {
73 | //holder.photoImageView.setImageURI(cell.getPhoto());
74 | Bitmap bitmap = RegisterPhoneNumber.HelperClass.decodeBitmapFromFile(new File(cell.getPhoto().toString()), 50, 50);
75 | holder.photoImageView.setImageBitmap(bitmap);
76 | }
77 | holder.nameTextView.setText(cell.getName());
78 | holder.lastMessageTextView.setText(cell.getLastMessage());
79 | holder.dateTextView.setText(cell.getDate());
80 |
81 | holder.photoImageView.setTag(cell);
82 | holder.layout.setTag(cell);
83 | holder.dateTextView.setTag(cell);
84 |
85 | holder.photoImageView.setOnClickListener(new View.OnClickListener() {
86 | @Override
87 | public void onClick(View v) {
88 | PersonCell personCell = (PersonCell) v.getTag();
89 | Intent intent = new Intent(getContext(), UserDetailsScreen.class);
90 | intent.putExtra("name", personCell.getName());
91 | intent.putExtra("phone", personCell.getPhone());
92 | getContext().startActivity(intent);
93 | }
94 | });
95 |
96 | holder.layout.setOnClickListener(new View.OnClickListener() {
97 | @Override
98 | public void onClick(View v) {
99 | PersonCell personCell = (PersonCell) v.getTag();
100 | Intent intent = new Intent(getContext(), MessageActivity.class);
101 | intent.putExtra("name", personCell.getName());
102 | intent.putExtra("phone", personCell.getPhone());
103 | getContext().startActivity(intent);
104 | }
105 | });
106 |
107 | holder.dateTextView.setOnClickListener(new View.OnClickListener() {
108 | @Override
109 | public void onClick(View v) {
110 | PersonCell personCell = (PersonCell) v.getTag();
111 | Intent intent = new Intent(getContext(), MessageActivity.class);
112 | intent.putExtra("name", personCell.getName());
113 | intent.putExtra("phone", personCell.getPhone());
114 | getContext().startActivity(intent);
115 | }
116 | });
117 |
118 | return convertView;
119 | }
120 |
121 | @NonNull
122 | @Override
123 | public Filter getFilter() {
124 | if(filter == null) {
125 | filter = new PersonFilter();
126 | }
127 | return filter;
128 | }
129 |
130 | private class PersonFilter extends Filter {
131 | @Override
132 | protected FilterResults performFiltering(CharSequence constraint) {
133 | FilterResults results = new FilterResults();
134 | if(constraint != null && constraint.length() > 0) {
135 | ArrayList filteredList = new ArrayList<>();
136 | for(PersonCell cell : items) {
137 | if(cell.getName().toLowerCase().contains(constraint.toString().toLowerCase())) {
138 | filteredList.add(cell);
139 | }
140 | }
141 | results.count = filteredList.size();
142 | results.values = filteredList;
143 | }
144 | else {
145 | results.count = items.size();
146 | results.values = items;
147 | }
148 | return results;
149 | }
150 |
151 | @Override
152 | protected void publishResults(CharSequence constraint, FilterResults results) {
153 | filteredItems = (ArrayList) results.values;
154 | notifyDataSetChanged();
155 | }
156 | }
157 | }
158 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/whatsapp/RegisterPhoneNumber.java:
--------------------------------------------------------------------------------
1 | package com.example.whatsapp;
2 |
3 | import android.*;
4 | import android.Manifest;
5 | import android.content.Context;
6 | import android.content.Intent;
7 | import android.content.pm.PackageManager;
8 | import android.content.res.Resources;
9 | import android.graphics.Bitmap;
10 | import android.graphics.BitmapFactory;
11 | import android.support.annotation.NonNull;
12 | import android.support.v4.app.ActivityCompat;
13 | import android.support.v4.content.ContextCompat;
14 | import android.support.v7.app.AppCompatActivity;
15 | import android.os.Bundle;
16 | import android.telephony.TelephonyManager;
17 | import android.util.Log;
18 | import android.view.View;
19 | import android.widget.AdapterView;
20 | import android.widget.ArrayAdapter;
21 | import android.widget.EditText;
22 | import android.widget.Spinner;
23 | import android.widget.TextView;
24 |
25 | import com.google.firebase.FirebaseException;
26 | import com.google.firebase.auth.FirebaseAuth;
27 | import com.google.firebase.auth.PhoneAuthCredential;
28 | import com.google.firebase.auth.PhoneAuthProvider;
29 | import com.google.firebase.database.FirebaseDatabase;
30 | import com.google.firebase.storage.FirebaseStorage;
31 |
32 | import java.io.File;
33 | import java.util.ArrayList;
34 | import java.util.Locale;
35 | import java.util.concurrent.TimeUnit;
36 |
37 | import static android.R.attr.phoneNumber;
38 |
39 | public class RegisterPhoneNumber extends AppCompatActivity {
40 |
41 | private String[] locales;
42 |
43 | FirebaseAuth mAuth;
44 |
45 | @Override
46 | protected void onCreate(Bundle savedInstanceState) {
47 | super.onCreate(savedInstanceState);
48 | setContentView(R.layout.activity_register_phone_number);
49 |
50 | try {
51 | FirebaseDatabase.getInstance().setPersistenceEnabled(true);
52 | FirebaseDatabase.getInstance().getReference("users").keepSynced(true);
53 | FirebaseDatabase.getInstance().getReference("inviteLink").keepSynced(true);
54 | }
55 | catch (Exception ex) {}
56 |
57 | //FirebaseDatabase.getInstance().getReference("inviteLink").setValue("abc");
58 |
59 | mAuth = FirebaseAuth.getInstance();
60 | if(mAuth.getCurrentUser() != null) {
61 | startActivity(new Intent(this, ChatActivity.class));
62 | finish();
63 | }
64 |
65 | createCountryDropDownMenu();
66 |
67 | if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
68 | ActivityCompat.requestPermissions(this,
69 | new String[]{Manifest.permission.READ_CONTACTS},
70 | 1);
71 | }
72 | }
73 |
74 | @Override
75 | public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
76 | switch (requestCode) {
77 | case 1:
78 | if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){}
79 | else finish();
80 | }
81 | }
82 |
83 | private void createCountryDropDownMenu() {
84 | ArrayList countries= getCountryNames();
85 | ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout.simple_spinner_dropdown_item, countries);
86 |
87 | Spinner countrySpinner = (Spinner) findViewById(R.id.country);
88 | countrySpinner.setAdapter(adapter);
89 |
90 | countrySpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
91 | @Override
92 | public void onItemSelected(AdapterView> parent, View view, int position, long id) {
93 | String CountryID= locales[position];
94 | String[] rl = getResources().getStringArray(R.array.CountryCodes);
95 | for(String x : rl){
96 | String[] g = x.split(",");
97 | if(g[1].trim().equals(CountryID.trim())){
98 | TextView textView = (TextView) findViewById(R.id.countryCode);
99 | textView.setText("+" + g[0]);
100 | return;
101 | }
102 | }
103 | }
104 |
105 | @Override
106 | public void onNothingSelected(AdapterView> parent) {
107 |
108 | }
109 | });
110 | }
111 |
112 | public void nextButton(View view) {
113 | TextView editText1 = (TextView) findViewById(R.id.countryCode);
114 | EditText editText2 = (EditText) findViewById(R.id.phone);
115 |
116 | Intent intent = new Intent(this, VerifyPhoneNumberActivity.class);
117 | intent.putExtra("phone", editText1.getText().toString() + editText2.getText().toString());
118 | startActivity(intent);
119 | }
120 |
121 | public ArrayList getCountryNames() {
122 |
123 | locales = Locale.getISOCountries();
124 | ArrayList countries = new ArrayList<>();
125 |
126 | for (String countryCode : locales) {
127 |
128 | Locale obj = new Locale("", countryCode);
129 | countries.add(obj.getDisplayCountry());
130 | }
131 | return countries;
132 | }
133 |
134 | public static class HelperClass {
135 | public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
136 | final int height = options.outHeight;
137 | final int width = options.outWidth;
138 | int inSampleSize = 1;
139 |
140 | if (height > reqHeight || width > reqWidth) {
141 | final int halfHeight = height / 2;
142 | final int halfWidth = width / 2;
143 |
144 | while ((halfHeight / inSampleSize) >= reqHeight
145 | && (halfWidth / inSampleSize) >= reqWidth) {
146 | inSampleSize *= 2;
147 | }
148 | }
149 | return inSampleSize;
150 | }
151 |
152 | public static Bitmap decodeBitmapFromFile(File file, int reqWidth, int reqHeight) {
153 | final BitmapFactory.Options options = new BitmapFactory.Options();
154 | options.inJustDecodeBounds = true;
155 | try {
156 | BitmapFactory.decodeFile(file.getAbsolutePath(), options);
157 |
158 | // Calculate inSampleSize
159 | options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
160 |
161 | // Decode bitmap with inSampleSize set
162 | options.inJustDecodeBounds = false;
163 | return BitmapFactory.decodeFile(file.getAbsolutePath(), options);
164 | }
165 | catch (Exception ex) {
166 | return null;
167 | }
168 | }
169 | }
170 | }
171 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | WhatsApp
3 |
4 |
5 | - 93,AF
6 | - 355,AL
7 | - 213,DZ
8 | - 376,AD
9 | - 244,AO
10 | - 672,AQ
11 | - 54,AR
12 | - 374,AM
13 | - 297,AW
14 | - 61,AU
15 | - 43,AT
16 | - 994,AZ
17 | - 973,BH
18 | - 880,BD
19 | - 375,BY
20 | - 32,BE
21 | - 501,BZ
22 | - 229,BJ
23 | - 975,BT
24 | - 591,BO
25 | - 387,BA
26 | - 267,BW
27 | - 55,BR
28 | - 673,BN
29 | - 359,BG
30 | - 226,BF
31 | - 95,MM
32 | - 257,BI
33 | - 855,KH
34 | - 237,CM
35 | - 1,CA
36 | - 238,CV
37 | - 236,CF
38 | - 235,TD
39 | - 56,CL
40 | - 86,CN
41 | - 61,CX
42 | - 61,CC
43 | - 57,CO
44 | - 269,KM
45 | - 242,CG
46 | - 243,CD
47 | - 682,CK
48 | - 506,CR
49 | - 385,HR
50 | - 53,CU
51 | - 357,CY
52 | - 420,CZ
53 | - 45,DK
54 | - 253,DJ
55 | - 670,TL
56 | - 593,EC
57 | - 20,EG
58 | - 503,SV
59 | - 240,GQ
60 | - 291,ER
61 | - 372,EE
62 | - 251,ET
63 | - 500,FK
64 | - 298,FO
65 | - 679,FJ
66 | - 358,FI
67 | - 33,FR
68 | - 689,PF
69 | - 241,GA
70 | - 220,GM
71 | - 995,GE
72 | - 49,DE
73 | - 233,GH
74 | - 350,GI
75 | - 30,GR
76 | - 299,GL
77 | - 502,GT
78 | - 224,GN
79 | - 245,GW
80 | - 592,GY
81 | - 509,HT
82 | - 504,HN
83 | - 852,HK
84 | - 36,HU
85 | - 91,IN
86 | - 62,ID
87 | - 98,IR
88 | - 964,IQ
89 | - 353,IE
90 | - 44,IM
91 | - 972,IL
92 | - 39,IT
93 | - 225,CI
94 | - 81,JP
95 | - 962,JO
96 | - 7,KZ
97 | - 254,KE
98 | - 686,KI
99 | - 965,KW
100 | - 996,KG
101 | - 856,LA
102 | - 371,LV
103 | - 961,LB
104 | - 266,LS
105 | - 231,LR
106 | - 218,LY
107 | - 423,LI
108 | - 370,LT
109 | - 352,LU
110 | - 853,MO
111 | - 389,MK
112 | - 261,MG
113 | - 265,MW
114 | - 60,MY
115 | - 960,MV
116 | - 223,ML
117 | - 356,MT
118 | - 692,MH
119 | - 222,MR
120 | - 230,MU
121 | - 262,YT
122 | - 52,MX
123 | - 691,FM
124 | - 373,MD
125 | - 377,MC
126 | - 976,MN
127 | - 382,ME
128 | - 212,MA
129 | - 258,MZ
130 | - 264,NA
131 | - 674,NR
132 | - 977,NP
133 | - 31,NL
134 | - 599,AN
135 | - 687,NC
136 | - 64,NZ
137 | - 505,NI
138 | - 227,NE
139 | - 234,NG
140 | - 683,NU
141 | - 850,KP
142 | - 47,NO
143 | - 968,OM
144 | - 92,PK
145 | - 680,PW
146 | - 507,PA
147 | - 675,PG
148 | - 595,PY
149 | - 51,PE
150 | - 63,PH
151 | - 870,PN
152 | - 48,PL
153 | - 351,PT
154 | - 1,PR
155 | - 974,QA
156 | - 40,RO
157 | - 7,RU
158 | - 250,RW
159 | - 590,BL
160 | - 685,WS
161 | - 378,SM
162 | - 239,ST
163 | - 966,SA
164 | - 221,SN
165 | - 381,RS
166 | - 248,SC
167 | - 232,SL
168 | - 65,SG
169 | - 421,SK
170 | - 386,SI
171 | - 677,SB
172 | - 252,SO
173 | - 27,ZA
174 | - 82,KR
175 | - 34,ES
176 | - 94,LK
177 | - 290,SH
178 | - 508,PM
179 | - 249,SD
180 | - 597,SR
181 | - 268,SZ
182 | - 46,SE
183 | - 41,CH
184 | - 963,SY
185 | - 886,TW
186 | - 992,TJ
187 | - 255,TZ
188 | - 66,TH
189 | - 228,TG
190 | - 690,TK
191 | - 676,TO
192 | - 216,TN
193 | - 90,TR
194 | - 993,TM
195 | - 688,TV
196 | - 971,AE
197 | - 256,UG
198 | - 44,GB
199 | - 380,UA
200 | - 598,UY
201 | - 1,US
202 | - 998,UZ
203 | - 678,VU
204 | - 39,VA
205 | - 58,VE
206 | - 84,VN
207 | - 681,WF
208 | - 967,YE
209 | - 260,ZM
210 | - 263,ZW
211 |
212 |
213 | ChatActivity
214 | CHATS
215 | CONTACTS
216 | Settings
217 | Hello World from section: %1$d
218 |
219 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/whatsapp/MessageAdapter.java:
--------------------------------------------------------------------------------
1 | package com.example.whatsapp;
2 |
3 | import android.content.Context;
4 | import android.content.Intent;
5 | import android.graphics.Bitmap;
6 | import android.net.Uri;
7 | import android.support.annotation.NonNull;
8 | import android.support.annotation.Nullable;
9 | import android.text.method.LinkMovementMethod;
10 | import android.view.LayoutInflater;
11 | import android.view.View;
12 | import android.view.ViewGroup;
13 | import android.widget.ArrayAdapter;
14 | import android.widget.Filter;
15 | import android.widget.Filterable;
16 | import android.widget.ImageView;
17 | import android.widget.LinearLayout;
18 | import android.widget.TextView;
19 | import android.widget.Toast;
20 |
21 | import com.google.firebase.auth.FirebaseAuth;
22 |
23 | import java.io.File;
24 | import java.util.ArrayList;
25 |
26 | /**
27 | * Created by farha on 16-Nov-17.
28 | */
29 |
30 | public class MessageAdapter extends ArrayAdapter implements Filterable {
31 | private Context context;
32 | private ArrayList messages;
33 | private ArrayList filteredMessages;
34 | private Filter filter;
35 |
36 | public MessageAdapter(Context context, ArrayList messages) {
37 | super(context, 0, messages);
38 | this.context = context;
39 | this.messages = messages;
40 | this.filteredMessages = messages;
41 | }
42 |
43 | @Nullable
44 | @Override
45 | public Message getItem(int position) {
46 | return filteredMessages.get(position);
47 | }
48 |
49 | @Override
50 | public int getCount() {
51 | return filteredMessages.size();
52 | }
53 |
54 | @NonNull
55 | @Override
56 | public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
57 | Message message = getItem(position);
58 |
59 | LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
60 |
61 | if(message instanceof TextMessage) {
62 | TextMessage textMessage = (TextMessage) message;
63 | if(textMessage.getSender().equals(FirebaseAuth.getInstance().getCurrentUser().getPhoneNumber())) {
64 | convertView = inflater.inflate(R.layout.sent_text, null);
65 | TextView sentText = (TextView) convertView.findViewById(R.id.sent_text);
66 | sentText.setText(textMessage.getMessage());
67 | if(textMessage.getMessage().contains("http://maps.google.com/maps/api/staticmap?center=")) {
68 | sentText.setMovementMethod(LinkMovementMethod.getInstance());
69 | }
70 | }
71 | else {
72 | convertView = inflater.inflate(R.layout.received_text, null);
73 | TextView receivedText = (TextView) convertView.findViewById(R.id.received_text);
74 | receivedText.setText(textMessage.getMessage());
75 | if(textMessage.getMessage().contains("http://maps.google.com/maps/api/staticmap?center=")) {
76 | receivedText.setMovementMethod(LinkMovementMethod.getInstance());
77 | }
78 | }
79 | }
80 | else {
81 | ImageMessage imageMessage = (ImageMessage) message;
82 | if(imageMessage.getSender().equals(FirebaseAuth.getInstance().getCurrentUser().getPhoneNumber())) {
83 | convertView = inflater.inflate(R.layout.sent_image, null);
84 | ImageView sentImage = (ImageView) convertView.findViewById(R.id.sent_image);
85 | try {
86 | //sentImage.setImageURI(imageMessage.getImageUri());
87 | sentImage.setTag(imageMessage.getImageUri().toString());
88 | Bitmap bitmap = RegisterPhoneNumber.HelperClass.decodeBitmapFromFile(new File(imageMessage.getImageUri().toString()), 150, 150);
89 | sentImage.setImageBitmap(bitmap);
90 | }
91 | catch (Exception ex) {}
92 | sentImage.setOnClickListener(new View.OnClickListener() {
93 | @Override
94 | public void onClick(View v) {
95 | String tag = (String) v.getTag();
96 | if(tag != null && new File(tag).exists()) {
97 | Intent intent = new Intent(getContext(), ShowImage.class);
98 | intent.putExtra("image", tag);
99 | getContext().startActivity(intent);
100 | }
101 | }
102 | });
103 | }
104 | else {
105 | convertView = inflater.inflate(R.layout.received_image, null);
106 | ImageView receivedImage = (ImageView) convertView.findViewById(R.id.received_image);
107 | try {
108 | //receivedImage.setImageURI(imageMessage.getImageUri());
109 | receivedImage.setTag(imageMessage.getImageUri().toString());
110 | Bitmap bitmap = RegisterPhoneNumber.HelperClass.decodeBitmapFromFile(new File(imageMessage.getImageUri().toString()), 150, 150);
111 | receivedImage.setImageBitmap(bitmap);
112 | }
113 | catch (Exception ex) {}
114 | receivedImage.setOnClickListener(new View.OnClickListener() {
115 | @Override
116 | public void onClick(View v) {
117 | String tag = (String) v.getTag();
118 | if( tag != null && new File(tag).exists()) {
119 | Intent intent = new Intent(getContext(), ShowImage.class);
120 | intent.putExtra("image", tag);
121 | getContext().startActivity(intent);
122 | }
123 | }
124 | });
125 | }
126 | }
127 |
128 | return convertView;
129 | }
130 |
131 | @NonNull
132 | @Override
133 | public Filter getFilter() {
134 | if(filter == null) {
135 | filter = new MessageFilter();
136 | }
137 | return filter;
138 | }
139 |
140 | private class MessageFilter extends Filter {
141 | @Override
142 | protected FilterResults performFiltering(CharSequence constraint) {
143 | FilterResults results = new FilterResults();
144 | if(constraint != null && constraint.length() > 0) {
145 | ArrayList filteredList = new ArrayList<>();
146 | for(Message message : messages) {
147 | if(message instanceof TextMessage && ((TextMessage) message).getMessage().toLowerCase().contains(constraint.toString().toLowerCase())) {
148 | if(!((TextMessage) message).getMessage().contains("http://maps.google.com/maps/api/staticmap?center="))
149 | filteredList.add(message);
150 | }
151 | }
152 | results.count = filteredList.size();
153 | results.values = filteredList;
154 | }
155 | else {
156 | results.count = messages.size();
157 | results.values = messages;
158 | }
159 | return results;
160 | }
161 |
162 | @Override
163 | protected void publishResults(CharSequence constraint, FilterResults results) {
164 | filteredMessages = (ArrayList) results.values;
165 | notifyDataSetChanged();
166 | }
167 | }
168 | }
169 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_message.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
13 |
14 |
32 |
33 |
51 |
52 |
58 |
59 |
66 |
67 |
74 |
75 |
76 |
77 |
83 |
84 |
91 |
92 |
99 |
100 |
101 |
102 |
108 |
109 |
116 |
117 |
125 |
126 |
127 |
128 |
129 |
130 |
145 |
146 |
156 |
157 |
167 |
168 |
169 |
170 |
184 |
185 |
190 |
191 |
192 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/whatsapp/Settings.java:
--------------------------------------------------------------------------------
1 | package com.example.whatsapp;
2 |
3 | import android.content.ContextWrapper;
4 | import android.content.DialogInterface;
5 | import android.content.Intent;
6 | import android.database.Cursor;
7 | import android.database.sqlite.SQLiteDatabase;
8 | import android.net.Uri;
9 | import android.support.v7.app.AlertDialog;
10 | import android.support.v7.app.AppCompatActivity;
11 | import android.os.Bundle;
12 | import android.view.View;
13 | import android.widget.TextView;
14 | import android.widget.Toast;
15 |
16 | import com.google.android.gms.appinvite.AppInviteInvitation;
17 | import com.google.firebase.auth.FirebaseAuth;
18 | import com.google.firebase.database.DataSnapshot;
19 | import com.google.firebase.database.DatabaseError;
20 | import com.google.firebase.database.DatabaseReference;
21 | import com.google.firebase.database.FirebaseDatabase;
22 | import com.google.firebase.database.ValueEventListener;
23 |
24 | import java.io.File;
25 |
26 | import de.hdodenhof.circleimageview.CircleImageView;
27 |
28 | import static com.example.whatsapp.DBHelper.DATABASE_NAME;
29 |
30 | public class Settings extends AppCompatActivity {
31 | private File image;
32 |
33 | @Override
34 | protected void onCreate(Bundle savedInstanceState) {
35 | super.onCreate(savedInstanceState);
36 | setContentView(R.layout.settings);
37 |
38 | TextView edit =(TextView) findViewById(R.id.textView3);
39 | edit.setOnClickListener(new View.OnClickListener() {
40 | @Override
41 | public void onClick(View view) {
42 | Intent intent = new Intent(Settings.this,editaccount.class);
43 | startActivity(intent);
44 | }
45 |
46 | });
47 |
48 | TextView delete = (TextView) findViewById(R.id.textView5);
49 | delete.setOnClickListener(new View.OnClickListener() {
50 | @Override
51 | public void onClick(View v) {
52 | new AlertDialog.Builder(Settings.this)
53 | .setTitle("Delete account?")
54 | .setMessage("Do you really want to delete your account?")
55 | .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
56 |
57 | public void onClick(DialogInterface dialog, int whichButton) {
58 | deleteAccount();
59 | }})
60 | .setNegativeButton("No", null).show();
61 | }
62 | });
63 |
64 | TextView invite =(TextView) findViewById(R.id.textView4);
65 | invite.setOnClickListener(new View.OnClickListener() {
66 | @Override
67 | public void onClick(View v) {
68 | FirebaseDatabase.getInstance().getReference("inviteLink").addValueEventListener(new ValueEventListener() {
69 | @Override
70 | public void onDataChange(DataSnapshot dataSnapshot) {
71 |
72 | String link = "";
73 | try {
74 | link = dataSnapshot.getValue(String.class);
75 | } catch (Exception ex) {}
76 |
77 | Intent intent = new AppInviteInvitation.IntentBuilder("Hey check this app")
78 | .setMessage("Hey thats a new messaging app. " + link)
79 | .setCallToActionText("Share")
80 | .build();
81 | startActivityForResult(intent, 2);
82 | }
83 |
84 | @Override
85 | public void onCancelled(DatabaseError databaseError) {
86 |
87 | }
88 | });
89 | }
90 | });
91 | }
92 |
93 | @Override
94 | protected void onResume() {
95 | super.onResume();
96 | final TextView name =(TextView) findViewById(R.id.textView2);
97 | final TextView status = (TextView) findViewById(R.id.status);
98 | final DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference("users").child(FirebaseAuth.getInstance().getCurrentUser().getPhoneNumber());
99 | databaseReference.addValueEventListener(new ValueEventListener() {
100 | @Override
101 | public void onDataChange(DataSnapshot dataSnapshot) {
102 | name.setText(dataSnapshot.child("name").getValue(String.class));
103 | status.setText(dataSnapshot.child("status").getValue(String.class));
104 | }
105 |
106 | @Override
107 | public void onCancelled(DatabaseError databaseError) {
108 |
109 | }
110 | });
111 |
112 | CircleImageView imageView = (CircleImageView) findViewById(R.id.imageView);
113 | ContextWrapper wrapper = new ContextWrapper(getApplicationContext());
114 | File file = wrapper.getDir("profilePictures",MODE_PRIVATE);
115 | file = new File(file, FirebaseAuth.getInstance().getCurrentUser().getPhoneNumber() + ".jpg");
116 | image = file;
117 | if(file.exists()) {
118 | imageView.setImageURI(Uri.parse(file.getAbsolutePath()));
119 | }
120 | }
121 |
122 | @Override
123 | protected void onActivityResult(int requestCode, int resultCode, Intent data) {
124 | super.onActivityResult(requestCode, resultCode, data);
125 | }
126 |
127 | public void imageClicked(View view) {
128 | if(image.exists()) {
129 | Intent intent = new Intent(this, ShowImage.class);
130 | intent.putExtra("image", image.getAbsolutePath());
131 | startActivity(intent);
132 | }
133 | }
134 |
135 | public void deleteAccount() {
136 | String user = FirebaseAuth.getInstance().getCurrentUser().getPhoneNumber();
137 | DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference("users").child(user);
138 | databaseReference.child("name").setValue(null);
139 | databaseReference.child("status").setValue(null);
140 |
141 | databaseReference = FirebaseDatabase.getInstance().getReference("messages");
142 | DBHelper dbHelper = new DBHelper(this);
143 | SQLiteDatabase db = dbHelper.getReadableDatabase();
144 | Cursor cursor = db.rawQuery("SELECT DISTINCT Friend FROM Message", null);
145 | while (cursor.moveToNext()) {
146 | String friend = cursor.getString(cursor.getColumnIndex("Friend"));
147 | databaseReference.child(user + " " + friend).addListenerForSingleValueEvent(new ValueEventListener() {
148 | @Override
149 | public void onDataChange(DataSnapshot dataSnapshot) {
150 | for(DataSnapshot ds : dataSnapshot.getChildren()) {
151 | ds.child("type").getRef().setValue(null);
152 | ds.child("message").getRef().setValue(null);
153 | }
154 | }
155 |
156 | @Override
157 | public void onCancelled(DatabaseError databaseError) {
158 |
159 | }
160 | });
161 | }
162 | cursor.close();
163 | FirebaseAuth.getInstance().signOut();
164 | try {
165 | deleteDatabase(DATABASE_NAME);
166 | }
167 | catch (Exception ex) {
168 | Toast.makeText(this, ex.getMessage(), Toast.LENGTH_SHORT).show();
169 | }
170 | ContextWrapper wrapper = new ContextWrapper(getApplicationContext());
171 | File file = wrapper.getDir("profilePictures",MODE_PRIVATE);
172 | if (file.isDirectory())
173 | {
174 | String[] children = file.list();
175 | for (String child : children)
176 | {
177 | new File(file, child).delete();
178 | }
179 | }
180 | stopService(new Intent(this, SyncMessagesService.class));
181 | finishAffinity();
182 | }
183 | }
184 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/whatsapp/editaccount.java:
--------------------------------------------------------------------------------
1 | package com.example.whatsapp;
2 |
3 | import android.app.ProgressDialog;
4 | import android.content.Context;
5 | import android.content.ContextWrapper;
6 | import android.content.DialogInterface;
7 | import android.content.Intent;
8 | import android.graphics.Bitmap;
9 | import android.graphics.drawable.BitmapDrawable;
10 | import android.net.ConnectivityManager;
11 | import android.net.Uri;
12 | import android.os.Bundle;
13 | import android.support.annotation.NonNull;
14 | import android.support.v7.app.AlertDialog;
15 | import android.support.v7.app.AppCompatActivity;
16 | import android.view.View;
17 | import android.widget.AbsListView;
18 | import android.widget.EditText;
19 | import android.widget.ImageView;
20 | import android.widget.TextView;
21 | import android.widget.Toast;
22 |
23 | import com.google.android.gms.tasks.OnFailureListener;
24 | import com.google.android.gms.tasks.OnSuccessListener;
25 | import com.google.firebase.auth.FirebaseAuth;
26 | import com.google.firebase.database.DataSnapshot;
27 | import com.google.firebase.database.DatabaseError;
28 | import com.google.firebase.database.DatabaseReference;
29 | import com.google.firebase.database.FirebaseDatabase;
30 | import com.google.firebase.database.ValueEventListener;
31 | import com.google.firebase.storage.FirebaseStorage;
32 | import com.google.firebase.storage.StorageReference;
33 | import com.google.firebase.storage.UploadTask;
34 |
35 | import java.io.ByteArrayOutputStream;
36 | import java.io.File;
37 | import java.io.FileOutputStream;
38 | import java.io.OutputStream;
39 |
40 | import static com.example.whatsapp.MessageActivity.GALLERY;
41 |
42 |
43 | /**
44 | * Created by sharjeel on 10/28/2017.
45 | */
46 |
47 | public class editaccount extends AppCompatActivity{
48 | DatabaseReference reference;
49 | private static ImageView imageView;
50 |
51 | private String name = "";
52 | private String status = "";
53 |
54 | @Override
55 | protected void onCreate(Bundle savedInstanceState) {
56 | super.onCreate(savedInstanceState);
57 | setContentView(R.layout.editaccount);
58 | imageView = new ImageView(this);
59 | reference = FirebaseDatabase.getInstance().getReference("users").child(FirebaseAuth.getInstance().getCurrentUser().getPhoneNumber());
60 |
61 | TextView updateName =(TextView) findViewById(R.id.updateName);
62 | updateName.setOnClickListener(new View.OnClickListener() {
63 | @Override
64 | public void onClick(View v) {
65 | showAlertDialog("Name");
66 | }
67 | });
68 |
69 | reference.addValueEventListener(new ValueEventListener() {
70 | @Override
71 | public void onDataChange(DataSnapshot dataSnapshot) {
72 | name = dataSnapshot.child("name").getValue(String.class);
73 | status = dataSnapshot.child("status").getValue(String.class);
74 | }
75 |
76 | @Override
77 | public void onCancelled(DatabaseError databaseError) {
78 |
79 | }
80 | });
81 |
82 | TextView updatePicture =(TextView) findViewById(R.id.updatePic);
83 | updatePicture.setOnClickListener(new View.OnClickListener() {
84 | @Override
85 | public void onClick(View v) {
86 | ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
87 | if (cm.getActiveNetworkInfo() != null) {
88 | showChangePicDialog();
89 | }
90 | else {
91 | Toast.makeText(editaccount.this, "No connection available", Toast.LENGTH_LONG).show();
92 | }
93 | }
94 | });
95 |
96 | TextView updateStatus =(TextView) findViewById(R.id.updateStatus);
97 | updateStatus.setOnClickListener(new View.OnClickListener() {
98 | @Override
99 | public void onClick(View v) {
100 | showAlertDialog("Status");
101 | }
102 | });
103 | }
104 |
105 | public void showAlertDialog(final String title) {
106 | AlertDialog.Builder builder = new AlertDialog.Builder(this);
107 | builder.setTitle(title);
108 | final EditText input = new EditText(this);
109 | input.setHint("New " + title);
110 | if(title.equals("Name")) input.setText(name);
111 | else input.setText(status);
112 | builder.setView(input);
113 | builder.setPositiveButton("Set", new DialogInterface.OnClickListener() {
114 | @Override
115 | public void onClick(DialogInterface dialog, int which) {
116 | if(title.equals("Name")) {
117 | changeName(input.getText().toString());
118 | }
119 | else {
120 | changeStatus(input.getText().toString());
121 | }
122 | }
123 | });
124 | builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
125 | @Override
126 | public void onClick(DialogInterface dialog, int which) {
127 | dialog.cancel();
128 | }
129 | });
130 | builder.show();
131 | }
132 |
133 | public void changeName(String title) {
134 | reference.child("name").setValue(null);
135 | reference.child("name").setValue(title);
136 | Toast.makeText(this, "Name changed", Toast.LENGTH_SHORT).show();
137 | }
138 |
139 | public void changeStatus(String status) {
140 | reference.child("status").setValue(null);
141 | reference.child("status").setValue(status);
142 | Toast.makeText(this, "Status changed", Toast.LENGTH_SHORT).show();
143 | }
144 |
145 | public void showChangePicDialog() {
146 | AlertDialog.Builder builder = new AlertDialog.Builder(this);
147 | builder.setTitle("Profile picture");
148 |
149 | ContextWrapper wrapper = new ContextWrapper(getApplicationContext());
150 | File file = wrapper.getDir("profilePictures",MODE_PRIVATE);
151 | file = new File(file, FirebaseAuth.getInstance().getCurrentUser().getPhoneNumber() + ".jpg");
152 |
153 | if(file.exists()) imageView.setImageURI(Uri.parse(file.getAbsolutePath()));
154 | else imageView.setImageResource(R.drawable.account);
155 | imageView.setOnClickListener(new View.OnClickListener() {
156 | @Override
157 | public void onClick(View v) {
158 | Intent gallery = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.INTERNAL_CONTENT_URI);
159 | startActivityForResult(gallery, GALLERY);
160 | }
161 | });
162 |
163 | builder.setView(imageView);
164 | builder.setPositiveButton("Set", new DialogInterface.OnClickListener() {
165 | @Override
166 | public void onClick(DialogInterface dialog, int which) {
167 | changeProfilePic();
168 | }
169 | });
170 | builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
171 | @Override
172 | public void onClick(DialogInterface dialog, int which) {
173 | dialog.cancel();
174 | }
175 | });
176 | builder.show();
177 | }
178 |
179 | public void changeProfilePic() {
180 | final Bitmap photo = ((BitmapDrawable)imageView.getDrawable()).getBitmap();
181 | StorageReference reference = FirebaseStorage.getInstance().getReference("profilePictures").child(FirebaseAuth.getInstance().getCurrentUser().getPhoneNumber() + ".jpg");
182 | ByteArrayOutputStream baos = new ByteArrayOutputStream();
183 | try {
184 | photo.compress(Bitmap.CompressFormat.JPEG, 100, baos);
185 | byte[] data = baos.toByteArray();
186 |
187 | final ProgressDialog dialog = ProgressDialog.show(this, "Please wait", "Uploading Image...", true);
188 | UploadTask uploadTask = reference.putBytes(data);
189 | uploadTask.addOnFailureListener(new OnFailureListener() {
190 | @Override
191 | public void onFailure(@NonNull Exception exception) {
192 | Toast.makeText(editaccount.this, exception.getMessage(), Toast.LENGTH_SHORT).show();
193 | }
194 | }).addOnSuccessListener(new OnSuccessListener() {
195 | @Override
196 | public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
197 | ContextWrapper wrapper = new ContextWrapper(getApplicationContext());
198 | File file = wrapper.getDir("profilePictures",MODE_PRIVATE);
199 | file = new File(file, FirebaseAuth.getInstance().getCurrentUser().getPhoneNumber() + ".jpg");
200 | OutputStream stream = null;
201 | try {
202 | stream = new FileOutputStream(file);
203 | photo.compress(Bitmap.CompressFormat.JPEG,100,stream);
204 | }
205 | catch (Exception ex) {
206 | Toast.makeText(editaccount.this, ex.getMessage(), Toast.LENGTH_SHORT).show();
207 | }
208 | finally {
209 | try {
210 | dialog.dismiss();
211 | Toast.makeText(editaccount.this, "Profile picture changed", Toast.LENGTH_SHORT).show();
212 | stream.flush();
213 | stream.close();
214 | }catch (Exception ex) {}
215 | }
216 | }
217 | });
218 | }
219 | catch (Exception ex) {
220 | }
221 | }
222 |
223 |
224 | @Override
225 | protected void onActivityResult(int requestCode, int resultCode, Intent data) {
226 | super.onActivityResult(requestCode, resultCode, data);
227 | if (resultCode == RESULT_OK) {
228 | if (requestCode == GALLERY) {
229 | Uri imageUri = data.getData();
230 | imageView.setImageURI(imageUri);
231 | }
232 | }
233 | }
234 | }
235 |
236 |
237 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/whatsapp/SyncMessagesService.java:
--------------------------------------------------------------------------------
1 | package com.example.whatsapp;
2 |
3 | import android.app.Notification;
4 | import android.app.NotificationManager;
5 | import android.app.PendingIntent;
6 | import android.app.Service;
7 | import android.content.BroadcastReceiver;
8 | import android.content.ContentValues;
9 | import android.content.Context;
10 | import android.content.ContextWrapper;
11 | import android.content.Intent;
12 | import android.content.IntentFilter;
13 | import android.database.Cursor;
14 | import android.database.sqlite.SQLiteDatabase;
15 | import android.os.IBinder;
16 | import android.support.annotation.NonNull;
17 | import android.support.v4.app.NotificationCompat;
18 | import android.support.v4.content.LocalBroadcastManager;
19 | import android.widget.Toast;
20 | import com.google.android.gms.tasks.OnFailureListener;
21 | import com.google.android.gms.tasks.OnSuccessListener;
22 | import com.google.firebase.auth.FirebaseAuth;
23 | import com.google.firebase.database.ChildEventListener;
24 | import com.google.firebase.database.DataSnapshot;
25 | import com.google.firebase.database.DatabaseError;
26 | import com.google.firebase.database.DatabaseReference;
27 | import com.google.firebase.database.FirebaseDatabase;
28 | import com.google.firebase.storage.FileDownloadTask;
29 | import com.google.firebase.storage.FirebaseStorage;
30 | import com.google.firebase.storage.StorageReference;
31 |
32 | import java.io.File;
33 | import java.text.SimpleDateFormat;
34 | import java.util.ArrayList;
35 | import java.util.Date;
36 |
37 | public class SyncMessagesService extends Service {
38 | public static String currentlyOpened = "";
39 | private ArrayList friends = new ArrayList<>();
40 |
41 | public SyncMessagesService() {
42 | try {
43 | FirebaseDatabase.getInstance().setPersistenceEnabled(true);
44 | FirebaseDatabase.getInstance().getReference("users").keepSynced(true);
45 | FirebaseDatabase.getInstance().getReference("inviteLink").keepSynced(true);
46 | }
47 | catch (Exception ex) {}
48 | }
49 |
50 | @Override
51 | public int onStartCommand(Intent intent, int flags, int startId) {
52 | syncFunction();
53 | return START_STICKY;
54 | }
55 |
56 | public void syncFunction() {
57 | final DBHelper helper = new DBHelper(this);
58 | final SQLiteDatabase db = helper.getReadableDatabase();
59 | Cursor cursor = db.rawQuery("SELECT Number FROM Friend", null);
60 | final String user = FirebaseAuth.getInstance().getCurrentUser().getPhoneNumber();
61 |
62 | DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference("messages");
63 | while (cursor.moveToNext()) {
64 | final String friend = cursor.getString(cursor.getColumnIndex("Number"));
65 | boolean contains = false;
66 | for(String string : friends) {
67 | if(string.equals(friend)) {
68 | contains = true;
69 | break;
70 | }
71 | }
72 | if(!friend.equals(user) && !contains) {
73 | friends.add(friend);
74 | DatabaseReference reference = databaseReference.child(user + " " + friend);
75 | reference.addChildEventListener(new ChildEventListener() {
76 | @Override
77 | public void onChildAdded(DataSnapshot dataSnapshot, String s) {
78 |
79 | String[] a = dataSnapshot.getKey().split(" ");
80 | String sender = a[2];
81 | String date = a[0] + " " + a[1];
82 | Cursor cursor1 = db.rawQuery("SELECT Friend FROM MyMessage WHERE Sender='" + sender + "' AND Date='" + date + "'", null);
83 |
84 | if(!cursor1.moveToNext()) {
85 | String type = dataSnapshot.child("type").getValue(String.class);
86 |
87 | DBHelper dbHelper = new DBHelper(SyncMessagesService.this);
88 | final SQLiteDatabase database = dbHelper.getWritableDatabase();
89 |
90 | final ContentValues values = new ContentValues();
91 | values.put("Friend", friend);
92 | values.put("Sender", sender);
93 | values.put("Date", date);
94 | values.put("Type", type);
95 | if(type.equals("text")) values.put("Message", dataSnapshot.child("message").getValue(String.class));
96 | else if(type.equals("image")) values.put("Message", "");
97 |
98 |
99 | if(!user.equals(sender) && type.equals("image")) {
100 | StorageReference reference = FirebaseStorage.getInstance().getReference(friend + " " + user).child(friend + " " + date + ".jpg");
101 | ContextWrapper wrapper = new ContextWrapper(getApplicationContext());
102 | File file = wrapper.getDir(friend,MODE_PRIVATE);
103 | file = new File(file, sender + " " + date + ".jpg");
104 | if(!file.exists()) {
105 | reference.getFile(file).addOnSuccessListener(new OnSuccessListener() {
106 | @Override
107 | public void onSuccess(FileDownloadTask.TaskSnapshot taskSnapshot) {
108 | database.insertWithOnConflict("Message", null, values, SQLiteDatabase.CONFLICT_REPLACE);
109 | database.insertWithOnConflict("MyMessage", null, values, SQLiteDatabase.CONFLICT_REPLACE);
110 | broadcastMessage();
111 | if (!currentlyOpened.equals(friend)) {
112 | NotificationCompat.Builder mBuilder =
113 | new NotificationCompat.Builder(SyncMessagesService.this)
114 | .setSmallIcon(R.drawable.icon_round)
115 | .setContentTitle(friend)
116 | .setContentText("Photo");
117 | Intent intent = new Intent(SyncMessagesService.this, ChatActivity.class);
118 | PendingIntent pendingIntent = PendingIntent.getActivity(SyncMessagesService.this, 0, intent, 0);
119 | mBuilder.setContentIntent(pendingIntent);
120 | mBuilder.setDefaults(Notification.DEFAULT_SOUND);
121 | NotificationManager mNotificationManager =
122 | (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
123 | mNotificationManager.notify(1, mBuilder.build());
124 | }
125 | }
126 | }).addOnFailureListener(new OnFailureListener() {
127 | @Override
128 | public void onFailure(@NonNull Exception e) {
129 | Toast.makeText(SyncMessagesService.this, e.getMessage(), Toast.LENGTH_SHORT).show();
130 | }
131 | });
132 | }
133 | }
134 | else {
135 | database.insertWithOnConflict("Message", null, values, SQLiteDatabase.CONFLICT_REPLACE);
136 | database.insertWithOnConflict("MyMessage", null, values, SQLiteDatabase.CONFLICT_REPLACE);
137 | broadcastMessage();
138 | if(!user.equals(sender) && !currentlyOpened.equals(friend)) {
139 | String message = dataSnapshot.child("message").getValue(String.class);
140 | if(message.contains("http://maps.google.com/maps/api/staticmap?center=")) message = "Location";
141 | NotificationCompat.Builder mBuilder =
142 | new NotificationCompat.Builder(SyncMessagesService.this)
143 | .setSmallIcon(R.drawable.icon_round)
144 | .setContentTitle(friend)
145 | .setContentText(message);
146 | Intent intent = new Intent(SyncMessagesService.this, ChatActivity.class);
147 | PendingIntent pendingIntent = PendingIntent.getActivity(SyncMessagesService.this, 0, intent, 0);
148 | mBuilder.setContentIntent(pendingIntent);
149 | mBuilder.setDefaults(Notification.DEFAULT_SOUND);
150 | //mBuilder.setPriority(Notification.PRIORITY_MAX);
151 | NotificationManager mNotificationManager =
152 | (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
153 | mNotificationManager.notify(001, mBuilder.build());
154 | }
155 | }
156 | }
157 | cursor1.close();
158 | }
159 |
160 | @Override
161 | public void onChildChanged(DataSnapshot dataSnapshot, String s) {
162 |
163 | }
164 |
165 | @Override
166 | public void onChildRemoved(DataSnapshot dataSnapshot) {
167 |
168 | }
169 |
170 | @Override
171 | public void onChildMoved(DataSnapshot dataSnapshot, String s) {
172 |
173 | }
174 |
175 | @Override
176 | public void onCancelled(DatabaseError databaseError) {
177 |
178 | }
179 | });
180 | }
181 | }
182 | cursor.close();
183 | }
184 |
185 | public void broadcastMessage() {
186 | Intent intent = new Intent("serviceMessage");
187 | intent.putExtra("message", "");
188 | LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
189 | }
190 |
191 | @Override
192 | public IBinder onBind(Intent intent) {
193 | return null;
194 | }
195 | }
196 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/whatsapp/ChatActivity.java:
--------------------------------------------------------------------------------
1 | package com.example.whatsapp;
2 |
3 | import android.content.BroadcastReceiver;
4 | import android.content.ContentResolver;
5 | import android.content.ContentValues;
6 | import android.content.Context;
7 | import android.content.ContextWrapper;
8 | import android.content.Intent;
9 | import android.content.IntentFilter;
10 | import android.database.Cursor;
11 | import android.database.sqlite.SQLiteDatabase;
12 | import android.net.Uri;
13 | import android.provider.ContactsContract;
14 | import android.support.annotation.NonNull;
15 | import android.support.design.widget.TabLayout;
16 | import android.support.design.widget.FloatingActionButton;
17 | import android.support.v4.content.LocalBroadcastManager;
18 | import android.support.v7.app.AppCompatActivity;
19 | import android.support.v7.widget.Toolbar;
20 | import android.support.v4.app.Fragment;
21 | import android.support.v4.app.FragmentManager;
22 | import android.support.v4.app.FragmentPagerAdapter;
23 | import android.support.v4.view.ViewPager;
24 | import android.os.Bundle;
25 | import android.text.Editable;
26 | import android.text.TextWatcher;
27 | import android.view.LayoutInflater;
28 | import android.view.Menu;
29 | import android.view.MenuItem;
30 | import android.view.View;
31 | import android.view.ViewGroup;
32 | import android.widget.EditText;
33 | import android.widget.LinearLayout;
34 | import android.widget.ListView;
35 | import android.widget.TextView;
36 | import android.widget.Toast;
37 |
38 | import com.android.volley.Request;
39 | import com.android.volley.RequestQueue;
40 | import com.android.volley.Response;
41 | import com.android.volley.VolleyError;
42 | import com.android.volley.toolbox.StringRequest;
43 | import com.android.volley.toolbox.Volley;
44 | import com.google.android.gms.tasks.OnFailureListener;
45 | import com.google.android.gms.tasks.OnSuccessListener;
46 | import com.google.firebase.auth.FirebaseAuth;
47 | import com.google.firebase.database.DataSnapshot;
48 | import com.google.firebase.database.DatabaseError;
49 | import com.google.firebase.database.DatabaseReference;
50 | import com.google.firebase.database.FirebaseDatabase;
51 | import com.google.firebase.database.ValueEventListener;
52 | import com.google.firebase.storage.FileDownloadTask;
53 | import com.google.firebase.storage.FirebaseStorage;
54 | import com.google.firebase.storage.StorageMetadata;
55 | import com.google.firebase.storage.StorageReference;
56 |
57 | import org.json.JSONArray;
58 | import org.json.JSONObject;
59 |
60 | import java.io.File;
61 | import java.net.URI;
62 | import java.text.SimpleDateFormat;
63 | import java.util.ArrayList;
64 | import java.util.Date;
65 |
66 | import de.hdodenhof.circleimageview.CircleImageView;
67 |
68 | public class ChatActivity extends AppCompatActivity {
69 |
70 | private static ChatAdapter chatAdapter;
71 | private static ContactAdapter contactAdapter;
72 | public static ArrayList names = new ArrayList<>();
73 | public static ArrayList phones = new ArrayList<>();
74 | private static Context applicationContext;
75 | private static StorageReference storageRef;
76 |
77 | private SectionsPagerAdapter mSectionsPagerAdapter;
78 | private ViewPager mViewPager;
79 |
80 | @Override
81 | protected void onCreate(Bundle savedInstanceState) {
82 | super.onCreate(savedInstanceState);
83 | setContentView(R.layout.activity_chat);
84 |
85 | applicationContext = getApplicationContext();
86 | loadContactsFromPhone();
87 | storageRef = FirebaseStorage.getInstance().getReference().child("profilePictures");
88 |
89 | Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
90 | setSupportActionBar(toolbar);
91 |
92 | mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
93 |
94 | mViewPager = (ViewPager) findViewById(R.id.container);
95 | mViewPager.setAdapter(mSectionsPagerAdapter);
96 |
97 | final TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
98 |
99 | mViewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
100 | tabLayout.addOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(mViewPager));
101 |
102 | EditText text = (EditText) findViewById(R.id.search);
103 | text.addTextChangedListener(new TextWatcher() {
104 | @Override
105 | public void beforeTextChanged(CharSequence s, int start, int count, int after) {
106 |
107 | }
108 |
109 | @Override
110 | public void onTextChanged(CharSequence s, int start, int before, int count) {
111 | if(tabLayout.getSelectedTabPosition() == 0) {
112 | chatAdapter.getFilter().filter(s.toString());
113 | }
114 | else {
115 | contactAdapter.getFilter().filter(s.toString());
116 | }
117 | }
118 |
119 | @Override
120 | public void afterTextChanged(Editable s) {
121 |
122 | }
123 | });
124 |
125 | }
126 |
127 | @Override
128 | public void onBackPressed() {
129 | LinearLayout linearLayout = (LinearLayout) findViewById(R.id.search_bar);
130 | if(linearLayout.getVisibility() == View.GONE)
131 | finishAffinity();
132 | else
133 | resetSearch(linearLayout);
134 | }
135 |
136 | public void backPressed(View view) {
137 | LinearLayout linearLayout = (LinearLayout) findViewById(R.id.search_bar);
138 | resetSearch(linearLayout);
139 | }
140 |
141 | public void resetSearch(LinearLayout linearLayout) {
142 | linearLayout.setVisibility(View.GONE);
143 | final TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
144 | EditText text = (EditText) findViewById(R.id.search);
145 | TabLayout tabs = (TabLayout) findViewById(R.id.tabs);
146 | tabs.setVisibility(View.VISIBLE);
147 | text.setText("");
148 | if(tabLayout.getSelectedTabPosition() == 0) {
149 | chatAdapter.getFilter().filter("");
150 | }
151 | else {
152 | contactAdapter.getFilter().filter("");
153 | }
154 | }
155 |
156 | private void loadContactsFromPhone() {
157 | ContentResolver cr = getContentResolver();
158 | Cursor cursor = cr.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
159 | while (cursor.moveToNext()) {
160 | String contactId = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
161 | //
162 | // Get all phone numbers.
163 | //
164 | Cursor phones = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = " + contactId, null, null);
165 |
166 | while (phones.moveToNext()) {
167 | String number = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)).replaceAll("\\s+","");
168 | String name = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
169 | if(!ChatActivity.phones.contains(number)) {
170 | ChatActivity.names.add(name);
171 | ChatActivity.phones.add(number);
172 | }
173 | }
174 | phones.close();
175 | }
176 | cursor.close();
177 | }
178 |
179 |
180 | @Override
181 | public boolean onCreateOptionsMenu(Menu menu) {
182 | getMenuInflater().inflate(R.menu.menu_chat, menu);
183 | return true;
184 | }
185 |
186 | @Override
187 | public boolean onOptionsItemSelected(MenuItem item) {
188 | int id = item.getItemId();
189 |
190 | if (id == R.id.home_settings) {
191 | startActivity(new Intent(this, Settings.class));
192 | return true;
193 | }
194 | else if(id == R.id.home_search) {
195 | LinearLayout linearLayout = (LinearLayout) findViewById(R.id.search_bar);
196 | linearLayout.setVisibility(View.VISIBLE);
197 | TabLayout tabs = (TabLayout) findViewById(R.id.tabs);
198 | tabs.setVisibility(View.GONE);
199 | return true;
200 | }
201 |
202 | return super.onOptionsItemSelected(item);
203 | }
204 |
205 | public static class PlaceholderFragment extends Fragment {
206 | private static View view1;
207 | private static View view2;
208 | private static final String ARG_SECTION_NUMBER = "section_number";
209 |
210 | private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
211 | @Override
212 | public void onReceive(Context context, Intent intent) {
213 | intent.getSerializableExtra("message");
214 | createFirstList();
215 | }
216 | };
217 |
218 | public PlaceholderFragment() {
219 | }
220 |
221 | public static PlaceholderFragment newInstance(int sectionNumber) {
222 | PlaceholderFragment fragment = new PlaceholderFragment();
223 | Bundle args = new Bundle();
224 | args.putInt(ARG_SECTION_NUMBER, sectionNumber);
225 | fragment.setArguments(args);
226 | return fragment;
227 | }
228 |
229 | @Override
230 | public void onResume() {
231 | super.onResume();
232 | createFirstList();
233 | LocalBroadcastManager.getInstance(getContext()).registerReceiver(mMessageReceiver, new IntentFilter("serviceMessage"));
234 | }
235 |
236 | @Override
237 | public void onPause() {
238 | LocalBroadcastManager.getInstance(getContext()).unregisterReceiver(mMessageReceiver);
239 | super.onPause();
240 | }
241 |
242 | @Override
243 | public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
244 | if(getArguments().getInt(ARG_SECTION_NUMBER) == 1) {
245 | view1 = inflater.inflate(R.layout.fragment_chat, container, false);
246 | FloatingActionButton fab = (FloatingActionButton) view1.findViewById(R.id.fab2);
247 | fab.setOnClickListener(new View.OnClickListener() {
248 | @Override
249 | public void onClick(View v) {
250 | Intent intent = new Intent(getContext(), ContactActivity.class);
251 | startActivity(intent);
252 | }
253 | });
254 | createFirstList();
255 | return view1;
256 | }
257 | else {
258 | view2 = inflater.inflate(R.layout.fragment_contacts, container, false);
259 | createSecondList();
260 | syncContactsWithFirebase();
261 | FloatingActionButton fab = (FloatingActionButton) view2.findViewById(R.id.fab);
262 | fab.setOnClickListener(new View.OnClickListener() {
263 | @Override
264 | public void onClick(View view) {
265 | Intent intent = new Intent(Intent.ACTION_INSERT, ContactsContract.Contacts.CONTENT_URI);
266 | startActivity(intent);
267 | /*Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
268 | .setAction("Action", null).show();*/
269 | }
270 | });
271 | return view2;
272 | }
273 | }
274 |
275 | private void createFirstList() {
276 | ListView listView = (ListView) view1.findViewById(R.id.list);
277 | ArrayList cells = new ArrayList<>();
278 | ContextWrapper wrapper = new ContextWrapper(applicationContext);
279 | File file = wrapper.getDir("profilePictures",MODE_PRIVATE);
280 | DBHelper helper = new DBHelper(getContext());
281 | SQLiteDatabase db = helper.getReadableDatabase();
282 | Cursor cursor = db.rawQuery("SELECT * FROM Message ORDER BY Date DESC", null);
283 | int i;
284 | while (cursor.moveToNext()) {
285 | String friend = cursor.getString(cursor.getColumnIndex("Friend"));
286 | String name = "";
287 | if((i = phones.indexOf(friend)) != -1) {
288 | name = names.get(i);
289 | }
290 | else name = friend;
291 | String date = cursor.getString(cursor.getColumnIndex("Date"));
292 | String cDate = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
293 | if(cDate.equals(date.split(" ")[0])) {
294 | String[] d = date.split(" ")[1].split(":");
295 | date = d[0] + ":" + d[1];
296 | }
297 | else {
298 | String[] d = date.split(" ")[0].split("-");
299 | date = d[2] + "/" + d[1] + "/" + d[0];
300 | }
301 | String message = cursor.getString(cursor.getColumnIndex("Message"));
302 | if(message.equals("")) message = "Photo";
303 | else if(message.contains("http://maps.google.com/maps/api/staticmap?center=")) message = "Location";
304 | File file1 = new File(file, friend + ".jpg");
305 | if(file1.exists()) {
306 | cells.add(new PersonCell(Uri.parse(file1.getAbsolutePath()), name, message, date, friend));
307 | }
308 | else {
309 | cells.add(new PersonCell(null, name, message, date, friend));
310 | }
311 | }
312 | chatAdapter = new ChatAdapter(getContext(), cells);
313 | listView.setAdapter(chatAdapter);
314 | }
315 |
316 | private void createSecondList() {
317 | ListView listView = (ListView) view2.findViewById(R.id.list);
318 | DBHelper helper = new DBHelper(getContext());
319 | SQLiteDatabase db = helper.getReadableDatabase();
320 | Cursor cursor = db.rawQuery("SELECT * FROM Friend", null);
321 | ArrayList cells = new ArrayList<>();
322 | ContextWrapper wrapper = new ContextWrapper(applicationContext);
323 | File file = wrapper.getDir("profilePictures",MODE_PRIVATE);
324 | int i;
325 | while (cursor.moveToNext()) {
326 | String number = cursor.getString(cursor.getColumnIndex("Number"));
327 | if((i = phones.indexOf(number)) != -1) {
328 | File file1 = new File(file, number + ".jpg");
329 | String status = cursor.getString(cursor.getColumnIndex("Status"));
330 | String name = names.get(i);
331 | if(file1.exists())
332 | cells.add(new ContactCell(Uri.parse(file1.getAbsolutePath()), name, status, number));
333 | else
334 | cells.add(new ContactCell(null, name, status, number));
335 | }
336 | }
337 | contactAdapter = new ContactAdapter(getContext(), cells);
338 | listView.setAdapter(contactAdapter);
339 | }
340 |
341 | private void syncContactsWithFirebase() {
342 | DatabaseReference reference = FirebaseDatabase.getInstance().getReference().child("users");
343 | reference.addListenerForSingleValueEvent(new ValueEventListener() {
344 | @Override
345 | public void onDataChange(DataSnapshot dataSnapshot) {
346 | DBHelper dbHelper = new DBHelper(getContext());
347 | SQLiteDatabase db = dbHelper.getWritableDatabase();
348 | db.execSQL("DELETE FROM Friend");
349 | ContextWrapper wrapper = new ContextWrapper(applicationContext);
350 | File file = wrapper.getDir("profilePictures",MODE_PRIVATE);
351 | for(DataSnapshot ds : dataSnapshot.getChildren()) {
352 | String number = ds.getKey();
353 | String status = ds.child("status").getValue(String.class);
354 |
355 | ContentValues values = new ContentValues();
356 | values.put("Number", number);
357 | values.put("Status", status);
358 | db.insertWithOnConflict("Friend", null, values, SQLiteDatabase.CONFLICT_REPLACE);
359 |
360 | if(!number.equals(FirebaseAuth.getInstance().getCurrentUser().getPhoneNumber()) && phones.contains(number)) {
361 | final StorageReference reference = storageRef.child(number + ".jpg");
362 | final File file1 = new File(file, number + ".jpg");
363 | if(file1.exists()) {
364 | final long localSize = file1.length();
365 | reference.getMetadata().addOnSuccessListener(new OnSuccessListener() {
366 | @Override
367 | public void onSuccess(StorageMetadata storageMetadata) {
368 | if(localSize != storageMetadata.getSizeBytes()) {
369 | reference.getFile(file1).addOnSuccessListener(new OnSuccessListener() {
370 | @Override
371 | public void onSuccess(FileDownloadTask.TaskSnapshot taskSnapshot) {
372 | }
373 | });
374 | }
375 | }
376 | });
377 | }
378 | else {
379 | reference.getFile(file1).addOnSuccessListener(new OnSuccessListener() {
380 | @Override
381 | public void onSuccess(FileDownloadTask.TaskSnapshot taskSnapshot) {
382 | }
383 | }).addOnFailureListener(new OnFailureListener() {
384 | @Override
385 | public void onFailure(@NonNull Exception e) {
386 | Toast.makeText(getContext(), e.getMessage(), Toast.LENGTH_SHORT).show();
387 | }
388 | });
389 | }
390 | }
391 | }
392 | createSecondList();
393 | getContext().startService(new Intent(getContext(), SyncMessagesService.class));
394 | }
395 |
396 | @Override
397 | public void onCancelled(DatabaseError databaseError) {
398 |
399 | }
400 | });
401 | }
402 | }
403 |
404 | public class SectionsPagerAdapter extends FragmentPagerAdapter {
405 |
406 | public SectionsPagerAdapter(FragmentManager fm) {
407 | super(fm);
408 | }
409 |
410 | @Override
411 | public Fragment getItem(int position) {
412 | // getItem is called to instantiate the fragment for the given page.
413 | // Return a PlaceholderFragment (defined as a static inner class below).
414 | return PlaceholderFragment.newInstance(position + 1);
415 | }
416 |
417 | @Override
418 | public int getCount() {
419 | // Show 3 total pages.
420 | return 2;
421 | }
422 | }
423 |
424 | static class ViewHolder {
425 | CircleImageView photoImageView;
426 | LinearLayout layout;
427 | TextView nameTextView;
428 | TextView lastMessageTextView;
429 | TextView dateTextView;
430 | }
431 | }
432 |
--------------------------------------------------------------------------------