From 08134ef5f100b5eb25bf19c10b68b54c1116ff83 Mon Sep 17 00:00:00 2001 From: Ammar Githam Date: Sat, 12 Sep 2020 00:51:00 +0900 Subject: [PATCH] Add activity checker service --- app/src/main/AndroidManifest.xml | 1 + .../instagrabber/InstaGrabberApplication.java | 5 - .../instagrabber/activities/MainActivity.java | 77 +++++++++- .../instagrabber/asyncs/DownloadAsync.java | 49 +++---- .../asyncs/GetActivityAsyncTask.java | 44 +++--- .../directdownload/DirectDownload.java | 105 +++++++------- .../NotificationsViewerFragment.java | 16 ++- .../settings/SettingsPreferencesFragment.java | 7 +- .../services/ActivityCheckerService.java | 132 ++++++++++++++++++ .../awais/instagrabber/utils/Constants.java | 7 +- .../java/awais/instagrabber/utils/Utils.java | 10 +- 11 files changed, 327 insertions(+), 126 deletions(-) create mode 100644 app/src/main/java/awais/instagrabber/services/ActivityCheckerService.java diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 7b9d8c27..9910d2cc 100755 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -138,5 +138,6 @@ android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/provider_paths" /> + \ No newline at end of file diff --git a/app/src/main/java/awais/instagrabber/InstaGrabberApplication.java b/app/src/main/java/awais/instagrabber/InstaGrabberApplication.java index 85bd02be..dbff1a60 100644 --- a/app/src/main/java/awais/instagrabber/InstaGrabberApplication.java +++ b/app/src/main/java/awais/instagrabber/InstaGrabberApplication.java @@ -4,7 +4,6 @@ import android.content.ClipboardManager; import android.content.Context; import android.util.Log; -import androidx.core.app.NotificationManagerCompat; import androidx.multidex.MultiDexApplication; import com.facebook.drawee.backends.pipeline.Fresco; @@ -26,7 +25,6 @@ import static awais.instagrabber.utils.Utils.clipboardManager; import static awais.instagrabber.utils.Utils.dataBox; import static awais.instagrabber.utils.Utils.datetimeParser; import static awais.instagrabber.utils.Utils.logCollector; -import static awais.instagrabber.utils.Utils.notificationManager; import static awais.instagrabber.utils.Utils.settingsHelper; public final class InstaGrabberApplication extends MultiDexApplication { @@ -67,9 +65,6 @@ public final class InstaGrabberApplication extends MultiDexApplication { LocaleUtils.setLocale(getBaseContext()); - if (notificationManager == null) - notificationManager = NotificationManagerCompat.from(appContext); - if (clipboardManager == null) clipboardManager = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); diff --git a/app/src/main/java/awais/instagrabber/activities/MainActivity.java b/app/src/main/java/awais/instagrabber/activities/MainActivity.java index d6b2f7b0..6d962c07 100644 --- a/app/src/main/java/awais/instagrabber/activities/MainActivity.java +++ b/app/src/main/java/awais/instagrabber/activities/MainActivity.java @@ -2,13 +2,20 @@ package awais.instagrabber.activities; import android.annotation.SuppressLint; +import android.app.NotificationChannel; +import android.app.NotificationManager; +import android.content.ComponentName; +import android.content.Context; import android.content.Intent; +import android.content.ServiceConnection; import android.content.res.TypedArray; import android.database.MatrixCursor; import android.net.Uri; import android.os.AsyncTask; +import android.os.Build; import android.os.Bundle; import android.os.Handler; +import android.os.IBinder; import android.provider.BaseColumns; import android.util.Log; import android.view.Menu; @@ -21,10 +28,12 @@ import androidx.annotation.Nullable; import androidx.appcompat.widget.SearchView; import androidx.appcompat.widget.Toolbar; import androidx.coordinatorlayout.widget.CoordinatorLayout; +import androidx.core.app.NotificationManagerCompat; import androidx.lifecycle.LiveData; import androidx.navigation.NavBackStackEntry; import androidx.navigation.NavController; import androidx.navigation.NavDestination; +import androidx.navigation.NavDirections; import androidx.navigation.ui.NavigationUI; import com.google.android.material.appbar.AppBarLayout; @@ -43,10 +52,12 @@ import awais.instagrabber.adapters.SuggestionsAdapter; import awais.instagrabber.asyncs.SuggestionsFetcher; import awais.instagrabber.customviews.helpers.CustomHideBottomViewOnScrollBehavior; import awais.instagrabber.databinding.ActivityMainBinding; +import awais.instagrabber.fragments.settings.MorePreferencesFragmentDirections; import awais.instagrabber.interfaces.FetchListener; import awais.instagrabber.models.IntentModel; import awais.instagrabber.models.SuggestionModel; import awais.instagrabber.models.enums.SuggestionType; +import awais.instagrabber.services.ActivityCheckerService; import awais.instagrabber.utils.Constants; import awais.instagrabber.utils.CookieUtils; import awais.instagrabber.utils.FlavorTown; @@ -93,7 +104,21 @@ public class MainActivity extends BaseLanguageActivity { private boolean showSearch = true; private Handler suggestionsFetchHandler; private int firstFragmentGraphIndex; - private boolean isLoggedIn; + private boolean isActivityCheckerServiceBound = false; + + private final ServiceConnection serviceConnection = new ServiceConnection() { + @Override + public void onServiceConnected(final ComponentName name, final IBinder service) { + // final ActivityCheckerService.LocalBinder binder = (ActivityCheckerService.LocalBinder) service; + // final ActivityCheckerService activityCheckerService = binder.getService(); + isActivityCheckerServiceBound = true; + } + + @Override + public void onServiceDisconnected(final ComponentName name) { + isActivityCheckerServiceBound = false; + } + }; static { NAV_TO_MENU_ID_MAP.put(R.navigation.direct_messages_nav_graph, R.id.direct_messages_nav_graph); @@ -112,6 +137,7 @@ public class MainActivity extends BaseLanguageActivity { setContentView(binding.getRoot()); final Toolbar toolbar = binding.toolbar; setSupportActionBar(toolbar); + createNotificationChannels(); if (savedInstanceState == null) { setupBottomNavigationBar(true); } @@ -120,9 +146,11 @@ public class MainActivity extends BaseLanguageActivity { final boolean checkUpdates = settingsHelper.getBoolean(Constants.CHECK_UPDATES); if (checkUpdates) FlavorTown.updateCheck(this); FlavorTown.changelogCheck(this); - final Intent intent = getIntent(); handleIntent(intent); + if (!TextUtils.isEmpty(cookie) && settingsHelper.getBoolean(Constants.CHECK_ACTIVITY)) { + bindActivityCheckerService(); + } } @Override @@ -176,6 +204,24 @@ public class MainActivity extends BaseLanguageActivity { handleIntent(intent); } + @Override + protected void onDestroy() { + super.onDestroy(); + unbindActivityCheckerService(); + } + + private void createNotificationChannels() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + final NotificationManagerCompat notificationManager = NotificationManagerCompat.from(getApplicationContext()); + notificationManager.createNotificationChannel(new NotificationChannel(Constants.DOWNLOAD_CHANNEL_ID, + Constants.DOWNLOAD_CHANNEL_NAME, + NotificationManager.IMPORTANCE_DEFAULT)); + notificationManager.createNotificationChannel(new NotificationChannel(Constants.ACTIVITY_CHANNEL_ID, + Constants.ACTIVITY_CHANNEL_NAME, + NotificationManager.IMPORTANCE_DEFAULT)); + } + } + private void setupSuggestions() { suggestionsFetchHandler = new Handler(); suggestionAdapter = new SuggestionsAdapter(this, (type, query) -> { @@ -318,7 +364,7 @@ public class MainActivity extends BaseLanguageActivity { private void setupBottomNavigationBar(final boolean setDefaultFromSettings) { int main_nav_ids = R.array.main_nav_ids; final String cookie = settingsHelper.getString(Constants.COOKIE); - isLoggedIn = !TextUtils.isEmpty(cookie) && CookieUtils.getUserIdFromCookie(cookie) != null; + final boolean isLoggedIn = !TextUtils.isEmpty(cookie) && CookieUtils.getUserIdFromCookie(cookie) != null; if (!isLoggedIn) { main_nav_ids = R.array.logged_out_main_nav_ids; binding.bottomNavView.getMenu().clear(); @@ -429,6 +475,10 @@ public class MainActivity extends BaseLanguageActivity { final String type = intent.getType(); // Log.d(TAG, action + " " + type); if (Intent.ACTION_MAIN.equals(action)) return; + if (Constants.ACTION_SHOW_ACTIVITY.equals(action)) { + showActivityView(); + return; + } if (Intent.ACTION_SEND.equals(action) && type != null) { if (type.equals("text/plain")) { handleUrl(intent.getStringExtra(Intent.EXTRA_TEXT)); @@ -511,4 +561,25 @@ public class MainActivity extends BaseLanguageActivity { bundle.putString("hashtag", "#" + hashtag); navController.navigate(R.id.action_global_hashTagFragment, bundle); } + + private void showActivityView() { + binding.bottomNavView.setSelectedItemId(R.id.more_nav_graph); + binding.bottomNavView.post(() -> { + final NavController navController = currentNavControllerLiveData.getValue(); + if (currentNavControllerLiveData == null || navController == null) return; + final NavDirections navDirections = MorePreferencesFragmentDirections.actionMorePreferencesFragmentToNotificationsViewer(); + navController.navigate(navDirections); + }); + } + + private void bindActivityCheckerService() { + bindService(new Intent(this, ActivityCheckerService.class), serviceConnection, Context.BIND_AUTO_CREATE); + isActivityCheckerServiceBound = true; + } + + private void unbindActivityCheckerService() { + if (!isActivityCheckerServiceBound) return; + unbindService(serviceConnection); + isActivityCheckerServiceBound = false; + } } \ No newline at end of file diff --git a/app/src/main/java/awais/instagrabber/asyncs/DownloadAsync.java b/app/src/main/java/awais/instagrabber/asyncs/DownloadAsync.java index e5cc4489..ddea126c 100755 --- a/app/src/main/java/awais/instagrabber/asyncs/DownloadAsync.java +++ b/app/src/main/java/awais/instagrabber/asyncs/DownloadAsync.java @@ -1,7 +1,5 @@ package awais.instagrabber.asyncs; -import android.app.NotificationChannel; -import android.app.NotificationManager; import android.app.PendingIntent; import android.content.ContentResolver; import android.content.Context; @@ -28,6 +26,7 @@ import androidx.core.content.FileProvider; import java.io.BufferedInputStream; import java.io.File; import java.io.FileOutputStream; +import java.io.InputStream; import java.net.URL; import java.net.URLConnection; import java.util.concurrent.atomic.AtomicReference; @@ -35,17 +34,16 @@ import java.util.concurrent.atomic.AtomicReference; import awais.instagrabber.BuildConfig; import awais.instagrabber.R; import awais.instagrabber.interfaces.FetchListener; +import awais.instagrabber.utils.Constants; import awais.instagrabber.utils.Utils; -import static awais.instagrabber.utils.Constants.CHANNEL_ID; -import static awais.instagrabber.utils.Constants.CHANNEL_NAME; import static awais.instagrabber.utils.Constants.NOTIF_GROUP_NAME; -import static awais.instagrabber.utils.Utils.isChannelCreated; import static awais.instagrabber.utils.Utils.logCollector; -import static awais.instagrabber.utils.Utils.notificationManager; import static awaisomereport.LogCollector.LogFile; public final class DownloadAsync extends AsyncTask { + private static final String TAG = "DownloadAsync"; + private static int lastNotifId = 1; private final int currentNotifId; private final AtomicReference context; @@ -55,8 +53,12 @@ public final class DownloadAsync extends AsyncTask { private final Resources resources; private final NotificationCompat.Builder downloadNotif; private String shortCode, username; + private final NotificationManagerCompat notificationManager; - public DownloadAsync(final Context context, final String url, final File outFile, final FetchListener fetchListener) { + public DownloadAsync(@NonNull final Context context, + final String url, + final File outFile, + final FetchListener fetchListener) { this.context = new AtomicReference<>(context); this.resources = context.getResources(); this.url = url; @@ -66,23 +68,18 @@ public final class DownloadAsync extends AsyncTask { this.currentNotifId = ++lastNotifId; if (++lastNotifId + 1 == Integer.MAX_VALUE) lastNotifId = 1; - if (notificationManager == null) - notificationManager = NotificationManagerCompat.from(context.getApplicationContext()); - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && !isChannelCreated) { - notificationManager.createNotificationChannel(new NotificationChannel(CHANNEL_ID, - CHANNEL_NAME, NotificationManager.IMPORTANCE_HIGH)); - isChannelCreated = true; - } - @StringRes final int titleRes = R.string.downloader_downloading_post; + downloadNotif = new NotificationCompat.Builder(context, Constants.DOWNLOAD_CHANNEL_ID) + .setCategory(NotificationCompat.CATEGORY_STATUS) + .setSmallIcon(R.mipmap.ic_launcher) + .setContentText(shortCode == null ? username : shortCode) + .setOngoing(true) + .setProgress(100, 0, false) + .setAutoCancel(false) + .setOnlyAlertOnce(true) + .setContentTitle(resources.getString(titleRes)); - downloadNotif = new NotificationCompat.Builder(context, CHANNEL_ID).setCategory(NotificationCompat.CATEGORY_STATUS) - .setSmallIcon(R.mipmap.ic_launcher) - .setContentText(shortCode == null ? username : shortCode).setOngoing(true) - .setProgress(100, 0, false).setAutoCancel(false).setOnlyAlertOnce(true) - .setContentTitle(resources.getString(titleRes)); - + notificationManager = NotificationManagerCompat.from(context.getApplicationContext()); notificationManager.notify(currentNotifId, downloadNotif.build()); } @@ -158,7 +155,7 @@ public final class DownloadAsync extends AsyncTask { new Pair<>("downloadNotif", downloadNotif), new Pair<>("currentNotifId", currentNotifId), new Pair<>("notificationManager", notificationManager)); - if (BuildConfig.DEBUG) Log.e("AWAISKING_APP", "", e); + if (BuildConfig.DEBUG) Log.e(TAG, "", e); } return null; } @@ -193,12 +190,12 @@ public final class DownloadAsync extends AsyncTask { final ContentResolver contentResolver = context.getContentResolver(); Bitmap bitmap = null; if (Utils.isImage(uri, contentResolver)) { - try { - bitmap = BitmapFactory.decodeStream(contentResolver.openInputStream(uri)); + try (final InputStream inputStream = contentResolver.openInputStream(uri)) { + bitmap = BitmapFactory.decodeStream(inputStream); } catch (final Exception e) { if (logCollector != null) logCollector.appendException(e, LogFile.ASYNC_DOWNLOADER, "onPostExecute::bitmap_1"); - if (BuildConfig.DEBUG) Log.e("AWAISKING_APP", "", e); + if (BuildConfig.DEBUG) Log.e(TAG, "", e); } } diff --git a/app/src/main/java/awais/instagrabber/asyncs/GetActivityAsyncTask.java b/app/src/main/java/awais/instagrabber/asyncs/GetActivityAsyncTask.java index d79f15c1..ff65a56b 100644 --- a/app/src/main/java/awais/instagrabber/asyncs/GetActivityAsyncTask.java +++ b/app/src/main/java/awais/instagrabber/asyncs/GetActivityAsyncTask.java @@ -9,25 +9,24 @@ import java.net.HttpURLConnection; import java.net.URL; import awais.instagrabber.utils.Constants; +import awais.instagrabber.utils.CookieUtils; import awais.instagrabber.utils.NetworkUtils; import awais.instagrabber.utils.TextUtils; -public class GetActivityAsyncTask extends AsyncTask { +public class GetActivityAsyncTask extends AsyncTask { private static final String TAG = "GetActivityAsyncTask"; - private String uid; - private String cookie; + private OnTaskCompleteListener onTaskCompleteListener; - public GetActivityAsyncTask(final String uid, final String cookie, final OnTaskCompleteListener onTaskCompleteListener) { - this.uid = uid; - this.cookie = cookie; + public GetActivityAsyncTask(final OnTaskCompleteListener onTaskCompleteListener) { this.onTaskCompleteListener = onTaskCompleteListener; } - protected NotificationCounts doInBackground(Void... voids) { - if (TextUtils.isEmpty(cookie)) { - return null; - } + protected NotificationCounts doInBackground(final String... cookiesArray) { + if (cookiesArray == null) return null; + final String cookie = cookiesArray[0]; + if (TextUtils.isEmpty(cookie)) return null; + final String uid = CookieUtils.getUserIdFromCookie(cookie); final String url = "https://www.instagram.com/graphql/query/?query_hash=0f318e8cfff9cc9ef09f88479ff571fb" + "&variables={\"id\":\"" + uid + "\"}"; HttpURLConnection urlConnection = null; @@ -40,9 +39,13 @@ public class GetActivityAsyncTask extends AsyncTask { + shouldRecreate(); + return true; + }); return preference; } diff --git a/app/src/main/java/awais/instagrabber/services/ActivityCheckerService.java b/app/src/main/java/awais/instagrabber/services/ActivityCheckerService.java new file mode 100644 index 00000000..fb01201c --- /dev/null +++ b/app/src/main/java/awais/instagrabber/services/ActivityCheckerService.java @@ -0,0 +1,132 @@ +package awais.instagrabber.services; + +import android.app.Notification; +import android.app.PendingIntent; +import android.app.Service; +import android.content.Intent; +import android.os.Binder; +import android.os.Handler; +import android.os.IBinder; +import android.text.TextUtils; + +import androidx.core.app.NotificationCompat; +import androidx.core.app.NotificationManagerCompat; + +import java.util.ArrayList; +import java.util.List; + +import awais.instagrabber.R; +import awais.instagrabber.activities.MainActivity; +import awais.instagrabber.asyncs.GetActivityAsyncTask; +import awais.instagrabber.asyncs.GetActivityAsyncTask.NotificationCounts; +import awais.instagrabber.asyncs.GetActivityAsyncTask.OnTaskCompleteListener; +import awais.instagrabber.utils.Constants; + +import static awais.instagrabber.utils.Utils.settingsHelper; + +public class ActivityCheckerService extends Service { + private static final String TAG = "ActivityCheckerService"; + private static final int INITIAL_DELAY_MILLIS = 200; + private static final int DELAY_MILLIS = 60000; + + private Handler handler; + private OnTaskCompleteListener onTaskCompleteListener; + private NotificationManagerCompat notificationManager; + + private final IBinder binder = new LocalBinder(); + private final Runnable runnable = () -> { + final String cookie = settingsHelper.getString(Constants.COOKIE); + final GetActivityAsyncTask activityAsyncTask = new GetActivityAsyncTask(onTaskCompleteListener); + activityAsyncTask.execute(cookie); + }; + + public class LocalBinder extends Binder { + public ActivityCheckerService getService() { + return ActivityCheckerService.this; + } + } + + @Override + public void onCreate() { + notificationManager = NotificationManagerCompat.from(getApplicationContext()); + handler = new Handler(); + onTaskCompleteListener = result -> { + // Log.d(TAG, "onTaskCompleteListener: result: " + result); + try { + if (result == null) return; + final String notification = getNotificationString(result); + if (notification == null) return; + final String notificationString = getString(R.string.activity_count_prefix) + " " + notification + "."; + showNotification(notificationString); + } finally { + handler.postDelayed(runnable, DELAY_MILLIS); + } + }; + } + + @Override + public IBinder onBind(Intent intent) { + startChecking(); + // Uncomment to test notifications + // final String notificationString = getNotificationString(new NotificationCounts( + // 1, + // 2, + // 3, + // 4, + // 5 + // )); + // showNotification(notificationString); + return binder; + } + + @Override + public boolean onUnbind(final Intent intent) { + stopChecking(); + return super.onUnbind(intent); + } + + private void startChecking() { + handler.postDelayed(runnable, INITIAL_DELAY_MILLIS); + } + + private void stopChecking() { + handler.removeCallbacks(runnable); + } + + private String getNotificationString(final NotificationCounts result) { + final List list = new ArrayList<>(); + if (result.getRelationshipsCount() != 0) { + list.add(getString(R.string.activity_count_relationship, result.getRelationshipsCount())); + } + if (result.getUserTagsCount() != 0) { + list.add(getString(R.string.activity_count_usertags, result.getUserTagsCount())); + } + if (result.getCommentsCount() != 0) { + list.add(getString(R.string.activity_count_comments, result.getCommentsCount())); + } + if (result.getCommentLikesCount() != 0) { + list.add(getString(R.string.activity_count_commentlikes, result.getCommentLikesCount())); + } + if (result.getLikesCount() != 0) { + list.add(getString(R.string.activity_count_likes, result.getLikesCount())); + } + if (list.isEmpty()) return null; + return TextUtils.join(", ", list); + } + + private void showNotification(final String notificationString) { + final Intent intent = new Intent(getApplicationContext(), MainActivity.class) + .setAction(Constants.ACTION_SHOW_ACTIVITY) + .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP); + final Notification notification = new NotificationCompat.Builder(this, Constants.ACTIVITY_CHANNEL_ID) + .setCategory(NotificationCompat.CATEGORY_STATUS) + .setSmallIcon(R.drawable.ic_notif) + .setAutoCancel(true) + .setPriority(NotificationCompat.PRIORITY_MIN) + .setContentTitle(getString(R.string.action_notif)) + .setContentText(notificationString) + .setContentIntent(PendingIntent.getActivity(getApplicationContext(), 1738, intent, PendingIntent.FLAG_UPDATE_CURRENT)) + .build(); + notificationManager.notify(Constants.ACTIVITY_NOTIFICATION_ID, notification); + } +} diff --git a/app/src/main/java/awais/instagrabber/utils/Constants.java b/app/src/main/java/awais/instagrabber/utils/Constants.java index df57564a..2c636acd 100644 --- a/app/src/main/java/awais/instagrabber/utils/Constants.java +++ b/app/src/main/java/awais/instagrabber/utils/Constants.java @@ -71,8 +71,11 @@ public final class Constants { public static final String FDROID_SHA1_FINGERPRINT = "C1661EB8FD09F618307E687786D5E5056F65084D"; public static final String SKIPPED_VERSION = "skipped_version"; public static final String DEFAULT_TAB = "default_tab"; - public static final String CHANNEL_ID = "InstaGrabber"; - public static final String CHANNEL_NAME = "Instagrabber"; + public static final String ACTIVITY_CHANNEL_ID = "activity"; + public static final String DOWNLOAD_CHANNEL_ID = "download"; + public static final String ACTIVITY_CHANNEL_NAME = "Activity"; + public static final String DOWNLOAD_CHANNEL_NAME = "Downloads"; public static final String NOTIF_GROUP_NAME = "awais.instagrabber.InstaNotif"; public static final int ACTIVITY_NOTIFICATION_ID = 1800000000; + public static final String ACTION_SHOW_ACTIVITY = "show_activity"; } \ No newline at end of file diff --git a/app/src/main/java/awais/instagrabber/utils/Utils.java b/app/src/main/java/awais/instagrabber/utils/Utils.java index 1256c848..6cedc400 100755 --- a/app/src/main/java/awais/instagrabber/utils/Utils.java +++ b/app/src/main/java/awais/instagrabber/utils/Utils.java @@ -6,8 +6,6 @@ import android.content.ClipData; import android.content.ClipboardManager; import android.content.ContentResolver; import android.content.Context; -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager; import android.content.res.Configuration; import android.content.res.Resources; import android.net.Uri; @@ -21,11 +19,9 @@ import android.webkit.MimeTypeMap; import android.widget.Toast; import androidx.annotation.NonNull; -import androidx.annotation.Nullable; import androidx.annotation.StringRes; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatDelegate; -import androidx.core.app.NotificationManagerCompat; import androidx.fragment.app.FragmentManager; import com.google.android.exoplayer2.database.ExoDatabaseProvider; @@ -56,9 +52,7 @@ public final class Utils { public static SettingsHelper settingsHelper; public static DataBox dataBox; public static boolean sessionVolumeFull = false; - public static NotificationManagerCompat notificationManager; public static final MimeTypeMap mimeTypeMap = MimeTypeMap.getSingleton(); - public static boolean isChannelCreated = false; public static ClipboardManager clipboardManager; public static DisplayMetrics displayMetrics = Resources.getSystem().getDisplayMetrics(); public static SimpleDateFormat datetimeParser; @@ -122,8 +116,8 @@ public final class Utils { clipboardManager = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE); int toastMessage = R.string.clipboard_error; - if (clipboardManager != null) { - clipboardManager.setPrimaryClip(ClipData.newPlainText(Constants.CHANNEL_NAME, string)); + if (clipboardManager != null && ctxNotNull) { + clipboardManager.setPrimaryClip(ClipData.newPlainText(context.getString(R.string.app_name), string)); toastMessage = R.string.clipboard_copied; } if (ctxNotNull) Toast.makeText(context, toastMessage, Toast.LENGTH_SHORT).show();