Android O(8.0)バックグラウンドサービス制限
4496 ワード
Androidのプラットフォームが更新されるたびに、アプリケーション権限の引き締めに努力しています.8.0も例外ではありません.今回はアプリケーションのバックグラウンドでサービスを起動する権限を制限します.関連する問題現象は、参考にすることができる.http://blog.csdn.net/chenshengfa/article/details/71407704.
しかし、本文はツッコミの下で新しいバックグラウンドの制限が8.0プラットフォームの適合に与える影響を除いて、主に本人が開発の中で発見したいくつかの回避可能な方法について話します.まず、アプリケーション権限の問題のため、本稿は一般的なアプリケーション開発に適していないことを宣言し、研究の参考にします.
Android公式はバックグラウンドサービスの起動を制限すると同時に、代替案も提示した.しかし、結局、いくつかの機能は、他の案が代替できないか、代替しても従来の効果を達成できない.例えば、ネットワークの変化を傍受したり、スクリーンを点滅させたりするなどのニーズがあります.本当に二度と戻らない穴で、ごろつきに慣れた私たちには、本当に不便ですね.以下、シナリオの本文です.
1. すべてのアプリケーションで使用できる解決策.
1).プラットフォーム区分,8.0以下,爱どう,以前どうだった.
2).8.0以上、1つの常駐サービスを統一し、フロントに移行する.方法:startServiceをstartForegroundServiceに変更し、対応するサービスが作成されたときにstartForegroundを使用して自分のnotificationを登録します.
3).はい、この方法はnotification付きです.つまり、常駐サービスを使いたいなら、ユーザーに知らせなければなりません.
2. システムアプリケーションで使用できる方法(システム権限が必要).
誰かが言ったかもしれませんが、私はシステムを応用しています.そんなに面倒なことはありません.私はもう特殊な従業員です.Androidは私に何を禁止していますか.そうですよ.7番目のおばさんと8番目のおばさんがいても権限を享受したいならどうしますか.私が担当しているアプリケーションには、灰色の地帯にあり、一部にはシステム権限があり、もう一部の弟は局の外で混じっています.
まず、ソースコードの起動部分を見てみましょう.
ActiveServices.java->startServiceLocked()という一節があります
サービスがfgRequiredフロントで起動していない場合は、サービスが持つアプリケーションMODEがAPP_であるかどうかを取得する必要があります.START_MODE_NORMAL.つまり、APP_として適用されるとSTART_MODE_NORMALは、楽屋サービスを楽しくスタートさせることができます.ActivityManagerServices.java->getAppStartModeLocked()にアクセスして定義を表示します.コアは基本的にこれです.
appServices RestrictedInBackgroundLocked()を直接見る
そして様々な判断があり、システム権限のあるアプリケーションとして、他のアプリケーションにバックドアを開けることができます.
このうちisOnDeviceIdleWhitelistLockedでは、ユーザーが設定→アプリケーション詳細→管理バッテリーアプリケーションにアクセスできます.ここではスイッチでこの値を変更したり、設定→バッテリー→右上のメニューを設定したりして、バッテリー最適化でアプリケーションリストを変更すればいいです.
以上のように
しかし、本文はツッコミの下で新しいバックグラウンドの制限が8.0プラットフォームの適合に与える影響を除いて、主に本人が開発の中で発見したいくつかの回避可能な方法について話します.まず、アプリケーション権限の問題のため、本稿は一般的なアプリケーション開発に適していないことを宣言し、研究の参考にします.
Android公式はバックグラウンドサービスの起動を制限すると同時に、代替案も提示した.しかし、結局、いくつかの機能は、他の案が代替できないか、代替しても従来の効果を達成できない.例えば、ネットワークの変化を傍受したり、スクリーンを点滅させたりするなどのニーズがあります.本当に二度と戻らない穴で、ごろつきに慣れた私たちには、本当に不便ですね.以下、シナリオの本文です.
1. すべてのアプリケーションで使用できる解決策.
1).プラットフォーム区分,8.0以下,爱どう,以前どうだった.
2).8.0以上、1つの常駐サービスを統一し、フロントに移行する.方法:startServiceをstartForegroundServiceに変更し、対応するサービスが作成されたときにstartForegroundを使用して自分のnotificationを登録します.
3).はい、この方法はnotification付きです.つまり、常駐サービスを使いたいなら、ユーザーに知らせなければなりません.
2. システムアプリケーションで使用できる方法(システム権限が必要).
誰かが言ったかもしれませんが、私はシステムを応用しています.そんなに面倒なことはありません.私はもう特殊な従業員です.Androidは私に何を禁止していますか.そうですよ.7番目のおばさんと8番目のおばさんがいても権限を享受したいならどうしますか.私が担当しているアプリケーションには、灰色の地帯にあり、一部にはシステム権限があり、もう一部の弟は局の外で混じっています.
まず、ソースコードの起動部分を見てみましょう.
ActiveServices.java->startServiceLocked()という一節があります
if(!r.startRequested && !fgRequired) {
// Before going further -- if this app isnot allowed to start services in the
// background, then at this point we aren'tgoing to let it period.
final int allowed =mAm.getAppStartModeLocked(r.appInfo.uid, r.packageName,
r.appInfo.targetSdkVersion,callingPid, false, false);
if (allowed !=ActivityManager.APP_START_MODE_NORMAL) {
Slog.w(TAG, "Background start notallowed: service "
+ service + " to " +r.name.flattenToShortString()
+ " from pid=" +callingPid + " uid=" + callingUid
+ " pkg=" +callingPackage);
if (allowed ==ActivityManager.APP_START_MODE_DELAYED) {
// In this case we are silentlydisabling the app, to disrupt as
// little as possible existing apps.
return null;
}
// This app knows it is in the newmodel where this operation is not
// allowed, so tell it what hashappened.
UidRecord uidRec = mAm.mActiveUids.get(r.appInfo.uid);
return new ComponentName("?","app is in background uid " + uidRec);
}
}
サービスがfgRequiredフロントで起動していない場合は、サービスが持つアプリケーションMODEがAPP_であるかどうかを取得する必要があります.START_MODE_NORMAL.つまり、APP_として適用されるとSTART_MODE_NORMALは、楽屋サービスを楽しくスタートさせることができます.ActivityManagerServices.java->getAppStartModeLocked()にアクセスして定義を表示します.コアは基本的にこれです.
final intstartMode = (alwaysRestrict)
? appRestrictedInBackgroundLocked(uid,packageName, packageTargetSdk)
:appServicesRestrictedInBackgroundLocked(uid, packageName,
packageTargetSdk);
appServices RestrictedInBackgroundLocked()を直接見る
intappServicesRestrictedInBackgroundLocked(int uid, String packageName, intpackageTargetSdk) {
// Persistent app?
if (mPackageManagerInt.isPackagePersistent(packageName)){
if (DEBUG_BACKGROUND_CHECK) {
Slog.i(TAG, "App " + uid+ "/" + packageName
+ " is persistent; notrestricted in background");
}
return ActivityManager.APP_START_MODE_NORMAL;
}
// Non-persistent but backgroundwhitelisted?
if (uidOnBackgroundWhitelist(uid)) {
if (DEBUG_BACKGROUND_CHECK) {
Slog.i(TAG, "App " + uid+ "/" + packageName
+ " on backgroundwhitelist; not restricted in background");
}
returnActivityManager.APP_START_MODE_NORMAL;
}
// Is this app on the battery whitelist?
if (isOnDeviceIdleWhitelistLocked(uid)) {
if (DEBUG_BACKGROUND_CHECK) {
Slog.i(TAG, "App " + uid+ "/" + packageName
+ " on idle whitelist;not restricted in background");
}
returnActivityManager.APP_START_MODE_NORMAL;
}
// None of the service-policy criteriaapply, so we apply the common criteria
return appRestrictedInBackgroundLocked(uid,packageName, packageTargetSdk);
}
そして様々な判断があり、システム権限のあるアプリケーションとして、他のアプリケーションにバックドアを開けることができます.
このうちisOnDeviceIdleWhitelistLockedでは、ユーザーが設定→アプリケーション詳細→管理バッテリーアプリケーションにアクセスできます.ここではスイッチでこの値を変更したり、設定→バッテリー→右上のメニューを設定したりして、バッテリー最適化でアプリケーションリストを変更すればいいです.
以上のように