【问题标题】:GCM How do I detect if app is open and if so pop up an alert box, instead of normal notification flow?GCM 如何检测应用程序是否打开,如果是,则弹出警报框,而不是正常的通知流程?
【发布时间】:2014-05-09 07:32:53
【问题描述】:

我有一个应用程序,我想在其中构建 2 个不同的流程:

  • 1.a 应用在任何活动中都打开
  • 1.b 应用程序显示是一个警报框,用户可以在其中选择转到有关通知的活动或停留在当前活动上。

  • 2.a 应用在后台运行

  • 2.b 通知栏中的通知,启动与通知相关的活动。

我目前有流程 2 工作,但不知道如何让流程 1 工作。这是一些代码:

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

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

【问题讨论】:

    标签: android push-notification google-cloud-messaging


    【解决方案1】:

    创建一个类扩展 Application 并实现 ActivityLifecycleCallbacks 并根据 on pause 和 onResume 更新一个公共布尔值。

    在收到推送时检查此布尔值并按照您的要求执行。

    希望对你有帮助

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

    }

    【讨论】:

    • 我认为这应该能够工作,但我需要在所有活动中实施这一点,对吧?
    • 无需在所有活动中实现这一点,只需在应用程序类上执行即可。见编辑部分。每次打开关闭(暂停)的活动时都会收到呼叫
    • 请注意这是在 ApI 级别 14 中实现的
    【解决方案2】:

    我会像这样写另一个BroadcastReceiver

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

    然后在MainActivity 中,我会覆盖这些方法,然后我没有收到通知,所以我拦截了 `Intent~ 并中止了另一个广播:

    @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】:

      在我的代码中,我有 public static ArrayList<Activity> activity_stack 每个活动都在 oncreate 中添加并在 ondestroy 方法中删除。我在 GcmBroadcastReceiver 中检查了这个堆栈。不知道有没有好办法。

      【讨论】:

        【解决方案4】:

        我刚刚找到的解决方案确实需要 GET_TASK 权限:

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

        更新

        为了启动警报框(这在此处不可能),我创建了一个自定义警报框并让它使用警报框作为主题。这是 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" >
        

        还有自定义活动:

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

        我用这个位更新了 onHandleIntent:

        if (isActivityFound) {
            Intent dialogIntent = new Intent(getBaseContext(),
                    NotificationAlertActivity.class);
            dialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            getApplication().startActivity(dialogIntent);
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-04-29
          • 1970-01-01
          • 2015-11-17
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多