Implicit Broadcast Reciever isn't calling - android

I searched the web for alot of time and I don't understand why my custom broadcast
isn't working.
<receiver
android:name=".myservice.MyReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.ACTION_POWER_CONNECTED" />
<action android:name="android.intent.action.ACTION_POWER_DISCONNECTED" />
<action android:name="android.intent.action.BATTERY_CHANGED"/>
<action android:name="android.intent.action.SCREEN_ON" />
<action android:name="android.intent.action.SCREEN_OFF" />
</intent-filter>
</receiver>
I don't it not recieve when I reconnet and disconnect the charger.
I did this for making thing simpale
public class MyReceiver extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
Toast.makeText(context,"Battery", Toast.LENGTH_SHORT).show();
Log.i("Recive", "Yes");
}
}

From docs:
ACTION_BATTERY_CHANGED
Broadcast Action: This is a sticky broadcast containing the charging state, level, and other information about the battery. See BatteryManager for documentation on the contents of the Intent.
You cannot receive this through components declared in manifests, only by explicitly registering for it with Context.registerReceiver(). See ACTION_BATTERY_LOW, ACTION_BATTERY_OKAY, ACTION_POWER_CONNECTED, and ACTION_POWER_DISCONNECTED for distinct battery-related broadcasts that are sent and can be received through manifest receivers
So, you cannot use this BroadcastReceiver decalred in Manifest, only registering explicitly from your context.
Also, your power connection BroadcastReceiver seems correct. Try to separate it into another BroadcastReceiver, maybe action ACTION_BATTERY_CHANGED is interfering with other actions.
This is my declared BroadcastReceiver which I use and it's working in my app.
<receiver android:name=".PowerConnectionBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.ACTION_POWER_CONNECTED"/>
<action android:name="android.intent.action.ACTION_POWER_DISCONNECTED"/>
</intent-filter>
</receiver>
PowerConnectionBroadcastReceiver
public class PowerConnectionBroadcastReceiver extends BroadcastReceiver {
private static final String TAG = "PowerRcvr";
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals(Intent.ACTION_POWER_CONNECTED)) {
Log.d(TAG, "Device is charging");
} else if (action.equals(Intent.ACTION_POWER_DISCONNECTED)) {
Log.d(TAG, "Device is NOT charging");
} else {
Log.d(TAG, "Unable to check if device is charging or not");
}
}
}
NOTE: This code is working on Android 8 with targetSdkVersion 25 or lower.
In targetSdkVersion 26 or higher most of BroadcastReceivers doesn't work through Manifest due to background limitations. Here are documentation (thanks to Pawel) about that. So your IntentFilters wont work. To keep it working you can download your targetSdkVersion to 25 or lower.

Related

How to make a screen not fall asleep if the app runs on boot?

I have the app which must start on device' boot. It works well but the problem is that when the app finishes booting, the screen is already dark. How can I make it not fall asleep?
My Receiver:
<receiver
android:enabled="true"
android:exported="true"
android:name=".view.receivers.BootReceiver"
android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
public class BootReceiver extends BroadcastReceiver {
private final static String LOG_TAG = BootReceiver.class.getSimpleName();
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
Log.i(LOG_TAG, "Loading after booting...");
Intent startCalendarActivityIntent = new Intent(context, CalendarActivity.class);
startCalendarActivityIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(startCalendarActivityIntent);
} else {
Log.e(LOG_TAG, "Error while restarting after boot.");
}
}
}
On this device is Android 6.0 .
You can either use wakelocks, which need certain permissions, or you can put a flag in your onCreate method, which according to the docs does not require a permission.
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
The wakelock documentation gave the example above.

BroadcastReceiver doesn't work accurately unless registered Manually

To put it simply; BroadcastReceiver Works when defined in Manifest but it works with a short Delay and it doesn't Always trigger unless Registered Manually.
Here is the BroadcastReceiver I created to capture event when date changes (day is passed):
public class BootBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, intent.getAction(), Toast.LENGTH_LONG).show();
switch (intent.getAction()){
case Intent.ACTION_TIME_TICK:
case Intent.ACTION_TIME_CHANGED:
case Intent.ACTION_TIMEZONE_CHANGED:
case Intent.ACTION_DATE_CHANGED:
case Intent.ACTION_BOOT_COMPLETED:
Log.d("BroadcastReceiver", intent.getAction().toString());
}
}
}
Here registered in Manifest, It works but has a short delay and also doesn't always trigger:
<receiver android:name=".Receivers.BootBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.TIME_TICK" />
<action android:name="android.intent.action.TIME_SET" />
<action android:name="android.intent.action.TIMEZONE_CHANGED" />
<action android:name="android.intent.action.DATE_CHANGED"/>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
But when registered manually via my background service it works just fine:
public class ApplicationService extends Service{
...
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(Intent.ACTION_DATE_CHANGED);
intentFilter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
intentFilter.addAction(Intent.ACTION_TIME_CHANGED);
intentFilter.addAction(Intent.ACTION_TIME_TICK);
registerReceiver(new BootBroadcastReceiver(), intentFilter);
return START_STICKY;
}
}
To investigate this issue further I created two similar app which in one BroadcastReceiver registered in Manifest and in the other one receiver is registered Manually via Service.
In the Manifest one all events are triggered few second after Manual one..
Try this :
<receiver android:name=".Receivers.BootBroadcastReceiver">
<intent-filter
android:enabled="true"
android:exported="true">
<action android:name="android.intent.action.TIME_TICK" />
<action android:name="android.intent.action.TIME_SET" />
<action android:name="android.intent.action.TIMEZONE_CHANGED" />
<action android:name="android.intent.action.DATE_CHANGED"/>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
I guess you can have multiple each one having its action.
https://developer.android.com/guide/components/intents-filters.html
The documentation says that "An app component should declare separate filters for each unique job it can do." This would allow finer grained detail for different actions
The answer was hidden in Intent documentation:
ACTION_TIME_TICK Added in API level 1
public static final String ACTION_TIME_TICK
Broadcast Action: The current time has changed. Sent every minute. You
cannot receive this through components declared in manifests, only by
explicitly registering for it with
Context#registerReceiver(BroadcastReceiver, IntentFilter).
To simply put, you can't receive TIME_TICK through registering the BroadcastReceiver in manifest, it has to be registered in your application components (Service, Activity, etc.)
Define a BootBroadcastReceiver anywhere in Activity/Fragment like this:
mBootBroadcastReceiver = new BootBroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG," BootBroadcastReceiver"); //do something with intent
}
};
mIntentFilter=new IntentFilter("action_name");
Now register the BootBroadcastReceiver in onResume() and Unregister in onPause()
#Override
protected void onResume() {
super.onResume();
registerReceiver(mBootBroadcastReceiver, mIntentFilter);
}
#Override
protected void onPause() {
if(mReceiver != null) {
unregisterReceiver(mBootBroadcastReceiver);
mBootBroadcastReceiver = null;
}
super.onPause();
}
add permission in your Manifest.
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="ANDROID.PERMISSION.RECEIVE_SMS" />
<uses-permission android:name="android.permission.READ_SMS" />

Android: How to detect if a broadcaster application is deleted?

I have 2 applications. One of them is doing broadcast custom strings continously and the other one is receiving. I have to be notified and delete some datas in the reciever application when the broadcaster application is deleted. Is there a method like onDelete() or something like that? How can I do this?
Yeah! There's an intent called ACTION_PACKAGE_REMOVED that you can listen for.
Add this inside <application> in your manifest: (don't forget to change the package name)
<receiver android:name="com.arjnklc.receiverapp.UninstallReceiver">
<intent-filter>
<action android:name="android.intent.action.PACKAGE_REMOVED"/>
<data android:scheme="package" />
</intent-filter>
</receiver>
Then you need to create the class mentioned above.
public class UninstallReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if(intent.getData().getSchemeSpecificPart() == "com.arjnklc.broadcasterapp")
cleanUpEverything();
}
}
Not exactly sure when you want to do but from what I understand, you want your second application to know when the first application is deleted?
If that's the case, do this:
In AndroidManifest.xml, you MUST have a new BroadcastReceiver because this receiver used a different data scheme:
<receiver
android:name=".PackageReceiver"
android:enabled="true"
android:exported="false">
<intent-filter>
<action android:name="android.intent.action.PACKAGE_ADDED" />
<data android:scheme="package" />
</intent-filter>
</receiver>
Then your BroadcastReceiver:
public class PackageReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals(Intent.ACTION_PACKAGE_REMOVED)) {
Log.d(TAG, "ACTION_PACKAGE_REMOVED");
String data = intent.getData().toString();
// data string has the package name
// if that is your package name, your first app was uninstalled
}
}
}
Just make sure, it's a separate BroadcastReceiver. It can not be combined with any other Receiver or the other actions will stop working.
Hope this works.

Are two Broadcast Receivers (one Alarm Manager and another for System Events) required?

I am calling the following BroadcastReceiver using AlarmManager every X mins. Its working fine.
public class MyAlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (CommonFuncs.isConnectedBySettings(context)) {
if(CommonFuncs.isUpdateTimeValid(context)){
Intent intentCurSvc = new Intent(context, CurrencySvc.class);
context.startService(intentCurSvc);
}
}
}
Manifest
<receiver
android:name=".service.AlarmSvcRecevier"
android:process=":remote" >
</receiver>
I want to use the same BroadcastReceiver for connectivity change as well, by just adding the following manifest.
<receiver
android:name=".service.AlarmSvcRecevier"
android:process=":remote" >
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>
But my receiver is not getting called when WIFI is connected. I am not sure what is the problem. Do I need a separate receiver for AlarmManager and CONNECTIVITY_CHANGE to perform same operation? Is my approach correct?

BOOT_COMPLETE and ACTION_SHUTDOWN never call the BroadcastReceiver

I want to catch ACTION_SHUTDOWN and BOOT_COMPLETE using BroadcastReceiver.
But it turns out both signals never trigger the BroadcastReceiver (I didn't see any log on logcat).
Here is my source code.
I give the permission on Manifest
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
and I try to register the BroadcastReceiver in both ways
protected void onCreate(Bundle savedInstanceState)
{
registerReceiver(BootReceiver, new IntentFilter(Intent.ACTION_BOOT_COMPLETED));
registerReceiver(ShutDownReceiver, new IntentFilter(Intent.ACTION_SHUTDOWN));
}
<receiver android:name=".BootReceiver"
android:permission="android.permission.RECEIVE_BOOT_COMPLETED" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
and the source code for BootReceiver and ShutDownReceiver are as
private BroadcastReceiver BootReceiver = new BroadcastReceiver()
{
private String ACTION_BOOT = "android.intent.action.BOOT_COMPLETED";
#Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals(ACTION_BOOT)){
//my stuff
Log.d("Power", "Boot Complete");
}
}
};
private BroadcastReceiver ShutDownReceiver = new BroadcastReceiver()
{
private String ACTION_SHUTDOWN = "android.intent.action.ACTION_SHUTDOWN";
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(ACTION_SHUTDOWN)) {
//my stuff
Log.d("Power", "Shutdown Complete");
}
}
};
also, I unregister both BoradcastReceiver in onDestroy
public void onDestroy()
{
unregisterReceiver(BootReceiver);
unregisterReceiver(ShutDownReceiver);
super.onDestroy();
}
Does anyone know what's wrong with my code?
Or anything I miss? Thank you.
I found out why it didn't work.
Since I use a HTC device, the broadcast messages are different from others.
Shut down event broadcasts "com.htc.intent.action.QUICKBOOT_POWEROFF"
Restart(reboot) event broadcasts "android.intent.action.ACTION_SHUTDOWN"
Power on event broadcasts "com.htc.intent.action.QUICKBOOT_POWERON"
In other device, when shutting down the device, it might broadcast "android.intent.action.QUICKBOOT_POWEROFF".
Chances are that your application is not yet added to the "BOOT_COMPLETED" possible receivers list, starting from Android 3.1, in order to get the "BOOT_COMPLETED" action, your application must have been started explicitly by the user, either showing an Activity or another Component, until then your application will not receive the broadcast you are expecting, is important to know that if you "Force Close" the application, it will be missing the broadcasts again, So, try to open an activity and then reboot your device, you will get it...
Hope this Helps!
Regards!
Try this.
<receiver
android:name="packagename.GPSReceiver"
android:enabled="true"
android:permission="android.permission.RECEIVE_BOOT_COMPLETED" >
<intent-filter android:priority="500" >
<action android:name="android.intent.action.BOOT_COMPLETED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
BOOT_COMPLETED must be registered in the manifest. You cannot register for it via registerReceiver(), because by the time you call registerReceiver(), the boot will have long since occurred.
AFAIK the shutdown broadcast works with registerReceiver(), though in your case it will only be around when your process is running.

Categories

Resources