Запуск приложения только в том случае, если оно не запущено в данный момент
Я посылаю push-уведомление пользователям, которые при нажатии на него открывают приложение.
Моя проблема заключается в том, что, когда приложение уже открыто, нажав на уведомление, запустите приложение снова.
Я только хочу, чтобы он запустил приложение, если оно еще не запущено.
Я использую отложенное намерение в уведомлении:
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, Splash.class), 0);
Я видел сообщения, которые говорят использовать:
<activity
android:name=".Splash"
android:launchMode="singleTask"
Но дело в том, что мое запущенное приложение запускает другую активность, а затем всплеск, который заканчивается после 7 секунды с момента запуска приложения, так что когда приложение работает всплеск не является текущей активностью
11 ответов:
Используйте "запуск
Intent" для вашего приложения, например:PackageManager pm = getPackageManager(); Intent launchIntent = pm.getLaunchIntentForPackage("your.package.name"); PendingIntent contentIntent = PendingIntent.getActivity(this, 0, launchIntent, 0);Заменить "your.package.name - с именем вашего пакета из манифеста Андроида.
Кроме того, вы должны удалить специальный
launchMode="singleTask"из вашего манифеста. Стандартное поведение Андроида сделает то, что вы хотите.
String appPackageName = ""; private void isApplicationInForeground() throws Exception { ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { final List<ActivityManager.RunningAppProcessInfo> processInfos = am .getRunningAppProcesses(); ActivityManager.RunningAppProcessInfo processInfo = processInfos .get(0); // for (ActivityManager.RunningAppProcessInfo processInfo : processInfos) { if (processInfo.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) { // getting process at 0th index means our application is on top on all apps or currently open appPackageName = (Arrays.asList(processInfo.pkgList).get(0)); } // } } else { List<ActivityManager.RunningTaskInfo> taskInfo = am.getRunningTasks(1); ComponentName componentInfo = null; componentInfo = taskInfo.get(0).topActivity; appPackageName = componentInfo.getPackageName(); } } private void notifyMessage(String text) { if (appPackageName.contains("com.example.test")) { // do not notify } else { // create notification and notify user } }
Для тех, кто использует Xamarin.Андроид . Xamarin версия ответа David Wasser приведена ниже:
//Create notification var notificationManager = GetSystemService(Context.NotificationService) as NotificationManager; Intent uiIntent = PackageManager.GetLaunchIntentForPackage("com.company.app"); //Create the notification var notification = new Notification(Android.Resource.Drawable.SymActionEmail, title); //Auto-cancel will remove the notification once the user touches it notification.Flags = NotificationFlags.AutoCancel; //Set the notification info //we use the pending intent, passing our ui intent over, which will get called //when the notification is tapped. notification.SetLatestEventInfo(this, title, desc, PendingIntent.GetActivity(this, 0, uiIntent, PendingIntentFlags.OneShot)); //Show the notification notificationManager.Notify(0, notification);
Вместо того, чтобы показывать активность всплеска при щелчке уведомления, покажите свою основную активность, потому что ваша активность всплеска будет закрыта через некоторое время, но основная активность останется открытой и
<activity android:name=".MainActivity" android:launchMode="singleTask"
Используйте взрывом фрагмент, а не активность. Сохраните фрагмент всплеска (7 секунд), замените его на нужный(целевая страница).
Добавьте в манифест launchMode="singleTask".
Как уже сказал Рахул,
onNewIntent()вызывается, если приложение уже запущено elseonCreate()@Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); }Или
Идите с ответомДэвида , кажется многообещающим.
Когда уведомление нажато и ваш код, который перенаправляет на ваш экран желания, просто замените этот код вызовом этого метода и перенаправьте на определенный экран на основе результата "true / false".
private boolean isAppOnForeground(Context context) { ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); List<RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses(); if (appProcesses == null) { return false; } final String packageName = context.getPackageName(); for (RunningAppProcessInfo appProcess : appProcesses) { if (appProcess.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND && appProcess.processName.equals(packageName)) { return true; } } return false; }
Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONTИ, возможно, не начинайте всплеск активности и снова откройте (выведите на передний план) MainActivity и обновите пользовательский интерфейс с помощью прослушивателя, который сообщает вам, что у вас есть новое уведомление (с флагом - boolean или с интерфейсом, чтобы сделать прослушиватель).
Для этого можно использовать упорядоченную трансляцию.
1) измените свой
PendingIntent, чтобы начатьBroadcastReceiver, который решит, начинать ли действие или ничего не делать:PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, new Intent(this, DecisionReceiver.class), 0);2) Создайте решение
BroadcastReceiver:public class DecisionReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { context.sendOrderedBroadcast(new Intent(MainActivity.NOTIFICATION_ACTION), null, new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { if (getResultCode() == MainActivity.IS_ALIVE) { // Activity is in the foreground } else { // Activity is not in the foreground } } }, null, 0, null, null); } }3) Создайте
BroadcastReceiverв своей деятельности, которая будет сигнализировать о том, что она жива:public static final String NOTIFICATION_ACTION = "com.mypackage.myapplication.NOTIFICATION"; public static final int IS_ALIVE = 1; private BroadcastReceiver mAliveReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { setResultCode(IS_ALIVE); } }; // Register onResume, unregister onPause // Essentially receiver only responds if the activity is the foreground activity @Override protected void onResume() { super.onResume(); registerReceiver(mAliveReceiver, new IntentFilter(NOTIFICATION_ACTION)); } @Override protected void onPause() { super.onPause(); unregisterReceiver(mAliveReceiver); }
NotificationIntent.addFlags (намерение.FLAG_ACTIVITY_SINGLE_TOP / намерение.FLAG_ACTIVITY_CLEAR_TOP / Intent.FLAG_ACTIVITY_NEW_TASK);
notificationIntent.putExtras(bundle); PendingIntent pintent = PendingIntent.getActivity(context, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Попробуйте добавить это к вашему намерению вывести активность на передний план, если она выполняется в фоновом режиме
Intent intent = new Intent(this, Splash.class); intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); PendingIntent contentIntent = PendingIntent.getActivity(this, 0, intent, 0);
Прежде всего задайте задачу по умолчанию
android:taskAffinity="com.example.testp.yourPreferredName"в вашем элементеApplicationв файле манифеста. Поддерживайте вашandroid:launchMode="singleTask"на вашемSplashActivity. Теперь, поскольку ваш SplashActivity является вашей основной записью, добавьте этот код к обоимonResume(),onNewIntent()и ещеonCreate()(на второй мысли onResume() не рекомендуется) - следуйте комментариям в коде//Note these following lines of code will work like magic only if its UPVOTED. //so upvote before you try it.-or it will crash with SecurityException ActivityManager am = (ActivityManager) this.getSystemService(ACTIVITY_SERVICE); List< ActivityManager.RunningTaskInfo > taskInfo = am.getRunningTasks(1000); for(int i =0; i< taskInfo.size(); i++){ String PackageName = taskInfo.get(i).baseActivity.getPackageName(); if(PackageName.equals("packagename.appname")){// suppose stackoverflow.answerer.Elltz //if the current runing actiivity is not the splash activity. it will be 1 //only if this is the first time your <taskAffinity> is be called as a task if(taskInfo.get(i).numActivities >1){ //other activities are running, so kill this splash dead!! reload!! finish(); // i am dying in onCreate..(the user didnt see nothing, that's the good part) //about this code. its a silent assassin } //Operation kill the Splash is done so retreat to base. break; } }Этот код не будет работать на api
21+; чтобы заставить его работать, вам нужно использовать AppTask , это сэкономит вам дополнительные строки кода, так как вы не будете в цикле, чтобы найдите свойTask.Надеюсь, это поможет
Comments