首页 > 解决方案 > BOOT COMPLETE BroadcastReceiver 自动注册

问题描述

当用户希望服务在启动时启动时,我正在尝试启动我的服务。所以我在我的设置片段上有一个复选框首选项来控制它。检查框并用户启动服务后,StartOnBootBroadcast将注册广播电台,并在启动完成后开始使用服务。默认情况下,除非用户需要,否则不会注册 BroadcastReceiver。但问题是如果我安装应用程序并重新启动设备,广播接收器会启动服务(但我从未注册过)。我已经用调试器检查了条件,并且启动接收器的条件从未满足。

广播接收器:

class StartOnBootBroadcast : BroadcastReceiver() {

    companion object {
        private var instance: StartOnBootBroadcast? = null
        fun getinstance(): StartOnBootBroadcast {
            if (instance == null) {
                instance = StartOnBootBroadcast()
            }
            return instance as StartOnBootBroadcast
        }
    }

    override fun onReceive(context: Context?, intent: Intent?) {

        Log.d("BOOTCAST", "onReceive: FIRED")
        
        val serviceIntent = Intent(context, MyService::class.java)

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            context!!.startForegroundService(serviceIntent)
        } else {
            context!!.startService(serviceIntent)
        }
    }
}

显现:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.sourav.bettere">
    <application
        android:name=".App"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity
            android:name=".activities.MainActivity"
            android:configChanges="orientation|screenSize">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <service android:name=".service.ChargeLoggerService" />

        <receiver android:name=".broadcasts.BatteryBroadcast">
            <intent-filter>
                <action android:name="android.intent.action.BATTERY_CHANGED" />
                <action android:name="android.intent.action.ACTION_POWER_CONNECTED" />
                <action android:name="android.intent.action.ACTION_POWER_DISCONNECTED" />
            </intent-filter>
        </receiver>

        <receiver android:name=".broadcasts.ChargingBroadcast">
            <intent-filter>
                <action android:name="android.intent.action.BATTERY_CHANGED" />
                <action android:name="android.intent.action.ACTION_POWER_CONNECTED" />
                <action android:name="android.intent.action.ACTION_POWER_DISCONNECTED" />
            </intent-filter>
        </receiver>

        <receiver android:name=".broadcasts.StartOnBootBroadcast">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
            </intent-filter>
        </receiver>

        <meta-data
            android:name="preloaded_fonts"
            android:resource="@array/preloaded_fonts" />
    </application>

</manifest>

注册/注销 BroadcastReciever 的方法:

prefViewmodel.getBootStatus.observe(viewLifecycleOwner, Observer { value ->
    onBoot = value
        if (Utilities.getInstance(mContext).isMyServiceRunning(ChargeLoggerService::class.java)){
            startOnBoot(onBoot)
        }
})

////unrelated codes

switch.setOnCheckedChangeListener { buttonView, isChecked ->
            if (isChecked) {
                startService()
                Utilities.getInstance(mContext)
                    .writeToPref(
                        Constants.PREF_TYPE_BOOL,
                        Constants.PREF_LOGGER_ACTIVE,
                        valueBool = true
                    )
            } else {
                stopService()
                Utilities.getInstance(mContext)
                    .writeToPref(
                        Constants.PREF_TYPE_BOOL,
                        Constants.PREF_LOGGER_ACTIVE,
                        valueBool = false
                    )
            }
            startOnBoot(onBoot)
        }

private fun startOnBoot(value: Boolean){
        when(value){
            true -> Utilities.getInstance(mContext).loadBroadcastReceiver(startOnBoot, IntentFilter(Intent.ACTION_BOOT_COMPLETED))
            false -> {
                try {
                    requireContext().unregisterReceiver(startOnBoot)
                }catch (e:Exception){
                    e.printStackTrace()
                }}

        }
        Log.d(TAG, "startOnBoot: $value")
    }

标签: androidkotlinservicebroadcastreceiverboot

解决方案


推荐阅读