I want to start services from Broadcast Receiver but Marshmallow and above SDK's will not callback. BOOT_COMPLETED is working fine with app foreground & background but CONNECTIVITY_CHANGE is not working on background .
My requirement is, i want to get callback when app with app foreground & background.
My manifest :
<receiver
android:name=".receivers.MessageBroadCastReceiver"
android:enabled="true"
android:exported="false">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>
My Broadcast Receiver:
public class MessageBroadCastReceiver extends BroadcastReceiver {
private static final String TAG = "MessageBroadCastReceive";
private Context ctx;
#Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG, "AppBroad " + intent.getAction());
this.ctx = context;
if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED")) {
RestartMessageService();
} else if (intent.getAction().equals("android.net.conn.CONNECTIVITY_CHANGE")) {
RestartMessageService();
}
}
}
am tired to registered the Broadcast actions in my main activity its working fine on foreground, once i close my app it will not call (Marshmallow and above SDK's).
Registered code:
private void RegisterReceivers() {
try {
MessageBroadCastReceiver broadCastReceiver = new MessageBroadCastReceiver();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
getBaseContext().registerReceiver(broadCastReceiver, intentFilter);
PrefManager.getInstance(this).setBroadcastReg(true);
} catch (IllegalArgumentException e) {
e.printStackTrace();
}
}
Please give me solution.
Advance thanks...
Related
Edit
Everybody thank you for reply,
unfortunately it was impossible to do this work at after Android Pie
https://nllapps.com/apps/acr/android9.htm
https://issuetracker.google.com/issues/112602629
I cannot keep the broadcast receiver running after the application is closed, I tried many methods but failed.
public class BoothService extends Service {
private final Handler mHandler = new Handler();
public BoothService() {
}
private String INCOMING_CALL_ACTION = "android.intent.action.PHONE_STATE";
private final BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String mAction = intent.getAction();
if(mAction.equals(INCOMING_CALL_ACTION)) {
Toast.makeText(context, "BoothService", Toast.LENGTH_SHORT).show();
}
}
};
public void onCreate() {
IntentFilter intentToReceiveFilter = new IntentFilter();
intentToReceiveFilter.addAction(INCOMING_CALL_ACTION);
this.registerReceiver(receiver, intentToReceiveFilter, null, mHandler);
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
This service run from activitymain
Intent BS = new Intent(ActivityMain.this, BoothService.class);
startService(BS);
my purpose is to capture incoming calls, even if the application is closed
My manifest
<receiver
android:name=".RingReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE" />
</intent-filter>
</receiver>
permission,
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
by the way this code works in the emulator ,but it doesn't work on real devices I've tried
Try to use JobService for register your implicit broadcast because after nought implicit broadcast is not working when app is close.
So register your broadcast reciever to jobservice and use schedule that service with jobservice.
Or you can refer this link as well
https://www.journaldev.com/23653/android-oreo-implicit-and-explicit-broadcast-receiver
I am listening for "android.net.conn.CONNECTIVITY_CHANGE" in my app with a broadcast receiver. It does work, but the only problem I have is that there is a huge delay in receiving this broadcast. It takes between 1-2 seconds for the app to receive this broadcast. Am I doing something wrong?
My Manifest entry -
<receiver android:name=".ConnectivityBroadcastReceiver"
android:exported="true">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
</intent-filter>
</receiver>
and ConnectivityBroadcastReceiver class -
public class ConnectivityBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.e(TAG,"Broadcast received");
final String action = intent.getAction();
if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
ConnectivityUtil.checkConnectivity(context);
}
}
}
I have a onBootCompleted broadcast receiver registered in the manifest.
It runs starts MyService. My service in the onCreate registers 3 more broadcast receivers dynamically.
The 3 new receivers filter on the following intent actions
LOCALE_CHANGED,
TIMEZONE_CHANGED and
CONNECTIVITY_CHANGED.
These works correctly when I run the application from Eclipse but, after I reboot the device and my service starts up none of receivers work.
I have a work around implementation but, I would like to know why this is happening?
Manifest:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<receiver android:name=".receiver.BootCompletedReceiver" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<category android:name="android.intent.category.HOME" />
</intent-filter>
</receiver>
<service
android:name=".MyService"
android:enabled="true"
android:exported="false"
android:stopWithTask="false" >
</service>
Service:
public class MyService()
{
LocationTimeZoneChangedReceiver mLocationTimeZoneChangedReceiver = new LocationTimeZoneChangedReceiver()
NetworkChangedReceiver mNetworkChangedReceiver = new NetworkChangedReceiver()
public void onCreate()
{
registerReceiver(mLocationTimeZoneChangedReceiver, new IntentFilter(Intent.ACTION_LOCALE_CHANGED));
registerReceiver(mLocationTimeZoneChangedReceiver, new IntentFilter(Intent.ACTION_TIMEZONE_CHANGED));
registerReceiver(mNetworkChangedReceiver, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
}
}
BootCompletedReceiver:
public class BootCompletedReceiver extends BroadcastReceiver
{
public void onReceive(Context context, Intent intent){}
}
MyApplication:
public class MyApplication extends Application
{
ServiceConnection mServiceConnection = new ServiceConnection() { anonymous class...}
public void onCreate()
{
bindService(new Intent(this, MyService.class), mServiceConnection,Context.BIND_AUTO_CREATE);
}
}
Edited:
Edited code for Plinio.Santos.
It's a big app with many moving parts so at best I can post small code snippets.
Following are the steps I am following for testing:
Push app via Eclipse,
test that network change receiver is working
leave wifi off
Now restart the device
wait for the process to start and turn on wifi.
I believe that the service is not started or bound due errors. Unfortunately I can not say it for sure without all binding/starting code.
Anyway, you can see bellow a code that worked fine after I rebooted (the app started, registered the receiver and is receiving the CONNECTIVITY_CHANGED broadcast.
AndroidManifest.xml:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<receiver android:name=".TestReceiver" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<service
android:name=".TestService"
android:exported="true" />
Receiver class:
public class TestReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent != null && Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
Toast.makeText(context, "Intent.ACTION_BOOT_COMPLETED receiverd !", Toast.LENGTH_SHORT).show();
context.startService(new Intent(context, TestService.class));
}
}
}
Service class:
public class TestService extends Service {
private BroadcastReceiver mConnectivityChangedReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (intent != null && ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) {
Toast.makeText(context, "ConnectivityManager.CONNECTIVITY_ACTION receiverd !", Toast.LENGTH_SHORT).show();
}
}
};
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
registerReceiver(mConnectivityChangedReceiver, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
}
}
I'm trying to turn WiFi off when the screen is OFF (locked), and turn it on again when screen is ON (unlocked).
I made a BroadcastReceiver; put in manifest this code:
<receiver android:name="MyIntentReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.SCREEN_OFF" />
<action android:name="android.intent.action.SCREEN_ON" />
<action android:name="android.intent.action.USER_PRESENT" />
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</receiver>
and this is the class MyIntentReceiver:
package org.androidpeople.boot;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class MyIntentReceiver extends BroadcastReceiver {
// Called when boot completes
public static boolean startup;
#Override
public void onReceive(Context context, Intent intent) {
// Set what activity should launch after boot completes
System.out.println("Intent Action: " + intent.getAction());
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
System.out.println("locked : ACTION_SCREEN_OFF");
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
System.out.println("not locked : ACTION_SCREEN_ON ");
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
System.out.println("User Unlocking it ");
}
else if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
// this to indicate that program is running
// automaticlly not manually by user
startup = true;
System.out.println("Automatic BOOT at StartUp");
Intent startupBootIntent = new Intent(context, LaunchActivity.class);
startupBootIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(startupBootIntent);
}
}
}
And the result is - both ACTION_SCREEN_ON
and ACTION_SCREEN_OFF never fired!
USER_PRESENT and BOOT_COMPLETED worked fine but the other did not. I'm using an emulator, not a real device - can this cause the problem?
Any help?
I need to catch the screen on and off in order to enable/disable WiFi
to save battery.
Thanks in advance
To capture the SCREEN_OFF and SCREEN_ON actions (and maybe others) you have to configure the BroadcastReceiver by code, not through the manifest.
IntentFilter intentFilter = new IntentFilter(Intent.ACTION_SCREEN_ON);
intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
BroadcastReceiver mReceiver = new ScreenStateBroadcastReceiver();
registerReceiver(mReceiver, intentFilter);
It's tested and works right.
You cannot catch those intents through XML (I forget why). However, you could use a Service that registers a BroadcastReceiver member in its onStartCommand() and unregisters it in its onDestroy(). This would require the service to be running in the background, constantly or as long as you need it to, so be sure to explore alternative routes.
You could define the BroadcastReceiver in your Service class like so:
private final class ScreenReceiver extends BroadcastReceiver {
#Override
public void onReceive(final Context context, final Intent intent) {
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
//stuff
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
//other stuff
}
}
}
For a slightly complicated example, but one that shows how the BroadcastReceiver and Service interact see CheckForScreenBugAccelerometerService from my app, ElectricSleep.
Is that possible that my android app receive a broadcast while my network provider changed?
thanks in advance.
Yes.It is posible to find this.
see the code
public class NetworkStateReceiver extends BroadcastReceiver {
public static final String TAG = "NetworkReceiver";
#Override
public void onReceive(Context context, Intent intent) {
boolean isNetworkDown = intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false); // 2
if (isNetworkDown) {
Log.d(TAG, "onReceive: NOT connected, stopping UpdaterService");
}
else
{
Log.d(TAG, "onReceive: connected, starting UpdaterService");
}
}
In the Manifes file add this code
<receiver android:name="NetworkStateReceiver" android:enabled="true">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>