Zerosero
Zerosero

Reputation: 343

What's the proper way of updating the current activity that is brought to the foreground via a notification click?

The scenario: When the app is asleep or in the background, a notification is sent to the device. User clicks the notification and expects the application to be open given the current activity displayed on the background.

The solutions I've tried so far.. In my

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

^ the above works fine given that I know already what activity is currently present when the app is brought to foreground BUT when I do not exactly know what activity is present.. (let's say we have two activities that are mainly used which are -- MyActivity and MyOtherActivity), this now won't work since on onResume() of MyOtherActivity, getIntent().getExtras() won't contain the new extras being set at my NotificationListener service class since MyActivity.class is explicitly defined.

And so I tried the solution #4 from this answer Android: How can I get the current foreground activity (from a service)? so that I can dynamically pass extras and reopen the said current activity. And this now brings me to the problem below.

The problem: Intent.ACTION_USER_FOREGROUND is somewhat restricted with this error Permission Denial: not allowed to send broadcast android.intent.action.USER_FOREGROUND

I'm seeing similar solutions which is to declare this in the manifest file <uses-permission android:name="android.permission.WRITE_SETTINGS" tools:ignore="ProtectedPermissions"/> but it doesn't really solve my problem, the same issue is being logged.

What proper Intent.action can we use in this scenario? or is there another proper way to handle this?


Manifest.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
    }
}

Upvotes: 0

Views: 275

Answers (1)

Zerosero
Zerosero

Reputation: 343

For people who'd also have the same concern.. and would like to try out some solutions

This is what I used to fix mine

  1. Use your activities showingInstance.. so when the application is brought to background I made sure my activities showingInstance doesn't get cleared.
  2. Made use of the onTrimMemory() method
  3. So when a message has been received, I check if what showingInstance is available and pass the necessary extras to that specific activity.
//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;
    }
}
}

Upvotes: 0

Related Questions