Canceling broadcast receiver on phone reboot. - android

I have BroadcastReceiver (NetworkListener).
public class NetworkReceiver extends BroadcastReceiver {
Context context;
public static NetworkReceiver instance = new NetworkReceiver();
public static InnerObservable observable = instance. new InnerObservable();
...
This receiver sends notifications:
#Override
public void onReceive(Context ctx, Intent intent) {
Log.d("tag", "onReceive");
NotificationManager notif = (NotificationManager) ctx.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new Notification(android.R.drawable.ic_dialog_alert,"bla-bla-bla",System.currentTimeMillis());
Manifest file:
<receiver
android:name="com.mypckg.network.NetworkReceiver" >
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>
It works fine. But after phone reboot, it continues to work. how to avoid it?

If you want your broadcast receiver to start working when application gets launched then you should register/unregister it programatically from your main activity:
private BroadcastReceiver networkReceiver;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
networkReceiver = new NetworkReceiver();
registerReceiver(networkReceiver, ConnectivityManager.CONNECTIVITY_ACTION);
}
#Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(networkReceiver)
}

You can mess around with the PackageManager to disable a BroadcastReceiver registered in your manifest, check this thread for code.
Another solution would be to register this receiver dynamically, possibly in a service. The receiver would be active and registered as long as the service is alive, so you could easily toggle the receiver by starting/stopping the service. This might not fit you use case however, you didn't provide much detail on that.

Related

Ways to registering broadcast receiver

in the project that I got to work on there's a use of Broadcast receivers. Now, those receivers are registered in the Manifest and also there's this method:
private static void enableComponent(Context context, Class<?> component) {
ComponentName connectionReceiverComponent = new ComponentName(context, component);
context.getPackageManager().setComponentEnabledSetting(connectionReceiverComponent, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);
}
I'm a bit confused about it, because since Android 8 we can't register receivers in the Manifest anymore, instead we have to use runtime registration, using context.registerReceiver(), thus it is not necessary even to put the receivers in the Manifest. And yet, the registration that uses ComponentName still works on Android 8 and Android 9.
Can you please explain what's difference between those two methods, and why it works and Android 8 and beyond?
In Activity you can register like this.
private BroadcastReceiver receiver;
#Override
public void onCreate(Bundle savedInstanceState){
IntentFilter filter = new IntentFilter();
filter.addAction("SOME_ACTION");
receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
//do something based on the intent's action
}
};
registerReceiver(receiver, filter);
}
Or in your ActivityManifest
<receiver
android:name=".ConnectivityBroadcastReceiver">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>

I cannot keep the broadcast receiver running after the application is closed

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

BroadcastReceiver doesn't work after app stops

I have a foreground service uploading images and broadcasting status using intent with action "myAction".
My app needs to react on the broadcast, like send a server request after receiving success message or pop up a notification after receiving failure message. I'm following this https://developer.android.com/training/run-background-service/report-status.html
Sending an broadcast Intent doesn't start or resume an Activity. The
BroadcastReceiver for an Activity receives and processes Intent
objects even when your app is in the background, but doesn't force
your app to the foreground. If you want to notify the user about an
event that happened in the background while your app was not visible,
use a Notification. Never start an Activity in response to an incoming
broadcast Intent.
I first try to register my broadcast receiver statically in Manifest. It doesn't work. Then, I follow this instruction, Keep broadcast receiver running after application is closed, to start a service to register my broadcast receiver. Both don't work(no log shows) when I swipe out or close the app.To be specific, I can see "HAHAHAHA" and "HEHEHEHE" logs come out when is in the foreground. It doesn't come out once I swipe it out from app lists or click back to exit the app.
Here is my code. Where do I miss?
In my manifest
<application...>
<receiver android:name=".MyBroadcastReceiver"
android:enabled="true"
android:exported="false">
<intent-filter android:priority="0">
<action android:name="myAction"/>
</intent-filter>
</receiver>
<service
android:name=".MyService"
android:exported="false"/>
</application>
MyBroadcastReceive.java
public class MyBroadcastReceiver extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
Log.d("HAHAHAHA", "Broadcast received.");
}
}
MyService.java
public class MyService extends Service {
BroadcastReceiver mReceiver;
// use this as an inner class like here or as a top-level class
public class MyReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// do something
Log.d("HEHEHEHE", "Broadcast received.");
}
}
#Override
public void onCreate() {
// get an instance of the receiver in your service
IntentFilter filter = new IntentFilter();
filter.addAction("myAction");
mReceiver = new MyReceiver();
registerReceiver(mReceiver, filter);
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onDestroy() {
Log.d("HEHEHEHE", "onDestroy");
super.onDestroy();
}
}
MainActivity.java
onStart() {
Intent intent = new Intent(this, MyService.class);
startService(intent);
}
Broadcast is called like below:
LocalBroadcastManager.getInstance(service).sendBroadcast(intent);
I first try to register my broadcast receiver statically in Manifest. It doesn't work.
You cannot use manifest-registered receivers with LocalBroadcastManager. Only receivers registered via LocalBroadcastManager.getInstance().registerReceiver() will respond to local broadcasts.
My app needs to react on the broadcast, like send a server request after receiving success message or pop up a notification after receiving failure message.
Get rid of the broadcast and do that work in the service.

Android BroadcastReceiver unable to receive Screen_On and Screen_Off broadcasts

I am trying to get my BroadcastReceiver, created inside of a service, to receive Screen_On and Screen_Off events. It is not working, here is what I am trying right now.
//OnCreate Method for the service
#Override
public void onCreate() {
super.onCreate();
myBroadcast = new MyBroadcastReceiver();
IntentFilter screenOn_Off = new IntentFilter();
screenOn_Off.addAction(Intent.ACTION_SCREEN_OFF);
screenOn_Off.addAction(Intent.ACTION_SCREEN_ON);
registerReceiver(myBroadcast, screenOn_Off);
}
//Inner class for the broadcast receiver, also in the service.
public class MyBroadcastReceiver extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
Log.d("Broadcast received", "Broadcast received");
if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)){
startTimers();
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)){
screenLocked();
}
}
};
//Declaration of receiver in manifest.
<receiver
android:name="com.bla.bla.bla$MyBroadcastReceiver"
android:enabled="true">
</receiver>
I purposely did not include the intent filters for the screen_on and off because I read that those must be declared programmatically, including them made not difference.

Unregister Receiver is it necessary?

I have an alarm manager whose receiver I had registered in my code. The whole point of having an alarm manager in case of Timer is that it should run in background when in Pause state. Now, do I unregister it in onPause() or in OnDestroy() and will it still run in background and wake up and the receiver would receive it?
EDIT:
#Override
public void onReceive(Context context, Intent intent) {
Intent i = new Intent(context, MyClass.class);
i.putExtra("fromReciever", true);
startActivity(i);
}
I would suggest that you register it in your AndroidManifest.xml file. Example:
<receiver android:name="com.example.android.MyReceiver" >
<intent-filter>
<action android:name="com.example.android.USER_ACTION" />
</intent-filter>
</receiver>
This will keep your receiver registered as long as the application is installed on your device. All you have to do is implement it:
public class MyReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "Intent Detected.", Toast.LENGTH_LONG).show();
}
}
And you are set.
Additionally, you can check out this tutorial for more information.
Added
If you want to resume your Activity you can add this code in your Receiver onReceive method.
Intent intent = new Intent(this, YourActivity.class);
intent.putExtra("fromOnReceive", true);
context.startActivity(intent);
Then, in your Activity onCreate method, you check if it was called from your Receiver
#Override
protected void onCreate(Bundle savedInstanceState) {
if(getIntent().hasExtras()){
boolean fromReceiver = getIntent().getExtras().getBoolean("fromOnReceive");
if(fromReceiver)
//Do work
}
}

Categories

Resources