android - 小米和OPPO限制后台服务

标签 android mqtt foreground-service xiaomi

我们正在开发一个在前台服务中运行 MQTT 的应用程序。
问题出在小米红米 Note 7 上,在我们关闭应用程序后服务被关闭,但在其他品牌上它运行良好。我没有在 Oppo 和 Vivo 上测试该应用程序,但当我搜索它们时,它们也有问题。
onCreate服务的方法,我叫startForeground(NOTIFICATION_ID, notification)我在 list 中的服务声明是这样的

<service
    android:name=".service.mqtt.MqttService"
    android:enabled="true"
    android:exported="false"
    android:foregroundServiceType="location" />

我也改了foregroundServiceTypeconnectedDevice|dataSync|mediaPlayback并添加了 android:stopWithTask="false"并返回 START_STICKYonStartCommand服务方法,但仍然无法正常工作。

最佳答案

终于找到答案了here

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

编辑:
检查用户是否启用自动启动也存在问题。
正如我搜索的那样,目前没有可用的解决方案。所以我自己设计了一个解决方案。
我创建了一个 worker ,它将每 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
        }

关于android - 小米和OPPO限制后台服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59442078/

相关文章:

java - 安装SDK 25后,无法找到带有哈希字符串 'android-25'的目标并不会消失

android - 从Android中的https URL下载和保存图像

c - ESP-32无法连接到MQTT代理:mqtt_client:网络响应错误

python - Django 在引发异常后停止接收/发送 MQTT 消息

ios - 如何使用 cocoaMQTT 在 iOS 中使订阅者离线

android - 是否可以在后台服务中获取wifi ssid?

android - react 原生 : Could not find com. android.tools.build :gradle:2. 2.3

java - 如何将应用程序存储在 SD 卡中

android - 谷歌cast MediaNotificationService 中的大量RemoteServiceExceptions

android - 收集服务中的流