我尝试制作通知,但似乎我的NotificationCompat.Builder
NPE
- 在此行mNotificationManager.notify(NOTIFICATION_ID, t);
处。
经过10个小时的研究,我解决了很多问题,包括确保我的Intent
作为服务运行,上下文正确解析,onCreate
运行一次。
这是我的清单
<?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)
答案 0 :(得分:1)
我的猜测:您尚未初始化mNotificationManager
字段。
您可能需要onHandleIntent()
中的以下内容:
if (mNotificationManager == null) {
mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
}
答案 1 :(得分: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版本并显示通知。 希望这会有所帮助。