├── .gitignore
├── .idea
├── assetWizardSettings.xml
├── caches
│ └── build_file_checksums.ser
├── codeStyles
│ └── Project.xml
├── gradle.xml
├── misc.xml
└── runConfigurations.xml
├── README.md
├── app
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── koddev
│ │ └── chatapp
│ │ └── ExampleInstrumentedTest.java
│ ├── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── com
│ │ │ └── koddev
│ │ │ └── chatapp
│ │ │ ├── Adapter
│ │ │ ├── MessageAdapter.java
│ │ │ └── UserAdapter.java
│ │ │ ├── Fragments
│ │ │ ├── APIService.java
│ │ │ ├── ChatsFragment.java
│ │ │ ├── ProfileFragment.java
│ │ │ └── UsersFragment.java
│ │ │ ├── LoginActivity.java
│ │ │ ├── MainActivity.java
│ │ │ ├── MessageActivity.java
│ │ │ ├── Model
│ │ │ ├── Chat.java
│ │ │ ├── Chatlist.java
│ │ │ └── User.java
│ │ │ ├── Notifications
│ │ │ ├── Client.java
│ │ │ ├── Data.java
│ │ │ ├── MyFirebaseIdService.java
│ │ │ ├── MyFirebaseMessaging.java
│ │ │ ├── MyResponse.java
│ │ │ ├── OreoNotification.java
│ │ │ ├── Sender.java
│ │ │ └── Token.java
│ │ │ ├── RegisterActivity.java
│ │ │ ├── ResetPasswordActivity.java
│ │ │ └── StartActivity.java
│ └── res
│ │ ├── drawable-hdpi
│ │ └── ic_action_name.png
│ │ ├── drawable-mdpi
│ │ └── ic_action_name.png
│ │ ├── drawable-v24
│ │ └── ic_launcher_foreground.xml
│ │ ├── drawable-xhdpi
│ │ └── ic_action_name.png
│ │ ├── drawable-xxhdpi
│ │ └── ic_action_name.png
│ │ ├── drawable
│ │ ├── background_left.xml
│ │ ├── background_right.xml
│ │ └── ic_launcher_background.xml
│ │ ├── layout
│ │ ├── activity_login.xml
│ │ ├── activity_main.xml
│ │ ├── activity_message.xml
│ │ ├── activity_register.xml
│ │ ├── activity_reset_password.xml
│ │ ├── activity_start.xml
│ │ ├── bar_layout.xml
│ │ ├── chat_item_left.xml
│ │ ├── chat_item_right.xml
│ │ ├── fragment_chats.xml
│ │ ├── fragment_profile.xml
│ │ ├── fragment_users.xml
│ │ └── user_item.xml
│ │ ├── menu
│ │ └── menu.xml
│ │ ├── mipmap-anydpi-v26
│ │ ├── ic_launcher.xml
│ │ └── ic_launcher_round.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
│ │ └── values
│ │ ├── colors.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ └── test
│ └── java
│ └── com
│ └── koddev
│ └── chatapp
│ └── ExampleUnitTest.java
├── build.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/libraries
5 | /.idea/modules.xml
6 | /.idea/workspace.xml
7 | .DS_Store
8 | /build
9 | /captures
10 | .externalNativeBuild
11 |
--------------------------------------------------------------------------------
/.idea/assetWizardSettings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
60 |
61 |
--------------------------------------------------------------------------------
/.idea/caches/build_file_checksums.ser:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/majlindavdylaj/ChatAppTutorial/4eea5c5d4100ab1e73661f02a04695d12176c0d0/.idea/caches/build_file_checksums.ser
--------------------------------------------------------------------------------
/.idea/codeStyles/Project.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
17 |
18 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/.idea/runConfigurations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ChatAppTutorial
2 |
3 | I have deleted google-services.json. Add yours
4 |
Change Authorization:key with your key from firebase project
5 |
6 |
Implementation Guide
7 |
1 - Project
8 |
1 - Open the Project in your android studio;
9 |
2 - *IMPORTANT* Change the Package Name. (https://stackoverflow.com/questions/16804093/android-studio-rename-package)
10 |
11 |
2 - Firebase Panel
12 |
- Create Firebase Project (https://console.firebase.google.com/);
13 |
- Import the file google-service.json into your project
14 |
- Connect to firebase console authentication and database from your IDE (video 2)
15 |
- in firebase Storage Rules, change value of "allow read, write:" from "if request.auth != null" to "if true;" (video 12)
16 |
- For sending notification, paste your Firebase project key into your project APIService.java (video 18)
17 |
- When you change database settings, you likely will need to uninstall and reinstall apps to avoid app crashes due to app caches.
18 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 27
5 | defaultConfig {
6 | applicationId "com.koddev.chatapp"
7 | minSdkVersion 16
8 | targetSdkVersion 27
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:27.1.1'
24 | implementation 'com.android.support.constraint:constraint-layout:1.1.2'
25 |
26 | //libraries we need for now
27 | implementation 'com.android.support:support-v4:27.1.1'
28 | implementation 'com.android.support:design:27.1.1'
29 | implementation 'com.google.firebase:firebase-auth:16.0.2'
30 | implementation 'com.google.firebase:firebase-database:16.0.1'
31 | implementation 'com.google.firebase:firebase-core:16.0.1'
32 | //add this
33 | implementation 'com.google.firebase:firebase-storage:16.0.1'
34 | implementation 'com.android.support:cardview-v7:27.1.1'
35 | implementation 'com.rengwuxian.materialedittext:library:2.1.4'
36 | //add this library and this
37 | implementation 'de.hdodenhof:circleimageview:2.2.0'
38 | implementation 'com.github.bumptech.glide:glide:4.8.0'
39 |
40 | //add these libraries
41 | implementation 'com.squareup.retrofit2:retrofit:2.3.0'
42 | implementation 'com.squareup.retrofit2:converter-gson:2.3.0'
43 | implementation 'com.google.firebase:firebase-messaging:17.3.1'
44 |
45 | testImplementation 'junit:junit:4.12'
46 | androidTestImplementation 'com.android.support.test:runner:1.0.2'
47 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
48 | }
49 |
50 | apply plugin: 'com.google.gms.google-services'
51 |
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/com/koddev/chatapp/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.koddev.chatapp;
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() {
21 | // Context of the app under test.
22 | Context appContext = InstrumentationRegistry.getTargetContext();
23 |
24 | assertEquals("com.koddev.chatapp", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
26 |
27 |
30 |
31 |
34 |
35 |
38 |
39 |
40 |
41 |
42 |
43 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/app/src/main/java/com/koddev/chatapp/Adapter/MessageAdapter.java:
--------------------------------------------------------------------------------
1 | package com.koddev.chatapp.Adapter;
2 |
3 | import android.content.Context;
4 | import android.support.annotation.NonNull;
5 | import android.support.v7.widget.RecyclerView;
6 | import android.view.LayoutInflater;
7 | import android.view.View;
8 | import android.view.ViewGroup;
9 | import android.widget.ImageView;
10 | import android.widget.TextView;
11 |
12 | import com.bumptech.glide.Glide;
13 | import com.google.firebase.auth.FirebaseAuth;
14 | import com.google.firebase.auth.FirebaseUser;
15 | import com.koddev.chatapp.Model.Chat;
16 | import com.koddev.chatapp.R;
17 |
18 | import java.util.List;
19 |
20 | public class MessageAdapter extends RecyclerView.Adapter {
21 |
22 | public static final int MSG_TYPE_LEFT = 0;
23 | public static final int MSG_TYPE_RIGHT = 1;
24 |
25 | private Context mContext;
26 | private List mChat;
27 | private String imageurl;
28 |
29 | FirebaseUser fuser;
30 |
31 | public MessageAdapter(Context mContext, List mChat, String imageurl){
32 | this.mChat = mChat;
33 | this.mContext = mContext;
34 | this.imageurl = imageurl;
35 | }
36 |
37 | @NonNull
38 | @Override
39 | public MessageAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
40 | if (viewType == MSG_TYPE_RIGHT) {
41 | View view = LayoutInflater.from(mContext).inflate(R.layout.chat_item_right, parent, false);
42 | return new MessageAdapter.ViewHolder(view);
43 | } else {
44 | View view = LayoutInflater.from(mContext).inflate(R.layout.chat_item_left, parent, false);
45 | return new MessageAdapter.ViewHolder(view);
46 | }
47 | }
48 |
49 | @Override
50 | public void onBindViewHolder(@NonNull MessageAdapter.ViewHolder holder, int position) {
51 |
52 | Chat chat = mChat.get(position);
53 |
54 | holder.show_message.setText(chat.getMessage());
55 |
56 | if (imageurl.equals("default")){
57 | holder.profile_image.setImageResource(R.mipmap.ic_launcher);
58 | } else {
59 | Glide.with(mContext).load(imageurl).into(holder.profile_image);
60 | }
61 |
62 | if (position == mChat.size()-1){
63 | if (chat.isIsseen()){
64 | holder.txt_seen.setText("Seen");
65 | } else {
66 | holder.txt_seen.setText("Delivered");
67 | }
68 | } else {
69 | holder.txt_seen.setVisibility(View.GONE);
70 | }
71 |
72 | }
73 |
74 | @Override
75 | public int getItemCount() {
76 | return mChat.size();
77 | }
78 |
79 | public class ViewHolder extends RecyclerView.ViewHolder{
80 |
81 | public TextView show_message;
82 | public ImageView profile_image;
83 | public TextView txt_seen;
84 |
85 | public ViewHolder(View itemView) {
86 | super(itemView);
87 |
88 | show_message = itemView.findViewById(R.id.show_message);
89 | profile_image = itemView.findViewById(R.id.profile_image);
90 | txt_seen = itemView.findViewById(R.id.txt_seen);
91 | }
92 | }
93 |
94 | @Override
95 | public int getItemViewType(int position) {
96 | fuser = FirebaseAuth.getInstance().getCurrentUser();
97 | if (mChat.get(position).getSender().equals(fuser.getUid())){
98 | return MSG_TYPE_RIGHT;
99 | } else {
100 | return MSG_TYPE_LEFT;
101 | }
102 | }
103 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/koddev/chatapp/Adapter/UserAdapter.java:
--------------------------------------------------------------------------------
1 | package com.koddev.chatapp.Adapter;
2 |
3 | import android.content.Context;
4 | import android.content.Intent;
5 | import android.support.annotation.NonNull;
6 | import android.support.v7.widget.RecyclerView;
7 | import android.view.LayoutInflater;
8 | import android.view.View;
9 | import android.view.ViewGroup;
10 | import android.widget.ImageView;
11 | import android.widget.TextView;
12 |
13 | import com.bumptech.glide.Glide;
14 | import com.google.firebase.auth.FirebaseAuth;
15 | import com.google.firebase.auth.FirebaseUser;
16 | import com.google.firebase.database.DataSnapshot;
17 | import com.google.firebase.database.DatabaseError;
18 | import com.google.firebase.database.DatabaseReference;
19 | import com.google.firebase.database.FirebaseDatabase;
20 | import com.google.firebase.database.ValueEventListener;
21 | import com.koddev.chatapp.MessageActivity;
22 | import com.koddev.chatapp.Model.Chat;
23 | import com.koddev.chatapp.Model.User;
24 | import com.koddev.chatapp.R;
25 |
26 | import java.util.List;
27 |
28 | public class UserAdapter extends RecyclerView.Adapter {
29 |
30 | private Context mContext;
31 | private List mUsers;
32 | private boolean ischat;
33 |
34 | String theLastMessage;
35 |
36 | public UserAdapter(Context mContext, List mUsers, boolean ischat){
37 | this.mUsers = mUsers;
38 | this.mContext = mContext;
39 | this.ischat = ischat;
40 | }
41 |
42 | @NonNull
43 | @Override
44 | public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
45 | View view = LayoutInflater.from(mContext).inflate(R.layout.user_item, parent, false);
46 | return new UserAdapter.ViewHolder(view);
47 | }
48 |
49 | @Override
50 | public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
51 |
52 | final User user = mUsers.get(position);
53 | holder.username.setText(user.getUsername());
54 | if (user.getImageURL().equals("default")){
55 | holder.profile_image.setImageResource(R.mipmap.ic_launcher);
56 | } else {
57 | Glide.with(mContext).load(user.getImageURL()).into(holder.profile_image);
58 | }
59 |
60 | if (ischat){
61 | lastMessage(user.getId(), holder.last_msg);
62 | } else {
63 | holder.last_msg.setVisibility(View.GONE);
64 | }
65 |
66 | if (ischat){
67 | if (user.getStatus().equals("online")){
68 | holder.img_on.setVisibility(View.VISIBLE);
69 | holder.img_off.setVisibility(View.GONE);
70 | } else {
71 | holder.img_on.setVisibility(View.GONE);
72 | holder.img_off.setVisibility(View.VISIBLE);
73 | }
74 | } else {
75 | holder.img_on.setVisibility(View.GONE);
76 | holder.img_off.setVisibility(View.GONE);
77 | }
78 |
79 | holder.itemView.setOnClickListener(new View.OnClickListener() {
80 | @Override
81 | public void onClick(View view) {
82 | Intent intent = new Intent(mContext, MessageActivity.class);
83 | intent.putExtra("userid", user.getId());
84 | mContext.startActivity(intent);
85 | }
86 | });
87 | }
88 |
89 | @Override
90 | public int getItemCount() {
91 | return mUsers.size();
92 | }
93 |
94 | public class ViewHolder extends RecyclerView.ViewHolder{
95 |
96 | public TextView username;
97 | public ImageView profile_image;
98 | private ImageView img_on;
99 | private ImageView img_off;
100 | private TextView last_msg;
101 |
102 | public ViewHolder(View itemView) {
103 | super(itemView);
104 |
105 | username = itemView.findViewById(R.id.username);
106 | profile_image = itemView.findViewById(R.id.profile_image);
107 | img_on = itemView.findViewById(R.id.img_on);
108 | img_off = itemView.findViewById(R.id.img_off);
109 | last_msg = itemView.findViewById(R.id.last_msg);
110 | }
111 | }
112 |
113 | //check for last message
114 | private void lastMessage(final String userid, final TextView last_msg){
115 | theLastMessage = "default";
116 | final FirebaseUser firebaseUser = FirebaseAuth.getInstance().getCurrentUser();
117 | DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Chats");
118 |
119 | reference.addValueEventListener(new ValueEventListener() {
120 | @Override
121 | public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
122 | for (DataSnapshot snapshot : dataSnapshot.getChildren()){
123 | Chat chat = snapshot.getValue(Chat.class);
124 | if (firebaseUser != null && chat != null) {
125 | if (chat.getReceiver().equals(firebaseUser.getUid()) && chat.getSender().equals(userid) ||
126 | chat.getReceiver().equals(userid) && chat.getSender().equals(firebaseUser.getUid())) {
127 | theLastMessage = chat.getMessage();
128 | }
129 | }
130 | }
131 |
132 | switch (theLastMessage){
133 | case "default":
134 | last_msg.setText("No Message");
135 | break;
136 |
137 | default:
138 | last_msg.setText(theLastMessage);
139 | break;
140 | }
141 |
142 | theLastMessage = "default";
143 | }
144 |
145 | @Override
146 | public void onCancelled(@NonNull DatabaseError databaseError) {
147 |
148 | }
149 | });
150 | }
151 | }
152 |
--------------------------------------------------------------------------------
/app/src/main/java/com/koddev/chatapp/Fragments/APIService.java:
--------------------------------------------------------------------------------
1 | package com.koddev.chatapp.Fragments;
2 |
3 | import com.koddev.chatapp.Notifications.MyResponse;
4 | import com.koddev.chatapp.Notifications.Sender;
5 |
6 | import retrofit2.Call;
7 | import retrofit2.http.Body;
8 | import retrofit2.http.Headers;
9 | import retrofit2.http.POST;
10 |
11 | public interface APIService {
12 | @Headers(
13 | {
14 | "Content-Type:application/json",
15 | "Authorization:key=ADD HERE YOUR KEY FROM FIREBASE PROJECT"
16 | }
17 | )
18 |
19 | @POST("fcm/send")
20 | Call sendNotification(@Body Sender body);
21 | }
22 |
--------------------------------------------------------------------------------
/app/src/main/java/com/koddev/chatapp/Fragments/ChatsFragment.java:
--------------------------------------------------------------------------------
1 | package com.koddev.chatapp.Fragments;
2 |
3 | import android.os.Bundle;
4 | import android.support.annotation.NonNull;
5 | import android.support.v4.app.Fragment;
6 | import android.support.v7.widget.LinearLayoutManager;
7 | import android.support.v7.widget.RecyclerView;
8 | import android.view.LayoutInflater;
9 | import android.view.View;
10 | import android.view.ViewGroup;
11 |
12 | import com.google.firebase.auth.FirebaseAuth;
13 | import com.google.firebase.auth.FirebaseUser;
14 | import com.google.firebase.database.DataSnapshot;
15 | import com.google.firebase.database.DatabaseError;
16 | import com.google.firebase.database.DatabaseReference;
17 | import com.google.firebase.database.FirebaseDatabase;
18 | import com.google.firebase.database.ValueEventListener;
19 | import com.google.firebase.iid.FirebaseInstanceId;
20 | import com.koddev.chatapp.Adapter.UserAdapter;
21 | import com.koddev.chatapp.Model.Chatlist;
22 | import com.koddev.chatapp.Model.User;
23 | import com.koddev.chatapp.Notifications.Token;
24 | import com.koddev.chatapp.R;
25 |
26 | import java.util.ArrayList;
27 | import java.util.List;
28 |
29 |
30 | public class ChatsFragment extends Fragment {
31 |
32 | private RecyclerView recyclerView;
33 |
34 | private UserAdapter userAdapter;
35 | private List mUsers;
36 |
37 | FirebaseUser fuser;
38 | DatabaseReference reference;
39 |
40 | private List usersList;
41 |
42 | @Override
43 | public View onCreateView(LayoutInflater inflater, ViewGroup container,
44 | Bundle savedInstanceState) {
45 | View view = inflater.inflate(R.layout.fragment_chats, container, false);
46 |
47 | recyclerView = view.findViewById(R.id.recycler_view);
48 | recyclerView.setHasFixedSize(true);
49 | recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
50 |
51 | fuser = FirebaseAuth.getInstance().getCurrentUser();
52 |
53 | usersList = new ArrayList<>();
54 |
55 | reference = FirebaseDatabase.getInstance().getReference("Chatlist").child(fuser.getUid());
56 | reference.addValueEventListener(new ValueEventListener() {
57 | @Override
58 | public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
59 | usersList.clear();
60 | for (DataSnapshot snapshot : dataSnapshot.getChildren()){
61 | Chatlist chatlist = snapshot.getValue(Chatlist.class);
62 | usersList.add(chatlist);
63 | }
64 |
65 | chatList();
66 | }
67 |
68 | @Override
69 | public void onCancelled(@NonNull DatabaseError databaseError) {
70 |
71 | }
72 | });
73 |
74 | updateToken(FirebaseInstanceId.getInstance().getToken());
75 |
76 |
77 | return view;
78 | }
79 |
80 | private void updateToken(String token){
81 | DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Tokens");
82 | Token token1 = new Token(token);
83 | reference.child(fuser.getUid()).setValue(token1);
84 | }
85 |
86 | private void chatList() {
87 | mUsers = new ArrayList<>();
88 | reference = FirebaseDatabase.getInstance().getReference("Users");
89 | reference.addValueEventListener(new ValueEventListener() {
90 | @Override
91 | public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
92 | mUsers.clear();
93 | for (DataSnapshot snapshot : dataSnapshot.getChildren()){
94 | User user = snapshot.getValue(User.class);
95 | for (Chatlist chatlist : usersList){
96 | if (user.getId().equals(chatlist.getId())){
97 | mUsers.add(user);
98 | }
99 | }
100 | }
101 | userAdapter = new UserAdapter(getContext(), mUsers, true);
102 | recyclerView.setAdapter(userAdapter);
103 | }
104 |
105 | @Override
106 | public void onCancelled(@NonNull DatabaseError databaseError) {
107 |
108 | }
109 | });
110 | }
111 |
112 | }
113 |
--------------------------------------------------------------------------------
/app/src/main/java/com/koddev/chatapp/Fragments/ProfileFragment.java:
--------------------------------------------------------------------------------
1 | package com.koddev.chatapp.Fragments;
2 |
3 | import android.app.ProgressDialog;
4 | import android.content.ContentResolver;
5 | import android.content.Intent;
6 | import android.net.Uri;
7 | import android.os.Bundle;
8 | import android.support.annotation.NonNull;
9 | import android.support.v4.app.Fragment;
10 | import android.view.LayoutInflater;
11 | import android.view.View;
12 | import android.view.ViewGroup;
13 | import android.webkit.MimeTypeMap;
14 | import android.widget.TextView;
15 | import android.widget.Toast;
16 |
17 | import com.bumptech.glide.Glide;
18 | import com.google.android.gms.tasks.Continuation;
19 | import com.google.android.gms.tasks.OnCompleteListener;
20 | import com.google.android.gms.tasks.OnFailureListener;
21 | import com.google.android.gms.tasks.Task;
22 | import com.google.firebase.auth.FirebaseAuth;
23 | import com.google.firebase.auth.FirebaseUser;
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.database.ValueEventListener;
29 | import com.google.firebase.storage.FirebaseStorage;
30 | import com.google.firebase.storage.StorageReference;
31 | import com.google.firebase.storage.StorageTask;
32 | import com.google.firebase.storage.UploadTask;
33 | import com.koddev.chatapp.Model.User;
34 | import com.koddev.chatapp.R;
35 |
36 | import java.util.HashMap;
37 |
38 | import de.hdodenhof.circleimageview.CircleImageView;
39 |
40 | import static android.app.Activity.RESULT_OK;
41 |
42 |
43 | public class ProfileFragment extends Fragment {
44 |
45 | CircleImageView image_profile;
46 | TextView username;
47 |
48 | DatabaseReference reference;
49 | FirebaseUser fuser;
50 |
51 | StorageReference storageReference;
52 | private static final int IMAGE_REQUEST = 1;
53 | private Uri imageUri;
54 | private StorageTask uploadTask;
55 |
56 |
57 | @Override
58 | public View onCreateView(LayoutInflater inflater, ViewGroup container,
59 | Bundle savedInstanceState) {
60 | // Inflate the layout for this fragment
61 | View view = inflater.inflate(R.layout.fragment_profile, container, false);
62 |
63 | image_profile = view.findViewById(R.id.profile_image);
64 | username = view.findViewById(R.id.username);
65 |
66 | storageReference = FirebaseStorage.getInstance().getReference("uploads");
67 |
68 | fuser = FirebaseAuth.getInstance().getCurrentUser();
69 | reference = FirebaseDatabase.getInstance().getReference("Users").child(fuser.getUid());
70 |
71 | reference.addValueEventListener(new ValueEventListener() {
72 | @Override
73 | public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
74 | User user = dataSnapshot.getValue(User.class);
75 | username.setText(user.getUsername());
76 | if (user.getImageURL().equals("default")){
77 | image_profile.setImageResource(R.mipmap.ic_launcher);
78 | } else {
79 | Glide.with(getContext()).load(user.getImageURL()).into(image_profile);
80 | }
81 | }
82 |
83 | @Override
84 | public void onCancelled(@NonNull DatabaseError databaseError) {
85 |
86 | }
87 | });
88 |
89 | image_profile.setOnClickListener(new View.OnClickListener() {
90 | @Override
91 | public void onClick(View view) {
92 | openImage();
93 | }
94 | });
95 |
96 | return view;
97 | }
98 |
99 | private void openImage() {
100 | Intent intent = new Intent();
101 | intent.setType("image/*");
102 | intent.setAction(Intent.ACTION_GET_CONTENT);
103 | startActivityForResult(intent, IMAGE_REQUEST);
104 | }
105 |
106 | private String getFileExtension(Uri uri){
107 | ContentResolver contentResolver = getContext().getContentResolver();
108 | MimeTypeMap mimeTypeMap = MimeTypeMap.getSingleton();
109 | return mimeTypeMap.getExtensionFromMimeType(contentResolver.getType(uri));
110 | }
111 |
112 | private void uploadImage(){
113 | final ProgressDialog pd = new ProgressDialog(getContext());
114 | pd.setMessage("Uploading");
115 | pd.show();
116 |
117 | if (imageUri != null){
118 | final StorageReference fileReference = storageReference.child(System.currentTimeMillis()
119 | +"."+getFileExtension(imageUri));
120 |
121 | uploadTask = fileReference.putFile(imageUri);
122 | uploadTask.continueWithTask(new Continuation>() {
123 | @Override
124 | public Task then(@NonNull Task task) throws Exception {
125 | if (!task.isSuccessful()){
126 | throw task.getException();
127 | }
128 |
129 | return fileReference.getDownloadUrl();
130 | }
131 | }).addOnCompleteListener(new OnCompleteListener() {
132 | @Override
133 | public void onComplete(@NonNull Task task) {
134 | if (task.isSuccessful()){
135 | Uri downloadUri = task.getResult();
136 | String mUri = downloadUri.toString();
137 |
138 | reference = FirebaseDatabase.getInstance().getReference("Users").child(fuser.getUid());
139 | HashMap map = new HashMap<>();
140 | map.put("imageURL", ""+mUri);
141 | reference.updateChildren(map);
142 |
143 | pd.dismiss();
144 | } else {
145 | Toast.makeText(getContext(), "Failed!", Toast.LENGTH_SHORT).show();
146 | pd.dismiss();
147 | }
148 | }
149 | }).addOnFailureListener(new OnFailureListener() {
150 | @Override
151 | public void onFailure(@NonNull Exception e) {
152 | Toast.makeText(getContext(), e.getMessage(), Toast.LENGTH_SHORT).show();
153 | pd.dismiss();
154 | }
155 | });
156 | } else {
157 | Toast.makeText(getContext(), "No image selected", Toast.LENGTH_SHORT).show();
158 | }
159 | }
160 |
161 | @Override
162 | public void onActivityResult(int requestCode, int resultCode, Intent data) {
163 | super.onActivityResult(requestCode, resultCode, data);
164 |
165 | if (requestCode == IMAGE_REQUEST && resultCode == RESULT_OK
166 | && data != null && data.getData() != null){
167 | imageUri = data.getData();
168 |
169 | if (uploadTask != null && uploadTask.isInProgress()){
170 | Toast.makeText(getContext(), "Upload in preogress", Toast.LENGTH_SHORT).show();
171 | } else {
172 | uploadImage();
173 | }
174 | }
175 | }
176 | }
177 |
--------------------------------------------------------------------------------
/app/src/main/java/com/koddev/chatapp/Fragments/UsersFragment.java:
--------------------------------------------------------------------------------
1 | package com.koddev.chatapp.Fragments;
2 |
3 | import android.os.Bundle;
4 | import android.support.annotation.NonNull;
5 | import android.support.v4.app.Fragment;
6 | import android.support.v7.widget.LinearLayoutManager;
7 | import android.support.v7.widget.RecyclerView;
8 | import android.text.Editable;
9 | import android.text.TextWatcher;
10 | import android.view.LayoutInflater;
11 | import android.view.View;
12 | import android.view.ViewGroup;
13 | import android.widget.EditText;
14 |
15 | import com.google.firebase.auth.FirebaseAuth;
16 | import com.google.firebase.auth.FirebaseUser;
17 | import com.google.firebase.database.DataSnapshot;
18 | import com.google.firebase.database.DatabaseError;
19 | import com.google.firebase.database.DatabaseReference;
20 | import com.google.firebase.database.FirebaseDatabase;
21 | import com.google.firebase.database.Query;
22 | import com.google.firebase.database.ValueEventListener;
23 | import com.koddev.chatapp.Adapter.UserAdapter;
24 | import com.koddev.chatapp.Model.User;
25 | import com.koddev.chatapp.R;
26 |
27 | import java.util.ArrayList;
28 | import java.util.List;
29 |
30 |
31 | public class UsersFragment extends Fragment {
32 |
33 | private RecyclerView recyclerView;
34 |
35 | private UserAdapter userAdapter;
36 | private List mUsers;
37 |
38 | EditText search_users;
39 |
40 |
41 | @Override
42 | public View onCreateView(LayoutInflater inflater, ViewGroup container,
43 | Bundle savedInstanceState) {
44 |
45 | View view = inflater.inflate(R.layout.fragment_users, container, false);
46 |
47 | recyclerView = view.findViewById(R.id.recycler_view);
48 | recyclerView.setHasFixedSize(true);
49 | recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
50 |
51 | mUsers = new ArrayList<>();
52 |
53 | readUsers();
54 |
55 | search_users = view.findViewById(R.id.search_users);
56 | search_users.addTextChangedListener(new TextWatcher() {
57 | @Override
58 | public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
59 |
60 | }
61 |
62 | @Override
63 | public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
64 | searchUsers(charSequence.toString().toLowerCase());
65 | }
66 |
67 | @Override
68 | public void afterTextChanged(Editable editable) {
69 |
70 | }
71 | });
72 |
73 | return view;
74 | }
75 |
76 | private void searchUsers(String s) {
77 |
78 | final FirebaseUser fuser = FirebaseAuth.getInstance().getCurrentUser();
79 | Query query = FirebaseDatabase.getInstance().getReference("Users").orderByChild("search")
80 | .startAt(s)
81 | .endAt(s+"\uf8ff");
82 |
83 | query.addValueEventListener(new ValueEventListener() {
84 | @Override
85 | public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
86 | mUsers.clear();
87 | for (DataSnapshot snapshot : dataSnapshot.getChildren()){
88 | User user = snapshot.getValue(User.class);
89 |
90 | assert user != null;
91 | assert fuser != null;
92 | if (!user.getId().equals(fuser.getUid())){
93 | mUsers.add(user);
94 | }
95 | }
96 |
97 | userAdapter = new UserAdapter(getContext(), mUsers, false);
98 | recyclerView.setAdapter(userAdapter);
99 | }
100 |
101 | @Override
102 | public void onCancelled(@NonNull DatabaseError databaseError) {
103 |
104 | }
105 | });
106 |
107 | }
108 |
109 | private void readUsers() {
110 |
111 | final FirebaseUser firebaseUser = FirebaseAuth.getInstance().getCurrentUser();
112 | DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Users");
113 |
114 | reference.addValueEventListener(new ValueEventListener() {
115 | @Override
116 | public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
117 | if (search_users.getText().toString().equals("")) {
118 | mUsers.clear();
119 | for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
120 | User user = snapshot.getValue(User.class);
121 |
122 | if (!user.getId().equals(firebaseUser.getUid())) {
123 | mUsers.add(user);
124 | }
125 |
126 | }
127 |
128 | userAdapter = new UserAdapter(getContext(), mUsers, false);
129 | recyclerView.setAdapter(userAdapter);
130 | }
131 | }
132 |
133 | @Override
134 | public void onCancelled(@NonNull DatabaseError databaseError) {
135 |
136 | }
137 | });
138 | }
139 | }
140 |
--------------------------------------------------------------------------------
/app/src/main/java/com/koddev/chatapp/LoginActivity.java:
--------------------------------------------------------------------------------
1 | package com.koddev.chatapp;
2 |
3 | import android.content.Intent;
4 | import android.os.Bundle;
5 | import android.support.annotation.NonNull;
6 | import android.support.v7.app.AppCompatActivity;
7 | import android.support.v7.widget.Toolbar;
8 | import android.text.TextUtils;
9 | import android.view.View;
10 | import android.widget.Button;
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.Task;
16 | import com.google.firebase.auth.AuthResult;
17 | import com.google.firebase.auth.FirebaseAuth;
18 | import com.rengwuxian.materialedittext.MaterialEditText;
19 |
20 | public class LoginActivity extends AppCompatActivity {
21 |
22 | MaterialEditText email, password;
23 | Button btn_login;
24 |
25 | FirebaseAuth auth;
26 | TextView forgot_password;
27 |
28 | @Override
29 | protected void onCreate(Bundle savedInstanceState) {
30 | super.onCreate(savedInstanceState);
31 | setContentView(R.layout.activity_login);
32 |
33 | Toolbar toolbar = findViewById(R.id.toolbar);
34 | setSupportActionBar(toolbar);
35 | getSupportActionBar().setTitle("Login");
36 | getSupportActionBar().setDisplayHomeAsUpEnabled(true);
37 |
38 | auth = FirebaseAuth.getInstance();
39 |
40 | email = findViewById(R.id.email);
41 | password = findViewById(R.id.password);
42 | btn_login = findViewById(R.id.btn_login);
43 | forgot_password = findViewById(R.id.forgot_password);
44 |
45 | forgot_password.setOnClickListener(new View.OnClickListener() {
46 | @Override
47 | public void onClick(View view) {
48 | startActivity(new Intent(LoginActivity.this, ResetPasswordActivity.class));
49 | }
50 | });
51 |
52 | btn_login.setOnClickListener(new View.OnClickListener() {
53 | @Override
54 | public void onClick(View view) {
55 | String txt_email = email.getText().toString();
56 | String txt_password = password.getText().toString();
57 |
58 | if (TextUtils.isEmpty(txt_email) || TextUtils.isEmpty(txt_password)){
59 | Toast.makeText(LoginActivity.this, "All fileds are required", Toast.LENGTH_SHORT).show();
60 | } else {
61 |
62 | auth.signInWithEmailAndPassword(txt_email, txt_password)
63 | .addOnCompleteListener(new OnCompleteListener() {
64 | @Override
65 | public void onComplete(@NonNull Task task) {
66 | if (task.isSuccessful()){
67 | Intent intent = new Intent(LoginActivity.this, MainActivity.class);
68 | intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
69 | startActivity(intent);
70 | finish();
71 | } else {
72 | Toast.makeText(LoginActivity.this, "Authentication failed!", Toast.LENGTH_SHORT).show();
73 | }
74 | }
75 | });
76 | }
77 | }
78 | });
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/app/src/main/java/com/koddev/chatapp/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.koddev.chatapp;
2 |
3 | import android.content.Intent;
4 | import android.os.Bundle;
5 | import android.support.annotation.NonNull;
6 | import android.support.annotation.Nullable;
7 | import android.support.design.widget.TabLayout;
8 | import android.support.v4.app.Fragment;
9 | import android.support.v4.app.FragmentManager;
10 | import android.support.v4.app.FragmentPagerAdapter;
11 | import android.support.v4.view.ViewPager;
12 | import android.support.v7.app.AppCompatActivity;
13 | import android.support.v7.widget.Toolbar;
14 | import android.view.Menu;
15 | import android.view.MenuItem;
16 | import android.widget.TextView;
17 |
18 | import com.bumptech.glide.Glide;
19 | import com.google.firebase.auth.FirebaseAuth;
20 | import com.google.firebase.auth.FirebaseUser;
21 | import com.google.firebase.database.DataSnapshot;
22 | import com.google.firebase.database.DatabaseError;
23 | import com.google.firebase.database.DatabaseReference;
24 | import com.google.firebase.database.FirebaseDatabase;
25 | import com.google.firebase.database.ValueEventListener;
26 | import com.koddev.chatapp.Fragments.ChatsFragment;
27 | import com.koddev.chatapp.Fragments.ProfileFragment;
28 | import com.koddev.chatapp.Fragments.UsersFragment;
29 | import com.koddev.chatapp.Model.Chat;
30 | import com.koddev.chatapp.Model.User;
31 |
32 | import java.util.ArrayList;
33 | import java.util.HashMap;
34 |
35 | import de.hdodenhof.circleimageview.CircleImageView;
36 |
37 | public class MainActivity extends AppCompatActivity {
38 |
39 | CircleImageView profile_image;
40 | TextView username;
41 |
42 | FirebaseUser firebaseUser;
43 | DatabaseReference reference;
44 |
45 | @Override
46 | protected void onCreate(Bundle savedInstanceState) {
47 | super.onCreate(savedInstanceState);
48 | setContentView(R.layout.activity_main);
49 |
50 | Toolbar toolbar = findViewById(R.id.toolbar);
51 | setSupportActionBar(toolbar);
52 | getSupportActionBar().setTitle("");
53 |
54 | profile_image = findViewById(R.id.profile_image);
55 | username = findViewById(R.id.username);
56 |
57 | firebaseUser = FirebaseAuth.getInstance().getCurrentUser();
58 | reference = FirebaseDatabase.getInstance().getReference("Users").child(firebaseUser.getUid());
59 |
60 | reference.addValueEventListener(new ValueEventListener() {
61 | @Override
62 | public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
63 | User user = dataSnapshot.getValue(User.class);
64 | username.setText(user.getUsername());
65 | if (user.getImageURL().equals("default")){
66 | profile_image.setImageResource(R.mipmap.ic_launcher);
67 | } else {
68 |
69 | //change this
70 | Glide.with(getApplicationContext()).load(user.getImageURL()).into(profile_image);
71 | }
72 | }
73 |
74 | @Override
75 | public void onCancelled(@NonNull DatabaseError databaseError) {
76 |
77 | }
78 | });
79 |
80 | final TabLayout tabLayout = findViewById(R.id.tab_layout);
81 | final ViewPager viewPager = findViewById(R.id.view_pager);
82 |
83 |
84 | reference = FirebaseDatabase.getInstance().getReference("Chats");
85 | reference.addValueEventListener(new ValueEventListener() {
86 | @Override
87 | public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
88 | ViewPagerAdapter viewPagerAdapter = new ViewPagerAdapter(getSupportFragmentManager());
89 | int unread = 0;
90 | for (DataSnapshot snapshot : dataSnapshot.getChildren()){
91 | Chat chat = snapshot.getValue(Chat.class);
92 | if (chat.getReceiver().equals(firebaseUser.getUid()) && !chat.isIsseen()){
93 | unread++;
94 | }
95 | }
96 |
97 | if (unread == 0){
98 | viewPagerAdapter.addFragment(new ChatsFragment(), "Chats");
99 | } else {
100 | viewPagerAdapter.addFragment(new ChatsFragment(), "("+unread+") Chats");
101 | }
102 |
103 | viewPagerAdapter.addFragment(new UsersFragment(), "Users");
104 | viewPagerAdapter.addFragment(new ProfileFragment(), "Profile");
105 |
106 | viewPager.setAdapter(viewPagerAdapter);
107 |
108 | tabLayout.setupWithViewPager(viewPager);
109 |
110 | }
111 |
112 | @Override
113 | public void onCancelled(@NonNull DatabaseError databaseError) {
114 |
115 | }
116 | });
117 |
118 |
119 | }
120 |
121 | @Override
122 | public boolean onCreateOptionsMenu(Menu menu) {
123 | getMenuInflater().inflate(R.menu.menu, menu);
124 | return true;
125 | }
126 |
127 | @Override
128 | public boolean onOptionsItemSelected(MenuItem item) {
129 | switch (item.getItemId()){
130 |
131 | case R.id.logout:
132 | FirebaseAuth.getInstance().signOut();
133 | // change this code beacuse your app will crash
134 | startActivity(new Intent(MainActivity.this, StartActivity.class).setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP));
135 | return true;
136 | }
137 |
138 | return false;
139 | }
140 |
141 | class ViewPagerAdapter extends FragmentPagerAdapter {
142 |
143 | private ArrayList fragments;
144 | private ArrayList titles;
145 |
146 | ViewPagerAdapter(FragmentManager fm){
147 | super(fm);
148 | this.fragments = new ArrayList<>();
149 | this.titles = new ArrayList<>();
150 | }
151 |
152 | @Override
153 | public Fragment getItem(int position) {
154 | return fragments.get(position);
155 | }
156 |
157 | @Override
158 | public int getCount() {
159 | return fragments.size();
160 | }
161 |
162 | public void addFragment(Fragment fragment, String title){
163 | fragments.add(fragment);
164 | titles.add(title);
165 | }
166 |
167 | // Ctrl + O
168 |
169 | @Nullable
170 | @Override
171 | public CharSequence getPageTitle(int position) {
172 | return titles.get(position);
173 | }
174 | }
175 |
176 | private void status(String status){
177 | reference = FirebaseDatabase.getInstance().getReference("Users").child(firebaseUser.getUid());
178 |
179 | HashMap hashMap = new HashMap<>();
180 | hashMap.put("status", status);
181 |
182 | reference.updateChildren(hashMap);
183 | }
184 |
185 | @Override
186 | protected void onResume() {
187 | super.onResume();
188 | status("online");
189 | }
190 |
191 | @Override
192 | protected void onPause() {
193 | super.onPause();
194 | status("offline");
195 | }
196 | }
197 |
--------------------------------------------------------------------------------
/app/src/main/java/com/koddev/chatapp/MessageActivity.java:
--------------------------------------------------------------------------------
1 | package com.koddev.chatapp;
2 |
3 | import android.content.Intent;
4 | import android.content.SharedPreferences;
5 | import android.os.Bundle;
6 | import android.support.annotation.NonNull;
7 | import android.support.v7.app.AppCompatActivity;
8 | import android.support.v7.widget.LinearLayoutManager;
9 | import android.support.v7.widget.RecyclerView;
10 | import android.support.v7.widget.Toolbar;
11 | import android.view.View;
12 | import android.widget.EditText;
13 | import android.widget.ImageButton;
14 | import android.widget.TextView;
15 | import android.widget.Toast;
16 |
17 | import com.bumptech.glide.Glide;
18 | import com.google.firebase.auth.FirebaseAuth;
19 | import com.google.firebase.auth.FirebaseUser;
20 | import com.google.firebase.database.DataSnapshot;
21 | import com.google.firebase.database.DatabaseError;
22 | import com.google.firebase.database.DatabaseReference;
23 | import com.google.firebase.database.FirebaseDatabase;
24 | import com.google.firebase.database.Query;
25 | import com.google.firebase.database.ValueEventListener;
26 | import com.koddev.chatapp.Adapter.MessageAdapter;
27 | import com.koddev.chatapp.Fragments.APIService;
28 | import com.koddev.chatapp.Model.Chat;
29 | import com.koddev.chatapp.Model.User;
30 | import com.koddev.chatapp.Notifications.Client;
31 | import com.koddev.chatapp.Notifications.Data;
32 | import com.koddev.chatapp.Notifications.MyResponse;
33 | import com.koddev.chatapp.Notifications.Sender;
34 | import com.koddev.chatapp.Notifications.Token;
35 |
36 | import java.util.ArrayList;
37 | import java.util.HashMap;
38 | import java.util.List;
39 |
40 | import de.hdodenhof.circleimageview.CircleImageView;
41 | import retrofit2.Call;
42 | import retrofit2.Callback;
43 | import retrofit2.Response;
44 |
45 | public class MessageActivity extends AppCompatActivity {
46 |
47 | CircleImageView profile_image;
48 | TextView username;
49 |
50 | FirebaseUser fuser;
51 | DatabaseReference reference;
52 |
53 | ImageButton btn_send;
54 | EditText text_send;
55 |
56 | MessageAdapter messageAdapter;
57 | List mchat;
58 |
59 | RecyclerView recyclerView;
60 |
61 | Intent intent;
62 |
63 | ValueEventListener seenListener;
64 |
65 | String userid;
66 |
67 | APIService apiService;
68 |
69 | boolean notify = false;
70 |
71 | @Override
72 | protected void onCreate(Bundle savedInstanceState) {
73 | super.onCreate(savedInstanceState);
74 | setContentView(R.layout.activity_message);
75 |
76 | Toolbar toolbar = findViewById(R.id.toolbar);
77 | setSupportActionBar(toolbar);
78 | getSupportActionBar().setTitle("");
79 | getSupportActionBar().setDisplayHomeAsUpEnabled(true);
80 | toolbar.setNavigationOnClickListener(new View.OnClickListener() {
81 | @Override
82 | public void onClick(View view) {
83 | // and this
84 | startActivity(new Intent(MessageActivity.this, MainActivity.class).setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP));
85 | }
86 | });
87 |
88 | apiService = Client.getClient("https://fcm.googleapis.com/").create(APIService.class);
89 |
90 | recyclerView = findViewById(R.id.recycler_view);
91 | recyclerView.setHasFixedSize(true);
92 | LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getApplicationContext());
93 | linearLayoutManager.setStackFromEnd(true);
94 | recyclerView.setLayoutManager(linearLayoutManager);
95 |
96 | profile_image = findViewById(R.id.profile_image);
97 | username = findViewById(R.id.username);
98 | btn_send = findViewById(R.id.btn_send);
99 | text_send = findViewById(R.id.text_send);
100 |
101 | intent = getIntent();
102 | userid = intent.getStringExtra("userid");
103 | fuser = FirebaseAuth.getInstance().getCurrentUser();
104 |
105 | btn_send.setOnClickListener(new View.OnClickListener() {
106 | @Override
107 | public void onClick(View view) {
108 | notify = true;
109 | String msg = text_send.getText().toString();
110 | if (!msg.equals("")){
111 | sendMessage(fuser.getUid(), userid, msg);
112 | } else {
113 | Toast.makeText(MessageActivity.this, "You can't send empty message", Toast.LENGTH_SHORT).show();
114 | }
115 | text_send.setText("");
116 | }
117 | });
118 |
119 |
120 | reference = FirebaseDatabase.getInstance().getReference("Users").child(userid);
121 |
122 | reference.addValueEventListener(new ValueEventListener() {
123 | @Override
124 | public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
125 | User user = dataSnapshot.getValue(User.class);
126 | username.setText(user.getUsername());
127 | if (user.getImageURL().equals("default")){
128 | profile_image.setImageResource(R.mipmap.ic_launcher);
129 | } else {
130 | //and this
131 | Glide.with(getApplicationContext()).load(user.getImageURL()).into(profile_image);
132 | }
133 |
134 | readMesagges(fuser.getUid(), userid, user.getImageURL());
135 | }
136 |
137 | @Override
138 | public void onCancelled(@NonNull DatabaseError databaseError) {
139 |
140 | }
141 | });
142 |
143 | seenMessage(userid);
144 | }
145 |
146 | private void seenMessage(final String userid){
147 | reference = FirebaseDatabase.getInstance().getReference("Chats");
148 | seenListener = reference.addValueEventListener(new ValueEventListener() {
149 | @Override
150 | public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
151 | for (DataSnapshot snapshot : dataSnapshot.getChildren()){
152 | Chat chat = snapshot.getValue(Chat.class);
153 | if (chat.getReceiver().equals(fuser.getUid()) && chat.getSender().equals(userid)){
154 | HashMap hashMap = new HashMap<>();
155 | hashMap.put("isseen", true);
156 | snapshot.getRef().updateChildren(hashMap);
157 | }
158 | }
159 | }
160 |
161 | @Override
162 | public void onCancelled(@NonNull DatabaseError databaseError) {
163 |
164 | }
165 | });
166 | }
167 |
168 | private void sendMessage(String sender, final String receiver, String message){
169 |
170 | DatabaseReference reference = FirebaseDatabase.getInstance().getReference();
171 |
172 | HashMap hashMap = new HashMap<>();
173 | hashMap.put("sender", sender);
174 | hashMap.put("receiver", receiver);
175 | hashMap.put("message", message);
176 | hashMap.put("isseen", false);
177 |
178 | reference.child("Chats").push().setValue(hashMap);
179 |
180 |
181 | // add user to chat fragment
182 | final DatabaseReference chatRef = FirebaseDatabase.getInstance().getReference("Chatlist")
183 | .child(fuser.getUid())
184 | .child(userid);
185 |
186 | chatRef.addListenerForSingleValueEvent(new ValueEventListener() {
187 | @Override
188 | public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
189 | if (!dataSnapshot.exists()){
190 | chatRef.child("id").setValue(userid);
191 | }
192 | }
193 |
194 | @Override
195 | public void onCancelled(@NonNull DatabaseError databaseError) {
196 |
197 | }
198 | });
199 |
200 | final DatabaseReference chatRefReceiver = FirebaseDatabase.getInstance().getReference("Chatlist")
201 | .child(userid)
202 | .child(fuser.getUid());
203 | chatRefReceiver.child("id").setValue(fuser.getUid());
204 |
205 | final String msg = message;
206 |
207 | reference = FirebaseDatabase.getInstance().getReference("Users").child(fuser.getUid());
208 | reference.addValueEventListener(new ValueEventListener() {
209 | @Override
210 | public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
211 | User user = dataSnapshot.getValue(User.class);
212 | if (notify) {
213 | sendNotifiaction(receiver, user.getUsername(), msg);
214 | }
215 | notify = false;
216 | }
217 |
218 | @Override
219 | public void onCancelled(@NonNull DatabaseError databaseError) {
220 |
221 | }
222 | });
223 | }
224 |
225 | private void sendNotifiaction(String receiver, final String username, final String message){
226 | DatabaseReference tokens = FirebaseDatabase.getInstance().getReference("Tokens");
227 | Query query = tokens.orderByKey().equalTo(receiver);
228 | query.addValueEventListener(new ValueEventListener() {
229 | @Override
230 | public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
231 | for (DataSnapshot snapshot : dataSnapshot.getChildren()){
232 | Token token = snapshot.getValue(Token.class);
233 | Data data = new Data(fuser.getUid(), R.mipmap.ic_launcher, username+": "+message, "New Message",
234 | userid);
235 |
236 | Sender sender = new Sender(data, token.getToken());
237 |
238 | apiService.sendNotification(sender)
239 | .enqueue(new Callback() {
240 | @Override
241 | public void onResponse(Call call, Response response) {
242 | if (response.code() == 200){
243 | if (response.body().success != 1){
244 | Toast.makeText(MessageActivity.this, "Failed!", Toast.LENGTH_SHORT).show();
245 | }
246 | }
247 | }
248 |
249 | @Override
250 | public void onFailure(Call call, Throwable t) {
251 |
252 | }
253 | });
254 | }
255 | }
256 |
257 | @Override
258 | public void onCancelled(@NonNull DatabaseError databaseError) {
259 |
260 | }
261 | });
262 | }
263 |
264 | private void readMesagges(final String myid, final String userid, final String imageurl){
265 | mchat = new ArrayList<>();
266 |
267 | reference = FirebaseDatabase.getInstance().getReference("Chats");
268 | reference.addValueEventListener(new ValueEventListener() {
269 | @Override
270 | public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
271 | mchat.clear();
272 | for (DataSnapshot snapshot : dataSnapshot.getChildren()){
273 | Chat chat = snapshot.getValue(Chat.class);
274 | if (chat.getReceiver().equals(myid) && chat.getSender().equals(userid) ||
275 | chat.getReceiver().equals(userid) && chat.getSender().equals(myid)){
276 | mchat.add(chat);
277 | }
278 |
279 | messageAdapter = new MessageAdapter(MessageActivity.this, mchat, imageurl);
280 | recyclerView.setAdapter(messageAdapter);
281 | }
282 | }
283 |
284 | @Override
285 | public void onCancelled(@NonNull DatabaseError databaseError) {
286 |
287 | }
288 | });
289 | }
290 |
291 | private void currentUser(String userid){
292 | SharedPreferences.Editor editor = getSharedPreferences("PREFS", MODE_PRIVATE).edit();
293 | editor.putString("currentuser", userid);
294 | editor.apply();
295 | }
296 |
297 | private void status(String status){
298 | reference = FirebaseDatabase.getInstance().getReference("Users").child(fuser.getUid());
299 |
300 | HashMap hashMap = new HashMap<>();
301 | hashMap.put("status", status);
302 |
303 | reference.updateChildren(hashMap);
304 | }
305 |
306 | @Override
307 | protected void onResume() {
308 | super.onResume();
309 | status("online");
310 | currentUser(userid);
311 | }
312 |
313 | @Override
314 | protected void onPause() {
315 | super.onPause();
316 | reference.removeEventListener(seenListener);
317 | status("offline");
318 | currentUser("none");
319 | }
320 | }
321 |
--------------------------------------------------------------------------------
/app/src/main/java/com/koddev/chatapp/Model/Chat.java:
--------------------------------------------------------------------------------
1 | package com.koddev.chatapp.Model;
2 |
3 | public class Chat {
4 |
5 | private String sender;
6 | private String receiver;
7 | private String message;
8 | private boolean isseen;
9 |
10 | public Chat(String sender, String receiver, String message, boolean isseen) {
11 | this.sender = sender;
12 | this.receiver = receiver;
13 | this.message = message;
14 | this.isseen = isseen;
15 | }
16 |
17 | public Chat() {
18 | }
19 |
20 | public String getSender() {
21 | return sender;
22 | }
23 |
24 | public void setSender(String sender) {
25 | this.sender = sender;
26 | }
27 |
28 | public String getReceiver() {
29 | return receiver;
30 | }
31 |
32 | public void setReceiver(String receiver) {
33 | this.receiver = receiver;
34 | }
35 |
36 | public String getMessage() {
37 | return message;
38 | }
39 |
40 | public void setMessage(String message) {
41 | this.message = message;
42 | }
43 |
44 | public boolean isIsseen() {
45 | return isseen;
46 | }
47 |
48 | public void setIsseen(boolean isseen) {
49 | this.isseen = isseen;
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/app/src/main/java/com/koddev/chatapp/Model/Chatlist.java:
--------------------------------------------------------------------------------
1 | package com.koddev.chatapp.Model;
2 |
3 | public class Chatlist {
4 | public String id;
5 |
6 | public Chatlist(String id) {
7 | this.id = id;
8 | }
9 |
10 | public Chatlist() {
11 | }
12 |
13 | public String getId() {
14 | return id;
15 | }
16 |
17 | public void setId(String id) {
18 | this.id = id;
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/app/src/main/java/com/koddev/chatapp/Model/User.java:
--------------------------------------------------------------------------------
1 | package com.koddev.chatapp.Model;
2 |
3 | public class User {
4 |
5 | private String id;
6 | private String username;
7 | private String imageURL;
8 | private String status;
9 | private String search;
10 |
11 | public User(String id, String username, String imageURL, String status, String search) {
12 | this.id = id;
13 | this.username = username;
14 | this.imageURL = imageURL;
15 | this.status = status;
16 | this.search = search;
17 | }
18 |
19 | public User() {
20 |
21 | }
22 |
23 | public String getId() {
24 | return id;
25 | }
26 |
27 | public void setId(String id) {
28 | this.id = id;
29 | }
30 |
31 | public String getUsername() {
32 | return username;
33 | }
34 |
35 | public void setUsername(String username) {
36 | this.username = username;
37 | }
38 |
39 | public String getImageURL() {
40 | return imageURL;
41 | }
42 |
43 | public void setImageURL(String imageURL) {
44 | this.imageURL = imageURL;
45 | }
46 |
47 | public String getStatus() {
48 | return status;
49 | }
50 |
51 | public void setStatus(String status) {
52 | this.status = status;
53 | }
54 |
55 | public String getSearch() {
56 | return search;
57 | }
58 |
59 | public void setSearch(String search) {
60 | this.search = search;
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/app/src/main/java/com/koddev/chatapp/Notifications/Client.java:
--------------------------------------------------------------------------------
1 | package com.koddev.chatapp.Notifications;
2 |
3 | import retrofit2.Retrofit;
4 | import retrofit2.converter.gson.GsonConverterFactory;
5 |
6 | public class Client {
7 |
8 | private static Retrofit retrofit = null;
9 |
10 | public static Retrofit getClient(String url){
11 | if (retrofit == null){
12 | retrofit = new Retrofit.Builder()
13 | .baseUrl(url)
14 | .addConverterFactory(GsonConverterFactory.create())
15 | .build();
16 | }
17 | return retrofit;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/app/src/main/java/com/koddev/chatapp/Notifications/Data.java:
--------------------------------------------------------------------------------
1 | package com.koddev.chatapp.Notifications;
2 |
3 | public class Data {
4 | private String user;
5 | private int icon;
6 | private String body;
7 | private String title;
8 | private String sented;
9 |
10 | public Data(String user, int icon, String body, String title, String sented) {
11 | this.user = user;
12 | this.icon = icon;
13 | this.body = body;
14 | this.title = title;
15 | this.sented = sented;
16 | }
17 |
18 | public Data() {
19 | }
20 |
21 | public String getUser() {
22 | return user;
23 | }
24 |
25 | public void setUser(String user) {
26 | this.user = user;
27 | }
28 |
29 | public int getIcon() {
30 | return icon;
31 | }
32 |
33 | public void setIcon(int icon) {
34 | this.icon = icon;
35 | }
36 |
37 | public String getBody() {
38 | return body;
39 | }
40 |
41 | public void setBody(String body) {
42 | this.body = body;
43 | }
44 |
45 | public String getTitle() {
46 | return title;
47 | }
48 |
49 | public void setTitle(String title) {
50 | this.title = title;
51 | }
52 |
53 | public String getSented() {
54 | return sented;
55 | }
56 |
57 | public void setSented(String sented) {
58 | this.sented = sented;
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/app/src/main/java/com/koddev/chatapp/Notifications/MyFirebaseIdService.java:
--------------------------------------------------------------------------------
1 | package com.koddev.chatapp.Notifications;
2 |
3 | import com.google.firebase.auth.FirebaseAuth;
4 | import com.google.firebase.auth.FirebaseUser;
5 | import com.google.firebase.database.DatabaseReference;
6 | import com.google.firebase.database.FirebaseDatabase;
7 | import com.google.firebase.iid.FirebaseInstanceId;
8 | import com.google.firebase.iid.FirebaseInstanceIdService;
9 |
10 | public class MyFirebaseIdService extends FirebaseInstanceIdService {
11 |
12 | @Override
13 | public void onTokenRefresh() {
14 | super.onTokenRefresh();
15 | FirebaseUser firebaseUser = FirebaseAuth.getInstance().getCurrentUser();
16 |
17 | String refreshToken = FirebaseInstanceId.getInstance().getToken();
18 | if (firebaseUser != null){
19 | updateToken(refreshToken);
20 | }
21 | }
22 |
23 | private void updateToken(String refreshToken) {
24 | FirebaseUser firebaseUser = FirebaseAuth.getInstance().getCurrentUser();
25 |
26 | DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Tokens");
27 | Token token = new Token(refreshToken);
28 | reference.child(firebaseUser.getUid()).setValue(token);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/app/src/main/java/com/koddev/chatapp/Notifications/MyFirebaseMessaging.java:
--------------------------------------------------------------------------------
1 | package com.koddev.chatapp.Notifications;
2 |
3 | import android.app.Notification;
4 | import android.app.NotificationManager;
5 | import android.app.PendingIntent;
6 | import android.content.Context;
7 | import android.content.Intent;
8 | import android.content.SharedPreferences;
9 | import android.media.RingtoneManager;
10 | import android.net.Uri;
11 | import android.os.Build;
12 | import android.os.Bundle;
13 | import android.support.v4.app.NotificationCompat;
14 |
15 | import com.google.firebase.auth.FirebaseAuth;
16 | import com.google.firebase.auth.FirebaseUser;
17 | import com.google.firebase.messaging.FirebaseMessagingService;
18 | import com.google.firebase.messaging.RemoteMessage;
19 | import com.koddev.chatapp.MessageActivity;
20 |
21 | public class MyFirebaseMessaging extends FirebaseMessagingService {
22 |
23 | @Override
24 | public void onMessageReceived(RemoteMessage remoteMessage) {
25 | super.onMessageReceived(remoteMessage);
26 |
27 | String sented = remoteMessage.getData().get("sented");
28 | String user = remoteMessage.getData().get("user");
29 |
30 | SharedPreferences preferences = getSharedPreferences("PREFS", MODE_PRIVATE);
31 | String currentUser = preferences.getString("currentuser", "none");
32 |
33 | FirebaseUser firebaseUser = FirebaseAuth.getInstance().getCurrentUser();
34 |
35 | if (firebaseUser != null && sented.equals(firebaseUser.getUid())){
36 | if (!currentUser.equals(user)) {
37 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
38 | sendOreoNotification(remoteMessage);
39 | } else {
40 | sendNotification(remoteMessage);
41 | }
42 | }
43 | }
44 | }
45 |
46 | private void sendOreoNotification(RemoteMessage remoteMessage){
47 | String user = remoteMessage.getData().get("user");
48 | String icon = remoteMessage.getData().get("icon");
49 | String title = remoteMessage.getData().get("title");
50 | String body = remoteMessage.getData().get("body");
51 |
52 | RemoteMessage.Notification notification = remoteMessage.getNotification();
53 | int j = Integer.parseInt(user.replaceAll("[\\D]", ""));
54 | Intent intent = new Intent(this, MessageActivity.class);
55 | Bundle bundle = new Bundle();
56 | bundle.putString("userid", user);
57 | intent.putExtras(bundle);
58 | intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
59 | PendingIntent pendingIntent = PendingIntent.getActivity(this, j, intent, PendingIntent.FLAG_ONE_SHOT);
60 | Uri defaultSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
61 |
62 | OreoNotification oreoNotification = new OreoNotification(this);
63 | Notification.Builder builder = oreoNotification.getOreoNotification(title, body, pendingIntent,
64 | defaultSound, icon);
65 |
66 | int i = 0;
67 | if (j > 0){
68 | i = j;
69 | }
70 |
71 | oreoNotification.getManager().notify(i, builder.build());
72 |
73 | }
74 |
75 | private void sendNotification(RemoteMessage remoteMessage) {
76 |
77 | String user = remoteMessage.getData().get("user");
78 | String icon = remoteMessage.getData().get("icon");
79 | String title = remoteMessage.getData().get("title");
80 | String body = remoteMessage.getData().get("body");
81 |
82 | RemoteMessage.Notification notification = remoteMessage.getNotification();
83 | int j = Integer.parseInt(user.replaceAll("[\\D]", ""));
84 | Intent intent = new Intent(this, MessageActivity.class);
85 | Bundle bundle = new Bundle();
86 | bundle.putString("userid", user);
87 | intent.putExtras(bundle);
88 | intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
89 | PendingIntent pendingIntent = PendingIntent.getActivity(this, j, intent, PendingIntent.FLAG_ONE_SHOT);
90 |
91 | Uri defaultSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
92 | NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
93 | .setSmallIcon(Integer.parseInt(icon))
94 | .setContentTitle(title)
95 | .setContentText(body)
96 | .setAutoCancel(true)
97 | .setSound(defaultSound)
98 | .setContentIntent(pendingIntent);
99 | NotificationManager noti = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
100 |
101 | int i = 0;
102 | if (j > 0){
103 | i = j;
104 | }
105 |
106 | noti.notify(i, builder.build());
107 | }
108 | }
109 |
--------------------------------------------------------------------------------
/app/src/main/java/com/koddev/chatapp/Notifications/MyResponse.java:
--------------------------------------------------------------------------------
1 | package com.koddev.chatapp.Notifications;
2 |
3 | public class MyResponse {
4 |
5 | public int success;
6 | }
7 |
--------------------------------------------------------------------------------
/app/src/main/java/com/koddev/chatapp/Notifications/OreoNotification.java:
--------------------------------------------------------------------------------
1 | package com.koddev.chatapp.Notifications;
2 |
3 | import android.annotation.TargetApi;
4 | import android.app.Notification;
5 | import android.app.NotificationChannel;
6 | import android.app.NotificationManager;
7 | import android.app.PendingIntent;
8 | import android.content.Context;
9 | import android.content.ContextWrapper;
10 | import android.net.Uri;
11 | import android.os.Build;
12 |
13 | public class OreoNotification extends ContextWrapper {
14 |
15 | private static final String CHANNEL_ID = "com.koddev.chatapp";
16 | private static final String CHANNEL_NAME = "chatapp";
17 |
18 | private NotificationManager notificationManager;
19 |
20 | public OreoNotification(Context base) {
21 | super(base);
22 |
23 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
24 | createChannel();
25 | }
26 | }
27 |
28 | @TargetApi(Build.VERSION_CODES.O)
29 | private void createChannel() {
30 |
31 | NotificationChannel channel = new NotificationChannel(CHANNEL_ID,
32 | CHANNEL_NAME,
33 | NotificationManager.IMPORTANCE_DEFAULT);
34 | channel.enableLights(false);
35 | channel.enableVibration(true);
36 | channel.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
37 |
38 | getManager().createNotificationChannel(channel);
39 | }
40 |
41 | public NotificationManager getManager(){
42 | if (notificationManager == null){
43 | notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
44 | }
45 |
46 | return notificationManager;
47 | }
48 |
49 | @TargetApi(Build.VERSION_CODES.O)
50 | public Notification.Builder getOreoNotification(String title, String body,
51 | PendingIntent pendingIntent, Uri soundUri, String icon){
52 | return new Notification.Builder(getApplicationContext(), CHANNEL_ID)
53 | .setContentIntent(pendingIntent)
54 | .setContentTitle(title)
55 | .setContentText(body)
56 | .setSmallIcon(Integer.parseInt(icon))
57 | .setSound(soundUri)
58 | .setAutoCancel(true);
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/app/src/main/java/com/koddev/chatapp/Notifications/Sender.java:
--------------------------------------------------------------------------------
1 | package com.koddev.chatapp.Notifications;
2 |
3 | public class Sender {
4 | public Data data;
5 | public String to;
6 |
7 | public Sender(Data data, String to) {
8 | this.data = data;
9 | this.to = to;
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/app/src/main/java/com/koddev/chatapp/Notifications/Token.java:
--------------------------------------------------------------------------------
1 | package com.koddev.chatapp.Notifications;
2 |
3 | public class Token {
4 | private String token;
5 |
6 | public Token(String token) {
7 | this.token = token;
8 | }
9 |
10 | public Token() {
11 | }
12 |
13 | public String getToken() {
14 | return token;
15 | }
16 |
17 | public void setToken(String token) {
18 | this.token = token;
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/app/src/main/java/com/koddev/chatapp/RegisterActivity.java:
--------------------------------------------------------------------------------
1 | package com.koddev.chatapp;
2 |
3 | import android.content.Intent;
4 | import android.os.Bundle;
5 | import android.support.annotation.NonNull;
6 | import android.support.v7.app.AppCompatActivity;
7 | import android.support.v7.widget.Toolbar;
8 | import android.text.TextUtils;
9 | import android.view.View;
10 | import android.widget.Button;
11 | import android.widget.Toast;
12 |
13 | import com.google.android.gms.tasks.OnCompleteListener;
14 | import com.google.android.gms.tasks.Task;
15 | import com.google.firebase.auth.AuthResult;
16 | import com.google.firebase.auth.FirebaseAuth;
17 | import com.google.firebase.auth.FirebaseUser;
18 | import com.google.firebase.database.DatabaseReference;
19 | import com.google.firebase.database.FirebaseDatabase;
20 | import com.rengwuxian.materialedittext.MaterialEditText;
21 |
22 | import java.util.HashMap;
23 |
24 | public class RegisterActivity extends AppCompatActivity {
25 |
26 | MaterialEditText username, email, password;
27 | Button btn_register;
28 |
29 | FirebaseAuth auth;
30 | DatabaseReference reference;
31 |
32 | @Override
33 | protected void onCreate(Bundle savedInstanceState) {
34 | super.onCreate(savedInstanceState);
35 | setContentView(R.layout.activity_register);
36 |
37 | Toolbar toolbar = findViewById(R.id.toolbar);
38 | setSupportActionBar(toolbar);
39 | getSupportActionBar().setTitle("Register");
40 | getSupportActionBar().setDisplayHomeAsUpEnabled(true);
41 |
42 | username = findViewById(R.id.username);
43 | email = findViewById(R.id.email);
44 | password = findViewById(R.id.password);
45 | btn_register = findViewById(R.id.btn_register);
46 |
47 | auth = FirebaseAuth.getInstance();
48 |
49 | btn_register.setOnClickListener(new View.OnClickListener() {
50 | @Override
51 | public void onClick(View view) {
52 | String txt_username = username.getText().toString();
53 | String txt_email = email.getText().toString();
54 | String txt_password = password.getText().toString();
55 |
56 | if (TextUtils.isEmpty(txt_username) || TextUtils.isEmpty(txt_email) || TextUtils.isEmpty(txt_password)){
57 | Toast.makeText(RegisterActivity.this, "All fileds are required", Toast.LENGTH_SHORT).show();
58 | } else if (txt_password.length() < 6 ){
59 | Toast.makeText(RegisterActivity.this, "password must be at least 6 characters", Toast.LENGTH_SHORT).show();
60 | } else {
61 | register(txt_username, txt_email, txt_password);
62 | }
63 | }
64 | });
65 | }
66 |
67 | private void register(final String username, String email, String password){
68 |
69 | auth.createUserWithEmailAndPassword(email, password)
70 | .addOnCompleteListener(new OnCompleteListener() {
71 | @Override
72 | public void onComplete(@NonNull Task task) {
73 | if (task.isSuccessful()){
74 | FirebaseUser firebaseUser = auth.getCurrentUser();
75 | assert firebaseUser != null;
76 | String userid = firebaseUser.getUid();
77 |
78 | reference = FirebaseDatabase.getInstance().getReference("Users").child(userid);
79 |
80 | HashMap hashMap = new HashMap<>();
81 | hashMap.put("id", userid);
82 | hashMap.put("username", username);
83 | hashMap.put("imageURL", "default");
84 | hashMap.put("status", "offline");
85 | hashMap.put("search", username.toLowerCase());
86 |
87 | reference.setValue(hashMap).addOnCompleteListener(new OnCompleteListener() {
88 | @Override
89 | public void onComplete(@NonNull Task task) {
90 | if (task.isSuccessful()){
91 | Intent intent = new Intent(RegisterActivity.this, MainActivity.class);
92 | intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
93 | startActivity(intent);
94 | finish();
95 | }
96 | }
97 | });
98 | } else {
99 | Toast.makeText(RegisterActivity.this, "You can't register woth this email or password", Toast.LENGTH_SHORT).show();
100 | }
101 | }
102 | });
103 | }
104 | }
105 |
--------------------------------------------------------------------------------
/app/src/main/java/com/koddev/chatapp/ResetPasswordActivity.java:
--------------------------------------------------------------------------------
1 | package com.koddev.chatapp;
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.support.v7.widget.Toolbar;
8 | import android.view.View;
9 | import android.widget.Button;
10 | import android.widget.EditText;
11 | import android.widget.Toast;
12 |
13 | import com.google.android.gms.tasks.OnCompleteListener;
14 | import com.google.android.gms.tasks.Task;
15 | import com.google.firebase.auth.FirebaseAuth;
16 |
17 | public class ResetPasswordActivity extends AppCompatActivity {
18 |
19 | EditText send_email;
20 | Button btn_reset;
21 |
22 | FirebaseAuth firebaseAuth;
23 |
24 | @Override
25 | protected void onCreate(Bundle savedInstanceState) {
26 | super.onCreate(savedInstanceState);
27 | setContentView(R.layout.activity_reset_password);
28 |
29 | Toolbar toolbar = findViewById(R.id.toolbar);
30 | setSupportActionBar(toolbar);
31 | getSupportActionBar().setTitle("Reset Password");
32 | getSupportActionBar().setDisplayHomeAsUpEnabled(true);
33 |
34 | send_email = findViewById(R.id.send_email);
35 | btn_reset = findViewById(R.id.btn_reset);
36 |
37 | firebaseAuth = FirebaseAuth.getInstance();
38 |
39 | btn_reset.setOnClickListener(new View.OnClickListener() {
40 | @Override
41 | public void onClick(View view) {
42 | String email = send_email.getText().toString();
43 |
44 | if (email.equals("")){
45 | Toast.makeText(ResetPasswordActivity.this, "All fileds are required!", Toast.LENGTH_SHORT).show();
46 | } else {
47 | firebaseAuth.sendPasswordResetEmail(email).addOnCompleteListener(new OnCompleteListener() {
48 | @Override
49 | public void onComplete(@NonNull Task task) {
50 | if (task.isSuccessful()){
51 | Toast.makeText(ResetPasswordActivity.this, "Please check you Email", Toast.LENGTH_SHORT).show();
52 | startActivity(new Intent(ResetPasswordActivity.this, LoginActivity.class));
53 | } else {
54 | String error = task.getException().getMessage();
55 | Toast.makeText(ResetPasswordActivity.this, error, Toast.LENGTH_SHORT).show();
56 | }
57 | }
58 | });
59 | }
60 | }
61 | });
62 |
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/app/src/main/java/com/koddev/chatapp/StartActivity.java:
--------------------------------------------------------------------------------
1 | package com.koddev.chatapp;
2 |
3 | import android.content.Intent;
4 | import android.os.Bundle;
5 | import android.support.v7.app.AppCompatActivity;
6 | import android.view.View;
7 | import android.widget.Button;
8 |
9 | import com.google.firebase.auth.FirebaseAuth;
10 | import com.google.firebase.auth.FirebaseUser;
11 |
12 | public class StartActivity extends AppCompatActivity {
13 |
14 | Button login, register;
15 |
16 | FirebaseUser firebaseUser;
17 |
18 | @Override
19 | protected void onStart() {
20 | super.onStart();
21 |
22 | firebaseUser = FirebaseAuth.getInstance().getCurrentUser();
23 |
24 | //check if user is null
25 | if (firebaseUser != null){
26 | Intent intent = new Intent(StartActivity.this, MainActivity.class);
27 | startActivity(intent);
28 | finish();
29 | }
30 | }
31 |
32 | @Override
33 | protected void onCreate(Bundle savedInstanceState) {
34 | super.onCreate(savedInstanceState);
35 | setContentView(R.layout.activity_start);
36 |
37 |
38 |
39 | login = findViewById(R.id.login);
40 | register = findViewById(R.id.register);
41 |
42 | login.setOnClickListener(new View.OnClickListener() {
43 | @Override
44 | public void onClick(View view) {
45 | startActivity(new Intent(StartActivity.this, LoginActivity.class));
46 | }
47 | });
48 |
49 | register.setOnClickListener(new View.OnClickListener() {
50 | @Override
51 | public void onClick(View view) {
52 | startActivity(new Intent(StartActivity.this, RegisterActivity.class));
53 | }
54 | });
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_action_name.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/majlindavdylaj/ChatAppTutorial/4eea5c5d4100ab1e73661f02a04695d12176c0d0/app/src/main/res/drawable-hdpi/ic_action_name.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_action_name.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/majlindavdylaj/ChatAppTutorial/4eea5c5d4100ab1e73661f02a04695d12176c0d0/app/src/main/res/drawable-mdpi/ic_action_name.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
12 |
13 |
19 |
22 |
25 |
26 |
27 |
28 |
34 |
35 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_action_name.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/majlindavdylaj/ChatAppTutorial/4eea5c5d4100ab1e73661f02a04695d12176c0d0/app/src/main/res/drawable-xhdpi/ic_action_name.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_action_name.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/majlindavdylaj/ChatAppTutorial/4eea5c5d4100ab1e73661f02a04695d12176c0d0/app/src/main/res/drawable-xxhdpi/ic_action_name.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/background_left.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/background_right.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/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/res/layout/activity_login.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
12 |
13 |
20 |
21 |
27 |
28 |
36 |
37 |
45 |
46 |
54 |
55 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
13 |
14 |
21 |
22 |
26 |
27 |
36 |
37 |
38 |
39 |
47 |
48 |
49 |
50 |
55 |
56 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_message.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
14 |
15 |
22 |
23 |
27 |
28 |
37 |
38 |
39 |
40 |
41 |
42 |
48 |
49 |
56 |
57 |
65 |
66 |
73 |
74 |
75 |
76 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_register.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
12 |
13 |
20 |
21 |
27 |
28 |
35 |
36 |
44 |
45 |
53 |
54 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_reset_password.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
13 |
14 |
19 |
20 |
28 |
29 |
37 |
38 |
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_start.xml:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
19 |
20 |
28 |
36 |
37 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/bar_layout.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/chat_item_left.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
14 |
24 |
25 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/chat_item_right.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
14 |
19 |
20 |
31 |
32 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_chats.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
12 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_profile.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
12 |
13 |
17 |
18 |
24 |
25 |
32 |
33 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_users.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
14 |
15 |
20 |
21 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/user_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
14 |
24 |
25 |
38 |
39 |
52 |
53 |
64 |
65 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/menu.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/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/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/majlindavdylaj/ChatAppTutorial/4eea5c5d4100ab1e73661f02a04695d12176c0d0/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/majlindavdylaj/ChatAppTutorial/4eea5c5d4100ab1e73661f02a04695d12176c0d0/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/majlindavdylaj/ChatAppTutorial/4eea5c5d4100ab1e73661f02a04695d12176c0d0/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/majlindavdylaj/ChatAppTutorial/4eea5c5d4100ab1e73661f02a04695d12176c0d0/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/majlindavdylaj/ChatAppTutorial/4eea5c5d4100ab1e73661f02a04695d12176c0d0/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/majlindavdylaj/ChatAppTutorial/4eea5c5d4100ab1e73661f02a04695d12176c0d0/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/majlindavdylaj/ChatAppTutorial/4eea5c5d4100ab1e73661f02a04695d12176c0d0/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/majlindavdylaj/ChatAppTutorial/4eea5c5d4100ab1e73661f02a04695d12176c0d0/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/majlindavdylaj/ChatAppTutorial/4eea5c5d4100ab1e73661f02a04695d12176c0d0/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/majlindavdylaj/ChatAppTutorial/4eea5c5d4100ab1e73661f02a04695d12176c0d0/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3eaeae
4 | #226e6e
5 | #226e6e
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | ChatApp
3 |
4 |
5 | Hello blank fragment
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/app/src/test/java/com/koddev/chatapp/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.koddev.chatapp;
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() {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 |
5 | repositories {
6 | google()
7 | jcenter()
8 | }
9 | dependencies {
10 | classpath 'com.android.tools.build:gradle:3.1.3'
11 |
12 |
13 | // NOTE: Do not place your application dependencies here; they belong
14 | // in the individual module build.gradle files
15 | classpath 'com.google.gms:google-services:3.2.1'
16 | }
17 | }
18 |
19 | allprojects {
20 | repositories {
21 | google()
22 | jcenter()
23 | }
24 | }
25 |
26 | task clean(type: Delete) {
27 | delete rootProject.buildDir
28 | }
29 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | org.gradle.jvmargs=-Xmx1536m
10 | # When configured, Gradle will run in incubating parallel mode.
11 | # This option should only be used with decoupled projects. More details, visit
12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
13 | # org.gradle.parallel=true
14 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/majlindavdylaj/ChatAppTutorial/4eea5c5d4100ab1e73661f02a04695d12176c0d0/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Sat Aug 18 13:07:23 CEST 2018
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 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Attempt to set APP_HOME
10 | # Resolve links: $0 may be a link
11 | PRG="$0"
12 | # Need this for relative symlinks.
13 | while [ -h "$PRG" ] ; do
14 | ls=`ls -ld "$PRG"`
15 | link=`expr "$ls" : '.*-> \(.*\)$'`
16 | if expr "$link" : '/.*' > /dev/null; then
17 | PRG="$link"
18 | else
19 | PRG=`dirname "$PRG"`"/$link"
20 | fi
21 | done
22 | SAVED="`pwd`"
23 | cd "`dirname \"$PRG\"`/" >/dev/null
24 | APP_HOME="`pwd -P`"
25 | cd "$SAVED" >/dev/null
26 |
27 | APP_NAME="Gradle"
28 | APP_BASE_NAME=`basename "$0"`
29 |
30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
31 | DEFAULT_JVM_OPTS=""
32 |
33 | # Use the maximum available, or set MAX_FD != -1 to use that value.
34 | MAX_FD="maximum"
35 |
36 | warn () {
37 | echo "$*"
38 | }
39 |
40 | die () {
41 | echo
42 | echo "$*"
43 | echo
44 | exit 1
45 | }
46 |
47 | # OS specific support (must be 'true' or 'false').
48 | cygwin=false
49 | msys=false
50 | darwin=false
51 | nonstop=false
52 | case "`uname`" in
53 | CYGWIN* )
54 | cygwin=true
55 | ;;
56 | Darwin* )
57 | darwin=true
58 | ;;
59 | MINGW* )
60 | msys=true
61 | ;;
62 | NONSTOP* )
63 | nonstop=true
64 | ;;
65 | esac
66 |
67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
68 |
69 | # Determine the Java command to use to start the JVM.
70 | if [ -n "$JAVA_HOME" ] ; then
71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
72 | # IBM's JDK on AIX uses strange locations for the executables
73 | JAVACMD="$JAVA_HOME/jre/sh/java"
74 | else
75 | JAVACMD="$JAVA_HOME/bin/java"
76 | fi
77 | if [ ! -x "$JAVACMD" ] ; then
78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
79 |
80 | Please set the JAVA_HOME variable in your environment to match the
81 | location of your Java installation."
82 | fi
83 | else
84 | JAVACMD="java"
85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
86 |
87 | Please set the JAVA_HOME variable in your environment to match the
88 | location of your Java installation."
89 | fi
90 |
91 | # Increase the maximum file descriptors if we can.
92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
93 | MAX_FD_LIMIT=`ulimit -H -n`
94 | if [ $? -eq 0 ] ; then
95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
96 | MAX_FD="$MAX_FD_LIMIT"
97 | fi
98 | ulimit -n $MAX_FD
99 | if [ $? -ne 0 ] ; then
100 | warn "Could not set maximum file descriptor limit: $MAX_FD"
101 | fi
102 | else
103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
104 | fi
105 | fi
106 |
107 | # For Darwin, add options to specify how the application appears in the dock
108 | if $darwin; then
109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
110 | fi
111 |
112 | # For Cygwin, switch paths to Windows format before running java
113 | if $cygwin ; then
114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
116 | JAVACMD=`cygpath --unix "$JAVACMD"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Escape application args
158 | save () {
159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
160 | echo " "
161 | }
162 | APP_ARGS=$(save "$@")
163 |
164 | # Collect all arguments for the java command, following the shell quoting and substitution rules
165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
166 |
167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
169 | cd "$(dirname "$0")"
170 | fi
171 |
172 | exec "$JAVACMD" "$@"
173 |
--------------------------------------------------------------------------------
/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 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS=
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 Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 |
53 | :win9xME_args
54 | @rem Slurp the command line arguments.
55 | set CMD_LINE_ARGS=
56 | set _SKIP=2
57 |
58 | :win9xME_args_slurp
59 | if "x%~1" == "x" goto execute
60 |
61 | set CMD_LINE_ARGS=%*
62 |
63 | :execute
64 | @rem Setup the command line
65 |
66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67 |
68 | @rem Execute Gradle
69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70 |
71 | :end
72 | @rem End local scope for the variables with windows NT shell
73 | if "%ERRORLEVEL%"=="0" goto mainEnd
74 |
75 | :fail
76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 | rem the _cmd.exe /c_ return code!
78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 | exit /b 1
80 |
81 | :mainEnd
82 | if "%OS%"=="Windows_NT" endlocal
83 |
84 | :omega
85 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------