我正在尝试使用this教程在我的应用中通过gcm实现推送通知 我成功地能够注册我的设备,但我得到了空指针异常 注册完成后,onMessage()。
Logcat:
04-21 15:03:11.450: E/AndroidRuntime(8406): FATAL EXCEPTION: IntentService[GCMIntentService-495933236312-2]
04-21 15:03:11.450: E/AndroidRuntime(8406): java.lang.NullPointerException
04-21 15:03:11.450: E/AndroidRuntime(8406): at com.ht.mobilecop.GCMIntentService.onMessage(GCMIntentService.java:65)
04-21 15:03:11.450: E/AndroidRuntime(8406): at com.google.android.gcm.GCMBaseIntentService.onHandleIntent(GCMBaseIntentService.java:223)
04-21 15:03:11.450: E/AndroidRuntime(8406): at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:65)
04-21 15:03:11.450: E/AndroidRuntime(8406): at android.os.Handler.dispatchMessage(Handler.java:99)
04-21 15:03:11.450: E/AndroidRuntime(8406): at android.os.Looper.loop(Looper.java:137)
04-21 15:03:11.450: E/AndroidRuntime(8406): at android.os.HandlerThread.run(HandlerThread.java:60)
createAccount part:
if (regId.equals("")) {
// Registration is not present, register now with GCM
GCMRegistrar.register(this, SENDER_ID);
} else {
// Device is already registered on GCM
// if (GCMRegistrar.isRegisteredOnServer(this)) {
// // Skips registration.
// Toast.makeText(getApplicationContext(), "Already registered with GCM", Toast.LENGTH_LONG).show();
// } else {
// Try to register again, but not in the UI thread.
// It's also necessary to cancel the thread onDestroy(),
// hence the use of AsyncTask instead of a raw thread.
final Context context = this;
mRegisterTask = new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
// Register on our server
// On server creates a new user
name = et_user_name.getText().toString();
email = et_email.getText().toString() ;
ServerUtilities.register(context, name, email, regId);
return null;
}
@Override
protected void onPostExecute(Void result) {
mRegisterTask = null;
editor = getSharedPreferences("account_status", 0).edit();
editor.putString("result", Constants.KEY_SUCCESS);
editor.commit();
Intent i = new Intent(CreateAccountActivity.this , TabHostActivity.class);
i.putExtra("name", et_user_name.getText().toString());
i.putExtra("email", et_email.getText().toString());
startActivity(i);
finish();
}
};
mRegisterTask.execute(null, null, null);
//}
}
GCMIntentService:
public class GCMIntentService extends GCMBaseIntentService {
private static final String TAG = "GCMIntentService";
private static final String CAMERA_REQUEST = null;
public GCMIntentService() {
super(SENDER_ID);
}
/**
* Method called on device registered
**/
@Override
protected void onRegistered(Context context, String registrationId) {
Log.i(TAG, "Device registered: regId = " + registrationId);
ServerUtilities.register(context, CreateAccountActivity.name, CreateAccountActivity.email, registrationId);
}
/**
* Method called on device un registred
* */
@Override
protected void onUnregistered(Context context, String registrationId) {
Log.i(TAG, "Device unregistered");
displayMessage(context, getString(R.string.gcm_unregistered));
ServerUtilities.unregister(context, registrationId);
}
/**
* Method called on Receiving a new message
* */
@Override
protected void onMessage(Context context, Intent intent) {
Log.i(TAG, "Received message");
String message = intent.getExtras().getString("alert");
displayMessage(context, message);
if(message.equals("login"))
{
showAlert(context); // for testing
}
// notifies user
generateNotification(context, message);
}
/**
* Method called on receiving a deleted message
* */
@Override
protected void onDeletedMessages(Context context, int total) {
Log.i(TAG, "Received deleted messages notification");
String message = getString(R.string.gcm_deleted, total);
displayMessage(context, message);
// notifies user
generateNotification(context, message);
}
/**
* Method called on Error
* */
@Override
public void onError(Context context, String errorId) {
Log.i(TAG, "Received error: " + errorId);
displayMessage(context, getString(R.string.gcm_error, errorId));
}
@Override
protected boolean onRecoverableError(Context context, String errorId) {
// log message
Log.i(TAG, "Received recoverable error: " + errorId);
displayMessage(context, getString(R.string.gcm_recoverable_error,
errorId));
return super.onRecoverableError(context, errorId);
}
/**
* Issues a notification to inform the user that server has sent a message.
*/
private static void generateNotification(Context context, String message) {
int icon = R.drawable.ic_launcher;
long when = System.currentTimeMillis();
NotificationManager notificationManager = (NotificationManager)
context.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new Notification(icon, message, when);
String title = context.getString(R.string.app_name);
Intent notificationIntent = new Intent(context, LoginActivity.class);
// set intent so it does not start a new activity
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP |
Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent intent =
PendingIntent.getActivity(context, 0, notificationIntent, 0);
notification.setLatestEventInfo(context, title, message, intent);
notification.flags |= Notification.FLAG_AUTO_CANCEL;
// Play default notification sound
notification.defaults |= Notification.DEFAULT_SOUND;
//notification.sound = Uri.parse("android.resource://" + context.getPackageName() + "your_sound_file_name.mp3");
// Vibrate if vibrate is enabled
notification.defaults |= Notification.DEFAULT_VIBRATE;
notificationManager.notify(0, notification);
}
答案 0 :(得分:0)
将GCMIntentService类放入主程序包而不是其他程序包,并在清单文件中注册,例如,在放置代码后,清单如下所示:
...
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="YOUR_PACKAGE_NAME_HERE.permission.C2D_MESSAGE" />
<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_NAME_HERE.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<receiver
android:name="com.google.android.gcm.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="YOUR_PACKAGE_NAME_HERE" />
</intent-filter>
</receiver>
<service android:name=".GCMIntentService" />
</application>
答案 1 :(得分:0)
您真的需要阅读How to check if my string is equal to null?
要解决您的问题,您需要执行
if(message == null) {
}
OR,Android给TextUtils.isEmpty()检查字符串是否为null或为空。
if(TextUtils.isEmpty(message)) {
// Handle null string
}
而不是
if(message.equals(null)|| message.equals("")) // Nullpointer at this line
{
}