只在Android应用程序未运行时显示推送通知

9

我的应用程序已经集成了 GCM 推送通知。每当有通知时,它都能正常显示。但是,即使用户在应用程序内部,推送通知也会出现。我希望只有当用户在应用程序外部时才会出现通知。

以下是我的推送通知代码:

GcmBroadcastReceiver

public class GcmBroadcastReceiver extends WakefulBroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {
    ComponentName comp = new ComponentName(GCMNotificationIntentService.class.getPackage().getName(), 
            GCMNotificationIntentService.class.getName());
    startWakefulService(context, (intent.setComponent(comp)));
    setResultCode(Activity.RESULT_OK);
}
}

GCMnotificationIntentService.Class

public class GCMNotificationIntentService extends IntentService {

public static int notificationId = 10;
private NotificationManager mNotificationManager;
NotificationCompat.Builder builder;
private boolean login_status = false;


public GCMNotificationIntentService() {
    super("GcmIntentService");
}

public static final String TAG = GCMNotificationIntentService.class.getSimpleName();

@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) ) {
            sendNotification("Send error: " + extras.toString());
        } else if ( GoogleCloudMessaging.MESSAGE_TYPE_DELETED.equals(messageType) ) {
            sendNotification("Deleted messages on server: " + extras.toString());
            // If it's a regular GCM message, do some work.
        } else if ( GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE.equals(messageType) ) {
            sendNotification(extras.getString("message"));
            Log.i(TAG, "Received: " + extras.toString());
        }
    }
    // Release the wake lock provided by the WakefulBroadcastReceiver.
    GcmBroadcastReceiver.completeWakefulIntent(intent);
}

private void sendNotification(String msg) {

    mNotificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);

    PendingIntent contentIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
    NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this).setSmallIcon(R.drawable.ic_launcher)
            .setContentTitle(getString(R.string.notification_title))
            .setStyle(new NotificationCompat.BigTextStyle().bigText(msg)).setContentText(msg);
    Uri uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
    mBuilder.setSound(uri);
    mBuilder.setContentIntent(contentIntent);
    mBuilder.setAutoCancel(true);
    mNotificationManager.notify(notificationId++, mBuilder.build());
}
}

在 ManifestFile 中

 <receiver
        android:name=".GcmBroadcastReceiver"
        android:permission="com.google.android.c2dm.permission.SEND" >
        <intent-filter>
            <action android:name="com.google.android.c2dm.intent.RECEIVE" />
            <action android:name="com.google.android.c2dm.intent.REGISTRATION" />

            <category android:name="com.medlife.deliveryagent" />
        </intent-filter>
    </receiver>
  <service android:name=".GCMNotificationIntentService" />

任何建议都将不胜感激!!!

你是否已经添加了以下权限? <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" /> <permission android:name="....permission.C2D_MESSAGE" android:protectionLevel="signature" /> <uses-permission android:name=".....permission.C2D_MESSAGE" /> - Amit
你可以控制通知中显示或不显示的内容。只需找到应用程序是否在前台即可。这个SO链接讨论了这个问题。去看看吧。https://dev59.com/qW035IYBdhLWcg3wTuFu - Alok Rao
@Amit 我已经在清单文件中添加了所有的权限,现在它才能工作。 - John
请查看https://dev59.com/lF0a5IYBdhLWcg3wPWpN#30703555。 - Haris Qurashi
你的意思是如果用户退出了应用程序,你想要显示通知吗? - Pankaj
@Clairvoyant:是的,完全正确。 - John
2个回答

4

通过调用下面的方法来检查您的应用程序是否在前台,根据返回值是true还是false来进行后续工作。

public boolean checkApp(){
       ActivityManager am = (ActivityManager) this
                .getSystemService(ACTIVITY_SERVICE);

        // get the info from the currently running task
        List<ActivityManager.RunningTaskInfo> taskInfo = am.getRunningTasks(1);

        ComponentName componentInfo = taskInfo.get(0).topActivity;
        if (componentInfo.getPackageName().equalsIgnoreCase("YourPackage")) {
            return true;
        } else {
           return false;
        }
  } 

对于packageName,我可以指定特定的classname吗? - John
是的,你可以使用类名,格式为:包名 + 类名 - Pankaj
我还有一个疑问。我有一个带有导航抽屉的主屏幕。假设我在第二个片段中,我收到了通知。如果我点击该通知,它应该重定向到第一个片段。如何实现?有什么想法吗? - John
3
从API v21开始,ActivityManager.getRunningTasks已经被弃用,因此不应再使用这个解决方案。 - wvdz
这已经被弃用了。 - cesards

2

Kotlin

 fun isAppRunning(context: Context, packageName: String): Boolean {
    val activityManager = context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
    val procInfos = activityManager.runningAppProcesses
    if (procInfos != null) {
        for (processInfo in procInfos) {
            if (processInfo.processName == packageName) {
                return true
            }
        }
    }
    return false
}

非常好的解决方案,它完美地工作,并且比被接受的答案更好,因为根据@wvdz的提及,自API v21起ActivityManager.getRunningTasks已被弃用。 - Alexander Cavalheiro Becker

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接