I am having problem receiving broadcast sent from android library module in app module.
I create an explicit broadcast with action and component name. And send this broadcast from android lib module.
val intent = Intent()
intent.action = "com.example.action.SOME_ACTION"
intent.component = ComponentName("com.example", "com.example.MyReceiver")
sendBroadcast(intent)
To receive this broadcast, I created a receiver and registered it in manifest.
<receiver
android:name=".MyReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.example.action.SOME_ACTION" />
</intent-filter>
</receiver>
This receiver prints received event, but unfortunately, I am not receiving any broadcast. Am I missing anything? Or is it supposed to be this way, i.e. You cannot receive broadcast sent from the library?
try to do like this, this is working for me
register receiver where you want to receive using this code
IntentFilter filter = new IntentFilter();
filter.addAction("myCustomAction");
registerReceiver(receiver, filter);
send a broadcast from different lib like this
Intent intent = new Intent("myCustomAction");
intent.putExtra("value", 0);
intent.setComponent(null);
context.sendBroadcast(intent);
now no need to register a receiver in AndroidManifest.xml
set ComponentName to null because ComponentName is
The name of the application component to handle the
intent, or null to let the system find one for you.
Related
I have a custom button in a sticky notification.
I used to attach a PendingIntent to it for receiving button clicks:
Intent intent = new Intent();
intent.setAction("com.example.app.intent.action.BUTTON_CLICK");
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 2000, intent, PendingIntent.FLAG_UPDATE_CURRENT);
contentViewExpanded.setOnClickPendingIntent(R.id.button, pendingIntent);
When i run this code on Oreo , i get BroadcastQueue: Background execution not allowed in logcat and don't receive button click.
I registered receiver with manifest:
<receiver
android:name=".BroadcastReceiver.NotificationActionReceiver"
android:enabled="true"
android:exported="false">
<intent-filter>
<action android:name="com.example.app.intent.action.BUTTON_CLICK"/>
</intent-filter>
</receiver>
I also tried registering receiver in my code:
NotificationActionReceiver mMyBroadcastReceiver = new NotificationActionReceiver();
IntentFilter filter = new IntentFilter("com.example.app.intent.action.BUTTON_CLICK");
mContext.registerReceiver(mMyBroadcastReceiver, filter);
This works but only when the app is visible to user.
Thanks for help
Never use an implicit Intent when an explicit Intent will work.
Replace:
Intent intent = new Intent();
intent.setAction("com.example.app.intent.action.BUTTON_CLICK");
with:
Intent intent = new Intent(this, NotificationActionReceiver.class);
And remove the <intent-filter> from the NotificationActionReceiver <receiver> element.
I ran into this issue as well on Android 8 - Oreo, but given my library project requirements, I don't have the explicitly named BroadcastReceiver class implementation, that the end-client will declare in it's AndroidManifest.
Solution:
Specify the application package on the Intent using setPackage(String).
Example:
// Application unique intent action String
final String receiverAction = getApplicationContext().getPackageName()
+ BaseLibraryReceiver.ACTION_SUFFIX;
// No need for Class definition in the constructor.
Intent intent = new Intent();
// Set the unique action.
intent.setAction(receiverAction);
// Set the application package name on the Intent, so only the application
// will have this Intent broadcasted, thus making it “explicit" and secure.
intent.setPackage(getApplicationContext().getPackageName());
...
From the Android Broadcasts: Security considerations and best practices docs.
In Android 4.0 and higher, you can specify a package with
setPackage(String) when sending a broadcast. The system restricts the
broadcast to the set of apps that match the package.
Here’s an example of the BroadcastReceiver declared (or merged) in to the end-client application’s AndroidManifest:
<receiver
android:name=“com.subclassed.receiver.ReceiverExtendedFromLibrary"
android:exported="false"
android:enabled="true">
<intent-filter>
<action android:name="${applicationId}.action.MY_UNIQUE_ACTION"/>
</intent-filter>
</receiver>
Since my example revolves around a library project that broadcasts an Intent, I’ve decided to keep the <intent-filter> and <action /> in the <receiver> declaration. Otherwise, there would be non-unique broadcast actions being fired, which could lead to potential issues where multiple applications receive the wrong broadcast. This is mostly a safety precaution. Of course you still need to check the action in the implementation of the BroadcastReceiver.
Hope someone finds this helpful!
I have a BroadcastReceiver and a Service in my application. I am receiving the action information in the service from an activity. I have to register this action dynamically with the receiver. I have a few actions defined in the AndroidManifest.xml, but this action has to be defined dynamically. Can someone please help me with this?
Thanks.
P.S. A sample receiver tag from the AndroidManifest.xml. BOOT_COMPLETED is one of the actions I am referring to. I am receiving this information in this service.
<receiver android:name="com.test.TestReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
You can use this:
IntentFilter intentFilter = new IntentFilter("android.intent.action.BOOT_COMPLETED");
YourReceiver receiver = new YourReceiver();
LocalBroadcastManager mBroadcastMgr = LocalBroadcastManager
.getInstance(getApplicationContext());
mBroadcastMgr.registerReceiver(receiver, intentFilter);
I'm trying to set up one class for receiving sms and sent status.
This is how my manifest looks for this task:
<receiver android:name=".SmsListener" android:permission="android.permission.BROADCAST_SMS" android:exported="true">
<intent-filter android:priority="5822">
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
<action android:name="android.provider.Telephony.SMS_SENT" />
</intent-filter>
</receiver>
I get received messages, but don't get SENT messages, is something wrong with my Manifest declarations?
PendingIntent _pendingIntent;
Intent _intent = new Intent();
_intent.setClass(ParkingOptionsActivity.this, SmsListener.class); // SmsListener extends BroadcastReceiver
_intent.putExtra("test","test");
_pendingIntent = PendingIntent.getActivity(ParkingOptionsActivity.this, 0, _intent, 0);
SmsManager sms = SmsManager.getDefault();
sms.sendTextMessage(phoneNumber, null, "test message", _pendingIntent, null);
You need to obtain your PendingIntent with getBroadcast() instead of getActivity(), since you want to send a broadcast to your BroadcastReceiver, not start an Activity.
In your current code, you can simply change that one line:
_pendingIntent = PendingIntent.getBroadcast(ParkingOptionsActivity.this, 0, _intent, 0);
Furthermore, the "android.provider.Telephony.SMS_SENT" action is not present in the SDK currently, and there is no system broadcast when an SMS is sent. Your app doesn't really need that <action> in the manifest entry, since the Intent is explicitly targeting your Receiver class.
If you do plan to use that action for something else - e.g., differentiating broadcasts in onReceive(), receiving implicit broadcasts from other apps, etc. - then you might consider changing it to use something other than the android.provider.Telephony package name, so as not to cause potential unwanted behavior or confusion in the future. Using your own app's package name is the norm, I would say.
I have a service that supposed to upload photos in the background. But when I try to start it, it doesn't start. In the logcat I've noticed that I get a warning Implicit intents with startService are not safe : Intent { .....}. I've already tripled checked that the action string is the same in the manifest and what I'm starting with. My code :manifest :
<service android:name=".photosupload.services.PhtosUploadService"
android:exported="false" android:process=":uploadPhotosServiceProcess">
<intent-filter>
<action android:name="com.yoovi.app.photosupload.services.action.START_UPLOAD" />
</intent-filter>
</service>
starting service code :
Intent i = new Intent(PhtosUploadService.ACTION_START_UPLOAD);
i.putExtra(PhtosUploadService.ALBUM_ID, albumID);
context.startService(i);
You need to understand implicit and explicit intents.
Explicit intent means you need to specify the exact class from which the intent will be serviced.
Your code should be similar to
Intent i = new Intent();
i.setClass(this, photosupload.services.PhtosUploadService.class);
If you want to send implicit intent to a service - Please Change to android:exported="true" in manifest.
Hello I was trying to implement a custom Broadcast receiver for my Geofence app. I just went through the solution given here But I found that he is sending the broadcast from the receiver class which receives the same broadcast. can someone please tell me how this works. I have not worked much on custom broadcast.
He is sending the broadcast from one class and receiving it in another receiver. The line below is where he sends out the broadcast.
Intent intent = new Intent("com.aol.android.geofence.ACTION_RECEIVE_GEOFENCE");
Here is his manifest where he registers a receiver for that broadcast
<receiver android:name="com.aol.android.geofence.GeofenceReceiver"
android:exported="false">
<intent-filter >
<action android:name="com.aol.android.geofence.ACTION_RECEIVE_GEOFENCE"/>
</intent-filter>
</receiver>
you can send one Broadcast in another one with following code:
ntent local = new Intent();
local.setAction("BroadCastPath"); // like android.receiver.MyReceiver
context.sendBroadcast(local);