0

我試圖建立通知,但它似乎我的NotificationCompat.BuilderNPE - 在這條線mNotificationManager.notify(NOTIFICATION_ID, t);


經過10個小時的研究,我已經解決了很多問題,包括確保我的Intent作爲服務運行,Context正確解析,並且onCreate只運行一次。

這裏是我的清單NullPointerException在通知NotificationCompat.Builder

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="com.willypt.himtichannelsubscribe" 
    android:versionCode="1" 
    android:versionName="1.0" > 

    <uses-sdk 
     android:minSdkVersion="9" 
     android:targetSdkVersion="16" /> 

    <uses-permission android:name="android.permission.INTERNET" /> 
    <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="com.willypt.himtichannelsubscribe.permission.C2D_MESSAGE" 
     android:protectionLevel="signature" /> 

    <uses-permission android:name="com.willypt.himtichannelsubscribe.permission.C2D_MESSAGE" /> 

    <application 
     android:allowBackup="true" 
     android:icon="@drawable/ic_launcher" 
     android:label="@string/app_name" 
     android:theme="@style/AppTheme" > 
     <activity 
      android:name="com.willypt.himtichannelsubscribe.MainActivity" 
      android:label="@string/app_name" > 
      <intent-filter> 
       <action android:name="android.intent.action.MAIN" /> 

       <category android:name="android.intent.category.LAUNCHER" /> 
      </intent-filter> 
     </activity> 

     <receiver 
      android:name="com.willypt.himtichannelsubscribe.GcmBroadcastReceiver" 
      android:permission="com.google.android.c2dm.permission.SEND" > 
      <intent-filter> 
       <action android:name="com.google.android.c2dm.intent.RECEIVE" /> 
       <category android:name="com.willypt.himtichannelsubscribe" /> 
      </intent-filter> 
     </receiver> 

     <service android:name="com.willypt.himtichannelsubscribe.GcmIntentService" /> 

     <activity 
      android:name="com.willypt.himtichannelsubscribe.ChannelActivity" 
      android:label="@string/title_activity_channel" > 
     </activity> 
    </application> 

</manifest> 

ParseJSON.java,我readLink()功能是誰調用GcmIntentService

package com.willypt.himtichannelsubscribe; 


import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.InputStreamReader; 
import java.util.ArrayList; 

import org.apache.http.HttpEntity; 
import org.apache.http.HttpResponse; 
import org.apache.http.StatusLine; 
import org.apache.http.client.ClientProtocolException; 
import org.apache.http.client.HttpClient; 
import org.apache.http.client.methods.HttpGet; 
import org.apache.http.impl.client.DefaultHttpClient; 
import org.json.JSONArray; 
import org.json.JSONObject; 

import android.app.Activity; 
import android.app.Notification; 
import android.app.NotificationManager; 
import android.app.PendingIntent; 
import android.content.Context; 
import android.content.Intent; 
import android.os.Bundle; 
import android.os.StrictMode; 
import android.support.v4.app.NotificationCompat; 
import android.util.Log; 
import com.willypt.himtichannelsubscribe.GcmIntentService; 

public class ParseJSON extends Activity { 

/** Called when the activity is first created. */ 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    StrictMode.ThreadPolicy policy = new StrictMode. 
    ThreadPolicy.Builder().permitAll().build(); 
    StrictMode.setThreadPolicy(policy); 
    } 
    public ArrayList<String> GetJSON(String url){ 
     ArrayList<String> val = new ArrayList<String>(); 
     String readLink = readLink(url); 
     JSONArray jsonArray = new JSONArray(); 
     try { 
      jsonArray = new JSONArray(readLink); 
      for (int i = 0; i < jsonArray.length(); i++) { 
       val.add(jsonArray.getString(i)); 
      } 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
     return val; 
    } 
    public String readLink(String url) { 
    StringBuilder builder = new StringBuilder(); 
    HttpClient client = new DefaultHttpClient(); 
    HttpGet httpGet = new HttpGet(url); 
    Log.e(ParseJSON.class.toString(),url); 
    try { 
     HttpResponse response = client.execute(httpGet); 
     StatusLine statusLine = response.getStatusLine(); 
     int statusCode = statusLine.getStatusCode(); 
     if (statusCode == 200) { 
     HttpEntity entity = response.getEntity(); 
     InputStream content = entity.getContent(); 
     BufferedReader reader = new BufferedReader(new InputStreamReader(content)); 
     String line; 
     while ((line = reader.readLine()) != null) { 
      builder.append(line); 
     } 
     } else { 
     Log.e(ParseJSON.class.toString(), "Failed to download file"); 

     Intent Notif = new Intent(this, GcmIntentService.class); 
     Notif.putExtra("PostThisNotifString", "Failed to download file"); 
     this.startService(Notif); 
     } 
    } catch (ClientProtocolException e) { 
     e.printStackTrace(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
    return builder.toString(); 
    } 
} 

GcmIntentService.java

package com.willypt.himtichannelsubscribe; 

import com.google.android.gms.gcm.GoogleCloudMessaging; 

import android.app.IntentService; 
import android.app.Notification; 
import android.app.NotificationManager; 
import android.app.PendingIntent; 
import android.content.Context; 
import android.content.Intent; 
import android.os.Bundle; 
import android.os.SystemClock; 
import android.support.v4.app.NotificationCompat; 
import android.util.Log; 

public class GcmIntentService extends IntentService { 
    public static final int NOTIFICATION_ID = 1; 
    private NotificationManager mNotificationManager; 
    NotificationCompat.Builder builder; 
    private PendingIntent contentIntent; 

    public GcmIntentService() { 
     super("GcmIntentService"); 
    } 
    public static final String TAG = "HIMTI Notification v2"; 
    @Override 
    protected void onHandleIntent(Intent intent) { 
     Bundle extras = intent.getExtras(); 
     GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this); 
     // The getMessageType() intent parameter must be the intent you received 
     // in your BroadcastReceiver. 
     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)) { 
       sendNotification("Send error: " + extras.toString()); 
      } else if (GoogleCloudMessaging.MESSAGE_TYPE_DELETED.equals(messageType)) { 
       sendNotification("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 (InterruptedException e) { 
        } 
       } 
       Log.i(TAG, "Completed work @ " + SystemClock.elapsedRealtime()); 
       // Post notification of received message. 
       sendNotification("Received: " + extras.toString()); 
       Log.i(TAG, "Received: " + extras.toString()); 
      } else { 
       //I just need to post a simple notification to user 
       String ex = intent.getStringExtra("PostThisNotifString"); 
       sendNotification(ex); 
      } 
     } 
     // Release the wake lock provided by the WakefulBroadcastReceiver. 
     GcmBroadcastReceiver.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. 
    public void sendNotification(String msg) { 
     Intent u = new Intent(this, MainActivity.class); 
     PendingIntent contentIntent = PendingIntent.getActivity(this, 0, u,0); 


     NotificationCompat.Builder mBuilder = 
       new NotificationCompat.Builder(this) 
     .setContentTitle("HIMTI Broadcast") 
     .setStyle(new NotificationCompat.BigTextStyle() 
     .bigText(msg)) 
     .setContentText(msg); 
     Notification t = mBuilder.build(); 
     mBuilder.setContentIntent(contentIntent); 
     mNotificationManager.notify(NOTIFICATION_ID, t); 
    } 
} 

這裏的logcat的一個

10-13 11:45:36.429: E/AndroidRuntime(16096): FATAL EXCEPTION: IntentService[GcmIntentService] 
10-13 11:45:36.429: E/AndroidRuntime(16096): java.lang.NullPointerException 
10-13 11:45:36.429: E/AndroidRuntime(16096): at com.willypt.himtichannelsubscribe.GcmIntentService.sendNotification(GcmIntentService.java:108) 
10-13 11:45:36.429: E/AndroidRuntime(16096): at com.willypt.himtichannelsubscribe.GcmIntentService.onHandleIntent(GcmIntentService.java:85) 
10-13 11:45:36.429: E/AndroidRuntime(16096): at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:65) 
10-13 11:45:36.429: E/AndroidRuntime(16096): at android.os.Handler.dispatchMessage(Handler.java:99) 
10-13 11:45:36.429: E/AndroidRuntime(16096): at android.os.Looper.loop(Looper.java:137) 
10-13 11:45:36.429: E/AndroidRuntime(16096): at android.os.HandlerThread.run(HandlerThread.java:60) 

回答

1

我的猜測:您還沒有初始化您的mNotificationManager字段。

你可能需要像下面你onHandleIntent()

if (mNotificationManager == null) { 
    mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); 
} 
+0

謝謝!錯誤似乎消失了,但通知並沒有激發起來。 –

1

您需要聲明的sendNotification的()以下:NotificationManager notificationManager = (NotificationManager) context .getSystemService(Context.NOTIFICATION_SERVICE);

 if (currentapiVersion < android.os.Build.VERSION_CODES.HONEYCOMB) { 
     Notification notification = new Notification(icon, message, when); 
      notification.setLatestEventInfo(context, appname, message, 
        contentIntent); 
      notification.flags = Notification.FLAG_AUTO_CANCEL; 
      notificationManager.notify(0, notification); 

     } else { 
      NotificationCompat.Builder builder = new NotificationCompat.Builder(
        context); 
      notification = builder.setContentIntent(contentIntent) 
        .setSmallIcon(icon).setTicker(appname).setWhen(when) 
        .setAutoCancel(true).setContentTitle(appname) 
        .setContentText(message).build(); 

      notificationManager.notify(0, notification); 

     } 

此代碼檢查API版本,並顯示通知。 希望這有助於。

+0

我不能僅僅使用'NotificationCompat.Builder'來擴展API嗎? –

+0

是的,你可以。通知類已在API級別11中棄用。 –

相關問題