关闭 android 应用程序时未收到 Azure 推送通知

Posted

技术标签:

【中文标题】关闭 android 应用程序时未收到 Azure 推送通知【英文标题】:Azure push notifications not received when android app is closed 【发布时间】:2016-08-25 11:31:51 【问题描述】:

为了快速了解,我正在使用以下教程:

https://azure.microsoft.com/en-us/documentation/articles/notification-hubs-android-push-notification-google-gcm-get-started/

问题我可以在应用程序打开时收到推送通知(从我的 Nodejs 服务器发送)。但是,当我关闭应用程序并将其从最近的应用程序中删除时,我不会收到任何推送通知。我正在使用 Azure 推送通知中心。

所有代码都在上面的链接中,但是,我也把它放在这里作为我的实现方式。

在 Android Manifest 文件中添加了以下块:(为简单起见,未显示标记,我已在正确的位置添加块)

<meta-data android:name="com.google.android.gms.version"
    android:value="@integer/google_play_services_version" />

<service android:name="<your package>.MyInstanceIDService" android:exported="false">
    <intent-filter>
        <action android:name="com.google.android.gms.iid.InstanceID"/>
    </intent-filter>
</service>

<service
    android:name="<your package>.RegistrationIntentService"
    android:exported="false">
</service>

<receiver android:name="com.microsoft.windowsazure.notifications.NotificationsBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND">
    <intent-filter>
        <action android:name="com.google.android.c2dm.intent.RECEIVE" />
        <category android:name="<your package name>" />
    </intent-filter>
</receiver>

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.GET_ACCOUNTS"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />

<permission android:name="<your package>.permission.C2D_MESSAGE" android:protectionLevel="signature" />
<uses-permission android:name="<your package>.permission.C2D_MESSAGE"/>

以下是我根据教程添加的类:

public class NotificationSettings 
    public static String SenderId = "<Your project number>";
    public static String HubName = "<Your HubName>";
    public static String HubListenConnectionString = "<Your default listen connection string>";

InstanceID 监听服务:

import android.content.Intent;
import android.util.Log;
import com.google.android.gms.iid.InstanceIDListenerService;

public class MyInstanceIDService extends InstanceIDListenerService 

    private static final String TAG = "MyInstanceIDService";

    @Override
    public void onTokenRefresh() 

        Log.i(TAG, "Refreshing GCM Registration Token");

        Intent intent = new Intent(this, RegistrationIntentService.class);
        startService(intent);
    
;

RegistrationIntentService 类:

import android.app.IntentService;
import android.content.Intent;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.util.Log;

import com.google.android.gms.gcm.GoogleCloudMessaging;
import com.google.android.gms.iid.InstanceID;
import com.microsoft.windowsazure.messaging.NotificationHub;

public class RegistrationIntentService extends IntentService 

    private static final String TAG = "RegIntentService";

    private NotificationHub hub;

    public RegistrationIntentService() 
        super(TAG);
    

    @Override
    protected void onHandleIntent(Intent intent)       
        SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
        String resultString = null;
        String regID = null;

        try 
            InstanceID instanceID = InstanceID.getInstance(this);
            String token = instanceID.getToken(NotificationSettings.SenderId,
                    GoogleCloudMessaging.INSTANCE_ID_SCOPE);        
            Log.i(TAG, "Got GCM Registration Token: " + token);

            // Storing the registration id that indicates whether the generated token has been
            // sent to your server. If it is not stored, send the token to your server,
            // otherwise your server should have already received the token.
            if ((regID=sharedPreferences.getString("registrationID", null)) == null)       
                NotificationHub hub = new NotificationHub(NotificationSettings.HubName,
                        NotificationSettings.HubListenConnectionString, this);
                Log.i(TAG, "Attempting to register with NH using token : " + token);

                regID = hub.register(token).getRegistrationId();

                // If you want to use tags...
                // Refer to : https://azure.microsoft.com/en-us/documentation/articles/notification-hubs-routing-tag-expressions/
                // regID = hub.register(token, "tag1", "tag2").getRegistrationId();

                resultString = "Registered Successfully - RegId : " + regID;
                Log.i(TAG, resultString);       
                sharedPreferences.edit().putString("registrationID", regID ).apply();
             else 
                resultString = "Previously Registered Successfully - RegId : " + regID;
            
         catch (Exception e) 
            Log.e(TAG, resultString="Failed to complete token refresh", e);
            // If an exception happens while fetching the new token or updating our registration data
            // on a third-party server, this ensures that we'll attempt the update at a later time.
        

        // Notify UI that registration has completed.
        if (MainActivity.isVisible) 
            MainActivity.mainActivity.ToastNotify(resultString);
        
    

和通知处理程序:

public class MyHandler extends NotificationsHandler 
    public static final int NOTIFICATION_ID = 1;
    private NotificationManager mNotificationManager;
    NotificationCompat.Builder builder;
    Context ctx;

    @Override
    public void onReceive(Context context, Bundle bundle) 
        ctx = context;
        String nhMessage = bundle.getString("message");
        sendNotification(nhMessage);
        if (MainActivity.isVisible) 
            MainActivity.mainActivity.ToastNotify(nhMessage);
        
    

    private void sendNotification(String msg) 

        Intent intent = new Intent(ctx, MainActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

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

        PendingIntent contentIntent = PendingIntent.getActivity(ctx, 0,
                intent, PendingIntent.FLAG_ONE_SHOT);

        Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
        NotificationCompat.Builder mBuilder =
                new NotificationCompat.Builder(ctx)
                        .setSmallIcon(R.mipmap.ic_launcher)
                        .setContentTitle("Notification Hub Demo")
                        .setStyle(new NotificationCompat.BigTextStyle()
                                .bigText(msg))
                        .setSound(defaultSoundUri)
                        .setContentText(msg);

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

还有一些我没有在这里包含的代码块,但可以从上面的链接中看到。

请告诉我是否有任何特殊权限可以在应用未运行时收听推送通知。

编辑

我认为,如果我们以某种方式让 onReceive 这个函数在应用程序关闭时保持活动状态,那么我们可以实现这一点。仍然不确定如何执行此操作。

【问题讨论】:

你找到答案了吗? 还没有。我还在想办法。 【参考方案1】:

我也遇到过类似的问题,不知道根本原因是不是和你一样。

当应用程序启动或在后台时,应用程序会收到推送通知,但当我从任务管理器中终止应用程序时会停止接收通知。

原来,问题出在我的清单中。来自documentation,

您的 + ".permission.C2D_MESSAGE" 权限 防止其他安卓应用注册和接收 Android 应用程序的消息。权限名称必须准确 匹配这个模式——否则 Android 应用程序将不会收到 消息。

我已将我的权限定义为

<permission
    android:name=".permission.C2D_MESSAGE"
    android:protectionLevel="signature" />

<uses-permission android:name=".permission.C2D_MESSAGE" />

我使用. 表示法而不是完整的包名称的原因是我在调试版本中使用了applicationIdSuffix。我假设 Gradle 会根据构建类型正确完成包名称。

这是我弄错的地方。显然 Gradle 不会在 Permissions 中更新带有后缀的包。为了解决这个问题,我将代码替换为,

<permission
    android:name="$applicationId.permission.C2D_MESSAGE"
    android:protectionLevel="signature" />

<uses-permission android:name="$applicationId.permission.C2D_MESSAGE" />

这样,应用程序即使在被终止时也开始接收通知。

【讨论】:

我正在使用像com.app.permission.C2D_MESSAGE这样的完整包。还是不行。我没有使用. 表示法 你在build.gradle中设置了applicationIdSuffix吗?

以上是关于关闭 android 应用程序时未收到 Azure 推送通知的主要内容,如果未能解决你的问题,请参考以下文章

应用关闭或被杀时未收到 Android FCM 通知

关闭应用程序时未收到 Xamarin Forms Android 推送通知

IBM Worklight 5.0.6.1 - 关闭电话/应用程序时未收到推送通知

系统刚启动时未收到 FCM 通知

Xamarin.iOS - 设备关闭时推送通知

发布时未发现 Azure SDK 存储程序集异常