成功接收通知但在尝试使用以下代码打开通知时,应用程序会崩溃。这似乎是一些初始化问题。请帮忙
NotificationActivity
public class NotificationActivity extends EzDrawerActivity {
public static ImageLoader imgLoader;
private static EzWebPageFragment ezWebPageFragment;
private static DashboardFragment dashboardFragment;
private static String Dashboard = EzDrawerActivity.MENU_HOME_Dashboard;
GcmIntentService gcm;
@Override
protected void onResume() {
super.onResume();
}
static boolean doInit;
static public void resetOnLogout() {
doInit = false;
}
private void doInit() {
if (doInit == true)
return;
doInit = true;
if (findViewById(R.id.fragment_container) == null)
return;
// set Dash board as default/active fragment after login
if (gcm.notify.getAction().equalsIgnoreCase("url")) {
ezWebPageFragment = new EzWebPageFragment();
mActiveFragment = ezWebPageFragment;
} else {
dashboardFragment = new DashboardFragment();
mActiveFragment = dashboardFragment;
}
}
@Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setToobar();
gcm = new GcmIntentService();
Log.v("DA:onCreate()", "IN... ");
doInit();
super.setHomeAsDrawerEnabled(savedInstanceState);
}
@Override
protected void setFragmentByTag(String item) {
Log.v("DA:setFragmentByTag()", "Tag : "
+ (item == null ? "NULL" : item));
// hide keyboard
EzUtils.hideKeyBoard(this);
if (EzUtils.isNetworkAvailable(this, true)) {
if (item == null || item.equals(Dashboard)) {
DashboardFragment.setWebPageURL(API.DASHBOARD());
showFragment(dashboardFragment, Dashboard);
mTitle = "Dashboard";
} else {
EzWebPageFragment.setWebPageURL(gcm.notify.getURL());
showFragment(ezWebPageFragment);
}
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
return super.onOptionsItemSelected(item);
}
@Override
protected void onStart() {
super.onStart();
this.setFragmentByTag(mActiveFragmentTag);
}
@Override
public void onPause() {
super.onPause();
}
@Override
public void onDestroy() {
super.onDestroy();
Log.v("DA::onDestroy()", "In..");
}
GcmIntentService
public class GcmIntentService extends IntentService {
public static final int NOTIFICATION_ID = 1;
public NotificationData notify;
private NotificationManager mNotificationManager;
NotificationCompat.Builder builder;
public GcmIntentService() {
super("GcmIntentService");
}
@Override
protected void onHandleIntent(final Intent intent) {
final Bundle extras = intent.getExtras();
final GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this);
// The getMessageType() intent parameter must be the intent you received
// in your BroadcastReceiver.
final String messageType = gcm.getMessageType(intent);
if (!extras.isEmpty()) { // has effect of unparcelling Bundle
/*
* Filter messages based on message type. Since it is likely that
* GCM will be extended in the future with new message types, just
*
* ignore any message types you're not interested in, or that you
* don't recognize.
*/
if (GoogleCloudMessaging.MESSAGE_TYPE_SEND_ERROR
.equals(messageType)) {
showNotification("Send error: " + extras.toString());
} else if (GoogleCloudMessaging.MESSAGE_TYPE_DELETED
.equals(messageType)) {
showNotification("Deleted messages on server: "
+ extras.toString());
// If it's a regular GCM message, do some work.
} else if (GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE
.equals(messageType)) {
// This loop represents the service doing some work.
for (int i = 0; i < 5; i++) {
Log.i("TAG", "Working... " + (i + 1) + "/5 @ "
+ SystemClock.elapsedRealtime());
try {
Thread.sleep(5000);
} catch (final InterruptedException e) {
}
}
Log.i("TAG",
"Completed work @ " + SystemClock.elapsedRealtime());
// Post notification of received message. |
// the actual message which gets displayed in the notification
// bar depending upon some restrictions
notify = new NotificationData(extras.getString("message"));
showNotification(notify.getDetails());
Log.i("TAG", "Received: " + extras.toString());
Log.i("TAG", "Received URL: " + notify.getAction());
}
}
// Release the wake lock provided by the WakefulBroadcastReceiver.
WakefulBroadcastReceiver.completeWakefulIntent(intent);
}
// Put the message into a notification and post it.
// This is just one simple example of what you might choose to do with
// a GCM message.
private void showNotification(String msg) {
mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
Intent intent = new Intent(this, NotificationActivity.class);
final PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
intent, 0);
final NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
this)
.setSmallIcon(R.drawable.ic_launcher)
.setLargeIcon(
BitmapFactory.decodeResource(getResources(),
R.drawable.ez))
.setContentTitle(getResources().getString(R.string.app_name))
.setAutoCancel(true)
.setStyle(new NotificationCompat.BigTextStyle().bigText(msg))
.setContentText(msg);
mBuilder.setContentIntent(contentIntent);
mNotificationManager.notify(GcmIntentService.NOTIFICATION_ID,
mBuilder.build());
}
NotificationData
public class NotificationData {
final static public String ND_KEY_ACTION = "action";
final static public String ND_KEY_DETAILS = "details";
final static public String ND_KEY_URL = "url";
JSONObject mData;
public NotificationData(String data) {
try {
mData = new JSONObject(data);
} catch (JSONException e) {
// Log
mData = new JSONObject();
}
}
public String getAction() {
String type = mData.optString(NotificationData.ND_KEY_ACTION);
return (type == null) ? NotificationData.ND_TYPE_MESG : type;
}
public String getDetails() {
String details = mData.optString(NotificationData.ND_KEY_DETAILS);
return (details == null) ? "" : details;
}
public String getURL() {
String url = mData.optString(NotificationData.ND_KEY_URL);
return (url == null) ? "" : url;
}
}
响应:
D/AndroidRuntime(9721): Shutting down VM
E/AndroidRuntime(9721): FATAL EXCEPTION: main
E/AndroidRuntime(9721): Process: com.package, PID: 9721
E/AndroidRuntime(9721): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.package/com.package.gcm.NotificationActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.package.gcm.NotificationData.getAction()' on a null object reference
E/AndroidRuntime(9721):at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3124)
E/AndroidRuntime(9721): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3233)
E/AndroidRuntime(9721): at android.app.ActivityThread.access$1000(ActivityThread.java:197)
E/AndroidRuntime(9721): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1656)
E/AndroidRuntime(9721): at android.os.Handler.dispatchMessage(Handler.java:102)
E/AndroidRuntime(9721): at android.os.Looper.loop(Looper.java:145)
E/AndroidRuntime(9721): at android.app.ActivityThread.main(ActivityThread.java:6873)
E/AndroidRuntime(9721): at java.lang.reflect.Method.invoke(Native Method)
E/AndroidRuntime(9721): at java.lang.reflect.Method.invoke(Method.java:372)
E/AndroidRuntime(9721): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1404)
E/AndroidRuntime(9721): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1199)
E/AndroidRuntime(9721): Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.package.gcm.NotificationData.getAction()' on a null object reference
E/AndroidRuntime(9721): at com.package.gcm.NotificationActivity.doInit(NotificationActivity.java:108)
E/AndroidRuntime(9721): at com.package.gcm.NotificationActivity.onCreate(NotificationActivity.java:159)
E/AndroidRuntime(9721): at android.app.Activity.performCreate(Activity.java:6550)
E/AndroidRuntime(9721): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1120)
E/AndroidRuntime(9721): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3077)
E/AndroidRuntime(9721): ... 10 more
EzDrawerActivity
protected void showFragment(Fragment fragment, String tag) {
Log.e("EDA:showFragment()", "Fragment= " + fragment + ", Tag=" + tag);
mActiveFragment = fragment;
mActiveFragmentTag = tag;
if (mActiveFragment == null) {
Log.e("EDA::showFragment()", "Error: Active Fragment is NULL");
return;
}
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
if (mActiveFragmentTag == null) {
ft.detach(mActiveFragment);
ft.attach(mActiveFragment);
ft.replace(R.id.fragment_container, mActiveFragment).commit();
} else {
ft.detach(mActiveFragment);
ft.attach(mActiveFragment);
ft.replace(R.id.fragment_container, mActiveFragment,
mActiveFragmentTag).commit();
}
// update selected item and title, then close the drawer
mListView.setItemChecked(getHighlightedRowIndex(), true);
}
答案 0 :(得分:0)
看起来您的String引用为null。
检查此行 -
if(gcm.notify.getAction()。equalsIgnoreCase(“url”))
答案 1 :(得分:0)
您的NotificationActivity
没有做任何真正处理通知的事情。在实例化Notification对象时,您也没有传递消息(内容)以及传递给PendingIntent
的Intent。因此,您应该在showNotification(String msg)
方法中进行以下更改:我将整个NotificationData
对象作为参数传递,而不是传递消息字符串,然后将其添加为extra
。请务必更改NotificationData
以实施Serializable
。
showNotification(NotificationData notificationData){
//specify the msg argument as extra in the intent
Intent intent = new Intent(this, NotificationActivity.class);
//using the method putExtra(String name, Serializable value)
intent.putExtra("data", notificationData);
final PendingIntent contentIntent = PendingIntent.getActivity(this, 0, intent, 0);
//the rest of your code ...
}
然后在Notification
中处理NotificationActivity
onCreate
,您可以在onCreate
中执行以下操作(这些是我建议您做的更改 - 替换您的protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setToobar();
//remove/comment out
// gcm = new GcmIntentService();
Log.v("DA:onCreate()", "IN... ");
super.setHomeAsDrawerEnabled(savedInstanceState);
//here is the code to handle the notification data
//get the notification intent (which will carry the extras)
Intent notificationIntent = getIntent();
//see changes I made to your doInit method
doInit(notificationIntent );
}
方法:< / p>
private void doInit(Intent intentData) {
if (doInit == true)
return;
doInit = true;
if (findViewById(R.id.fragment_container) == null)
return;
NotificationData notificationData = null;
if(intentData != null){
//get the extra if available
notificationData = (NotificationData) intentData.getSerializableExtra("data");
}
//now you can check for URL, etc:
// set Dash board as default/active fragment after login
if (notificationData != null && notificationData.getURL().equalsIgnoreCase("url")) {
ezWebPageFragment = new EzWebPageFragment();
mActiveFragment = ezWebPageFragment;
} else {
dashboardFragment = new DashboardFragment();
mActiveFragment = dashboardFragment;
}
}
这些是我建议你的doInit方法(处理通知)的改变
{{1}}
我真的希望这会对你有所帮助。很抱歉有很多变化 - 但这是基于我查看代码时遇到的问题。请试一试,让我知道。