在 Android 上解析接收通知

Posted

技术标签:

【中文标题】在 Android 上解析接收通知【英文标题】:Parse receiving notifications on Android 【发布时间】:2015-06-23 01:00:00 【问题描述】:

在我的 android 应用中,当我尝试在 logcat 中接收推送通知时出现此错误:

6-22 14:38:16.016 6570-6570/com.tekinarslan.material.sample E/com.parse.ManifestInfo﹕无法使用 GCM 进行推送,因为应用程序 manifest 缺少一些必需的声明。请确保 这些权限被声明为根的孩子 元素: 另外,请确保将这些服务和广播接收器声明为元素的子元素: 06-22 14:38:16.021 6570-6570/com.tekinarslan.material.sample E/com.parse.PushService﹕ 尝试使用推送,但此应用未配置推送,原因如下: 未为此应用配置推送,因为应用清单是 缺少必需的声明。请添加以下声明 到您的应用清单以支持 GCM 或 PPNS 进行推送(或两者)。 要启用 GCM 支持,请确保这些权限是 声明为根元素的子元素: 另外,请确保将这些服务和广播接收器声明为元素的子元素: 要启用 PPNS 支持,请确保将这些权限声明为根元素的子元素: 另外,请确保将这些服务和广播接收器声明为元素的子元素:

我认为我的清单中有我需要的一切,这里是:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.tekinarslan.material.sample"
    android:versionCode="1"
    android:versionName="1.0">
    <uses-sdk android:minSdkVersion="9"/>
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.MANAGE_DOCUMENTS" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-permission android:name="android.permission.VIBRATE" />
    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
    <!-- Permissions required for parse.com notifications -->
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-permission android:name="android.permission.VIBRATE" />
    <uses-permission android:name="android.permission.WAKE_LOCK"/>
    <!-- END Parse permissions -->

    <!--
      IMPORTANT: Change "com.parse.tutorials.pushnotifications.permission.C2D_MESSAGE" in the lines below
      to match your app's package name + ".permission.C2D_MESSAGE".
    -->
    <permission android:protectionLevel="signature"
        android:name="com.tekinarslan.material.sample.permission.C2D_MESSAGE" />
    <uses-permission android:name="com.tekinarslan.material.sample.permission.C2D_MESSAGE" />

    <application
        android:name=".App"
        android:allowBackup="true"
        android:label="DONUT"
        android:theme="@style/AppTheme" >
        <meta-data
            android:name="com.facebook.sdk.ApplicationId"
            android:value="@string/facebook_app_id"/>
        <activity
            android:name=".SampleActivity"
            android:label="@string/app_name" >

        </activity>
        <activity
            android:name=".FbLoginActivity" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            </activity>


        <activity
            android:name="com.facebook.FacebookActivity"
            android:configChanges="keyboard|keyboardHidden|screenLayout|screenSize|orientation"
            android:label="@string/app_name"
            android:theme="@android:style/Theme.Translucent.NoTitleBar"/>

        <!-- My custom receiver -->
        <receiver android:name=".ParseReceiver" >
            <intent-filter>
                <action android:name="com.tekinarslan.material.sample.RECEIVE_PUSH" />
            </intent-filter>
        </receiver>
        <!-- END my custom receiver -->


        <!-- Required for Parse.com notifications -->
        <service android:name="com.parse.PushService" />

        <receiver android:name="com.parse.ParseBroadcastReceiver" >
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
                <action android:name="android.intent.action.USER_PRESENT" />
            </intent-filter>
        </receiver>
        <!-- END Parse.com requirements -->

    </application>

</manifest>

**我的 ParseReceiver - **

package com.tekinarslan.material.sample;

import java.util.Iterator;

import org.json.JSONException;
import org.json.JSONObject;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
/*****************************
 * This class will receive custom push notifications
 * from parse.com. These are different than the "plain"
 * message push notifications. 
 * 
 * There must be an action defined within the Intent-Filter
 * for this receiver in the manifest.xml file. And the same
 * action must be specified on the notification when it is
 * pushed.
 * 
 * You can optionally pass JSON data from parse.com which will
 * be avaialable in the onReceive() method here.
 *****************************/
public class ParseReceiver extends BroadcastReceiver 
    private final String TAG = "Parse Notification";
    private String msg = "";
    @Override
    public void onReceive(Context ctx, Intent intent) 
        Log.i(TAG, "PUSH RECEIVED!!!");

        try 
            String action = intent.getAction();
            String channel = intent.getExtras().getString("com.parse.Channel");
            JSONObject json = new JSONObject(intent.getExtras().getString("com.parse.Data"));

            Log.d(TAG, "got action " + action + " on channel " + channel + " with:");
            Iterator itr = json.keys();
            while (itr.hasNext()) 
                String key = (String) itr.next();
                Log.d(TAG, "..." + key + " => " + json.getString(key));
                if(key.equals("string"))
                    msg = json.getString(key);
                
            
         catch (JSONException e) 
            Log.d(TAG, "JSONException: " + e.getMessage());
        


        Bitmap icon = BitmapFactory.decodeResource(ctx.getResources(),
                R.drawable.ic_launcher);

        Intent launchActivity = new Intent(ctx, SampleActivity.class);
        PendingIntent pi = PendingIntent.getActivity(ctx, 0, launchActivity, 0);

        Notification noti = new NotificationCompat.Builder(ctx)
        .setContentTitle("PUSH RECEIVED")
        .setContentText(msg)
        .setSmallIcon(R.drawable.ic_launcher)
        .setLargeIcon(icon)
        .setContentIntent(pi)
        .setAutoCancel(true)
        .build();

        NotificationManager nm = (NotificationManager)ctx.getSystemService(Context.NOTIFICATION_SERVICE);
        nm.notify(0, noti);

    


【问题讨论】:

【参考方案1】:

您的自定义接收器需要在意图过滤器中执行以下操作:

<receiver
  android:name=".ParseReceiver"
  android:exported="false">
  <intent-filter>
    <action android:name="com.parse.push.intent.RECEIVE"/>
    <action android:name="com.parse.push.intent.DELETE"/>
    <action android:name="com.parse.push.intent.OPEN"/>
    ...
  </intent-filter>
</receiver>

<receiver
  android:name="com.parse.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="at.a1telekom.android.newsroom"/>
  </intent-filter>
</receiver>

编辑:

您是否订阅这样的解析?

Parse.initialize(context, appId, clientKey);    
ParsePush.subscribeInBackground( yourChannels, new SaveCallback() ...);

【讨论】:

已添加,没有错误但通知仍未到达.. @Rithe 啊,我看到还是少了点什么。我更新了我的答案。也尝试添加 GcmBroadcastReceiver 设置。【参考方案2】:

清单中缺少给定的代码。在标记之前的清单文件底部包含给定的代码。

 <receiver
        android:name="com.parse.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" />

            <!-- IMPORTANT: Change "com.parse.tutorials.pushnotifications" to match your app's package name. -->
            <category android:name="com.tekinarslan.material.sample" />
        </intent-filter>
    </receiver>
    <receiver
        android:name="com.tekinarslan.material.sample.NotificationReceiver"
        android:exported="false" >
        <intent-filter>
            <action android:name="com.tekinarslan.material.sample.UPDATE_STATUS" />
        </intent-filter>
    </receiver>

【讨论】:

现在我没有错误但通知仍然没有到达...@Rasika 这行你加了吗,PushService.setDefaultPushCallback(this, context);在应用程序类中?这是推动工作的强制性要求。 parse.com/docs/android/api/com/parse/PushService.html ,你可以得到答案。如果您使用的是最新的解析 SDK

以上是关于在 Android 上解析接收通知的主要内容,如果未能解决你的问题,请参考以下文章

如何启用和禁用解析推送通知 Android

无法从 android 上的解析推送通知接收额外数据

当应用程序被杀死Android时无法接收解析推送通知

当该应用的通知关闭时,在 Android 上接收 Firebase 静默通知

使用解析的 Android 推送在一段时间后停止工作

Android11 Notification功能解析