Android - make programmatically created broadcast receiver exported - android

I am trying to make my receiver that I statically defined in the manifest dynamic by creating it programmatically.
That's the static version in the manifest:
<receiver android:name=".receivers.PackageReceiver" android:enabled="true" android:exported="true">
<intent-filter>
<action android:name="android.intent.action.PACKAGE_ADDED" />
<action android:name="android.intent.action.PACKAGE_REMOVED" />
<action android:name="android.intent.action.PACKAGE_CHANGED" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="package" />
</intent-filter>
</receiver>
That's how I did it in code:
val intentFilter = IntentFilter()
intentFilter.addAction(ACTION_PACKAGE_ADDED)
intentFilter.addAction(ACTION_PACKAGE_REMOVED)
intentFilter.addCategory(CATEGORY_DEFAULT)
intentFilter.addDataScheme("package")
registerReceiver(PackageReceiver(), intentFilter)
The programmatic version is not triggered when a package is installed/uninstalled whereas the static one is. I figure it's because the first version is exported - how can I achieve this in code?

Related

how to set android:host in BroadcastReceiver or Activity in android programmatically?

i am trying to add android:host="8097" in activity or broadcastReceiver programmatically but i didn't get any answer i searched lot..
<receiver android:name=".CallReceiver">
<intent-filter>
<action android:name="android.provider.Telephony.SECRET_CODE" />
<data android:scheme="android_secret_code" android:host="8097"/>
</intent-filter>
</receiver>
so i want to add android:host="8097" programmatically not in manifests..

Intent filter for PACKAGE_ADDED for a specific package

In my Android app, I'm catching the PACKAGE_ADDED broadcast:
<receiver android:name=".OnAppInstall">
<intent-filter>
<action android:name="android.intent.action.PACKAGE_INSTALL" />
<action android:name="android.intent.action.PACKAGE_ADDED" />
<data android:scheme="package" />
</intent-filter>
</receiver>
My app is only concerned with installation of a specific companion app. The data string in the intent goes: package:com.acme.myapp. The intent data Uri is an instance of OpaqueUri; getHost(), getPath(), and getQuery() all return nulls.
Can I somehow make an intent filter that only allows intents for one specific package ID?
Try the following.
<intent-filter>
<action android:name="android.intent.action.PACKAGE_ADDED" />
<data android:scheme="package"
android:sspPrefix="com.acme.myapp" />
</intent-filter>
This matches with the corresponding API call here.

Android studio: Element receiver duplicated

In my application, I would like to detect when my package is replaced and hence I have a receiver that is enabled in this way:
<receiver
android:name="com.x.y.ApplicationsReceiver"
android:enabled="#bool/is_at_most_api_11" >
<intent-filter>
<action android:name="android.intent.action.PACKAGE_REPLACED" />
<data android:scheme="package" />
</intent-filter>
</receiver>
<receiver
android:name="com.x.y.ApplicationsReceiver"
android:enabled="#bool/is_at_least_api_12" >
<intent-filter>
<action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
</intent-filter>
</receiver>
When importing my project from Eclipse to Android Studio, I got the following error:
Element receiver#com.x.y.ApplicationsReceiver at AndroidManifest.xml duplicated with element declared at AndroidManifest.xml.
Any idea how can I can solve this issue given hat I need to enable the receiver for different intent filters according to the Android API level?
Issue is occurring because adding same class two times in AndroidManifest for registering BroadcastReceiver for different Action.
Do it as by adding more then one Action in single BroadcastReceiver :
<receiver
android:name="com.x.y.ApplicationsReceiver"
android:enabled="#bool/is_at_most_api_11" >
<intent-filter>
<action android:name="android.intent.action.PACKAGE_REPLACED" />
<action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
<data android:scheme="package" />
</intent-filter>
</receiver>
Now in onReceive method of ApplicationsReceiver class get Action from Intent and do what want to do according to API level:
#Override
public void onReceive(Context context,Intent intent) {
String action=intent.getAction();
if(action.equalsIgnoreCase("android.intent.action.MY_PACKAGE_REPLACED")){
// do your code here
}else{
// do your code here
}
}

Android Notification App

I'm currently working on an android application. I have to log any new installed app name whenever the user is installing/downloading a new third party app. How can I get the notification if the user is installing a new app. Thanks in advance.
Java File
public class ApplicationBroadcastService extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
System.out.print("-------");
}
}
Manifest
<receiver android:name=".applicationlog.ApplicationBroadcastService">
<intent-filter>
<action android:name="android.intent.action.PACKAGE_ADDED" />
<action android:name="android.intent.action.PACKAGE_CHANGED" />
<action android:name="android.intent.action.PACKAGE_INSTALL" />
<action android:name="android.intent.action.PACKAGE_REMOVED" />
<action android:name="android.intent.action.PACKAGE_REPLACED" />
</intent-filter>
</receiver>
But still I do not enter the onReceive method, when I am installing/uninstalling any app.
Here is the solution:
I did a small change in my Manifest file.
<intent-filter>
<category android:name="android.intent.category.DEFAULT" />
<action android:name="android.intent.action.PACKAGE_ADDED" />
<action android:name="android.intent.action.PACKAGE_CHANGED" />
<action android:name="android.intent.action.PACKAGE_INSTALL" />
<action android:name="android.intent.action.PACKAGE_REMOVED" />
<action android:name="android.intent.action.PACKAGE_REPLACED" />
<data android:scheme="package" />
</intent-filter>
Now it's working fine.. :)
Thanks again #willytate
Ajay,
You will need to setup a BroadcastReceiver with an intent filter to receive the following Action: ACTION_PACKAGE_ADDED then from the onReceive() method of the BroadcastReceiver you can launch a Notification.
Take a look at the intent documentation. You are looking for ACTION_PACKAGE_INSTALL (which seems to be never used, see comments) and ACTION_PACKAGE_REMOVED.
You can listen for the android.intent.action.PACKAGE_ADDED intent.

Android - Intent Filter?

I am trying to register my Activity so that it can be used by the Activity chooser/picker allowing a user to choose whether or not to select my application/Activity to complete what they are trying to do.
I want to provide the option for the user to be able to select my application when they want to send an SMS message and when they want to place an outgoing call, to try to achieve this I added the following pieces of code within my Activity tags in my manifest:
<intent-filter>
<action android:name="android.intent.action.SENDTO" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.NEW_OUTGOING_CALL" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
However the Activity chooser never appears and the native apps are used without providing a choice to the user. Can anyone see where I am going wrong?
EDIT:
I have figured out I need to add
<data android:scheme="sms" />
<data android:scheme="smsto" />
for the SMS message but what do I use for the outgoing call?
EDIT 2:
I have tried the following for the outgoing call:
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<action android:name="android.intent.action.DIAL" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="tel" />
</intent-filter>
But again with no luck, has this been blocked from 1.6 on?
Edit 3:
This is what happens when I click Text Mobile:
So i want the same thing when I click Call mobile
I think it should help you
<intent-filter >
<action android:name="android.intent.action.CALL_PRIVILEGED" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="tel" />
</intent-filter>
Tested on Android 2.1
This is because activities and services can not pickup outside intents on their own. You need to use a BroadcastReceiver. To implement this, do the following:
Extend Android's BroadcastReceiver class like so:
public class MyReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Context context = getApplicationContext();
Intent sendIntent = new Intent();
if ( intent.getAction().equals(Intent.NEW_OUTGOING_CALL) ) {
sendIntent.setClass(context, MyActivity.class);
context.startActivity(sendIntent);
}
else if ( intent.getAction().equals(Intent.SOME_OTHER_INTENT) {
sendIntent.setClass(context, MyService.class);
context.startService(sendIntent);
}
// More else ifs for more intents you want to catch.
}
}
Then you need to declare the receiver in your manifest like this:
<receiver android:name="MyReceiver">
<intent-filter>
<action android:name="android.intent.action.NEW_OUTGOING_CALL" />
// more intents you want to catch here
</intent-filter>
</receiver>
Only intents declared in the manifest will be caught by your Receiver, so if you want to catch several intents thrown by the system or other programs and want to do the exact same thing when their intents are caught then specify those intents here in the manifest and skip the if/else blocks in the onReceive method.
this worked for me
<activity
android:label="#string/app_name"
android:name=".TestIntentActivity" >
<intent-filter>
<action android:name="android.intent.action.CALL" />
<category android:name="android.intent.category.DEFAULT" />
<action android:name="android.intent.action.CALL_PRIVILEGED" />
<data android:scheme="tel" />
</intent-filter>
</activity>
You need to add a priority to the intent filter so that Android takes it into account. For example:
<activity android:name="YourActivity">
<intent-filter android:priority="100">
<action android:name="android.intent.action.CALL_PRIVILEGED" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
</intent-filter>
</activity>

Categories

Resources