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
Related
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...
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 want to capture the network connection type change in Android Service and run a code of this Service when the event fires. How to do that inside a Service class only without separate class? I have this code, but it doesn't work.
BroadcastReceiver networkStateReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
playlist="NETWORK TYPE CHANGED";
}
};
public void playSong(Context c, String url) {
try
{
IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
registerReceiver(networkStateReceiver, filter);
Your BroadcastReceiver needs to receive the Intent from the system, so you need to register your BroadcastReceiver in your AndroidManifest
<receiver
android:name=".ConnectivityReceiver
android:exported="false" >
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>
and do not forget the permission
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
I want to implement a minimal screen activity logger app. So, the application should run on the background (no user interaction) and it will log the screen on and off activities. I have started these codes, but it seems that I need to register my ScreenBroadcastReceiver broadcastreceiver. If I do it with the below code in main activity, it works. However, I do not want to register it in main because the user cannot launch the activity every time. So, where should i register my BroadcastReceiver so that the application works without user interaction?
oncreate in main activity
//I need to find another place to put these code, Where ???
//IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
//filter.addAction(Intent.ACTION_SCREEN_OFF);
//BroadcastReceiver screenOnReceiver = new ScreenBroadcastReceiver();
//registerReceiver(screenOnReceiver, filter);
This is ScreenBroadcastReceiver, it will be triggered when the screen is on.
public class ScreenBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
Log.w("OnReceive", "SCREEN IS ON");
}
}
}
This is the BootReceiver to run the program on the background itself.
public class BootReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent service = new Intent(context, ScreenListenerService.class);
context.startService(service);
//IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
//filter.addAction(Intent.ACTION_SCREEN_OFF);
//BroadcastReceiver screenOnReceiver = new ScreenBroadcastReceiver();
//context.registerReceiver(screenOnReceiver, filter);
}
}
This is the manifest:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<service android:name=".ScreenListenerService"></service>
<receiver android:name=".BootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
Update:
I added a service, but it does not work. Did i forget to add something? or what ?
public class ScreenListenerService extends Service {
public void OnCreate(){
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
BroadcastReceiver screenOnReceiver = new ScreenBroadcastReceiver();
registerReceiver(screenOnReceiver, filter);
}
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
}
use Service for your purpose and do the same as you did in the activity.
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.