发送来自 Android 服务的通知

我有一个服务运行,并希望发送通知。太糟糕了,通知对象需要 Context,就像 Activity一样,而不是 Service

你知道怎么绕过去吗?我尝试为每个通知创建一个 Activity,但它看起来很丑陋,我找不到一种方法来启动一个没有任何 ViewActivity

156145 次浏览

Both Activity and Service actually extend Context so you can simply use this as your Context within your Service.

NotificationManager notificationManager =
(NotificationManager) getSystemService(Service.NOTIFICATION_SERVICE);
Notification notification = new Notification(/* your notification */);
PendingIntent pendingIntent = /* your intent */;
notification.setLatestEventInfo(this, /* your content */, pendingIntent);
notificationManager.notify(/* id */, notification);

This type of Notification is deprecated as seen from documents:

@java.lang.Deprecated
public Notification(int icon, java.lang.CharSequence tickerText, long when) { /* compiled code */ }


public Notification(android.os.Parcel parcel) { /* compiled code */ }


@java.lang.Deprecated
public void setLatestEventInfo(android.content.Context context, java.lang.CharSequence contentTitle, java.lang.CharSequence contentText, android.app.PendingIntent contentIntent) { /* compiled code */ }

Better way
You can send a notification like this:

// prepare intent which is triggered if the
// notification is selected


Intent intent = new Intent(this, NotificationReceiver.class);
PendingIntent pIntent = PendingIntent.getActivity(this, 0, intent, 0);


// build notification
// the addAction re-use the same intent to keep the example short
Notification n  = new Notification.Builder(this)
.setContentTitle("New mail from " + "test@gmail.com")
.setContentText("Subject")
.setSmallIcon(R.drawable.icon)
.setContentIntent(pIntent)
.setAutoCancel(true)
.addAction(R.drawable.icon, "Call", pIntent)
.addAction(R.drawable.icon, "More", pIntent)
.addAction(R.drawable.icon, "And more", pIntent).build();




NotificationManager notificationManager =
(NotificationManager) getSystemService(NOTIFICATION_SERVICE);


notificationManager.notify(0, n);

Best way
Code above needs minimum API level 11 (Android 3.0).
If your minimum API level is lower than 11, you should you use support library's NotificationCompat class like this.

So if your minimum target API level is 4+ (Android 1.6+) use this:

    import android.support.v4.app.NotificationCompat;
-------------
NotificationCompat.Builder builder =
new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.mylogo)
.setContentTitle("My Notification Title")
.setContentText("Something interesting happened");
int NOTIFICATION_ID = 12345;


Intent targetIntent = new Intent(this, MyFavoriteActivity.class);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, targetIntent, PendingIntent.FLAG_UPDATE_CURRENT);
builder.setContentIntent(contentIntent);
NotificationManager nManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
nManager.notify(NOTIFICATION_ID, builder.build());

Well, I'm not sure if my solution is best practice. Using the NotificationBuilder my code looks like that:

private void showNotification() {
Intent notificationIntent = new Intent(this, MainActivity.class);


PendingIntent contentIntent = PendingIntent.getActivity(
this, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
builder.setContentIntent(contentIntent);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(NOTIFICATION_ID, builder.build());
}

Manifest:

    <activity
android:name=".MainActivity"
android:launchMode="singleInstance"
</activity>

and here the Service:

    <service
android:name=".services.ProtectionService"
android:launchMode="singleTask">
</service>

I don't know if there really is a singleTask at Service but this works properly at my application...

@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
public void PushNotification()
{
NotificationManager nm = (NotificationManager)context.getSystemService(NOTIFICATION_SERVICE);
Notification.Builder builder = new Notification.Builder(context);
Intent notificationIntent = new Intent(context, MainActivity.class);
PendingIntent contentIntent = PendingIntent.getActivity(context,0,notificationIntent,0);


//set
builder.setContentIntent(contentIntent);
builder.setSmallIcon(R.drawable.cal_icon);
builder.setContentText("Contents");
builder.setContentTitle("title");
builder.setAutoCancel(true);
builder.setDefaults(Notification.DEFAULT_ALL);


Notification notification = builder.build();
nm.notify((int)System.currentTimeMillis(),notification);
}

If none of these work, try getBaseContext(), instead of context or this.