android 应用接收器中的推送通知,发送者 Web 服务

Posted

技术标签:

【中文标题】android 应用接收器中的推送通知,发送者 Web 服务【英文标题】:Push Notifications in android app receiver, Sender Web Service 【发布时间】:2015-08-04 10:33:35 【问题描述】:

我正在尝试一个示例应用程序,用于仅接收 android 应用程序中的推送通知。

我有一个广播接收器和一个服务:

public class GcmBroadcastReceiver extends WakefulBroadcastReceiver 

public class GcmIntentService extends IntentService

我使用以下代码获得了 regId:

regid = gcm.register(SENDER_ID); 

1.如何验证收到的 regID 是否正常?

2。这足以从我的应用程序接收通知吗?我问这个是因为我见过的大多数示例都在 Android 应用中实现了 Sender

3.我已经有一个广播接收器为什么我需要一个服务?

4.我打算实现一个可以与 GCM 通信的 Web 服务器。为此,我的应用程序需要将 redId 发送到 Web 服务器。我了解网络服务需求 注册 ID、API 密钥、发送到 GCM 的消息文本。 JSON 的格式是什么?如果是,则 URL 和方法类型 GET 或 POST 是什么。或 ASP .net 中的任何示例

5.是否有任何开放软件,我可以在其中测试我的应用通知接收器行为而无需自己实现服务器?

谢谢

【问题讨论】:

【参考方案1】:

我试着回答 1)如果gcm注册不了,可以在logcat上查看。 2)我不明白。 3) BroadcastReceiver 没有被唤醒。另外,如果您想要后台任务,则无法执行。所以你可以使用 WakefulBroadcastReceiver 和 startWakefullService。所以你可以随心所欲。 4)您可以在https://developers.google.com/cloud-messaging/那里获得更多信息 5) 我找到了https://github.com/uniqush,但我没有尝试。如果你没有足够的时间,你可以使用 Parse :)

【讨论】:

感谢您的回答。关于我的第二个问题,我看到的所有示例都将 regId 和用户信息发送到 Web 服务器?这是否意味着所有设备都发送这个?为什么我们需要这样做?所有用户的 regId 都不同吗? 是的,所有设备都必须将 regid 发送到您的服务器,因为 Google GCM 服务器会使用 regid 识别设备。 但是推送通知是发送给所有应用用户的,那为什么我们需要这样做呢?一个设备的单个 regId 应该足够了吧?【参考方案2】:

1) 有效的 GCM 注册 ID 以“APA..”开头。所以打印它并检查这个值;

2) 旧文档建议使用一个名为 GcmManager 的类来处理设备注册,它是这样的:

public class GcmManager 

    private static final String PROPERTY_REG_ID = "registration_id";
    private static final String PROPERTY_APP_VERSION = "appVersion";
    private static final String TAG = GcmManager.class.getSimpleName();
    private GoogleCloudMessaging gcm;
    private Context mContext;

    public GcmManager(Context context) 
        this.mContext = context.getApplicationContext();
    

    public void registerIfNeeded() 
        final String regId = getRegistrationId();
        Log.d(TAG, "regId: " + regId);
        if (regId.isEmpty()) 
            registerInBackground();
        
        else 
            new Thread(new Runnable() 
                public void run() 
                    sendRegistrationIdToBackend(regId);
                
            ).run();
        
    

    private void storeRegistrationId(Context context, String regId) 
        final SharedPreferences prefs = getGcmPreferences(context);
        int appVersion = getAppVersion(context);
        SharedPreferences.Editor editor = prefs.edit();
        editor.putString(PROPERTY_REG_ID, regId);
        editor.putInt(PROPERTY_APP_VERSION, appVersion);
        editor.apply();
    

    public String getRegistrationId() 
        final SharedPreferences prefs = getGcmPreferences(mContext);
        String registrationId = prefs.getString(PROPERTY_REG_ID, "");
        if (registrationId.isEmpty()) 
            Log.i(TAG, "Registration not found.");
            return "";
        

        int registeredVersion = prefs.getInt(PROPERTY_APP_VERSION, Integer.MIN_VALUE);
        int currentVersion = getAppVersion(mContext);
        if (registeredVersion != currentVersion) 
            Log.i(TAG, "App version changed.");
            return "";
        
        return registrationId;
    

    private void registerInBackground() 
        new AsyncTask<Void, Void, String>() 
            @Override
            protected String doInBackground(Void... params) 
                String msg = "";
                try 
                    if (gcm == null) 
                        gcm = GoogleCloudMessaging.getInstance(mContext);
                    
                    String regId = gcm.register(Constants.GCM_SENDER_ID);
                    storeRegistrationId(mContext, regId);
                 catch (IOException ex) 
                    msg = "Error :" + ex.getMessage();
                
                return msg;
            

            @Override
            protected void onPostExecute(String msg) 
                final String regId = getRegistrationId();
                if (!regId.isEmpty()) 
                    sendRegistrationIdToBackend(regId);
                
            

        .execute(null, null, null);
    

    private static int getAppVersion(Context context) 
        try 
            PackageInfo packageInfo = context.getPackageManager()
                    .getPackageInfo(context.getPackageName(), 0);
            return packageInfo.versionCode;
         catch (PackageManager.NameNotFoundException e) 
            throw new RuntimeException("Could not get package name: " + e);
        
    

    private SharedPreferences getGcmPreferences(Context context) 
        return context.getSharedPreferences(GcmManager.class.getSimpleName(),
                Context.MODE_PRIVATE);
    

    private void sendRegistrationIdToBackend(String regId) 
        // Send registration Id to your API
    

那么你应该调用方法registerIfNeeded来检查设备是否已经注册,顾名思义;

3)WakefulBroadcastReceiver的官方文档说明:

实现 BroadcastReceiver 的通用模式的助手,它接收设备唤醒事件,然后将工作传递给服务,同时确保设备在转换期间不会重新进入睡眠状态。

4 和 5) This answer 展示了如何使用 Postman 轻松地直接向 GCM 发出请求。这是一种很好的测试方法,您可以将请求用作您自己的 API 的示例

【讨论】:

感谢您的回答,如果应用程序安装在 10 个用户的手机上,是否所有用户都将 regId 发送到服务器?我尝试使用一个用户 regId 发送推送通知,我确实收到了通知但这是否意味着只有一个用户会收到它?为什么我们需要将所有用户 regId 发送到服务器?在这种情况下,如何为所有应用用户发送推送通知?有没有其他办法? 此架构将消息从服​​务器提供给唯一标识符引用的 ONE 设备。然而,谷歌云消息传递已经发展,并且有关于这个主题的文档developers.google.com/cloud-messaging/notifications

以上是关于android 应用接收器中的推送通知,发送者 Web 服务的主要内容,如果未能解决你的问题,请参考以下文章

在android中没有收到推送通知

实现细粒度启用/禁用推送通知

android应用程序中的推送通知

SendBird 只推送一个通知 - android

当app在前台时发送推送通知

向 Android Native App 中的好友列表发送推送通知