应用程序崩溃点击通知

时间:2016-05-24 16:08:28

标签: android google-cloud-messaging

成功接收通知但在尝试使用以下代码打开通知时,应用程序会崩溃。这似乎是一些初始化问题。请帮忙

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);
}

2 个答案:

答案 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}}

我真的希望这会对你有所帮助。很抱歉有很多变化 - 但这是基于我查看代码时遇到的问题。请试一试,让我知道。