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

标签 push-notification google-cloud-messaging azure-mobile-services

有关快速信息,我正在使用以下教程:

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

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

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

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

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

注册意图服务类:
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 即使在应用程序关闭时也能保持事件状态,那么我们就可以实现这一点。仍然不确定如何执行此操作。

最佳答案

我遇到了类似的问题,不知道根本原因是否与您的相同。

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

事实证明,问题出在我的 list 中。来自 documentation ,

Your + ".permission.C2D_MESSAGE" permission to prevent other Android applications from registering and receiving the Android application's messages. The permission name must exactly match this pattern—otherwise the Android application will not receive the messages.



我已将我的许可定义为
<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" />

有了这个,应用程序即使在被杀死时也开始接收通知。

关于push-notification - 关闭 android 应用程序时未收到 Azure 推送通知,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39144129/

相关文章:

swift - 收到消息时将徽章添加到聊天按钮

ios - 桥接 header 导入找不到目标。如何正确导入?

android - 使用 4.0.4 android 版本或 3.2 的设备运行 GCM 通知项目有什么区别吗?

azure - 使用移动应用程序中的 AAD 自定义登录对 Azure 应用程序服务进行身份验证

azure - 允许在未经授权的情况下访问单个 API?

ios - 强制 ios 应用程序再次请求权限

ios - 为什么在Swift5中无法读取推送消息数据?

android - 找不到 ID 为 'com.google.gms.google-services' 的插件

android - GCM 从谷歌服务器手动注销不起作用

c# - 在移动应用程序中使用 ApiController