diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..aa724b7
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,15 @@
+*.iml
+.gradle
+/local.properties
+/.idea/caches
+/.idea/libraries
+/.idea/modules.xml
+/.idea/workspace.xml
+/.idea/navEditor.xml
+/.idea/assetWizardSettings.xml
+.DS_Store
+/build
+/captures
+.externalNativeBuild
+.cxx
+local.properties
diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..26d3352
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/.idea/.name b/.idea/.name
new file mode 100644
index 0000000..9b4a4ed
--- /dev/null
+++ b/.idea/.name
@@ -0,0 +1 @@
+Remote SMS
\ No newline at end of file
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
new file mode 100644
index 0000000..fb7f4a8
--- /dev/null
+++ b/.idea/compiler.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/deploymentTargetDropDown.xml b/.idea/deploymentTargetDropDown.xml
new file mode 100644
index 0000000..0c0c338
--- /dev/null
+++ b/.idea/deploymentTargetDropDown.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/gradle.xml b/.idea/gradle.xml
new file mode 100644
index 0000000..0897082
--- /dev/null
+++ b/.idea/gradle.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml
new file mode 100644
index 0000000..a5f05cd
--- /dev/null
+++ b/.idea/jarRepositories.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/migrations.xml b/.idea/migrations.xml
new file mode 100644
index 0000000..f8051a6
--- /dev/null
+++ b/.idea/migrations.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..0609234
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..94a25f7
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/.gitignore b/app/.gitignore
new file mode 100644
index 0000000..42afabf
--- /dev/null
+++ b/app/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
new file mode 100644
index 0000000..c3780a0
--- /dev/null
+++ b/app/build.gradle
@@ -0,0 +1,57 @@
+plugins {
+ id 'com.android.application'
+}
+
+android {
+ compileSdkVersion 30
+ buildToolsVersion "30.0.3"
+
+ defaultConfig {
+ applicationId "com.appetize.remotesms"
+ minSdk 26
+ targetSdk 26
+ versionCode 1
+ versionName "1.0"
+
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+ }
+ }
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+}
+
+apply plugin: 'com.android.application'
+apply plugin: 'com.google.gms.google-services'
+
+dependencies {
+
+ implementation 'androidx.appcompat:appcompat:1.3.0'
+ implementation 'com.google.android.material:material:1.4.0'
+ implementation 'androidx.constraintlayout:constraintlayout:2.1.2'
+ implementation 'com.google.firebase:firebase-database:19.2.1'
+
+ def core_version = "1.6.0"
+
+ implementation "androidx.core:core:$core_version"
+ testImplementation 'junit:junit:4.+'
+ androidTestImplementation 'androidx.test.ext:junit:1.1.3'
+ androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
+
+ //room
+ def room_version = "2.2.0"
+ implementation "androidx.room:room-runtime:$room_version"
+ annotationProcessor "androidx.room:room-compiler:$room_version"
+
+ //telegram api
+ implementation 'com.github.pengrad:java-telegram-bot-api:7.4.0'
+
+ implementation("com.squareup.okhttp3:okhttp:4.12.0")
+}
\ No newline at end of file
diff --git a/app/google-services.json b/app/google-services.json
new file mode 100644
index 0000000..d86d566
--- /dev/null
+++ b/app/google-services.json
@@ -0,0 +1,39 @@
+{
+ "project_info": {
+ "project_number": "330167566800",
+ "project_id": "remote-sms-8bd49",
+ "storage_bucket": "remote-sms-8bd49.appspot.com"
+ },
+ "client": [
+ {
+ "client_info": {
+ "mobilesdk_app_id": "1:330167566800:android:c3cdf5e9b1fe2c16dff9d5",
+ "android_client_info": {
+ "package_name": "com.appetize.remotesms"
+ }
+ },
+ "oauth_client": [
+ {
+ "client_id": "330167566800-qtisjrr3200jgqscf9cupuv9v0cafc6t.apps.googleusercontent.com",
+ "client_type": 3
+ }
+ ],
+ "api_key": [
+ {
+ "current_key": "AIzaSyCdQhkLZrzAufM9aufxIXEE9BysI2X8kfM"
+ }
+ ],
+ "services": {
+ "appinvite_service": {
+ "other_platform_oauth_client": [
+ {
+ "client_id": "330167566800-qtisjrr3200jgqscf9cupuv9v0cafc6t.apps.googleusercontent.com",
+ "client_type": 3
+ }
+ ]
+ }
+ }
+ }
+ ],
+ "configuration_version": "1"
+}
\ No newline at end of file
diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro
new file mode 100644
index 0000000..481bb43
--- /dev/null
+++ b/app/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
\ No newline at end of file
diff --git a/app/src/androidTest/java/com/appetize/remotesms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/appetize/remotesms/ExampleInstrumentedTest.java
new file mode 100644
index 0000000..75e93cd
--- /dev/null
+++ b/app/src/androidTest/java/com/appetize/remotesms/ExampleInstrumentedTest.java
@@ -0,0 +1,26 @@
+package com.appetize.remotesms;
+
+import android.content.Context;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.*;
+
+/**
+ * Instrumented test, which will execute on an Android device.
+ *
+ * @see Testing documentation
+ */
+@RunWith(AndroidJUnit4.class)
+public class ExampleInstrumentedTest {
+ @Test
+ public void useAppContext() {
+ // Context of the app under test.
+ Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
+ assertEquals("com.appetize.remotesms", appContext.getPackageName());
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..71f86ca
--- /dev/null
+++ b/app/src/main/AndroidManifest.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml.orig b/app/src/main/AndroidManifest.xml.orig
new file mode 100644
index 0000000..cc19753
--- /dev/null
+++ b/app/src/main/AndroidManifest.xml.orig
@@ -0,0 +1,62 @@
+
+
+
+
+
+
+<<<<<<< HEAD
+
+=======
+
+
+>>>>>>> ffc10bc47fc096361f163e2dd464765400da1ef3
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<<<<<<< HEAD
+
+
+
+=======
+
+
+
+>>>>>>> ffc10bc47fc096361f163e2dd464765400da1ef3
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/java/com/appetize/remotesms/AddDevice.java b/app/src/main/java/com/appetize/remotesms/AddDevice.java
new file mode 100644
index 0000000..8fbd609
--- /dev/null
+++ b/app/src/main/java/com/appetize/remotesms/AddDevice.java
@@ -0,0 +1,247 @@
+package com.appetize.remotesms;
+
+import android.content.pm.PackageManager;
+import android.graphics.drawable.Animatable;
+import android.os.Bundle;
+import android.telephony.SubscriptionInfo;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
+import android.util.Log;
+import android.view.View;
+import android.view.animation.Animation;
+import android.view.animation.AnimationUtils;
+import android.widget.Button;
+import android.widget.CheckBox;
+import android.widget.FrameLayout;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.core.app.ActivityCompat;
+import androidx.core.graphics.Insets;
+import androidx.core.view.ViewCompat;
+import androidx.core.view.WindowInsetsCompat;
+
+import com.pengrad.telegrambot.Callback;
+import com.pengrad.telegrambot.TelegramBot;
+import com.pengrad.telegrambot.model.Message;
+import com.pengrad.telegrambot.model.Update;
+import com.pengrad.telegrambot.request.GetUpdates;
+import com.pengrad.telegrambot.request.SendMessage;
+import com.pengrad.telegrambot.response.GetUpdatesResponse;
+import com.pengrad.telegrambot.response.SendResponse;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Random;
+
+public class AddDevice extends AppCompatActivity {
+ private int page_no;
+ private long chat_id;
+ private final String code = randCode(4, 4);
+ FrameLayout p1;
+ FrameLayout p2;
+ Button btn_nxt;
+ Button btn_back;
+ SubscriptionManager subscriptionManager;
+ CheckBox[] boxes;
+ TelegramBot bot;
+ List sims;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_add_device);
+ ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
+ Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
+ v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
+ return insets;
+ });
+ page_no = 0;
+ p1 = (FrameLayout) findViewById(R.id.p1);
+ p2 = (FrameLayout) findViewById(R.id.p2);
+ btn_nxt = (Button) findViewById(R.id.btn_nxt);
+ btn_back = (Button) findViewById(R.id.btn_back);
+
+ ((TextView) findViewById(R.id.conn_code)).setText(code);
+ bot = new TelegramBot(this.getString(R.string.bot_token));
+
+ subscriptionManager = SubscriptionManager.from(this);
+ if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
+ // TODO: Consider calling
+ // ActivityCompat#requestPermissions
+ // here to request the missing permissions, and then overriding
+ // public void onRequestPermissionsResult(int requestCode, String[] permissions,
+ // int[] grantResults)
+ // to handle the case where the user grants the permission. See the documentation
+ // for ActivityCompat#requestPermissions for more details.
+ return;
+ }
+ sims = subscriptionManager.getActiveSubscriptionInfoList();
+ Log.d("subscription", "onCreate: "+ sims.get(0).getSubscriptionId());
+ LinearLayout ll = findViewById(R.id.ll_sims);
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
+ boxes = new CheckBox[sims.size()];
+ for(int i = 0; i < sims.size(); i++){
+ boxes[i] = new CheckBox(AddDevice.this);
+ boxes[i].setText("SIM " + sims.get(i).getNumber());
+ int finalI = i;
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ ll.addView(boxes[finalI]);
+ }
+ });
+ }
+ }
+ }).start();
+ }
+
+ public void back(View view) {
+ switch (page_no){
+ case 0:
+ finish();
+ break;
+ case 1:
+ page_no = 0;
+ p1.setVisibility(View.VISIBLE);
+ Animation a1 = AnimationUtils.loadAnimation(this, R.anim.slide_in_left);
+ p1.startAnimation(a1);
+
+ Animation a2 = AnimationUtils.loadAnimation(this,R.anim.slide_out_right);
+ a2.setAnimationListener(new Animation.AnimationListener() {
+ @Override
+ public void onAnimationStart(Animation animation) {
+
+ }
+
+ @Override
+ public void onAnimationEnd(Animation animation) {
+ p2.setVisibility(View.INVISIBLE);
+ }
+
+ @Override
+ public void onAnimationRepeat(Animation animation) {
+
+ }
+ });
+ p2.startAnimation(a2);
+ ((Button)findViewById(R.id.btn_nxt)).setText(R.string.next);
+ ((Button)findViewById(R.id.btn_back)).setText(R.string.cancel);
+ break;
+ }
+ }
+
+ public void nxt(View view) {
+ switch (page_no){
+ case 0:
+ page_no=1;
+ Animation a1 = AnimationUtils.loadAnimation(this, R.anim.slide_out_left);
+ a1.setAnimationListener(new Animation.AnimationListener() {
+ @Override
+ public void onAnimationStart(Animation animation) {
+
+ }
+
+ @Override
+ public void onAnimationEnd(Animation animation) {
+ p1.setVisibility(View.INVISIBLE);
+ }
+
+ @Override
+ public void onAnimationRepeat(Animation animation) {
+
+ }
+ });
+ p1.startAnimation(a1);
+
+ p2.setVisibility(View.VISIBLE);
+ Animation a2 = AnimationUtils.loadAnimation(this,R.anim.slide_in_right);
+ p2.startAnimation(a2);
+ btn_nxt.setText(R.string.finish);
+ btn_back.setText(R.string.back);
+ break;
+ case 1:
+ StringBuilder backsims = new StringBuilder();
+ for(int i=0; i < boxes.length; i++){
+ if(boxes[i].isChecked()){
+ if(!backsims.toString().isEmpty())
+ backsims.append('#');
+ backsims.append(sims.get(i).getSubscriptionId());
+ }
+ }
+ dbViewmodel dbv = new dbViewmodel(this);
+ Rule rule = new Rule();
+ rule.name = ((TextView)findViewById(R.id.txt_blk_name)).getText().toString();
+ rule.sims = backsims.toString();
+ rule.chat_id = chat_id;
+ dbv.add_rule(rule);
+ SendMessage request = new SendMessage(chat_id, "Congratulations!\nYour Telegram account is now verified as a SMS receiver account of your target device. From now on, all the incoming SMSs will be forwarded here to you. ;)");
+ bot.execute(request);
+ finish();
+ break;
+ }
+ }
+ static String randCode(int length, int section){
+ StringBuilder buffer = new StringBuilder((length*section)+section-1);
+ for(int i = 1; i<=section; i++){
+ for(int j=0;j() {
+ @Override
+ public void onResponse(GetUpdates request, GetUpdatesResponse response) {
+ List updates = response.updates();
+ boolean verified = false;
+ for (Update update : updates){
+ if(update.message().text().equals(code)){
+ verified = true;
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ updateChatID(update.message().chat().id());
+ Toast.makeText(AddDevice.this, "Verified", Toast.LENGTH_LONG).show();
+ }
+ });
+ }
+ }
+ if(!verified){
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ Toast.makeText(AddDevice.this, "Could not verify", Toast.LENGTH_SHORT).show();
+ }
+ });
+ }
+ }
+
+ @Override
+ public void onFailure(GetUpdates request, IOException e) {
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ Toast.makeText(AddDevice.this, "Could not verify", Toast.LENGTH_SHORT).show();
+ }
+ });
+ }
+ });
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/appetize/remotesms/DeviceAdapter.java b/app/src/main/java/com/appetize/remotesms/DeviceAdapter.java
new file mode 100644
index 0000000..5b825c9
--- /dev/null
+++ b/app/src/main/java/com/appetize/remotesms/DeviceAdapter.java
@@ -0,0 +1,36 @@
+package com.appetize.remotesms;
+
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import java.util.List;
+
+public class DeviceAdapter extends ArrayAdapter {
+ List devices;
+ Context context;
+ int resource;
+ public DeviceAdapter(@NonNull Context context, int resource, @NonNull List objects) {
+ super(context, resource, objects);
+ this.context = context;
+ this.resource = resource;
+ this.devices = objects;
+ }
+
+ @NonNull
+ @Override
+ public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
+ LayoutInflater inflater = LayoutInflater.from(context);
+ View view = inflater.inflate(R.layout.block,null);
+ Rule q = devices.get(position);
+ ((TextView)view.findViewById(R.id.blk_name)).setText(q.name);
+ ((TextView)view.findViewById(R.id.blk_sims)).setText(String.valueOf(q.sims));
+ return view;
+ }
+}
diff --git a/app/src/main/java/com/appetize/remotesms/Home.java b/app/src/main/java/com/appetize/remotesms/Home.java
new file mode 100644
index 0000000..c9542d1
--- /dev/null
+++ b/app/src/main/java/com/appetize/remotesms/Home.java
@@ -0,0 +1,51 @@
+package com.appetize.remotesms;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+import android.widget.ListView;
+
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.core.graphics.Insets;
+import androidx.core.view.ViewCompat;
+import androidx.core.view.WindowInsetsCompat;
+import androidx.lifecycle.LifecycleOwner;
+import androidx.lifecycle.Observer;
+
+import com.appetize.remotesms.fgService;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class Home extends AppCompatActivity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_home);
+ ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
+ Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
+ v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
+ return insets;
+ });
+
+ dbViewmodel dbv = new dbViewmodel(this);
+ dbv.get_rules().observe(this, new Observer>() {
+ @Override
+ public void onChanged(List rules) {
+ DeviceAdapter deviceAdapter = new DeviceAdapter(Home.this,R.layout.block, rules);
+ ((ListView) findViewById(R.id.devices)).setAdapter(deviceAdapter);
+ }
+ });
+ if(!fgService.isServiceRunning){
+ Intent intent = new Intent(this,fgService.class);
+ startForegroundService(intent);
+ }
+ }
+
+ public void add_device(View view) {
+ Intent intent = new Intent(this, AddDevice.class);
+ startActivity(intent);
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/appetize/remotesms/MainActivity.java b/app/src/main/java/com/appetize/remotesms/MainActivity.java
new file mode 100644
index 0000000..5ea70ac
--- /dev/null
+++ b/app/src/main/java/com/appetize/remotesms/MainActivity.java
@@ -0,0 +1,77 @@
+package com.appetize.remotesms;
+
+import android.Manifest;
+import android.app.Activity;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.Button;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.core.app.ActivityCompat;
+import androidx.core.content.ContextCompat;
+import androidx.core.graphics.Insets;
+import androidx.core.view.ViewCompat;
+import androidx.core.view.WindowInsetsCompat;
+
+public class MainActivity extends AppCompatActivity {
+
+ private final int MY_PERMISSION = 5;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+ ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
+ Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
+ v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
+ return insets;
+ });
+
+ Button grant = (Button) findViewById(R.id.perm_grant);
+
+ if (!(ContextCompat.checkSelfPermission(
+ this, Manifest.permission.READ_PHONE_STATE) ==
+ PackageManager.PERMISSION_GRANTED)){
+ ((TextView)findViewById(R.id.perm_name)).setText(R.string.read_phone_state);
+ ((TextView)findViewById(R.id.perm_des)).setText(R.string.read_phone_state_des);
+ grant.setEnabled(true);
+ grant.setOnClickListener(new View.OnClickListener(){
+ @Override
+ public void onClick(View v) {
+ ActivityCompat.requestPermissions(MainActivity.this,new String[]{Manifest.permission.READ_PHONE_STATE},MY_PERMISSION);
+ }
+ });
+ } else if (!(ContextCompat.checkSelfPermission(
+ this, Manifest.permission.RECEIVE_SMS) ==
+ PackageManager.PERMISSION_GRANTED)){
+ ((TextView)findViewById(R.id.perm_name)).setText(R.string.receive_sms);
+ ((TextView)findViewById(R.id.perm_des)).setText(R.string.receive_sms_des);
+ grant.setEnabled(true);
+ grant.setOnClickListener(new View.OnClickListener(){
+ @Override
+ public void onClick(View v) {
+ ActivityCompat.requestPermissions(MainActivity.this,new String[]{Manifest.permission.RECEIVE_SMS},MY_PERMISSION);
+ }
+ });
+ }
+ else{
+ Intent intent = new Intent(this, Home.class);
+ startActivity(intent);
+ finish();
+ }
+ }
+
+ @Override
+ public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
+ super.onRequestPermissionsResult(requestCode, permissions, grantResults);
+ if (requestCode == MY_PERMISSION){
+ Intent intent = new Intent(this, MainActivity.class);
+ startActivity(intent);
+ finish();
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/appetize/remotesms/NetworkUtil.java b/app/src/main/java/com/appetize/remotesms/NetworkUtil.java
new file mode 100644
index 0000000..96e52a5
--- /dev/null
+++ b/app/src/main/java/com/appetize/remotesms/NetworkUtil.java
@@ -0,0 +1,41 @@
+package com.appetize.remotesms;
+
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+
+public class NetworkUtil {
+ public static final int TYPE_WIFI = 1;
+ public static final int TYPE_MOBILE = 2;
+ public static final int TYPE_NOT_CONNECTED = 0;
+ public static final int NETWORK_STATUS_NOT_CONNECTED = 0;
+ public static final int NETWORK_STATUS_WIFI = 1;
+ public static final int NETWORK_STATUS_MOBILE = 2;
+
+ public static int getConnectivityStatus(Context context) {
+ ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
+
+ NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
+ if (null != activeNetwork) {
+ if(activeNetwork.getType() == ConnectivityManager.TYPE_WIFI)
+ return TYPE_WIFI;
+
+ if(activeNetwork.getType() == ConnectivityManager.TYPE_MOBILE)
+ return TYPE_MOBILE;
+ }
+ return TYPE_NOT_CONNECTED;
+ }
+
+ public static int getConnectivityStatusString(Context context) {
+ int conn = NetworkUtil.getConnectivityStatus(context);
+ int status = 0;
+ if (conn == NetworkUtil.TYPE_WIFI) {
+ status = NETWORK_STATUS_WIFI;
+ } else if (conn == NetworkUtil.TYPE_MOBILE) {
+ status = NETWORK_STATUS_MOBILE;
+ } else if (conn == NetworkUtil.TYPE_NOT_CONNECTED) {
+ status = NETWORK_STATUS_NOT_CONNECTED;
+ }
+ return status;
+ }
+}
diff --git a/app/src/main/java/com/appetize/remotesms/Rule.java b/app/src/main/java/com/appetize/remotesms/Rule.java
new file mode 100644
index 0000000..6c5a2cb
--- /dev/null
+++ b/app/src/main/java/com/appetize/remotesms/Rule.java
@@ -0,0 +1,17 @@
+package com.appetize.remotesms;
+
+import androidx.annotation.NonNull;
+import androidx.room.ColumnInfo;
+import androidx.room.Entity;
+import androidx.room.PrimaryKey;
+
+@Entity
+public class Rule {
+ @PrimaryKey
+ @NonNull
+ public long chat_id;
+ @ColumnInfo(name = "name")
+ public String name;
+ @ColumnInfo(name = "sims")
+ public String sims;
+}
diff --git a/app/src/main/java/com/appetize/remotesms/SMS.java b/app/src/main/java/com/appetize/remotesms/SMS.java
new file mode 100644
index 0000000..85e4e96
--- /dev/null
+++ b/app/src/main/java/com/appetize/remotesms/SMS.java
@@ -0,0 +1,19 @@
+package com.appetize.remotesms;
+
+import androidx.room.ColumnInfo;
+import androidx.room.Entity;
+import androidx.room.PrimaryKey;
+
+@Entity
+public class SMS {
+ @PrimaryKey(autoGenerate = true)
+ public int id;
+ @ColumnInfo(name="sender")
+ public String sender;
+ @ColumnInfo(name="body")
+ public String body;
+ @ColumnInfo(name = "datetime")
+ public long datetime;
+ @ColumnInfo(name = "sim")
+ public int sim_no;
+}
diff --git a/app/src/main/java/com/appetize/remotesms/Setting.java b/app/src/main/java/com/appetize/remotesms/Setting.java
new file mode 100644
index 0000000..4778e94
--- /dev/null
+++ b/app/src/main/java/com/appetize/remotesms/Setting.java
@@ -0,0 +1,15 @@
+package com.appetize.remotesms;
+
+import androidx.annotation.NonNull;
+import androidx.room.ColumnInfo;
+import androidx.room.Entity;
+import androidx.room.PrimaryKey;
+
+@Entity
+public class Setting {
+ @PrimaryKey
+ @NonNull
+ public String name;
+ @ColumnInfo(name = "value")
+ public String value;
+}
diff --git a/app/src/main/java/com/appetize/remotesms/dbDao.java b/app/src/main/java/com/appetize/remotesms/dbDao.java
new file mode 100644
index 0000000..e205ab4
--- /dev/null
+++ b/app/src/main/java/com/appetize/remotesms/dbDao.java
@@ -0,0 +1,34 @@
+package com.appetize.remotesms;
+
+import androidx.lifecycle.LiveData;
+import androidx.room.Dao;
+import androidx.room.Delete;
+import androidx.room.Insert;
+import androidx.room.OnConflictStrategy;
+import androidx.room.Query;
+
+import java.util.List;
+
+@Dao
+public interface dbDao {
+ @Insert(onConflict = OnConflictStrategy.REPLACE)
+ void add_rule(Rule rule);
+ @Insert
+ void add_sms(SMS sms);
+ @Insert(onConflict = OnConflictStrategy.REPLACE)
+ void add_setting(Setting setting);
+ @Query("SELECT * FROM SMS")
+ List getSMSList();
+ @Query("SELECT * FROM Setting")
+ List getSettings();
+ @Query("SELECT * FROM Rule")
+ LiveData> getRules();
+ @Query("SELECT * FROM Rule")
+ List getIRules();
+ @Delete
+ void rem_rule(Rule rule);
+ @Delete
+ void rem_sms(SMS sms);
+ @Delete
+ void rem_setting(Setting setting);
+}
diff --git a/app/src/main/java/com/appetize/remotesms/dbMain.java b/app/src/main/java/com/appetize/remotesms/dbMain.java
new file mode 100644
index 0000000..aa5aa6e
--- /dev/null
+++ b/app/src/main/java/com/appetize/remotesms/dbMain.java
@@ -0,0 +1,28 @@
+package com.appetize.remotesms;
+
+import android.content.Context;
+
+import androidx.room.Database;
+import androidx.room.Room;
+import androidx.room.RoomDatabase;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+@Database(entities = {Rule.class, Setting.class, SMS.class}, version = 1)
+public abstract class dbMain extends RoomDatabase {
+ public abstract dbDao dao();
+ public static volatile dbMain INSTANCE;
+ private static final int NUMBER_OF_THREADS = 4;
+ static final ExecutorService databaseWriteExecutor = Executors.newFixedThreadPool(NUMBER_OF_THREADS);
+ static dbMain getDB(final Context context){
+ if (INSTANCE == null){
+ synchronized (dbMain.class){
+ if (INSTANCE == null){
+ INSTANCE = Room.databaseBuilder(context.getApplicationContext(),dbMain.class,"core_database").build();
+ }
+ }
+ }
+ return INSTANCE;
+ }
+}
diff --git a/app/src/main/java/com/appetize/remotesms/dbViewmodel.java b/app/src/main/java/com/appetize/remotesms/dbViewmodel.java
new file mode 100644
index 0000000..c7ff387
--- /dev/null
+++ b/app/src/main/java/com/appetize/remotesms/dbViewmodel.java
@@ -0,0 +1,57 @@
+package com.appetize.remotesms;
+
+import android.content.Context;
+import android.os.AsyncTask;
+
+import androidx.annotation.NonNull;
+import androidx.lifecycle.LiveData;
+
+import java.util.List;
+
+public class dbViewmodel {
+ private dbDao dao;
+ private dbMain db;
+ public dbViewmodel(@NonNull Context context){
+ db = dbMain.getDB(context);
+ dao = db.dao();
+ }
+ public void add_rule(Rule rule){
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
+ dao.add_rule(rule);
+ }
+ }).start();
+ }
+ public void add_sms(SMS sms){
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
+ dao.add_sms(sms);
+ }
+ }).start();
+ }
+ public void add_setting(Setting setting){
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
+ dao.add_setting(setting);
+ }
+ }).start();
+ }
+ public LiveData> get_rules(){
+ return dao.getRules();
+ }
+ public List get_i_rules(){
+ return dao.getIRules();
+ }
+ public List get_smsList(){
+ return dao.getSMSList();
+ }
+ public List get_settings(){
+ return dao.getSettings();
+ }
+ public void rem_SMS(SMS sms){
+ dao.rem_sms(sms);
+ }
+}
diff --git a/app/src/main/java/com/appetize/remotesms/fgService.java b/app/src/main/java/com/appetize/remotesms/fgService.java
new file mode 100644
index 0000000..c7aab25
--- /dev/null
+++ b/app/src/main/java/com/appetize/remotesms/fgService.java
@@ -0,0 +1,205 @@
+package com.appetize.remotesms;
+
+import android.app.Notification;
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.app.Service;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.telephony.SmsMessage;
+import android.util.Log;
+
+import androidx.core.app.NotificationCompat;
+
+import com.pengrad.telegrambot.TelegramBot;
+import com.pengrad.telegrambot.model.Message;
+import com.pengrad.telegrambot.model.request.ForceReply;
+import com.pengrad.telegrambot.model.request.ParseMode;
+import com.pengrad.telegrambot.request.SendMessage;
+import com.pengrad.telegrambot.response.SendResponse;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.List;
+
+public class fgService extends Service {
+ private static final String SMS_RECEIVED = "android.provider.Telephony.SMS_RECEIVED";
+ private static final String CONNECTIVITY_CHANGE = "android.net.conn.CONNECTIVITY_CHANGE";
+ public static boolean isServiceRunning;
+ private String CHANNEL_ID = "FG_SERVICE_CHANNEL";
+
+ public fgService() {
+ isServiceRunning = false;
+ }
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ createNotificationChannel();
+ isServiceRunning = true;
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(SMS_RECEIVED);
+ filter.addAction(CONNECTIVITY_CHANGE);
+ registerReceiver(receiver, filter);
+ }
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return null;
+ }
+
+ @Override
+ public int onStartCommand(Intent intent, int flags, int startId) {
+ Intent notificationIntent = new Intent(this, Home.class);
+ PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
+ Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
+ .setContentTitle("Remote SMS service is running")
+ .setContentText("Monitoring for new SMS")
+ .setSmallIcon(R.drawable.common_google_signin_btn_icon_dark)
+ .setContentIntent(pendingIntent)
+ .setColor(getResources().getColor(R.color.design_default_color_primary))
+ .build();
+
+ startForeground(1, notification);
+ return START_STICKY;
+ }
+
+ private void createNotificationChannel() {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ String appName = getString(R.string.app_name);
+ NotificationChannel serviceChannel = new NotificationChannel(CHANNEL_ID, appName, NotificationManager.IMPORTANCE_DEFAULT);
+ NotificationManager manager = getSystemService(NotificationManager.class);
+ manager.createNotificationChannel(serviceChannel);
+ }
+ }
+
+ @Override
+ public void onDestroy() {
+ isServiceRunning = false;
+ stopForeground(true);
+ //Intent broadcastIntent = new Intent(this, SMSReciever.class);
+ //sendBroadcast(broadcastIntent);
+ unregisterReceiver(receiver);
+ super.onDestroy();
+ }
+
+ private final BroadcastReceiver receiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ dbViewmodel dbv = new dbViewmodel(context);
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
+ TelegramBot bot = new TelegramBot(getString(R.string.bot_token));
+ List rules = dbv.get_i_rules();
+ if(intent.getAction().equals(SMS_RECEIVED)) {
+ Log.d("Foreground", "onReceive: Recieve korsi");
+ Bundle bundle = intent.getExtras();
+ if(bundle != null){
+ Object[] pdus = (Object[]) bundle.get("pdus");
+ SmsMessage[] messages = new SmsMessage[pdus.length];
+ for(int i=0; i smsList = dbv.get_smsList();
+ for (SMS sms : smsList){
+ for(Rule rule:rules){
+ String[] sims = rule.sims.split("#");
+ for(String rsim:sims){
+ if(rsim.equals(String.valueOf(sms.sim_no))){
+ try {
+ SendMessage request = new SendMessage(rule.chat_id, "From:\n" + sms.sender + "\n\nBody:\n" + sms.body + "\n\nDatetime:\n" + new SimpleDateFormat("dd MMM yyyy HH:mm:ss Z").format(new Date(sms.datetime)));
+ SendResponse sendResponse = bot.execute(request);
+ if (sendResponse.isOk()) {
+ dbv.rem_SMS(sms);
+ }
+ }
+ catch (Exception e){
+ Log.e("Foreground Error", e.getMessage() );
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }).start();
+ }
+ int capturedSIM(Bundle bundle){
+ String TAG = "SIM ID";
+ int simid = -1;
+ if(bundle.containsKey("subscription")){
+ simid = bundle.getInt("subscription");
+ Log.d(TAG, "capturedSIM: " + simid + " #subscription");
+ }
+ if(simid >= 0 && simid < 5){
+ return simid;
+ }
+ else{
+ if(bundle.containsKey("simId")){
+ simid = bundle.getInt("simId");
+ Log.d(TAG, "capturedSIM: " + simid + " #simid");
+ }
+ else if(bundle.containsKey("com.android.phone.extra.slot")){
+ simid = bundle.getInt("com.android.phone.extra.slot");
+ Log.d(TAG, "capturedSIM: " + simid + " #com.android.phone.extra.slot");
+ }
+ else if(bundle.containsKey("slot")){
+ simid = bundle.getInt("slot");
+ Log.d(TAG, "capturedSIM: " + simid + " #slolt");
+ }
+ else{
+ String keyName = "";
+ for(String key: bundle.keySet()){
+ if(key.contains("sim"))
+ keyName = key;
+ }
+ simid = bundle.getInt(keyName);
+ Log.d(TAG, "capturedSIM: " + simid + " #" + keyName);
+ }
+ return simid;
+ }
+ }
+ };
+}
\ No newline at end of file
diff --git a/app/src/main/res/anim/blink_anim.xml b/app/src/main/res/anim/blink_anim.xml
new file mode 100644
index 0000000..5cdc674
--- /dev/null
+++ b/app/src/main/res/anim/blink_anim.xml
@@ -0,0 +1,8 @@
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/anim/bounce.xml b/app/src/main/res/anim/bounce.xml
new file mode 100644
index 0000000..17da7cf
--- /dev/null
+++ b/app/src/main/res/anim/bounce.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/anim/btn_bounce.xml b/app/src/main/res/anim/btn_bounce.xml
new file mode 100644
index 0000000..bdc888b
--- /dev/null
+++ b/app/src/main/res/anim/btn_bounce.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/anim/fadein.xml b/app/src/main/res/anim/fadein.xml
new file mode 100644
index 0000000..9d7ee72
--- /dev/null
+++ b/app/src/main/res/anim/fadein.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/anim/fadeout.xml b/app/src/main/res/anim/fadeout.xml
new file mode 100644
index 0000000..7a8095c
--- /dev/null
+++ b/app/src/main/res/anim/fadeout.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/anim/lefttoright.xml b/app/src/main/res/anim/lefttoright.xml
new file mode 100644
index 0000000..8329877
--- /dev/null
+++ b/app/src/main/res/anim/lefttoright.xml
@@ -0,0 +1,6 @@
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/anim/mixed_anim.xml b/app/src/main/res/anim/mixed_anim.xml
new file mode 100644
index 0000000..930ffac
--- /dev/null
+++ b/app/src/main/res/anim/mixed_anim.xml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/anim/righttoleft.xml b/app/src/main/res/anim/righttoleft.xml
new file mode 100644
index 0000000..efdc676
--- /dev/null
+++ b/app/src/main/res/anim/righttoleft.xml
@@ -0,0 +1,7 @@
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/anim/rotate.xml b/app/src/main/res/anim/rotate.xml
new file mode 100644
index 0000000..5e0c46d
--- /dev/null
+++ b/app/src/main/res/anim/rotate.xml
@@ -0,0 +1,11 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/anim/sample_anim.xml b/app/src/main/res/anim/sample_anim.xml
new file mode 100644
index 0000000..972b3a1
--- /dev/null
+++ b/app/src/main/res/anim/sample_anim.xml
@@ -0,0 +1,9 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/res/anim/slide_in_left.xml b/app/src/main/res/anim/slide_in_left.xml
new file mode 100644
index 0000000..92b69f3
--- /dev/null
+++ b/app/src/main/res/anim/slide_in_left.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/anim/slide_in_right.xml b/app/src/main/res/anim/slide_in_right.xml
new file mode 100644
index 0000000..91ecf0b
--- /dev/null
+++ b/app/src/main/res/anim/slide_in_right.xml
@@ -0,0 +1,7 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/anim/slide_out_left.xml b/app/src/main/res/anim/slide_out_left.xml
new file mode 100644
index 0000000..79f5c25
--- /dev/null
+++ b/app/src/main/res/anim/slide_out_left.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/anim/slide_out_right.xml b/app/src/main/res/anim/slide_out_right.xml
new file mode 100644
index 0000000..36ab81f
--- /dev/null
+++ b/app/src/main/res/anim/slide_out_right.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/anim/zoomin.xml b/app/src/main/res/anim/zoomin.xml
new file mode 100644
index 0000000..9caa250
--- /dev/null
+++ b/app/src/main/res/anim/zoomin.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/anim/zoomout.xml b/app/src/main/res/anim/zoomout.xml
new file mode 100644
index 0000000..52dbe8c
--- /dev/null
+++ b/app/src/main/res/anim/zoomout.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
new file mode 100644
index 0000000..2b068d1
--- /dev/null
+++ b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/avatar.png b/app/src/main/res/drawable/avatar.png
new file mode 100644
index 0000000..cc8e607
Binary files /dev/null and b/app/src/main/res/drawable/avatar.png differ
diff --git a/app/src/main/res/drawable/ic_baseline_add_24.xml b/app/src/main/res/drawable/ic_baseline_add_24.xml
new file mode 100644
index 0000000..eb23254
--- /dev/null
+++ b/app/src/main/res/drawable/ic_baseline_add_24.xml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_baseline_check_24.xml b/app/src/main/res/drawable/ic_baseline_check_24.xml
new file mode 100644
index 0000000..0432fa6
--- /dev/null
+++ b/app/src/main/res/drawable/ic_baseline_check_24.xml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml
new file mode 100644
index 0000000..07d5da9
--- /dev/null
+++ b/app/src/main/res/drawable/ic_launcher_background.xml
@@ -0,0 +1,170 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/activity_add_device.xml b/app/src/main/res/layout/activity_add_device.xml
new file mode 100644
index 0000000..e8011b3
--- /dev/null
+++ b/app/src/main/res/layout/activity_add_device.xml
@@ -0,0 +1,141 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_home.xml b/app/src/main/res/layout/activity_home.xml
new file mode 100644
index 0000000..1ab18a6
--- /dev/null
+++ b/app/src/main/res/layout/activity_home.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
new file mode 100644
index 0000000..77b5296
--- /dev/null
+++ b/app/src/main/res/layout/activity_main.xml
@@ -0,0 +1,48 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/block.xml b/app/src/main/res/layout/block.xml
new file mode 100644
index 0000000..5fc558d
--- /dev/null
+++ b/app/src/main/res/layout/block.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
new file mode 100644
index 0000000..eca70cf
--- /dev/null
+++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
new file mode 100644
index 0000000..eca70cf
--- /dev/null
+++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.png b/app/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 0000000..a571e60
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
new file mode 100644
index 0000000..61da551
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.png b/app/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 0000000..c41dd28
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
new file mode 100644
index 0000000..db5080a
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/app/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..6dba46d
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..da31a87
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..15ac681
Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..b216f2d
Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 0000000..f25a419
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..e96783c
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/values-night/themes.xml b/app/src/main/res/values-night/themes.xml
new file mode 100644
index 0000000..6fdcaf0
--- /dev/null
+++ b/app/src/main/res/values-night/themes.xml
@@ -0,0 +1,16 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
new file mode 100644
index 0000000..f8c6127
--- /dev/null
+++ b/app/src/main/res/values/colors.xml
@@ -0,0 +1,10 @@
+
+
+ #FFBB86FC
+ #FF6200EE
+ #FF3700B3
+ #FF03DAC5
+ #FF018786
+ #FF000000
+ #FFFFFFFF
+
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000..fbd442b
--- /dev/null
+++ b/app/src/main/res/values/strings.xml
@@ -0,0 +1,15 @@
+
+ Remote SMS via Telegram
+ Read Phone State
+ With this permission, the app would be able to detect the information of the SIM/s installed.
+ GRANT PERMISSION
+ Receive SMS
+ With the help of this permission the app will be able to do the one it is ment for.
+ Device Name
+ Assigned SIM/s
+ Cancel
+ Next
+ Finish
+ Back
+ 5590669418:AAGkPInP-hGExhrj5cC7j39CBDoUz3jSPDI
+
\ No newline at end of file
diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml
new file mode 100644
index 0000000..260ac3a
--- /dev/null
+++ b/app/src/main/res/values/themes.xml
@@ -0,0 +1,16 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/test/java/com/appetize/remotesms/ExampleUnitTest.java b/app/src/test/java/com/appetize/remotesms/ExampleUnitTest.java
new file mode 100644
index 0000000..4a7a2ae
--- /dev/null
+++ b/app/src/test/java/com/appetize/remotesms/ExampleUnitTest.java
@@ -0,0 +1,17 @@
+package com.appetize.remotesms;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Example local unit test, which will execute on the development machine (host).
+ *
+ * @see Testing documentation
+ */
+public class ExampleUnitTest {
+ @Test
+ public void addition_isCorrect() {
+ assertEquals(4, 2 + 2);
+ }
+}
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
new file mode 100644
index 0000000..39bd1b7
--- /dev/null
+++ b/build.gradle
@@ -0,0 +1,24 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+buildscript {
+ repositories {
+ google()
+ jcenter()
+ }
+ dependencies {
+ classpath 'com.android.tools.build:gradle:7.2.2'
+ classpath 'com.google.gms:google-services:4.3.10'
+ // NOTE: Do not place your application dependencies here; they belong
+ // in the individual module build.gradle files
+ }
+}
+
+allprojects {
+ repositories {
+ google()
+ jcenter()
+ }
+}
+
+task clean(type: Delete) {
+ delete rootProject.buildDir
+}
\ No newline at end of file
diff --git a/gradle.properties b/gradle.properties
new file mode 100644
index 0000000..52f5917
--- /dev/null
+++ b/gradle.properties
@@ -0,0 +1,19 @@
+# Project-wide Gradle settings.
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
+# AndroidX package structure to make it clearer which packages are bundled with the
+# Android operating system, and which are packaged with your app"s APK
+# https://developer.android.com/topic/libraries/support-library/androidx-rn
+android.useAndroidX=true
+# Automatically convert third-party libraries to use AndroidX
+android.enableJetifier=true
\ No newline at end of file
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..f6b961f
Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..8059054
--- /dev/null
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Thu Dec 23 11:14:33 BDT 2021
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip
diff --git a/gradlew b/gradlew
new file mode 100644
index 0000000..cccdd3d
--- /dev/null
+++ b/gradlew
@@ -0,0 +1,172 @@
+#!/usr/bin/env sh
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=$(save "$@")
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
+if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
+ cd "$(dirname "$0")"
+fi
+
+exec "$JAVACMD" "$@"
diff --git a/gradlew.bat b/gradlew.bat
new file mode 100644
index 0000000..f955316
--- /dev/null
+++ b/gradlew.bat
@@ -0,0 +1,84 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windows variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/settings.gradle b/settings.gradle
new file mode 100644
index 0000000..6b02e2e
--- /dev/null
+++ b/settings.gradle
@@ -0,0 +1,2 @@
+include ':app'
+rootProject.name = "Remote SMS"
\ No newline at end of file