在 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 上解析接收通知的主要内容,如果未能解决你的问题,请参考以下文章