まず、私はそれが悪い習慣であることを知っていると言いましょう、良くない、おそらく(技術的に)等、等...私のアプリから別のサービスを強制的に停止することはできません。私のアプリから別のAndroidサービスを強制停止するにはどうすればいいですか?
しかし、この必要性を保証するためにいくつかのユースケースがあります。私の場合、例えば、私のアプリケーション(私はそれがバーコードスキャンSDKです)への参照のために私のアプリによってインストールされているサードパーティのサービスがあります。 SDKには、私はこの呼び出しはサービスを開始またはそれが既に実行されている場合は、それにインスタンスを取得するかということを観察している
GetScannerService();
と呼ばれるものにメソッドを呼び出す必要があることを述べています。
さらに、このサードパーティのサービスを効果的に停止する、私のアプリケーションのonStopとonDestroyの間に行わなければならない呼び出しがあります。
私はこのサービスが奇妙な状態で立ち往生するケースを見てきました。私はこのパッケージのコード(およびバグ)を制御できません。はい、私は彼らに手を差し伸べましたが、根本的な原因を解決するためにこれまでに成功していませんでした。この状態でスタックされていると、実行中のサービスの一覧に表示されます(キャッシュされたサービスの一覧に表示されることもあります)が、GetScannerServiceを呼び出すと、サービスが開始できないという例外がスローされます。 ..それはすでにです。
これは、実行中のサービスリストを手動で検索して(再びキャッシュされることがある)、強制停止をクリックすると、これが修正され、私のアプリケーションは再び期待どおりに動作します。それは再び起こります。
だから、私のアプリがこのサービスを制御したいと思う。私がGetScannerServiceへの最初の呼び出しを行うときに、起動時にその考えがあります。例外が返された場合は、基本的に強制的に停止して、再度呼び出すことができます。つまり、強制停止機能を自動化したいのです。
私は技術的にこれが許可されていないことを知っていますが、私はまた、ルートを持っていなくても、それを行う方法があることを読みました。
これまでのところ、実行中のすべてのサービスの一覧を取得できます。問題のサービスがリストに表示されます。これは、実行中のサービスに関する多くの情報にもアクセスできることを意味します。しかし、私が試したことはうまくいかない。私はKillBackgroundProcessesを試してみましたが、うまくいきませんでした。サービスはまだリストにあります。ここで
は、私がこれまで試してみましたです:
private void Button_Click(object sender, EventArgs e)
{
var am = (ActivityManager)this.Application.ApplicationContext.GetSystemService(Context.ActivityService);
var taskList = am.GetRunningServices(serviceListLimit);
List<string> serviceNames = new List<string>();
foreach(var t in taskList)
{
serviceNames.Add(t.Service.PackageName);
}
var adapter = new ArrayAdapter<string>(this, Android.Resource.Layout.SimpleListItem1, serviceNames);
services.Adapter = adapter;
if (serviceNames.Contains(emdkServiceName))
testKillService(am, emdkClass);
}
private void testKillService(ActivityManager am, Class emdkClass)
{
am.KillBackgroundProcesses(emdkServiceName);
}
だから、私はそれらを一覧表示し、リスト内の項目については、リストでそれを見るだけでなく、グラブの詳細をすることができます。誰も私がそれを強制停止する方法を知っていますか?
この度はお返事ありがとうございました。それは動作しているようです(つまり例外はありません)が、プロセスを実際に終了させるわけではありませんが、まだリストにあります。私が最初にあなたが言及したようにpidを取得し、ブレークポイントの間に、私は私が(私はクラス名、PIDなどを参照してください)私が関心を持つプロセスを持っていることがわかります。その後Android.OS.Process.KillProcess(pid)を呼び出します。しかし、それは死ぬことはありません! Java.Lang.Processがありますが、それは1つではありません。私は自分のマニフェストで自分のパーミッションもチェックしました。私が1つを見逃していなければ、私はそれらをすべて持っていると思う。他の考え? –
実際には、プロセスのUIDが自分のUIDと一致する場合、そのProcess.KillProcessはプロセスをkillするだけです。これは犯人かもしれません。私のSDKの呼び出しはこのプロセスを開始しますが、私はそれが私のアプリと同じUIDを持っていることを確信することはできません。これはAndroid OS(安全機能として)が実際にそれを殺さない理由かもしれません。しかし、KILL_BACKGROUND_PROCESSESパーミッションを指定すると、私が行ったActivityManager.KillBackgroundProcesses(name)を使用することもできますが、これも機能していません。名前を正しく指定していない可能性がありますか? –
ここでの主な問題は、それらのサービスの 'START_STICKY'フラグだと思います。 あなたのkill実装をすべて確認したら、そのうちの最小のものがサービスを強制終了するはずです。しかし、サービスがSTICKYとして開始されたため、OSは毎回それを再起動します。 'logcat'で確認できます。そして、あなたが以前に殺したものと同じではありません(例えば、 'top'コマンドを使ってコンソールで)killされていないサービスのPIDをチェックすれば、それは同じではありません。 – danesz