diff --git a/src/app/src/debug/res/drawable-anydpi/add.xml b/src/app/src/debug/res/drawable-anydpi/add.xml
new file mode 100644
index 0000000..672478e
--- /dev/null
+++ b/src/app/src/debug/res/drawable-anydpi/add.xml
@@ -0,0 +1,11 @@
+
+
+
diff --git a/src/app/src/debug/res/drawable-hdpi/add.png b/src/app/src/debug/res/drawable-hdpi/add.png
new file mode 100644
index 0000000..9a20be8
Binary files /dev/null and b/src/app/src/debug/res/drawable-hdpi/add.png differ
diff --git a/src/app/src/debug/res/drawable-mdpi/add.png b/src/app/src/debug/res/drawable-mdpi/add.png
new file mode 100644
index 0000000..be6d625
Binary files /dev/null and b/src/app/src/debug/res/drawable-mdpi/add.png differ
diff --git a/src/app/src/debug/res/drawable-xhdpi/add.png b/src/app/src/debug/res/drawable-xhdpi/add.png
new file mode 100644
index 0000000..6eedadf
Binary files /dev/null and b/src/app/src/debug/res/drawable-xhdpi/add.png differ
diff --git a/src/app/src/debug/res/drawable-xxhdpi/add.png b/src/app/src/debug/res/drawable-xxhdpi/add.png
new file mode 100644
index 0000000..7a27534
Binary files /dev/null and b/src/app/src/debug/res/drawable-xxhdpi/add.png differ
diff --git a/src/app/src/main/AndroidManifest.xml b/src/app/src/main/AndroidManifest.xml
index 17e5caf..d822bff 100644
--- a/src/app/src/main/AndroidManifest.xml
+++ b/src/app/src/main/AndroidManifest.xml
@@ -23,6 +23,13 @@
android:supportsRtl="true"
android:theme="@style/Theme.LocateMyDevice"
tools:targetApi="30">
+
+
+
diff --git a/src/app/src/main/java/com/xfarrow/locatemydevice/MainActivity.java b/src/app/src/main/java/com/xfarrow/locatemydevice/MainActivity.java
index b35516f..0a75e9c 100644
--- a/src/app/src/main/java/com/xfarrow/locatemydevice/MainActivity.java
+++ b/src/app/src/main/java/com/xfarrow/locatemydevice/MainActivity.java
@@ -67,39 +67,6 @@ public class MainActivity extends AppCompatActivity {
}
}
- @Override
- public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
- super.onRequestPermissionsResult(requestCode, permissions, grantResults);
-
- // Grant Background location if and only if FINE_LOCATION is already granted
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
- if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
- && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_BACKGROUND_LOCATION) != PackageManager.PERMISSION_GRANTED)
- {
- ActivityCompat.requestPermissions(this,
- new String[]{Manifest.permission.ACCESS_BACKGROUND_LOCATION},
- Utils.PERMISSION_ACCESS_BACKGROUND_LOCATION);
- }
- }
- }
-
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- getMenuInflater().inflate(R.menu.menu, menu);
- return super.onCreateOptionsMenu(menu);
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- int id = item.getItemId();
-
- if (id == R.id.settings_button) {
- Intent myIntent = new Intent(MainActivity.this, SettingsActivity.class);
- MainActivity.this.startActivity(myIntent);
- }
- return super.onOptionsItemSelected(item);
- }
-
public void displayDrawOverlayPermissionDialog(){
AlertDialog.Builder alert = new AlertDialog.Builder(this);
alert.setTitle("Display over other apps");
@@ -129,4 +96,39 @@ public class MainActivity extends AppCompatActivity {
" permission to provide the 'lock' feature.");
startActivity(intent);
}
+
+ @Override
+ public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
+ super.onRequestPermissionsResult(requestCode, permissions, grantResults);
+
+ // Grant Background location if and only if FINE_LOCATION is already granted
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
+ if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
+ && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_BACKGROUND_LOCATION) != PackageManager.PERMISSION_GRANTED)
+ {
+ ActivityCompat.requestPermissions(this,
+ new String[]{Manifest.permission.ACCESS_BACKGROUND_LOCATION},
+ Utils.PERMISSION_ACCESS_BACKGROUND_LOCATION);
+ }
+ }
+ }
+
+ // Add settings button on the top
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ getMenuInflater().inflate(R.menu.menu_settings, menu);
+ return super.onCreateOptionsMenu(menu);
+ }
+
+ // Settings button click
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ int id = item.getItemId();
+
+ if (id == R.id.settings_button) {
+ Intent myIntent = new Intent(MainActivity.this, SettingsActivity.class);
+ MainActivity.this.startActivity(myIntent);
+ }
+ return super.onOptionsItemSelected(item);
+ }
}
\ No newline at end of file
diff --git a/src/app/src/main/java/com/xfarrow/locatemydevice/Settings.java b/src/app/src/main/java/com/xfarrow/locatemydevice/Settings.java
index 55069dd..210830d 100644
--- a/src/app/src/main/java/com/xfarrow/locatemydevice/Settings.java
+++ b/src/app/src/main/java/com/xfarrow/locatemydevice/Settings.java
@@ -6,6 +6,7 @@ import android.content.SharedPreferences;
public class Settings {
public static final int PASSWORD = 0;
public static final int SMS_COMMAND = 1;
+ public static final int WHITELIST_ENABLED = 2;
private final SharedPreferences sharedPreferences;
@@ -29,6 +30,8 @@ public class Settings {
return CipherUtils.get256Sha("0000");
case SMS_COMMAND:
return "LMD";
+ case WHITELIST_ENABLED:
+ return "false";
}
return null;
}
diff --git a/src/app/src/main/java/com/xfarrow/locatemydevice/SettingsActivity.java b/src/app/src/main/java/com/xfarrow/locatemydevice/SettingsActivity.java
index caf99a5..342f344 100644
--- a/src/app/src/main/java/com/xfarrow/locatemydevice/SettingsActivity.java
+++ b/src/app/src/main/java/com/xfarrow/locatemydevice/SettingsActivity.java
@@ -1,13 +1,17 @@
package com.xfarrow.locatemydevice;
+import android.annotation.SuppressLint;
import android.content.DialogInterface;
+import android.content.Intent;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.text.method.PasswordTransformationMethod;
import android.view.View;
import android.widget.Button;
+import android.widget.CompoundButton;
import android.widget.EditText;
+import android.widget.Switch;
import android.widget.Toast;
import androidx.appcompat.app.AlertDialog;
@@ -17,6 +21,9 @@ public class SettingsActivity extends AppCompatActivity {
private Button buttonEnterPin;
private EditText editTextLmdCommand;
+ @SuppressLint("UseSwitchCompatOrMaterialCode")
+ private Switch whitelistSwitch;
+ private Button addContactsButton;
private Settings settings;
@Override
@@ -24,6 +31,7 @@ public class SettingsActivity extends AppCompatActivity {
super.onCreate(savedInstanceState);
setContentView(R.layout.settings);
settings = new Settings(this);
+
setViews();
setValues();
setListeners();
@@ -32,6 +40,11 @@ public class SettingsActivity extends AppCompatActivity {
private void setViews(){
buttonEnterPin = findViewById(R.id.buttonEnterPassword);
editTextLmdCommand = findViewById(R.id.editTextLmdCommand);
+ whitelistSwitch = findViewById(R.id.SwitchWhitelist);
+ addContactsButton = findViewById(R.id.buttonAddContacts);
+
+ addContactsButton.setEnabled(Boolean.parseBoolean(settings.get(Settings.WHITELIST_ENABLED)));
+ whitelistSwitch.setChecked(Boolean.parseBoolean(settings.get(Settings.WHITELIST_ENABLED)));
}
private void setValues(){
@@ -105,5 +118,22 @@ public class SettingsActivity extends AppCompatActivity {
}
}
});
+
+ whitelistSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
+ @Override
+ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+ addContactsButton.setEnabled(isChecked);
+ settings.set(Settings.WHITELIST_ENABLED, String.valueOf(isChecked));
+ }
+ });
+
+ addContactsButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ Intent myIntent = new Intent(SettingsActivity.this, WhitelistContactsActivity.class);
+ SettingsActivity.this.startActivity(myIntent);
+ }
+ });
+
}
}
diff --git a/src/app/src/main/java/com/xfarrow/locatemydevice/SmsHandler.java b/src/app/src/main/java/com/xfarrow/locatemydevice/SmsHandler.java
index 1775b4c..9dc2746 100644
--- a/src/app/src/main/java/com/xfarrow/locatemydevice/SmsHandler.java
+++ b/src/app/src/main/java/com/xfarrow/locatemydevice/SmsHandler.java
@@ -50,6 +50,12 @@ public class SmsHandler {
String providedOption = "";
String providedPassword = "";
+ // Deny communication to those not in the whitelist, if enabled
+ WhitelistDbHandler whitelistDbHandler = new WhitelistDbHandler(context);
+ if(Boolean.parseBoolean(settings.get(Settings.WHITELIST_ENABLED)) && !whitelistDbHandler.isContactPresent(sender)){
+ return;
+ }
+
String regexToMatch = "^"
+ command
+ "\\s"
diff --git a/src/app/src/main/java/com/xfarrow/locatemydevice/WhitelistContactsActivity.java b/src/app/src/main/java/com/xfarrow/locatemydevice/WhitelistContactsActivity.java
new file mode 100644
index 0000000..f5fd913
--- /dev/null
+++ b/src/app/src/main/java/com/xfarrow/locatemydevice/WhitelistContactsActivity.java
@@ -0,0 +1,89 @@
+package com.xfarrow.locatemydevice;
+
+import androidx.appcompat.app.AppCompatActivity;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Bundle;
+import android.provider.ContactsContract;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.widget.ArrayAdapter;
+import android.widget.ListView;
+import android.widget.Toast;
+
+import java.util.ArrayList;
+
+public class WhitelistContactsActivity extends AppCompatActivity {
+
+ ListView contactsListView;
+ ArrayList contacts;
+ ArrayAdapter listviewAdapter;
+ WhitelistDbHandler whitelistDbHandler = new WhitelistDbHandler(this);
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_whitelist_contacts);
+ setTitle("Whitelist");
+ setViews();
+
+ contacts = whitelistDbHandler.getAllContacts();
+ listviewAdapter = new ArrayAdapter(this,
+ android.R.layout.simple_list_item_1,
+ contacts);
+ contactsListView.setAdapter(listviewAdapter);
+ }
+
+ private void setViews(){
+ contactsListView = findViewById(R.id.ContactsListView);
+ }
+
+ // Add "add" button on the top
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ getMenuInflater().inflate(R.menu.menu_add, menu);
+ return super.onCreateOptionsMenu(menu);
+ }
+
+ // "Add contact" click
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ int id = item.getItemId();
+
+ if (id == R.id.add_button) {
+ Intent pickContact = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);
+ pickContact.setType(ContactsContract.CommonDataKinds.Phone.CONTENT_TYPE);
+ startActivityForResult(pickContact, 123);
+ }
+ return super.onOptionsItemSelected(item);
+ }
+
+ // Gets fired when the user has chosen the contact
+ @Override
+ protected void onActivityResult (int requestCode, int resultCode, Intent data) {
+ super.onActivityResult(requestCode, resultCode, data);
+ if (resultCode == Activity.RESULT_OK && requestCode == 123) {
+ Uri contactData = data.getData();
+ Cursor c = getContentResolver().query(contactData, null, null, null, null);
+ if (c.moveToFirst()) {
+ int phoneIndex = c.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
+ String number = c.getString(phoneIndex).trim().replace("\\s+", "");
+ contactSelected(number);
+ }
+ c.close();
+ }
+ }
+
+ private void contactSelected(String number){
+ if(whitelistDbHandler.isContactPresent(number)){
+ Toast.makeText(this, "Contact already in the list", Toast.LENGTH_SHORT).show();
+ return;
+ }
+ whitelistDbHandler.addContact(number);
+ contacts.add(number);
+ listviewAdapter.notifyDataSetChanged();
+ }
+}
\ No newline at end of file
diff --git a/src/app/src/main/java/com/xfarrow/locatemydevice/WhitelistDbHandler.java b/src/app/src/main/java/com/xfarrow/locatemydevice/WhitelistDbHandler.java
new file mode 100644
index 0000000..cc7e30f
--- /dev/null
+++ b/src/app/src/main/java/com/xfarrow/locatemydevice/WhitelistDbHandler.java
@@ -0,0 +1,83 @@
+package com.xfarrow.locatemydevice;
+
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+
+import androidx.annotation.Nullable;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class WhitelistDbHandler extends SQLiteOpenHelper {
+
+ private static final int DATABASE_VERSION = 1;
+ private static final String DATABASE_NAME = "WhitelistDb";
+ private static final String TABLE_CONTACTS = "Contacts";
+ private static final String KEY_ID = "id";
+ private static final String KEY_PH_NO = "phone_number";
+
+ public WhitelistDbHandler(@Nullable Context context) {
+ super(context, DATABASE_NAME, null, DATABASE_VERSION);
+ }
+
+ @Override
+ public void onCreate(SQLiteDatabase db) {
+ String CREATE_CONTACTS_TABLE = "CREATE TABLE " + TABLE_CONTACTS + "("
+ + KEY_ID + " " + "INTEGER PRIMARY KEY,"
+ + KEY_PH_NO + " " + "TEXT" + ")";
+ db.execSQL(CREATE_CONTACTS_TABLE);
+ }
+
+ @Override
+ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+ db.execSQL("DROP TABLE IF EXISTS " + TABLE_CONTACTS);
+ onCreate(db);
+ }
+
+ // Add a contact
+ void addContact(String phoneNo){
+ SQLiteDatabase db = this.getWritableDatabase();
+ ContentValues values = new ContentValues();
+ values.put(KEY_PH_NO, phoneNo); // Contact Phone
+ db.insert(TABLE_CONTACTS, null, values);
+ db.close(); // Closing database connection
+ }
+
+ // Deleting single contact
+ public void deleteContact(String phoneNo) {
+ SQLiteDatabase db = this.getWritableDatabase();
+ db.delete(TABLE_CONTACTS, KEY_ID + " = ?", new String[] { phoneNo });
+ db.close();
+ }
+
+ public ArrayList getAllContacts() {
+ ArrayList array_list = new ArrayList();
+
+ //hp = new HashMap();
+ SQLiteDatabase db = this.getReadableDatabase();
+ Cursor cursor = db.rawQuery( "select * from " + TABLE_CONTACTS, null );
+ cursor.moveToFirst();
+
+ int columnIndex = cursor.getColumnIndex(KEY_PH_NO);
+
+ while(!cursor.isAfterLast()){
+ array_list.add(cursor.getString(columnIndex));
+ cursor.moveToNext();
+ }
+ cursor.close();
+ return array_list;
+ }
+
+ public boolean isContactPresent(String phoneNo){
+ SQLiteDatabase db = this.getWritableDatabase();
+ String query = "Select * from " + TABLE_CONTACTS + " where " + KEY_PH_NO + " = " + "\"" + phoneNo + "\"";
+ Cursor cursor = db.rawQuery(query, null);
+ int count = cursor.getCount();
+ cursor.close();
+ return count > 0;
+ }
+
+}
diff --git a/src/app/src/main/res/layout/activity_whitelist_contacts.xml b/src/app/src/main/res/layout/activity_whitelist_contacts.xml
new file mode 100644
index 0000000..4544ad6
--- /dev/null
+++ b/src/app/src/main/res/layout/activity_whitelist_contacts.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/app/src/main/res/layout/settings.xml b/src/app/src/main/res/layout/settings.xml
index 41464ad..d20da32 100644
--- a/src/app/src/main/res/layout/settings.xml
+++ b/src/app/src/main/res/layout/settings.xml
@@ -60,11 +60,48 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/app/src/main/res/menu/menu_add.xml b/src/app/src/main/res/menu/menu_add.xml
new file mode 100644
index 0000000..02db146
--- /dev/null
+++ b/src/app/src/main/res/menu/menu_add.xml
@@ -0,0 +1,9 @@
+
diff --git a/src/app/src/main/res/menu/menu.xml b/src/app/src/main/res/menu/menu_settings.xml
similarity index 100%
rename from src/app/src/main/res/menu/menu.xml
rename to src/app/src/main/res/menu/menu_settings.xml