GCM How do I detect if app is open and if so pop u

2020-05-21 06:02发布

I have an app where I want to build 2 different flow's in:

  • 1.a App is open on any activity
  • 1.b App show's an alertbox where user can choose to go to the activity regarding the notification or stay on the current activity.

  • 2.a App is running in background

  • 2.b Notification in notification bar, starts the activity regarding to the notification.

I currently have flow 2 working, but cannot find out how to get flow 1 working. Here's some code:

In GcmIntentService:

@Override
    protected void onHandleIntent(Intent intent) {
        Bundle extras = intent.getExtras();
        GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this);
        // The getMessageType() intent parameter must be the intent you received
        // in your BroadcastReceiver.
        String messageType = gcm.getMessageType(intent);

        if (!extras.isEmpty()) {  // has effect of unparcelling Bundle
            /*
             * Filter messages based on message type. Since it is likely that GCM will be
             * extended in the future with new message types, just ignore any message types you're
             * not interested in, or that you don't recognize.
             */
            if (GoogleCloudMessaging.MESSAGE_TYPE_SEND_ERROR.equals(messageType)) {
                Log.e("GCM", "Send error: " + extras.toString());
            } else if (GoogleCloudMessaging.MESSAGE_TYPE_DELETED.equals(messageType)) {
                Log.e("GCM", "Deleted messages on server: " + extras.toString());
            // If it's a regular GCM message, do some work.
            } else if (GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE.equals(messageType)) {
                Log.i(TAG, "Completed work @ " + SystemClock.elapsedRealtime());
                // Post notification of received message.
                sendNotification(extras);
                Log.i(TAG, "Received: " + extras.toString());
            }
        }
        // Release the wake lock provided by the WakefulBroadcastReceiver.
        GcmBroadcastReceiver.completeWakefulIntent(intent);
    }

    // Put the message into a notification and post it.
    // This is just one simple example of what you might choose to do with
    // a GCM message.
    private void sendNotification(Bundle extras) {
        mNotificationManager = (NotificationManager)
                this.getSystemService(Context.NOTIFICATION_SERVICE);

        String message = extras.getString("message");
        Intent openIntent = new Intent(this, HomeActivity.class);
        if (extras != null) {
            if (extras.containsKey("tipid")) {
                openIntent.putExtra("tipid", extras.getString("tipid"));
            } else if (extras.containsKey("discussionid")) {
                openIntent.putExtra("discussionid", extras.getString("discussionid"));
            }
        }

        PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
                openIntent, PendingIntent.FLAG_CANCEL_CURRENT);
        NotificationCompat.Builder mBuilder =
                new NotificationCompat.Builder(this)
        .setSmallIcon(R.drawable.ic_launcher)
        .setContentTitle("StadseBoeren")
        .setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
        .setStyle(new NotificationCompat.BigTextStyle()
        .bigText(message))
        .setContentText(message);

        mBuilder.setContentIntent(contentIntent)
        .setAutoCancel(true);
        mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
    }

GcmBroadcastReceiver

public class GcmBroadcastReceiver extends WakefulBroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        // Explicitly specify that GcmIntentService will handle the intent.
        ComponentName comp = new ComponentName(context.getPackageName(),
                GcmIntentService.class.getName());
        // Start the service, keeping the device awake while it is launching.
        startWakefulService(context, (intent.setComponent(comp)));
        setResultCode(Activity.RESULT_OK);
    }
}

The HomeActivity onCreate:

Bundle extras = intent.getExtras();
if (extras != null) {
    if (extras.containsKey("tipid")) {
        pendingObjectId = extras.getString("tipid");
        modelFlag = ModelFlag.TIP;
    } else if (extras.containsKey("discussionid")) {
        pendingObjectId = extras.getString("discussionid");
        modelFlag = ModelFlag.DISCUSSION;
    }
}

4条回答
虎瘦雄心在
2楼-- · 2020-05-21 06:21

I'd just write another BroadcastReceiver like this:

public class MainActivityBroadcastReceiver extends BroadcastReceiver {

    public MainActivityBroadcastReceiver(Activity mainActivity) {

    }

    @Override
    public void onReceive(Context context, Intent intent) {
        Toast toast = Toast.makeText(context, "hola", Toast.LENGTH_LONG);
        toast.show();   
        abortBroadcast();
    }

}

and then in the MainActivity I'd override the methods and then I don't receive the notification so I intercept the `Intent~ and abort the other broadcast:

@Override
protected void onPause() {
    unregisterReceiver(mainActivityBroadcastReceiver);
    super.onPause();
}

@Override
public void onResume() {
    IntentFilter filter = new IntentFilter("com.google.android.c2dm.intent.RECEIVE");
    filter.setPriority(1);
    registerReceiver(mainActivityBroadcastReceiver, filter);

    super.onResume();
}
查看更多
趁早两清
3楼-- · 2020-05-21 06:37

A solution I just found does require a GET_TASK permission:

ActivityManager activityManager = (ActivityManager) getApplicationContext().getSystemService(Context.ACTIVITY_SERVICE);
List<RunningTaskInfo> services = activityManager
        .getRunningTasks(Integer.MAX_VALUE);
boolean isActivityFound = false;

if (services.get(0).topActivity.getPackageName().toString()
        .equalsIgnoreCase(getApplicationContext().getPackageName().toString())) {
    isActivityFound = true;
}

Log.d("GCM", "Activity open: "+isActivityFound);

UPDATE

In order to launch an alertbox (which isn't possible here) I created a custom alert box and let it use the AlertBox as theme. This is the activity in AndroidManifest.xml:

<activity
    android:name="nl.raakict.android.stadseboeren.NotificationAlertActivity"
    android:label="@string/title_activity_notification_alert"
    android:launchMode="singleInstance"
    android:theme="@android:style/Theme.Dialog" >

And the custom activity:

public class NotificationAlertActivity extends Activity implements
        Observer, OnClickListener {

    private String pendingObjectId;
    private ModelFlag modelFlag;
    private Database db;
    private ArrayList<Discussion> discussions;
    private ArrayList<Tip> tips;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_notification_alert);

        findViewById(R.id.button_yes).setOnClickListener(this);
        findViewById(R.id.button_no).setOnClickListener(this);

    }

I updated the onHandleIntent with this bit:

if (isActivityFound) {
    Intent dialogIntent = new Intent(getBaseContext(),
            NotificationAlertActivity.class);
    dialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    getApplication().startActivity(dialogIntent);
}
查看更多
迷人小祖宗
4楼-- · 2020-05-21 06:41

In my code I have public static ArrayList<Activity> activity_stack every activity is added in oncreate and removed in ondestroy methods. I check this stack in GcmBroadcastReceiver. I don't know if it's a good solution.

查看更多
Root(大扎)
5楼-- · 2020-05-21 06:44

Make a class extends Application and implement ActivityLifecycleCallbacks and according to on pause and onResume update a public boolean.

At the time push received check this Boolean and perform as your requirement.

Hope this will help you

public class TestApplication extends Application implements ActivityLifecycleCallbacks{
boolean applicationOnPause = false;
@Override
public void onCreate() {
    super.onCreate();
    registerActivityLifecycleCallbacks(this);
}



@Override
public void onActivityCreated(Activity arg0, Bundle arg1) {
    Log.e("","onActivityCreated");

}
@Override
public void onActivityDestroyed(Activity activity) {
    Log.e("","onActivityDestroyed ");

}
@Override
public void onActivityPaused(Activity activity) {
    applicationOnPause = true;
    Log.e("","onActivityPaused "+activity.getClass());

}
@Override
public void onActivityResumed(Activity activity) {
    applicationOnPause = false;
    Log.e("","onActivityResumed "+activity.getClass());

}
@Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
    Log.e("","onActivitySaveInstanceState");

}
@Override
public void onActivityStarted(Activity activity) {
    Log.e("","onActivityStarted");

}
@Override
public void onActivityStopped(Activity activity) {
    Log.e("","onActivityStopped");

}

}

查看更多
登录 后发表回答