问题描述
|
我有c2dm的注册ID和身份验证令牌。然后我将这些值存储在db中。并使用PHP,我可以向c2dm服务器发送一条消息。但是我的问题是我不知道如何在应用程序中接收消息。我不确定我收到消息的方式是否正确。无论如何,我将在下面给出。
我有一个使用注册意图向c2dm注册的活动。一个接收器,接收reg_id和通知消息。它正在向c2dm注册并且不接收消息。
表现
<intent-filter>
<action android:name=\"com.google.android.c2dm.intent.REGISTRATION\"></action>
<category android:name=\"my.android.c2dm\"></category>
</intent-filter>
<intent-filter>
<action android:name=\"com.google.android.c2dm.intent.RECEIVE\"></action>
<category android:name=\"my.android.c2dm\"></category>
</intent-filter>
</receiver>
</application>
C2dmRegistration.class(活动)
Intent objRegIntnet=new Intent(\"com.google.android.c2dm.intent.REGISTER\");
objRegIntnet.putExtra(\"app\",PendingIntent.getbroadcast(this,new Intent(),0));
objRegIntnet.putExtra(\"sender\",\"mymail@gmail.com\");
startService(objRegIntnet);
c2dmReceiver
public class c2dmReceiver extends broadcastReceiver
{
private static String KEY = \"c2dmPref\";
private static String REGISTRATION_KEY = \"registrationKey\";
private Context context;
@Override
public void onReceive(Context context,Intent intent)
{
this.context = context;
if (intent.getAction().equals(\"com.google.android.c2dm.intent.REGISTRATION\"))
{
handleRegistration(context,intent);
}
else if (intent.getAction().equals(\"com.google.android.c2dm.intent.RECEIVE\"))
{
handleMessage(context,intent);
}
}
private void handleRegistration(Context context,Intent intent)
{
//handles registeration
}
private void handleMessage(Context context,Intent intent)
{
String title= intent.getStringExtra(\"title\");
String message= intent.getStringExtra(\"msg\");
Toast.makeText(context,\"title : \"+title+\"\\n message : \"+message,1).show();
//Do whatever you want with the message
}
请告诉我我做错了什么...
更新
大家好,今天相同的代码对我来说很麻烦。我所做的错误是与PHP代码有关。即时将值传递为POST,我将其发送为GET。当我将其更改为POST时,将显示Toast消息。但是仍然存在一些问题。
标题和msg值在此处为空。
我的PHP代码是:
function sendMessagetoPhone($authCode,$deviceRegistrationId,$msgType,$messageText)
{
//$messageText=\"have a nice day\";
//$msgtype=\"important\";
$headers = array(\'Authorization: GoogleLogin auth=\' . $authCode);
$data = array(
\'registration_id\' => $deviceRegistrationId,\'collapse_key\' => $msgType,\'data.message\' => $messageText
);
$ch = curl_init();
curl_setopt($ch,CURLOPT_URL,\"https://android.apis.google.com/c2dm/send\");
if ($headers)
curl_setopt($ch,CURLOPT_HTTPHEADER,$headers);
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,false);
curl_setopt($ch,CURLOPT_POST,true);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,CURLOPT_POSTFIELDS,$data);
$response = curl_exec($ch);
curl_close($ch);
return $response;
}
实际上,我不确定应将哪种类型的值用于crash_key和data.message变量。
请帮我...
谢谢...
解决方法
最终,我找到了提供crash_key和and数据的方法。
crash_key应该是一个字符串,它是一组消息的名称或特定类型的消息。如果我们使用相同的crash_key发送多个消息,则最新消息将从c2dm服务器发送到设备。
例如:$ collapse_key = \“ important \”;
和数据。是重要的这将包含我们要发送的消息。
例如:如果我们要发送消息“祝您有愉快的一天”,那么我应该给它起一个关键的名字。
数据。= \“祝您有美好的一天\”;
这里的“愿望”是关键。在接收器中,我应该检索具有相同键名的消息。
private void handleMessage(Context context,Intent intent)
{
String mywish= intent.getStringExtra(\"wishes\");
Toast.makeText(context,\"my wishes : \"+mywish,1).show();
}
对不起。
, 这是我的代码,我已使用它接收C2DM服务器的通知表单,它还在通知栏上显示通知。它正在运行,您可以将您的代码与我的代码进行比较,并更正错误(如果有)。
希望对您有所帮助。
/ **
* C2D消息接收器的基类。包括所用字符串的常量
协议中的*。
* /
public abstract class C2DMBaseReceiver extends IntentService {
private static final String C2DM_RETRY = \"com.google.android.c2dm.intent.RETRY\";
public static final String REGISTRATION_CALLBACK_INTENT = \"com.google.android.c2dm.intent.REGISTRATION\";
private static final String C2DM_INTENT = \"com.google.android.c2dm.intent.RECEIVE\";
// Logging tag
private static final String TAG = \"C2DM\";
// Extras in the registration callback intents.
public static final String EXTRA_UNREGISTERED = \"unregistered\";
public static final String EXTRA_ERROR = \"error\";
public static final String EXTRA_REGISTRATION_ID = \"registration_id\";
public static final String ERR_SERVICE_NOT_AVAILABLE = \"SERVICE_NOT_AVAILABLE\";
public static final String ERR_ACCOUNT_MISSING = \"ACCOUNT_MISSING\";
public static final String ERR_AUTHENTICATION_FAILED = \"AUTHENTICATION_FAILED\";
public static final String ERR_TOO_MANY_REGISTRATIONS = \"TOO_MANY_REGISTRATIONS\";
public static final String ERR_INVALID_PARAMETERS = \"INVALID_PARAMETERS\";
public static final String ERR_INVALID_SENDER = \"INVALID_SENDER\";
public static final String ERR_PHONE_REGISTRATION_ERROR = \"PHONE_REGISTRATION_ERROR\";
// wakelock
private static final String WAKELOCK_KEY = \"C2DM_LIB\";
private static PowerManager.WakeLock mWakeLock;
private final String senderId;
/**
* The C2DMReceiver class must create a no-arg constructor and pass the
* sender id to be used for registration.
*/
public C2DMBaseReceiver(String senderId) {
// senderId is used as base name for threads,etc.
super(senderId);
this.senderId = senderId;
}
/**
* Called when a cloud message has been received.
*/
protected abstract void onMessage(Context context,Intent intent);
/**
* Called on registration error. Override to provide better error messages.
*
* This is called in the context of a Service - no dialog or UI.
*/
public abstract void onError(Context context,String errorId);
/**
* Called when a registration token has been received.
*/
public void onRegistrered(Context context,String registrationId)
throws IOException {
}
/**
* Called when the device has been unregistered.
*/
public void onUnregistered(Context context) {
}
@Override
public final void onHandleIntent(Intent intent) {
try {
Context context = getApplicationContext();
if (intent.getAction().equals(REGISTRATION_CALLBACK_INTENT)) {
handleRegistration(context,intent);
} else if (intent.getAction().equals(C2DM_INTENT)) {
//**C2DM Start
Bundle extras = intent.getExtras();
String pushNo =extras != null ? extras.getString(\"pushNo\"):\"\";
String scoreId =extras != null ? extras.getString(\"scoreId\"):\"\";
String notfId =extras != null ? extras.getString(\"notfId\"):\"\";
String fromId =extras != null ? extras.getString(\"fromId\"):\"\";
String toId =extras != null ? extras.getString(\"toId\"):\"\";
String matchId =extras != null ? extras.getString(\"matchId\"):\"\";
String msg =extras != null ? extras.getString(\"msg\"):\"\";
String ns = Context.NOTIFICATION_SERVICE;
NotificationManager mNotificationManager = (NotificationManager) getSystemService(ns);
int icon = R.drawable.icon;
CharSequence tickerText = \"Notification Receive\";
long when = System.currentTimeMillis();
Notification notification = new Notification(icon,tickerText,when);
Context context1 = context;
//*****************
final int CUSTOM_VIEW_ID = 1;
RemoteViews contentView = new RemoteViews(getPackageName(),R.layout.custom_notification_layout);
contentView.setImageViewResource(R.id.image,R.drawable.icon);
contentView.setTextViewText(R.id.text,\"Racquetime \\n\"+msg);
notification.contentView = contentView;
notification.defaults=Notification.FLAG_ONLY_ALERT_ONCE+Notification.FLAG_AUTO_CANCEL;
Intent notificationIntent;
if(GUIStatics.boolLoginStatus)
{
notificationIntent = new Intent(this,ShowAllNotificationActiviry.class);
}
else{
notificationIntent = new Intent(this,HomeActivity.class);
}
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notification.defaults |= Notification.DEFAULT_SOUND;
notification.flags |= Notification.FLAG_SHOW_LIGHTS;
notificationIntent.putExtra(\"Tag\",\"C2DMBaseReceiver\");
PendingIntent contentIntent = PendingIntent.getActivity(this,notificationIntent,0);
notification.contentIntent = contentIntent;
mNotificationManager.notify(CUSTOM_VIEW_ID,notification);
//**C2DM End
// onMessage(context,intent);
} else if (intent.getAction().equals(C2DM_RETRY)) {
C2DMessaging.register(context,senderId);
}
} finally {
// Release the power lock,so phone can get back to sleep.
// The lock is reference counted by default,so multiple
// messages are ok.
// If the onMessage() needs to spawn a thread or do something else,// it should use it\'s own lock.
mWakeLock.release();
}
}
/**
* Called from the broadcast receiver. Will process the received intent,* call handleMessage(),registered(),etc. in background threads,with a
* wake lock,while keeping the service alive.
*/
static void runIntentInService(Context context,Intent intent) {
if (mWakeLock == null) {
// This is called from BroadcastReceiver,there is no init.
PowerManager pm = (PowerManager) context
.getSystemService(Context.POWER_SERVICE);
mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,WAKELOCK_KEY);
}
mWakeLock.acquire();
// Use a naming convention,similar with how permissions and intents are
// used. Alternatives are introspection or an ugly use of statics.
String receiver =\"com.commonsware.android.c2dm.C2DMReceiver\";
intent.setClassName(context,receiver);
context.startService(intent);
}
private void handleRegistration(final Context context,Intent intent) {
final String registrationId = intent
.getStringExtra(EXTRA_REGISTRATION_ID);
String error = intent.getStringExtra(EXTRA_ERROR);
String removed = intent.getStringExtra(EXTRA_UNREGISTERED);
if (Log.isLoggable(TAG,Log.DEBUG)) {
Log.d(TAG,\"dmControl: registrationId = \" + registrationId
+ \",error = \" + error + \",removed = \" + removed);
}
if (removed != null) {
// Remember we are unregistered
C2DMessaging.clearRegistrationId(context);
onUnregistered(context);
return;
} else if (error != null) {
// we are not registered,can try again
C2DMessaging.clearRegistrationId(context);
// Registration failed
Log.e(TAG,\"Registration error \" + error);
onError(context,error);
if (\"SERVICE_NOT_AVAILABLE\".equals(error)) {
long backoffTimeMs = C2DMessaging.getBackoff(context);
Log.d(TAG,\"Scheduling registration retry,backoff = \"
+ backoffTimeMs);
Intent retryIntent = new Intent(C2DM_RETRY);
PendingIntent retryPIntent = PendingIntent
.getBroadcast(context,0 /* requestCode */,retryIntent,0 /* flags */);
AlarmManager am = (AlarmManager) context
.getSystemService(Context.ALARM_SERVICE);
am.set(AlarmManager.ELAPSED_REALTIME,backoffTimeMs,retryPIntent);
// Next retry should wait longer.
backoffTimeMs *= 2;
C2DMessaging.setBackoff(context,backoffTimeMs);
}
} else {
try {
onRegistrered(context,registrationId);
C2DMessaging.setRegistrationId(context,registrationId);
GUIStatics.registrationID=registrationId;
} catch (IOException ex) {
Log.e(TAG,\"Registration error \" + ex.getMessage());
}
}
}
, 我的消息仅在我开始使用时才通过:
Bundle extras = intent.getExtras();
String message = (String)extras.get(\"message\");
Log.d(\"Tag\",\"msg:\" + message);