Intereting Posts
Webview не загружает файл Как использовать пользовательский ArrayAdapter в отдельном классе? Отделив тесты интеграции от модульных тестов в Android Studio Как добавить столбец в onUpgrade и установить существующие строки на определенное значение? Живые обои с игровым движком или нет? Как проверить, работает ли приложение на Android? Исключение при фокусировке EditText в PopupWindow, запущенном на устройстве Как использовать ресурс Idluso Idling Ошибка: невозможно получить заблокированный буффер, очень вероятный клиент пытается заблокировать больше, чем maxImages buffers Android: ACTION_BATTERY_LOW не запускается в эмуляторе. Получатель, зарегистрированный в коде, не отображается Сдвиг позиции прокрутки HorizontalGridView / RecyclerView после загрузки изображения Picasso Android TTS onUtteranceCompleted callback не вызван AlertDialog изнутри BroadcastReceiver ?? Это можно сделать? Настройте GridView на все размеры экрана Как решить эту ошибку "com.android.internal.telephony не может быть разрешен для типа" в android

Нажмите на уведомление, чтобы перейти к текущей деятельности

Я использую это решение: как сделать намерение уведомления возобновить, а не делать новые намерения?

Я отлично работаю, когда я обычно запускаю свое приложение. Однако мое приложение имеет функцию общего доступа.

Когда я выбираю изображения, которые хочу передать из приложения галереи, и он открывает его в моей деятельности, я создаю уведомление в этой операции. Я хочу, чтобы, когда пользователь нажимает на уведомление, он открывает существующее действие (открытое приложением галереи)

Проблема в том, что когда я нажимаю на уведомление, он не возобновляет эту операцию, а вместо этого открывает новый экземпляр действия или другого экземпляра, который уже был открыт ранее

Изменить: Больше объяснений

Мое приложение называется ShareApp, и эта деятельность называется ShareActivity. Проблема заключается в том, что когда я открываю приложение ShareActivity через галерею, экземпляр ShareActivity создается в стеке приложения приложения галереи. Теперь, когда я создаю уведомление, указывающее на мой ShareActivity, я использую намерение:

Intent intent = new Intent(this, ShareActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 

Проблема в том, что когда я нажимаю на уведомление, он указывает на экземпляр ShareActivity в стеке задачи ShareApp вместо стека задачи приложения галереи.

Любая идея, как указать на стек правильной задачи?

Edit 2: мой код

  int defaults = Notification.FLAG_NO_CLEAR; NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this) .setSmallIcon(R.drawable.ic_launcher) .setContentTitle(getString(R.string.app_name)) .setContentText(text) .setDefaults(defaults); Intent intent = new Intent(this, this.getClass()); intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT); mBuilder.setContentIntent(pendingIntent); NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); mNotificationManager.notify(_ID, mBuilder.build()); по  int defaults = Notification.FLAG_NO_CLEAR; NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this) .setSmallIcon(R.drawable.ic_launcher) .setContentTitle(getString(R.string.app_name)) .setContentText(text) .setDefaults(defaults); Intent intent = new Intent(this, this.getClass()); intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT); mBuilder.setContentIntent(pendingIntent); NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); mNotificationManager.notify(_ID, mBuilder.build()); 

Редактировать 3: действие adb shell dumpsys (после применения кода David https://stackoverflow.com/a/16901603/1334268 )

Мое приложение называется shareApp, и моя деятельность – это ShareActivity

Прежде чем нажимать на уведомление:

 Main stack: TaskRecord{41965708 #6 A com.android.gallery3d} Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.android.gallery3d/.app.Gallery bnds=[364,50][108,108]} Hist #2: ActivityRecord{417ccc28 com.yeahman.shareapp/.ShareActivity} Intent { act=android.intent.action.SEND_MULTIPLE typ=image/* cmp=com.yeahman.shareapp/.ShareActivity (has extras) } ProcessRecord{41c868d0 6088:com.yeahman.shareapp/10116} Hist #1: ActivityRecord{4135e540 com.android.gallery3d/.app.Gallery} Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.android.gallery3d/.app.Gallery bnds=[364,50][108,108] } 

После нажатия уведомления:

  Main stack: TaskRecord{41965708 #6 A com.android.gallery3d} Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.android.gallery3d/.app.Gallery bnds=[364,50][108,108]} Hist #3: ActivityRecord{4169f358 com.android.gallery3d/.app.Gallery} Intent { flg=0x20000000 cmp=com.android.gallery3d/.app.Gallery bnds=[0,205][480,301] } ProcessRecord{4175dd28 5808:com.android.gallery3d/10036} Hist #2: ActivityRecord{417ccc28 com.yeahman.shareapp/.ShareActivity} Intent { act=android.intent.action.SEND_MULTIPLE typ=image/* cmp=com.yeahman.shareapp/.ShareActivity (has extras) } ProcessRecord{41c868d0 6088:com.yeahman.shareapp/10116} Hist #1: ActivityRecord{4135e540 com.android.gallery3d/.app.Gallery} Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.android.gallery3d/.app.Gallery bnds=[364,50][108,108] } 

Solutions Collecting From Web of "Нажмите на уведомление, чтобы перейти к текущей деятельности"

Если у вас есть несколько экземпляров ShareActivity работающих в разных задачах, вы не можете сообщить Android о том, какая задача активируется, запустив вашу активность. Мне кажется, что то, что вы хотите сделать, в этом случае – это запуск не вашей деятельности, а приложения Gallery. Если приложение «Галерея» уже запущено, а ваша деятельность находится в верхней части стека задач, все, что вам нужно сделать, это принести приложение «Галерея» на передний план. Для этого создайте «Запуск запуска» для приложения «Галерея» и не забудьте установить Intent.FLAG_ACTIVITY_NEW_TASK в намерении. Вы должны иметь возможность «запускать намерение» из PackageManager с помощью getLaunchIntentForPackage()

EDIT: пример кода с помощью ActivityManager

Вы можете попробовать следующее:

 // Get the root activity of the task that your activity is running in ActivityManager am = (ActivityManager)getSystemService(ACTIVITY_SERVICE); List<ActivityManager.RunningTaskInfo> tasks = am.getRunningTasks(1); ActivityManager.RunningTaskInfo task = tasks.get(0); // Should be my task ComponentName rootActivity = task.baseActivity; // Now build an Intent that will bring this task to the front Intent intent = new Intent(); intent.setComponent(rootActivity); // Set the action and category so it appears that the app is being launched intent.setAction(Intent.ACTION_MAIN); intent.addCategory(Intent.CATEGORY_LAUNCHER); 

ПРИМЕЧАНИЕ. Для этого вам понадобится разрешение GET_TASKS . Я не пробовал этого и не могу гарантировать, что это сработает. Использование getRunningTasks() не рекомендуется документацией, но это не значит, что оно не подходит для ваших целей.

EDIT добавила действие / категорию в намерение

ПРИМЕЧАНИЕ. Я действительно построил небольшое приложение, чтобы проверить это. Мне нужно было добавить ACTION = MAIN и CATEGORY = LAUNCHER в Intent (который был бы там, если вы использовали PackageManager.getLaunchIntentForPackage() . У меня есть HTC One S, поэтому на моем устройстве приложение «Галерея» на самом деле называется com.htc.album/.AlbumMain.ActivityMainDropList , но это все равно должно работать для вас.

  Notification.Builder mBuilder = new Notification.Builder(this) .setSmallIcon(R.drawable.cmplayer) .setContentTitle("CoderoMusicPlayer") .setContentText("PLayer0!"); Intent resultIntent = new Intent(this, AndroidBuildingMusicPlayerActivity.class); resultIntent.setAction(Intent.ACTION_MAIN); resultIntent.addCategory(Intent.CATEGORY_LAUNCHER); PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, resultIntent, 0); mBuilder.setContentIntent(pendingIntent); NotificationManager mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); mNotificationManager.notify(1, mBuilder.build()); 

Просто скопируйте код и вставьте его в свою основную деятельность.

Задавать

 android:launchMode="singleTop" 

В вашем manifest.xml для вашего основного вида деятельности и посмотреть, поможет ли это.

Это решение, которое я использую в течение многих лет.

Ваша проблема заключается в том, что ваш PendingIntent запускает свою цель из яблок.

Ваш первый шаг – привести результат вашего намерения в контексте ваших приложений. Чтобы сделать это, ваше уведомление выведет трансляцию на «ForwardingReceiver»

 Intent newIntent = new Intent(context, ForwardingReceiver.class); ... mBuilder.setContentIntent(PendingIntent.getBroadcast(context, category, newIntent, PendingIntent.FLAG_UPDATE_CURRENT)); 

ForwardingReceiver расширяет BroadcastReceiver и в onReceive() теперь у вас есть текущий контекст приложений и вы можете использовать sendOrderedBroadcast() следующим образом:

 Intent forwardIntent = new Intent(); forwardIntent.putExtras(intent.getExtras()); forwardIntent.setAction(GenericReceiver.class.getCanonicalName()); context.sendOrderedBroadcast(forwardIntent, null); 

Теперь, забавная часть. Вам необходимо расширить все ваши приложения. Действия от общего родителя Activity. Вы уже можете сделать это для ведения журнала или анализа. В этом CommonActivityParent onResume() вам необходимо зарегистрироваться для приема трансляций с приоритетом выше 0 (например, 10)

 mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { performActionUsingIntent(intent); } }; IntentFilter filter = new IntentFilter(); filter.addAction(GenericReceiver.class.getCanonicalName()); filter.setPriority(10); registerReceiver(mReceiver, filter); 

(Не забудьте отменить регистрацию в onPause ())

Это будет означать, что если ваше приложение находится на переднем плане, оно получит уведомление (косвенно) и позволит вам выполнить действие.

Однако, если вы заняты в фоновом режиме, у него не будет зарегистрирован этот ресивер. Нет проблем, ваш «GenericReceiver» должен выглядеть примерно так

 @Override public void onReceive(Context context, Intent intent) { PackageManager pm = context.getPackageManager(); Intent newIntent = pm.getLaunchIntentForPackage(context.getPackageName()); newIntent.putExtras(intent.getExtras()); context.startActivity(newIntent); } 

Что начнет вашу деятельность. Этот запуск должен иметь код в onCreate (), чтобы определить, является ли это корнем задач. Если это не так, он должен немедленно закрыть (и, следовательно, никогда не отображается пользователю). Это фактически заставляет последнюю открытую задачу выходить на передний план:

 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (!isTaskRoot() && getIntent().hasCategory(Intent.CATEGORY_LAUNCHER) && getIntent().getAction() != null && getIntent().getAction().equals(Intent.ACTION_MAIN)) { // Use this space to add the intent to a static singleton. This will be used in CommonActivityParent to perform an action. CommonActivityParent.sIntent = getIntent(); finish(); return; } } 

Чтобы закончить, убедитесь, что сразу после вызова registerReceiver() выше в CommonActivityParent вы выполните следующую проверку:

 if(sIntent != null) { Intent tempIntent = sIntent; sIntent = null; performActionUsingIntent(tempIntent); } 

Теперь приложение «presto – You» будет действовать так, как будто клик для уведомлений на самом деле является кликом из вашего приложения. И все, что нужно, было чертовски много!

Надеюсь, у кого-то есть менее запутанный способ сделать это.