As per the Android O developer preview, we can no longer use the PACKAGE_REPLACED intent to use with a receiver declared inside the manifest.
The alternative is MY_PACKAGE_REPLACED. But this intent does not seem to fire when i update the app via android studio after code changes. Whereas the old broader intent always fired properly.
<receiver
android:name=".Receivers.BootEventReceiver"
android:exported="true"
android:enabled="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
</intent-filter>
</receiver>
assume that the receiver itself just prints a log message in onReceive().
Googling suggested this seems to be some android manifest merger issue. But i really couldn't follow how to solve this.
Can someone point me in the right direction
Instead of having one receiver with two intent filters, i decided to make a separate receiver with MY_PACKAGE_REPLACED intent filter.
The receiver started working again. Hope this helps anyone interested
Related
According to the migration guide to Android O given by Google, most of the implicit broadcast intent should not be registered in the Manifest (minus a few exceptions found here) but explicit broadcast intents remain untouched.
We are looking to move any needed broadcast away from the manifest. But how do we recognise if a receiver is implicit? Is there a general rule?
Here is a sample of the broadcasts we register in the manifest. Should we look only at the "action" tag and see if it is whitelisted to keep it in the manifest?
<receiver
android:name=".receiver.ImageBroadcastReceiver"
android:enabled="true" >
<intent-filter>
<action android:name="android.hardware.action.NEW_PICTURE" />
<category android:name="android.intent.category.OPENABLE" />
<data android:mimeType="image/*" />
</intent-filter>
</receiver>
<receiver
android:name=".receiver.InstallReferrerReceiver"
android:exported="true">
<intent-filter>
<action android:name="com.android.vending.INSTALL_REFERRER" />
</intent-filter>
</receiver>
<receiver android:name=".receiver.JoinEventReceiver" >
<intent-filter>
<action android:name="JOIN_ACTION" />
<action android:name="CANCEL_ACTION" />
<action android:name="DECLINE_ACTION" />
</intent-filter>
</receiver>
For example, the "com.android.vending.INSTALL_REFERRER" intent is not whitelisted. Should we register it in an Activity? If so wouldn't it be never fired as when we register it the app is already installed? This is what confuses me when trying to understand if a broadcast receiver is implicit or explicit as I thought I only had to check that "action" tag.
But how do we recognise if a receiver is implicit?
If the Intent has a ComponentName, the Intent is explicit. Otherwise, it is implicit.
That ComponentName can be obtained in one of a few ways, including:
It can be directly put on the Intent (e.g., new Intent(this, TheReallyAwesomeReceiver.class)
It can be directly put on the Intent after using PackageManager and queryIntentReceivers() to find the right one based on action strings, etc.
It can be derived by the system from the action string, etc. plus the package defined via setPackage()
Should we look only at the "action" tag and see if it is whitelisted to keep it in the manifest?
No. You also need to think about the nature of the broadcast: is it going to any registered receiver, or only to a specific app?
For example, the "com.android.vending.INSTALL_REFERRER" intent is not whitelisted. Should we register it in an Activity?
No. That broadcast will only go to the app that was recently installed, and so it must be an explicit Intent. The action string and such are there to help the system determine which of your registered receivers is the relevant one.
Contrast that with ACTION_PACKAGE_ADDED. That is broadcast to any registered receiver; it is not going to just one specific app. Hence, that Intent must be implicit (as otherwise it would have a ComponentName identifying a specific receiver in a specific app). And, since ACTION_PACKAGE_ADDED is not on the whitelist, the assumption should be that you cannot register for this broadcast in the manifest on Android 8.0+.
i have been trying to overcome issue of Boot_complete receiver not working in certain devices.
Like Vivo device which have iManager app with auto-start manager.
Where user can toggle app from auto start on device boot.
What should i use along with below as intent-filter to restart my service after device reboot.
Earlier thought of using Battery_Change receiver but it won't work from manifest, as i has to be runtime receiver register.
Any suggestion would be really help-full.
Below is what i have used as intent-filter for my app. In most devices its working as expected. But not in all.
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
<action android:name="android.intent.action.REBOOT" />
</intent-filter>
There is one thing my team and I discovered when facing a similar issue.
You can monitor the usb state like so:
<receiver
android:name=".MyReceiver"
android:enabled="true">
<intent-filter>
<action android:name="android.hardware.usb.action.USB_STATE" />
</intent-filter>
</receiver>
And if memory serves me right, this will send a broadcast before the regular BOOT_COMPLETED action telling you there is or isn't anything USB connected.
Some manufacturers use their own version of BOOT_COMPLETED as you can read here but the USB_STATE is an alternative, based on the things you want to do. Do note you can get multiple broadcasts using this method!
Alternatively you could look into using an AccessibilityService or the JobService from the firebase sdk. More details here.
I am working on an app which will be pre-installed in the android device and i want to trigger it in background when end user actually start using its smart phone from the very first time. So is there any broadcast fired for this purpose or any other possible way to do this?
I've used a BroadcastReceiver to accomplish the running something on start, and as for knowing if it's the first time, you could use a shared preference for the app to track it's status of first time or not with a boolean.
Define a BroadcastReceiver the receiver will need the following in the manifest:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<receiver
android:name="com.androidfactorem.airwaves.BootAirWaveService"
android:enabled="true"
android:permission="android.permission.RECEIVE_BOOT_COMPLETED" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
You can see a full implementation of a BroadcastReceiver on boot in my git project https://github.com/pbirdsall/airwave
I was wondering if it is possible to find a list that includes all the receivers associated to a certain action.
For example I have the following receiver that executes everytime that an SMS is received:
<receiver android:name=".SmsReceiver" android:enabled="true">
<intent-filter android:priority="101">
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
So with the priority="101" it´s executed even before than the default message service in Android.
I would like to find all the intent-filter associated to a certail action, in this case "android.provider.Telephony.SMS_RECEIVED"
I tried to get into /data/data/com.android.provider.telephony/databases but no info is stored in ther.
It would be great if anybody could tell me where can I find that info, and even if it is possible.
Regards,
Pablo
Use PackageManager and queryBroadcastReceivers() to find out all of the BroadcastReceivers that will respond to a given Intent. In your case, you would create an SMS_RECEIVED Intent.
I would like my app to do something when another application is opened.
The current approach I have taken is to create a broadcast receiver that monitors all
android.intent.action.MAIN
events, but either I am not doing it correctly or the way I am going about it is incorrect. The section of the manifest looks like this:
<receiver android:name=".GetApp">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</receiver>
I included the launcher category just as a test. GetApp currently is only set to make a log entry when called.
If anyone has any experience doing something like this your help would be greatly appreciated!
After doing some more digging in the Android documentation I found that a broadcast receiver would not pick up on an app starting because it goes through createActivity(). Calls to createActivity() are not considered broadcasts and therefore cannot be received by broadcast receiver.