サービスを作成し、フォアグラウンドで実行したいと考えています。
ほとんどのコード例には通知があります。しかし、通知を表示したくありません。それは可能ですか?
いくつか例を教えてください。代替手段はありますか?
私のアプリ サービスは mediaplayer を実行しています。アプリがそれ自体を強制終了する以外は、システムが私のサービスを強制終了しないようにする方法(ボタンで音楽を一時停止または停止するなど)。
サービスを作成し、フォアグラウンドで実行したいと考えています。
ほとんどのコード例には通知があります。しかし、通知を表示したくありません。それは可能ですか?
いくつか例を教えてください。代替手段はありますか?
私のアプリ サービスは mediaplayer を実行しています。アプリがそれ自体を強制終了する以外は、システムが私のサービスを強制終了しないようにする方法(ボタンで音楽を一時停止または停止するなど)。
Androidプラットフォームのセキュリティ機能として、いかなる状況においても、通知なしにフォアグラウンドサービスを利用することはできません。これは、フォアグラウンドサービスが大量のリソースを消費し、バックグラウンドサービスとは異なるスケジューリング制約を受け(つまり、すぐに強制終了されない)、ユーザーはバッテリーを消費している可能性があるものを知る必要があるためです。だから、これをしないでください。
ただし、「偽の」通知を受け取ることは可能です。つまり、透明な通知アイコン(iirc)を作成できます。これはユーザーにとって非常に不誠実であり、ユーザーのバッテリーを殺してマルウェアを作成する以外に、それを行う理由はありません。
更新:これは Android 7.1 で「修正」されました。 https://code.google.com/p/android/issues/detail?id=213309
4.3のアップデート以降、基本的に通知なしでサービスを開始することはできません。startForeground()
ただし、公式の API を使用してアイコンを非表示にすることはできます...透明なアイコンは必要ありません: (NotificationCompat
古いバージョンをサポートするために使用)
NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
builder.setPriority(Notification.PRIORITY_MIN);
通知自体はまだそこにある必要があるという事実に同意しましたが、それでも非表示にしたい人のために、その回避策も見つけたかもしれません:
startForeground()
通知とすべてで偽のサービスを開始します。startForeground()
(同じ通知 ID で)開始します。stopSelf()
onDestroy call を呼び出すことができますstopForeground(true)
)。ほら!通知はまったくなく、2 番目のサービスは引き続き実行されます。
警告: この回答は機能しているように見えますが、実際にはサービスがフォアグラウンド サービスになるのを黙って防止します。
元の答え:
通知の ID をゼロに設定するだけです。
// field for notification ID
private static final int NOTIF_ID = 0;
...
startForeground(NOTIF_ID, mBuilder.build());
NotificationManager mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
mNotificationManager.cancel(NOTIF_ID);
...
得られる利点は、Service
メモリ プレッシャーが高い場合を除き、Android システムによって破壊されることなく、高い優先度で実行できることです。
Pre-Honeycomb および Android 4.4 以降で動作させるNotificationCompat.Builder
には、Notification.Builder
.
編集
新しい API レベルではセキュリティ上の理由により、このコードは機能しなくなります
NotificationId
「0」に設定することはできません (アプリがクラッシュします)。
startForeground(1, notification)
これは、通知を表示するのに最適な方法です (推奨される方法)
ただし、推奨される方法に関係なく必要な場合は"notificationManager.createNotificationChannel("channel_id")"
、コードから を削除してみてください。
または
使用notificationManager.removeNotificationChannel(channel)
ここでのほとんどの回答は、機能しないか、フォアグラウンド サービスを中断するか、 Google Play ポリシーに違反します。
通知を確実かつ安全に非表示にする唯一の方法は、ユーザーに通知をブロックさせることです。
唯一の方法は、アプリからのすべての通知をブロックすることです。
ユーザーをアプリの詳細画面に送ります:
Uri uri = Uri.fromParts("package", getPackageName(), null);
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).setData(uri);
startActivity(intent);
ユーザーにアプリの通知をブロックさせる
これにより、アプリのトーストもブロックされることに注意してください。
Android O で通知をブロックする価値はありません。OS が「バックグラウンドで実行中」または「バッテリーを使用中」の通知に置き換えるだけだからです。
通知チャネルを使用して、他の通知に影響を与えずにサービス通知をブロックします。
ユーザーに通知チャネルの設定を送信する
Intent intent = new Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS)
.putExtra(Settings.EXTRA_APP_PACKAGE, getPackageName())
.putExtra(Settings.EXTRA_CHANNEL_ID, myNotificationChannel.getId());
startActivity(intent);
ユーザーにチャンネルの通知をブロックしてもらう
更新: これは Android 4.3 以降では機能しなくなりました
Notification のコンストラクターの icon パラメーターを 0 に設定し、結果の通知を startForeground() に渡しました。ログにエラーはなく、通知も表示されません。ただし、サービスが正常にフォアグラウンド化されたかどうかはわかりません。確認する方法はありますか?
編集: dumpsys で確認しましたが、実際にサービスは私の 2.3 システムでフォアグラウンドになっています。他のOSバージョンはまだ確認していません。
バージョン 4.3(18) 以降ではサービス通知を非表示にすることはできませんが、アイコンを無効にすることはできます。バージョン 4.3(18) 以降では通知を非表示にすることができます
Notification noti = new Notification();
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.JELLY_BEAN) {
noti.priority = Notification.PRIORITY_MIN;
}
startForeground(R.string.app_name, noti);
更新: これは Android 7.1 以降では機能しなくなりました
アプリの oom_adj を 1 にする方法は次のとおりです (ANDROID 6.0 SDK エミュレータでテスト済み).一時的なサービスをメイン サービス コールに追加しますstartForgroundService(NOTIFICATION_ID, notificion)
。そして、startForgroundService(NOTIFICATION_ID, notificion)
一時的なサービス コール stopForgroundService(true) でしばらくしてから、同じ通知 ID で一時的なサービス コールを再度開始し、onging ontification を破棄します。
アプリケーションを永続的として宣言することもできます。
<application
android:icon="@drawable/icon"
android:label="@string/app_name"
android:theme="@style/Theme"
*android:persistent="true"* >
</application>
これにより、基本的にアプリのメモリ優先度が高くなり、アプリが強制終了される可能性が低くなります。