[英]Background Services are restricted in Xiaomi and Oppo
我們正在開發一個在前台服務中運行 MQTT 的應用程序。 問題出在小米紅米 Note 7 上,我們殺死應用程序后服務被終止,但在其他品牌上它工作正常。 我沒有在 Oppo 和 Vivo 上測試該應用程序,但當我搜索時,它們也有問題。 在服務的onCreate
方法中,我調用了startForeground(NOTIFICATION_ID, notification)
並且我在清單中的服務聲明是這樣的
<service
android:name=".service.mqtt.MqttService"
android:enabled="true"
android:exported="false"
android:foregroundServiceType="location" />
我還將foregroundServiceType
更改為connectedDevice|dataSync|mediaPlayback
並添加了android:stopWithTask="false"
並在onStartCommand
服務方法中返回了START_STICKY
但仍然無法正常工作。
最后我在這里找到了答案
private static final Intent[] POWERMANAGER_INTENTS = {
new Intent().setComponent(new ComponentName("com.miui.securitycenter", "com.miui.permcenter.autostart.AutoStartManagementActivity")),
new Intent().setComponent(new ComponentName("com.letv.android.letvsafe", "com.letv.android.letvsafe.AutobootManageActivity")),
new Intent().setComponent(new ComponentName("com.huawei.systemmanager", "com.huawei.systemmanager.startupmgr.ui.StartupNormalAppListActivity")),
new Intent().setComponent(new ComponentName("com.huawei.systemmanager", "com.huawei.systemmanager.optimize.process.ProtectActivity")),
new Intent().setComponent(new ComponentName("com.huawei.systemmanager", "com.huawei.systemmanager.appcontrol.activity.StartupAppControlActivity")),
new Intent().setComponent(new ComponentName("com.coloros.safecenter", "com.coloros.safecenter.permission.startup.StartupAppListActivity")),
new Intent().setComponent(new ComponentName("com.coloros.safecenter", "com.coloros.safecenter.startupapp.StartupAppListActivity")),
new Intent().setComponent(new ComponentName("com.oppo.safe", "com.oppo.safe.permission.startup.StartupAppListActivity")),
new Intent().setComponent(new ComponentName("com.iqoo.secure", "com.iqoo.secure.ui.phoneoptimize.AddWhiteListActivity")),
new Intent().setComponent(new ComponentName("com.iqoo.secure", "com.iqoo.secure.ui.phoneoptimize.BgStartUpManager")),
new Intent().setComponent(new ComponentName("com.vivo.permissionmanager", "com.vivo.permissionmanager.activity.BgStartUpManagerActivity")),
new Intent().setComponent(new ComponentName("com.samsung.android.lool", "com.samsung.android.sm.ui.battery.BatteryActivity")),
new Intent().setComponent(new ComponentName("com.htc.pitroad", "com.htc.pitroad.landingpage.activity.LandingPageActivity")),
new Intent().setComponent(new ComponentName("com.asus.mobilemanager", "com.asus.mobilemanager.MainActivity"))
};
for (Intent intent : POWERMANAGER_INTENTS)
if (getPackageManager().resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY) != null) {
// show dialog to ask user action
break;
}
編輯:檢查用戶是否啟用自動啟動也有問題。 正如我所搜索的,目前沒有可用的解決方案。 所以我自己設計了一個解決方案。 我創建了一個工人,它將每 25 分鍾在首選項中節省系統時間。 每次打開應用程序時,我都會檢查首選項,如果距離保存時間超過 30 分鍾,則意味着工作人員無法完成工作,因此可能用戶上次沒有啟用自動啟動,必須再次提示。
class BackgroundCheckWorker(val appContext: Context, val workerParams: WorkerParameters) :
Worker(appContext, workerParams), KoinComponent {
override fun doWork(): Result {
val pref = appContext.getSharedPreferences(PermissionHandler.AUTO_START_PREF, Context.MODE_PRIVATE)
val editor = pref.edit()
editor.putString(AUTO_START_PREF_KEY, Calendar.getInstance().time.toString())
editor.apply()
return Result.success()
}
}
在飛濺中,我調用了這個函數:
fun requestUnrestrictedBackgroundService(context: Activity): Boolean {
val pref = context.getSharedPreferences(AUTO_START_PREF, Context.MODE_PRIVATE)
var updated = false
val lastUpdate = pref.getString(AUTO_START_PREF_KEY, "")
updated = if (lastUpdate == null || lastUpdate == "") {
val editor = pref.edit()
editor.putString(AUTO_START_PREF_KEY, Calendar.getInstance().time.toString())
editor.apply()
false
} else lastUpdate != "" &&
DateUtil.minAgo(lastUpdate) <= 30
if (!updated) {
for (intent in POWERMANAGER_INTENTS)
if (context.packageManager.resolveActivity(
intent,
PackageManager.MATCH_DEFAULT_ONLY
) != null
) {
val dialog = AlertDialog.Builder(context)
dialog.setMessage("On this device you must allow us to run services in background")
.setPositiveButton("Yes") { paramDialogInterface, paramInt ->
val editor = pref.edit()
editor.putString(AUTO_START_PREF_KEY, Calendar.getInstance().time.toString())
editor.apply()
context.startActivityForResult(intent, 1234)
}
.setNegativeButton("Cancel") { paramDialogInterface, paramInt -> context.finish() }
dialog.show()
return false
}
}
return true
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.