1 year ago

#354826

test-img

Electroma

Update widget by Broadcast message

I want to develop widget, which shows my public IP. For updating this widget I want use next broadcast messages:

android.net.conn.CONNECTIVITY_CHANGE
android.net.wifi.STATE_CHANGE
android.intent.action.AIRPLANE_MODE_CHANGED

It was simple with android-manifest:

    <receiver
        android:name=".IpView"
        android:exported="true">
        <intent-filter>
            <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
            <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
            <action android:name="android.net.wifi.STATE_CHANGE" />
            <action android:name="android.intent.action.AIRPLANE_MODE_CHANGED" />
        </intent-filter>
        <meta-data
            android:name="android.appwidget.provider"
            android:resource="@xml/ip_view_info" />
    </receiver>

But in new versions of Android, Google introduced restrictions on the use of broadcast messages in manifest, now avialible few of thems:https://developer.android.com/guide/components/broadcast-exceptions

This means, that I should use broadcast with 'registerReceiver' in code and create receiver. Since the message must always be processed, I decided to create a service that will have the receiver. Now I create Service and ServiceStarter, which starts the service on BOOT_COMPLETED by Broadcast

Android Manifest:

    <receiver android:name=".ServiceAutoStarter" android:exported="true">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED"/>
        </intent-filter>
    </receiver>

ServiceAutoStarter:

class ServiceAutoStarter : BroadcastReceiver() {
    override fun onReceive(p0: Context?, p1: Intent?) {
        val serv = Intent(p0, MyIPService::class.java)
        p0?.startService(serv)
    }
}

Service:

class MyIPService : Service() {
    companion object{
        var Started : Boolean = false
    }
    val receiver  = ChangeNetworkReceiver()

    override fun onCreate() {
        MyIPService.Started = true
    }

    override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
        registerReceiver(receiver, IntentFilter("android.net.conn.CONNECTIVITY_CHANGE"))
        registerReceiver(receiver, IntentFilter("android.net.wifi.STATE_CHANGE"))
        registerReceiver(receiver, IntentFilter("android.intent.action.AIRPLANE_MODE_CHANGED"))
        return START_STICKY
    }

    override fun onBind(intent: Intent): IBinder? {
        // We don't provide binding, so return null
        return null
    }

    override fun onDestroy() {
    }
}

Now, after start Service subscribe receiver to need broadcasts, it is works and my Receiver can update widget. The problem is that after 1-2 minutes the system terminates the service, due to which the receiver also dies and stops working.

The only solution I found is a notification service: https://developer.android.com/guide/components/foreground-services But I don't want use Notification service for this simple widget.

What other ways are there to subscribe to the necessary broadcasts in the background, without launching the application? I want the receiver to be always on.

android

kotlin

broadcastreceiver

android-service

android-widget

0 Answers

Your Answer

Accepted video resources