diff --git a/app/build.gradle b/app/build.gradle index db57bfc..bcbd765 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,7 +1,7 @@ apply plugin: 'com.android.application' android { - compileSdkVersion 23 + compileSdkVersion 29 buildToolsVersion "23.0.3" defaultConfig { @@ -9,11 +9,11 @@ android { testApplicationId "me.angrybyte.contactsgenerator.test" minSdkVersion 14 - targetSdkVersion 23 + targetSdkVersion 29 versionCode 10 versionName "2.0.0" - testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner' } dexOptions { @@ -49,29 +49,29 @@ android { dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) - compile 'com.android.support:appcompat-v7:23.4.0' - compile 'com.android.support:cardview-v7:23.4.0' - compile 'com.google.code.gson:gson:2.4' + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'androidx.cardview:cardview:1.0.0' + implementation 'com.google.code.gson:gson:2.8.6' - compile 'com.squareup.okhttp:okhttp:2.4.0' - compile 'com.pkmmte.view:circularimageview:1.1' + implementation 'com.squareup.okhttp:okhttp:2.4.0' + implementation 'com.pkmmte.view:circularimageview:1.1' - compile 'me.angrybyte.picker:picker:1.2.0' + implementation 'me.angrybyte.picker:picker:1.2.0' - compile 'io.reactivex:rxandroid:1.2.1' + implementation 'io.reactivex:rxandroid:1.2.1' // Because RxAndroid releases are few and far between, it is recommended you also // explicitly depend on RxJava's latest version for bug fixes and new features. - compile 'io.reactivex:rxjava:1.2.2' + implementation 'io.reactivex:rxjava:1.2.2' - compile 'com.squareup.sqlbrite:sqlbrite:0.8.0' - compile 'com.venmo.cursor:library:0.4' + implementation 'com.squareup.sqlbrite:sqlbrite:0.8.0' + implementation 'com.venmo.cursor:library:0.4' // set this dependency to use the JUnit instrumentation runner - androidTestCompile 'com.android.support.test:runner:0.4.1' + androidTestImplementation 'androidx.test.ext:junit:1.1.2' // set this dependency to use JUnit 4 rules - androidTestCompile 'com.android.support.test:rules:0.4.1' + androidTestImplementation 'androidx.test:rules:1.3.0' // set this dependency to build and run Espresso tests - androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' // Lollipop only: set this dependency to build and run UI Automator tests // androidTestCompile 'com.android.support.test.uiautomator:uiautomator-v18:2.1.1' diff --git a/app/src/androidTest/java/me/angrybyte/contactsgenerator/test/app/MainActivityTest.java b/app/src/androidTest/java/me/angrybyte/contactsgenerator/test/app/MainActivityTest.java index cd27a4a..6fbd24e 100644 --- a/app/src/androidTest/java/me/angrybyte/contactsgenerator/test/app/MainActivityTest.java +++ b/app/src/androidTest/java/me/angrybyte/contactsgenerator/test/app/MainActivityTest.java @@ -1,7 +1,7 @@ package me.angrybyte.contactsgenerator.test.app; -import android.support.v7.widget.Toolbar; +import androidx.appcompat.widget.Toolbar; import android.test.ActivityInstrumentationTestCase2; import android.test.suitebuilder.annotation.SmallTest; diff --git a/app/src/androidTest/java/me/angrybyte/contactsgenerator/test/app/OperationTest.java b/app/src/androidTest/java/me/angrybyte/contactsgenerator/test/app/OperationTest.java index f255bbb..8bf4156 100644 --- a/app/src/androidTest/java/me/angrybyte/contactsgenerator/test/app/OperationTest.java +++ b/app/src/androidTest/java/me/angrybyte/contactsgenerator/test/app/OperationTest.java @@ -9,7 +9,7 @@ import android.net.NetworkInfo; import android.os.Build; import android.os.RemoteException; -import android.support.v4.app.ActivityCompat; +import androidx.core.app.ActivityCompat; import android.test.ActivityInstrumentationTestCase2; import android.test.suitebuilder.annotation.MediumTest; import android.test.suitebuilder.annotation.SmallTest; diff --git a/app/src/main/java/me/angrybyte/contactsgenerator/MainActivity.java b/app/src/main/java/me/angrybyte/contactsgenerator/MainActivity.java index 88b5d6e..f3e0d5c 100644 --- a/app/src/main/java/me/angrybyte/contactsgenerator/MainActivity.java +++ b/app/src/main/java/me/angrybyte/contactsgenerator/MainActivity.java @@ -11,18 +11,17 @@ import android.content.ServiceConnection; import android.content.SharedPreferences; import android.content.pm.PackageManager; -import android.database.Cursor; import android.graphics.Color; import android.net.Uri; import android.os.Bundle; import android.os.IBinder; -import android.provider.ContactsContract; -import android.support.annotation.NonNull; -import android.support.annotation.RequiresPermission; -import android.support.v4.app.ActivityCompat; -import android.support.v7.app.AlertDialog; -import android.support.v7.app.AppCompatActivity; -import android.support.v7.widget.Toolbar; + +import androidx.annotation.NonNull; +import androidx.annotation.RequiresPermission; +import androidx.core.app.ActivityCompat; +import androidx.appcompat.app.AlertDialog; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.Toolbar; import android.util.Log; import android.view.MenuItem; import android.view.View; @@ -30,7 +29,6 @@ import android.widget.RadioButton; import android.widget.Toast; -import me.angrybyte.contactsgenerator.api.ContactOperations; import me.angrybyte.contactsgenerator.api.Gender; import me.angrybyte.contactsgenerator.api.Operations; import me.angrybyte.contactsgenerator.parser.data.Person; diff --git a/app/src/main/java/me/angrybyte/contactsgenerator/ProgressActivity.java b/app/src/main/java/me/angrybyte/contactsgenerator/ProgressActivity.java index 9b10167..5372714 100644 --- a/app/src/main/java/me/angrybyte/contactsgenerator/ProgressActivity.java +++ b/app/src/main/java/me/angrybyte/contactsgenerator/ProgressActivity.java @@ -6,10 +6,10 @@ import android.content.ServiceConnection; import android.os.Bundle; import android.os.IBinder; -import android.support.annotation.FloatRange; -import android.support.annotation.IntRange; -import android.support.annotation.NonNull; -import android.support.v7.app.AppCompatActivity; +import androidx.annotation.FloatRange; +import androidx.annotation.IntRange; +import androidx.annotation.NonNull; +import androidx.appcompat.app.AppCompatActivity; import android.util.Log; import android.view.View; import android.view.ViewGroup; diff --git a/app/src/main/java/me/angrybyte/contactsgenerator/StatsActivity.java b/app/src/main/java/me/angrybyte/contactsgenerator/StatsActivity.java index b6ca3be..cac7b16 100644 --- a/app/src/main/java/me/angrybyte/contactsgenerator/StatsActivity.java +++ b/app/src/main/java/me/angrybyte/contactsgenerator/StatsActivity.java @@ -7,8 +7,8 @@ import android.graphics.Color; import android.os.Bundle; import android.os.IBinder; -import android.support.v7.app.AppCompatActivity; -import android.support.v7.widget.Toolbar; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.Toolbar; import android.text.TextUtils; import android.util.Log; import android.view.View; diff --git a/app/src/main/java/me/angrybyte/contactsgenerator/api/ContactOperations.java b/app/src/main/java/me/angrybyte/contactsgenerator/api/ContactOperations.java index 50b7651..69aff96 100644 --- a/app/src/main/java/me/angrybyte/contactsgenerator/api/ContactOperations.java +++ b/app/src/main/java/me/angrybyte/contactsgenerator/api/ContactOperations.java @@ -9,10 +9,11 @@ import android.net.Uri; import android.os.RemoteException; import android.provider.ContactsContract; -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; import android.util.Log; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + import com.squareup.sqlbrite.BriteContentResolver; import com.squareup.sqlbrite.SqlBrite; import com.venmo.cursor.IterableCursor; @@ -22,7 +23,9 @@ import java.io.Closeable; import java.io.IOException; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; +import java.util.Random; import me.angrybyte.contactsgenerator.parser.data.Person; import rx.Observable; @@ -42,7 +45,7 @@ public class ContactOperations { // private static final String EXAMPLE_DOMAIN = "@example.com"; private static final Uri CONTENT_URI = ContactsContract.CommonDataKinds.Email.CONTENT_URI; - private static final String[] PROJECTION = new String[] { + private static final String[] PROJECTION = new String[]{ ContactsContract.CommonDataKinds.Email.CONTACT_ID, ContactsContract.CommonDataKinds.Email.DISPLAY_NAME, ContactsContract.CommonDataKinds.Email.ADDRESS, @@ -50,7 +53,7 @@ public class ContactOperations { ContactsContract.CommonDataKinds.Email.LOOKUP_KEY }; private static final String SELECTION = ContactsContract.CommonDataKinds.Email.ADDRESS + " LIKE ?"; - private static final String[] SELECTION_ARGS = new String[] {"%" + EXAMPLE_DOMAIN}; + private static final String[] SELECTION_ARGS = new String[]{"%" + EXAMPLE_DOMAIN}; private static final int ID = 0; private static final int DISPLAY_NAME = 1; @@ -94,16 +97,20 @@ public void storeContact(@NonNull Person person) throws RemoteException, Operati operations.add(providerOperation.build()); - providerOperation = ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI) - .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0) - .withValue(ContactsContract.Data.MIMETYPE, - ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE) - .withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, - person.getPhone()) - .withValue(ContactsContract.CommonDataKinds.Phone.TYPE, - ContactsContract.CommonDataKinds.Phone.TYPE_HOME); + // Phone + final List phoneNumbers = Arrays.asList(person.getPhone(), generatePhoneNumber()); + final Random rndPhoneTypeGenerator = new Random(); - operations.add(providerOperation.build()); + for (String phoneNumber : phoneNumbers) { + operations.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI) + .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0) + .withValue(ContactsContract.Data.MIMETYPE, + ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE) + .withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, + phoneNumber) + .withValue(ContactsContract.CommonDataKinds.Phone.TYPE, + getPhoneType(rndPhoneTypeGenerator)).build()); + } providerOperation = ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI) .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0) @@ -158,7 +165,6 @@ public void storeContacts(@NonNull List persons) throws RemoteException, * @param matchingEmail You can parametrize the search query of the cursor with an email address. Sending {@code * null} will find all the contacts, while sending in a valid email address will find contacts * with only that email address associated with them - * * @return {@code True} if the cursor has been opened successfully, {@code false} otherwise */ public boolean prepareCursorForScrubbing(@Nullable String matchingEmail) { @@ -168,16 +174,16 @@ public boolean prepareCursorForScrubbing(@Nullable String matchingEmail) { String[] whereArgs; if (matchingEmail != null) { mMatchingEmail = matchingEmail; - projection = new String[] { + projection = new String[]{ ContactsContract.Contacts.LOOKUP_KEY, ContactsContract.CommonDataKinds.Email.ADDRESS }; where = ContactsContract.CommonDataKinds.Email.ADDRESS + " LIKE ?"; - whereArgs = new String[] { + whereArgs = new String[]{ "%" + matchingEmail }; } else { - projection = new String[] { + projection = new String[]{ ContactsContract.Contacts.LOOKUP_KEY }; @@ -225,7 +231,7 @@ public boolean deleteNextContact() { Uri uri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_LOOKUP_URI, lookupKey); int deletedRows = mContentResolver.delete(uri, null, null); if (deletedRows < 1) { - Log.w(TAG, "Nothing deleted for URI " + String.valueOf(uri)); + Log.w(TAG, "Nothing deleted for URI " + uri); return false; } } @@ -241,12 +247,36 @@ public boolean deleteNextContact() { return true; } + private String generatePhoneNumber() { + Random rndGenerator = new Random(); + StringBuilder stringBuilder = new StringBuilder(); + + while (stringBuilder.length() < 11) { + stringBuilder.append(rndGenerator.nextInt(9)); + } + + return stringBuilder.toString(); + } + + private int getPhoneType(Random rndPhoneTypeGenerator) { + switch (rndPhoneTypeGenerator.nextInt(2) + 1) { + + case ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE: + return ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE; + + case ContactsContract.CommonDataKinds.Phone.TYPE_WORK: + return ContactsContract.CommonDataKinds.Phone.TYPE_WORK; + + default: return ContactsContract.CommonDataKinds.Phone.TYPE_HOME; + } + } + private void close(Closeable closeable) { if (closeable != null) { try { closeable.close(); } catch (Exception e) { - Log.w(TAG, "Cannot close the closeable " + String.valueOf(closeable)); + Log.w(TAG, "Cannot close the closeable " + closeable); } } } diff --git a/app/src/main/java/me/angrybyte/contactsgenerator/api/Gender.java b/app/src/main/java/me/angrybyte/contactsgenerator/api/Gender.java index 544845d..8eaed0c 100644 --- a/app/src/main/java/me/angrybyte/contactsgenerator/api/Gender.java +++ b/app/src/main/java/me/angrybyte/contactsgenerator/api/Gender.java @@ -1,7 +1,7 @@ package me.angrybyte.contactsgenerator.api; -import android.support.annotation.StringDef; +import androidx.annotation.StringDef; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/app/src/main/java/me/angrybyte/contactsgenerator/api/GeneratorStats.java b/app/src/main/java/me/angrybyte/contactsgenerator/api/GeneratorStats.java index 7f38041..e2f3ae3 100644 --- a/app/src/main/java/me/angrybyte/contactsgenerator/api/GeneratorStats.java +++ b/app/src/main/java/me/angrybyte/contactsgenerator/api/GeneratorStats.java @@ -1,7 +1,7 @@ package me.angrybyte.contactsgenerator.api; -import android.support.annotation.Nullable; +import androidx.annotation.Nullable; import java.io.Serializable; diff --git a/app/src/main/java/me/angrybyte/contactsgenerator/api/Operations.java b/app/src/main/java/me/angrybyte/contactsgenerator/api/Operations.java index 2f3930a..b37232f 100644 --- a/app/src/main/java/me/angrybyte/contactsgenerator/api/Operations.java +++ b/app/src/main/java/me/angrybyte/contactsgenerator/api/Operations.java @@ -4,10 +4,10 @@ import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; -import android.support.annotation.IntRange; -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; -import android.support.annotation.RawRes; +import androidx.annotation.IntRange; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.RawRes; import android.util.Log; import com.squareup.okhttp.OkHttpClient; diff --git a/app/src/main/java/me/angrybyte/contactsgenerator/parser/json/JsonParser.java b/app/src/main/java/me/angrybyte/contactsgenerator/parser/json/JsonParser.java index 28e9a8f..6265537 100644 --- a/app/src/main/java/me/angrybyte/contactsgenerator/parser/json/JsonParser.java +++ b/app/src/main/java/me/angrybyte/contactsgenerator/parser/json/JsonParser.java @@ -1,7 +1,7 @@ package me.angrybyte.contactsgenerator.parser.json; -import android.support.annotation.NonNull; +import androidx.annotation.NonNull; import com.google.gson.JsonArray; import com.google.gson.JsonElement; diff --git a/app/src/main/java/me/angrybyte/contactsgenerator/service/GeneratorService.java b/app/src/main/java/me/angrybyte/contactsgenerator/service/GeneratorService.java index cc83578..a177574 100644 --- a/app/src/main/java/me/angrybyte/contactsgenerator/service/GeneratorService.java +++ b/app/src/main/java/me/angrybyte/contactsgenerator/service/GeneratorService.java @@ -8,13 +8,14 @@ import android.os.AsyncTask; import android.os.Handler; import android.os.IBinder; -import android.support.annotation.FloatRange; -import android.support.annotation.IntRange; -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; -import android.support.v4.app.NotificationCompat; import android.util.Log; +import androidx.annotation.FloatRange; +import androidx.annotation.IntRange; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.core.app.NotificationCompat; + import java.util.Locale; import me.angrybyte.contactsgenerator.ProgressActivity; @@ -29,6 +30,7 @@ public class GeneratorService extends Service implements ServiceApi, OnGenerateP public static final String TAG = GeneratorService.class.getSimpleName(); public static final int NOTIFICATION_ID = 1475369; + public static final String CONTACTS_GENERATOR_CHANNEL = "CONTACTS_GENERATOR_CHANNEL"; private Person mLastGenerated; private Handler mHandler; @@ -40,6 +42,7 @@ public class GeneratorService extends Service implements ServiceApi, OnGenerateP private OnGenerateResultListener mResultListener; private OnGenerateProgressListener mProgressListener; private AsyncTask mDeletionTask; + private boolean mIsForceStopped; private boolean mIsGenerating; private boolean mIsDeleting; @@ -57,7 +60,7 @@ public void onCreate() { @Override public int onStartCommand(Intent intent, int flags, int startId) { - Log.d(TAG, "Starting " + TAG + " with intent " + String.valueOf(intent)); + Log.d(TAG, "Starting " + TAG + " with intent " + intent); if (ServiceApi.DELETE_CONTACTS_ACTION.equals(intent.getAction())) { mContactOperations = new ContactOperations(this); @@ -72,7 +75,7 @@ public int onStartCommand(Intent intent, int flags, int startId) { @Nullable @Override public IBinder onBind(Intent intent) { - Log.d(TAG, "Binding " + TAG + " with intent " + String.valueOf(intent)); + Log.d(TAG, "Binding " + TAG + " with intent " + intent); return mBinder; } @@ -108,7 +111,7 @@ public void onTaskRemoved(Intent rootIntent) { } private void showNotification() { - mBuilder = new NotificationCompat.Builder(this); + mBuilder = new NotificationCompat.Builder(this, CONTACTS_GENERATOR_CHANNEL); mBuilder.setCategory(NotificationCompat.CATEGORY_SERVICE); mBuilder.setSmallIcon(R.drawable.ic_stat_generator); mBuilder.setContentTitle(getString(R.string.app_name)); diff --git a/app/src/main/java/me/angrybyte/contactsgenerator/service/GeneratorServiceBinder.java b/app/src/main/java/me/angrybyte/contactsgenerator/service/GeneratorServiceBinder.java index 2d406f4..bc3cc40 100644 --- a/app/src/main/java/me/angrybyte/contactsgenerator/service/GeneratorServiceBinder.java +++ b/app/src/main/java/me/angrybyte/contactsgenerator/service/GeneratorServiceBinder.java @@ -2,7 +2,7 @@ package me.angrybyte.contactsgenerator.service; import android.os.Binder; -import android.support.annotation.NonNull; +import androidx.annotation.NonNull; import java.lang.ref.WeakReference; diff --git a/app/src/main/java/me/angrybyte/contactsgenerator/service/GeneratorThread.java b/app/src/main/java/me/angrybyte/contactsgenerator/service/GeneratorThread.java index 22b533b..4d286f2 100644 --- a/app/src/main/java/me/angrybyte/contactsgenerator/service/GeneratorThread.java +++ b/app/src/main/java/me/angrybyte/contactsgenerator/service/GeneratorThread.java @@ -3,9 +3,9 @@ import android.graphics.Bitmap; import android.os.Handler; -import android.support.annotation.IntRange; -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; +import androidx.annotation.IntRange; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import android.util.Log; import java.util.ArrayList; diff --git a/app/src/main/java/me/angrybyte/contactsgenerator/service/OnGenerateProgressListener.java b/app/src/main/java/me/angrybyte/contactsgenerator/service/OnGenerateProgressListener.java index 9b3ea53..73d4adc 100644 --- a/app/src/main/java/me/angrybyte/contactsgenerator/service/OnGenerateProgressListener.java +++ b/app/src/main/java/me/angrybyte/contactsgenerator/service/OnGenerateProgressListener.java @@ -1,8 +1,8 @@ package me.angrybyte.contactsgenerator.service; -import android.support.annotation.FloatRange; -import android.support.annotation.IntRange; +import androidx.annotation.FloatRange; +import androidx.annotation.IntRange; public interface OnGenerateProgressListener { diff --git a/app/src/main/java/me/angrybyte/contactsgenerator/service/OnGenerateResultListener.java b/app/src/main/java/me/angrybyte/contactsgenerator/service/OnGenerateResultListener.java index e4c60bd..4eb8642 100644 --- a/app/src/main/java/me/angrybyte/contactsgenerator/service/OnGenerateResultListener.java +++ b/app/src/main/java/me/angrybyte/contactsgenerator/service/OnGenerateResultListener.java @@ -1,7 +1,7 @@ package me.angrybyte.contactsgenerator.service; -import android.support.annotation.NonNull; +import androidx.annotation.NonNull; import me.angrybyte.contactsgenerator.api.GeneratorStats; diff --git a/app/src/main/java/me/angrybyte/contactsgenerator/service/ServiceApi.java b/app/src/main/java/me/angrybyte/contactsgenerator/service/ServiceApi.java index 8a0d195..8a3f6c5 100644 --- a/app/src/main/java/me/angrybyte/contactsgenerator/service/ServiceApi.java +++ b/app/src/main/java/me/angrybyte/contactsgenerator/service/ServiceApi.java @@ -2,8 +2,8 @@ package me.angrybyte.contactsgenerator.service; import android.content.ComponentName; -import android.support.annotation.IntRange; -import android.support.annotation.Nullable; +import androidx.annotation.IntRange; +import androidx.annotation.Nullable; import me.angrybyte.contactsgenerator.api.Gender; import me.angrybyte.contactsgenerator.api.GeneratorStats; diff --git a/app/src/main/res/layout-land/activity_main.xml b/app/src/main/res/layout-land/activity_main.xml index ee16b7d..6bdf950 100644 --- a/app/src/main/res/layout-land/activity_main.xml +++ b/app/src/main/res/layout-land/activity_main.xml @@ -138,7 +138,7 @@ - - - - - + - - + - - + - - + diff --git a/app/src/main/res/layout-sw600dp-land/activity_stats.xml b/app/src/main/res/layout-sw600dp-land/activity_stats.xml index 9084f3c..01e045b 100644 --- a/app/src/main/res/layout-sw600dp-land/activity_stats.xml +++ b/app/src/main/res/layout-sw600dp-land/activity_stats.xml @@ -9,7 +9,7 @@ android:orientation="vertical" tools:context="me.angrybyte.contactsgenerator.StatsActivity"> - - + - - + - - + - - +