click on notification to go current activity

后端 未结 5 1427
借酒劲吻你
借酒劲吻你 2020-12-03 08:18

i am using this solution : How to make notification intent resume rather than making a new intent?

I works fine when i run my app normally.. however my app has a sha

相关标签:
5条回答
  • 2020-12-03 08:43
        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());
    

    Just Copy the code and paste it in your main launcher activity.

    0 讨论(0)
  • 2020-12-03 08:58

    If you have multiple instances of ShareActivity active in different tasks, there is no way for you to tell Android which task to reactivate by launching your activity. It sounds to me like what you want to do, in this case, is to launch not your activity, but the Gallery application. If the Gallery app is already running and your activity is on the top of the task stack, then all you need to do is to bring the Gallery app to the foreground. To do this, create a "launch Intent" for the Gallery app and make sure to set Intent.FLAG_ACTIVITY_NEW_TASK on the Intent. You should be able to get a "launch Intent" from the PackageManager by using getLaunchIntentForPackage()

    EDIT: Example code using ActivityManager

    You might try this:

    // 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);
    

    NOTE: You will need GET_TASKS permission for this. I haven't tried this and can't guarantee it will work. The use of getRunningTasks() is discouraged by the documentation, but that doesn't mean that it won't suit your purposes.

    EDIT added action/category to the Intent

    NOTE: I actually built a small app to test this. I needed to add the ACTION=MAIN and CATEGORY=LAUNCHER to the Intent (which would be there if you used PackageManager.getLaunchIntentForPackage(). I've got an HTC One S, so on my device the "Gallery" app is actually called com.htc.album/.AlbumMain.ActivityMainDropList, but this should still work for you.

    0 讨论(0)
  • 2020-12-03 09:01

    for additional info, dont forget to add pending intent flag to make onNewIntent works!

    true:

    PendingIntent.getActivity(context, 0, resultIntent, PendingIntent.FLAG_UPDATE_CURRENT)
    

    false:

    PendingIntent.getActivity(context, 0, resultIntent, 0)
    

    Please vote up if this benefit for you, cheers!

    0 讨论(0)
  • 2020-12-03 09:07

    Set

    android:launchMode="singleTop"
    

    in your manifest.xml for your main activity and see if that helps.

    0 讨论(0)
  • 2020-12-03 09:09

    This is a solution I've been using for years.

    Your problem is that your PendingIntent starts it's target from an appless content.

    Your first step is to bring the result of your Intent inside your apps context. To do this have your notification call a broadcast to "ForwardingReceiver"

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

    The ForwardingReceiver extends BroadcastReceiver and in it's onReceive() method you now have you're apps current context and can use sendOrderedBroadcast() like so:

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

    Now, the fun part. You need to extend all of your apps Activities from a common Activity parent. You may already do this for logging or analytic. In this CommonActivityParent onResume() you need to register to receive broadcasts at a priority of above 0 (such as 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);
    

    (Remember to unregister this in onPause())

    This will mean that if your app is in the foreground, it will receive the notification click (indirectly) and allow you to perform an action.

    However, if you Activity is in the background, it won't have this receiver registered. No problem, your "GenericReceiver" should look something like this

    @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);
    }
    

    Which will start your launch activity. This launch activity should have code in it's onCreate() to detect if it's the tasks root. If it isn't it should close immediately (and therefore is never visible to the user). This effectively forces the last open task into the foreground:

    @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;
        }
    }
    

    To finish, ensure just after your registerReceiver() call above in CommonActivityParent, you perform the following check:

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

    An hey presto - You're app will now act as if a notification click is actually a click from within your app. And all it took was a hell of a lot of work!

    Hopefully someone has a less convoluted way of doing this.

    0 讨论(0)
提交回复
热议问题