首页 > 解决方案 > 更新通过通知点击带到前台的当前活动的正确方法是什么?

问题描述

场景: 当应用程序处于睡眠状态或在后台时,会向设备发送通知。用户单击通知并期望应用程序在后台显示当前活动的情况下打开。

到目前为止我尝试过的解决方案..在我的

NotificationLister extends IntentService {

@Override
    protected void onHandleIntent(Intent intent) {
    //I directy 
      Intent intent = new Intent(this, MyActivity.class);
      //pass necessary extras here and flags
      getApplication().startActivity(intent);
    }
}

^ 以上工作很好,因为我已经知道当应用程序被带到前台时当前存在什么活动但是当我不完全知道存在什么活动时..(假设我们有两个主要使用的活动是 -MyActivityMyOtherActivity),这现在将不起作用,因为 on onResume() of MyOtherActivitygetIntent().getExtras()将不包含在我的 NotificationListener 服务类中设置的新附加内容,因为MyActivity.class已明确定义。

所以我尝试了这个答案中的解决方案#4 Android: How can I get the current foreground activity (from a service)? 这样我就可以动态传递额外内容并重新打开所述当前活动。现在这让我想到了下面的问题。

问题: Intent.ACTION_USER_FOREGROUND受此错误限制Permission Denial: not allowed to send broadcast android.intent.action.USER_FOREGROUND

我看到了类似的解决方案,即在清单文件中声明它, <uses-permission android:name="android.permission.WRITE_SETTINGS" tools:ignore="ProtectedPermissions"/>但它并没有真正解决我的问题,同样的问题正在被记录。

Intent.action在这种情况下我们可以使用什么合适的?还是有另一种合适的方法来处理这个?


清单.xml

<service android:name=".NotificationListener"/>
<receiver android:name=".MyBroadcastReceiver"/>

MyOtherActivity.java

 @Override
    protected void onResume() {
        super.onResume();
        
        IntentFilter filter = new IntentFilter(Intent.ACTION_USER_FOREGROUND);
        BroadcastReceiver mReceiver = new MyBroadcastReceiver();
        registerReceiver(mReceiver, filter);
    }

    @Override
    protected void onPause() {
        super.onPause();
        //I think it could also be okay to registerReceiver here
    }

    @Override
    public void onDestroy() {
        this.unregisterReceiver(broadcastReceiver);
        super.onDestroy();
        //on debug this is always called after sendBroadcast() and then the Permission Denial error
    }

NotificationListener.class

NotificationLister extends IntentService {

@Override
    protected void onHandleIntent(Intent intent) {
      Intent broadcastIntent = new Intent();
        broadcastIntent.addCategory(Intent.CATEGORY_DEFAULT);
        broadcastIntent.setAction(Intent.ACTION_USER_FOREGROUND);
        broadcastIntent.putExtra("myNecessaryExtra", intent.getStringExtra("test"));
        sendBroadcast(broadcastIntent);
    }
}

MyBroadcastReceiver.class

public class MyBroadcastReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        String responseString = intent.getStringExtra("myNecessaryExtra");
       //on debug this doesn't get called because of the Permission Denial error
    }
}

标签: androidandroid-activitynotificationsbroadcastreceiverintentservice

解决方案


对于也有同样担忧的人..并想尝试一些解决方案

这是我用来修复我的

  1. 使用您的活动显示实例.. 所以当应用程序进入后台时,我确保我的活动显示实例没有被清除。
  2. 使用了 onTrimMemory() 方法
  3. 因此,当收到一条消息时,我会检查是否有可用的显示实例,并将必要的附加信息传递给该特定活动。
//MyActivity.java
@Override
protected void onPause() {
    //when the activity is brought to the background
    //do not clear its activityInstance
}

public boolean isInBackground() {
    return ((MyApplication) getApplication()).appIsInBackground();
}

//MessagingService.java
@Override
public void onMessageReceived(RemoteMessage message) {
    boolean onBackground = MyActivity.showingInstance != null && MyActivity.isInBackground();
    //do the necessary processing here on showing your notification
    if (onBackground) {
        //bring the application to the foreground
    }
}


//MyApplication.java
@Override
public void onTrimMemory(int level) {
    super.onTrimMemory(level);
    if (level == ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN || level == ComponentCallbacks2.TRIM_MEMORY_COMPLETE) {
        //The application here goes to the background
        appIsInBackground = true;
    }
}
}

推荐阅读