web-dev-qa-db-ja.com

Androidのサービスから通知を送信する

サービスを実行していますが、通知を送信したいと思います。通知オブジェクトには、Contextではなく、ActivityなどのServiceが必要です。

それを回避する方法を知っていますか?通知ごとにActivityを作成しようとしましたが、見苦しく、ActivityなしでViewを起動する方法が見つかりません。

98
e-satis

ActivityServiceの両方は、実際にはextendContext なので、this内でContextServiceとして単純に使用できます。

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);
105
Josef Pfleger

このタイプの通知は、ドキュメントからわかるように非推奨です。

@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 */ }

より良い方法
次のような通知を送信できます。

// 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 " + "[email protected]")
        .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); 

最良の方法
上記のコードには、最小APIレベル11(Android 3.0)が必要です。
最小APIレベルが11未満の場合、このように support library のNotificationCompatクラスを使用する必要があります。

したがって、最小ターゲットAPIレベルが4+(Android 1.6+)の場合、これを使用します。

    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());
75
trante
@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);
}
7
王怡飞

私のソリューションがベストプラクティスであるかどうかはわかりません。 NotificationBuilderを使用すると、私のコードは次のようになります。

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

マニフェスト:

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

そして、ここでサービス:

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

singleTaskServiceが本当にあるかどうかはわかりませんが、これはアプリケーションで正常に機能します...

1
Martin Pfeffer