Keep connectivity broadcast receiver running after application is closed

When I need to use Internet connection and it is not posible I want to set a broadcast receiver which keeps working if the app is closed.

I am using a service for that, but that it is not working. It works fine when the app is on screen or paused but it stops working if I close it. I am not pretty sure if I should use other thing or if I am doing something wrong.

This is my code:

package com.example.ana.exampleapp;

import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.os.IBinder;
import android.util.Log;

public class TestsService extends Service {

    private static BroadcastReceiver networkChangeReceiver;
    private static String TAG = "Service";

    @Override
    public IBinder onBind(Intent arg0) {
        return null;
    }

    @Override
    public void onCreate() {
        Log.v(TAG, "Service created");
        boolean keep = needTokeepWaiting()
        if(!keep)
            stopSelf();
    }

    @Override
    public void onDestroy() {
        if (networkChangeReceiver != null)
            unregisterReceiver(networkChangeReceiver);
        networkChangeReceiver = null;
        Log.v(TAG, "Service destroyed");
    }

    private void registerNetworkChangeReceiver() {
        networkChangeReceiver = new BroadcastReceiver() {
            private String TAG = "NetworkReceiver";

            @Override
            public void onReceive(Context context, Intent intent) {
                Log.v(TAG, "Connection changed received");
                            boolean keep = needTokeepWaiting()
                if(!keep)
                    stopSelf();
            }
        };
        IntentFilter filter = new IntentFilter(android.net.ConnectivityManager.CONNECTIVITY_ACTION);
        registerReceiver(networkChangeReceiver, filter);
    }
}

And my manisfest:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.ana.exampleapp">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity
            android:name=".MainActivity"
            android:windowSoftInputMode="stateHidden">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".RegisterActivity"></activity>
        <activity android:name=".FinishRegisterActivity"></activity>
        <activity android:name=".TestActivity"></activity>
        <activity android:name=".InformationActivity"></activity>
        <service android:name=".TestsService"></service>
    </application>

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
</manifest>

And in the TestActivity when it is necessary I do:

Intent service = new Intent(this, TestsService.class);
startService(service);

What I am doing is similar to what it is suggested here, but it doesn't work:

Keep broadcast receiver running after application is closed

I have also tried to do it without a service and registering in the manifest, but It didn't work neither:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.ana.exampleapp">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity"
            android:windowSoftInputMode="stateHidden">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".RegisterActivity">
        </activity>
        <activity android:name=".FinishRegisterActivity" >
        </activity>
        <activity android:name=".TestActivity">
        </activity>
        <activity android:name=".InformationActivity" >
        </activity>
        <receiver android:name=".NetworkChangeReceiver"
            android:enabled="false">
            <intent-filter>
                <action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
            </intent-filter>
        </receiver>
    </application>
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
</manifest>

Upvotes: 1

Views: 3518

Answers (2)

I have just found the problem. There is a bug in Android 4.4.x which kills background services when closing the app. I was testing my app in Android 4.4.2. Here there is a detailed explanation:

http://www.androidpolice.com/2014/03/07/bug-watch-stopping-apps-on-android-4-4-2-can-silently-kill-related-background-services-a-fix-is-on-the-way/

So my code was right as I have tried in Android 4.2.2 and it works (I have tried overriding onStartCommand() so maybe that was needed).

Upvotes: 2

Jofre Mateu
Jofre Mateu

Reputation: 2430

If you don't want your service to stop when the app is closed, you should override onStartCommand() method doing something like this:

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    return START_REDELIVER_INTENT;
}

You can return START_STICKY or START_REDELIVER_INTENT, whatever works better for you

Upvotes: -1

Related Questions