Facing this issue on non system app when attempting to do: "BluetoothAdapter::getProfileProxy". Observed only on android 8.1 but not reproducible.
Caused by: java.lang.SecurityException: query intent receivers: Neither user 15010171 nor current process has android.permission.INTERACT_ACROSS_USERS.
at android.os.Parcel.readException(Parcel.java:2021)
at android.os.Parcel.readException(Parcel.java:1967)
at android.content.pm.IPackageManager$Stub$Proxy.queryIntentServices(IPackageManager.java:4830)
at android.app.ApplicationPackageManager.queryIntentServicesAsUser(ApplicationPackageManager.java:1255)
at android.content.Intent.resolveSystemServiceAsUser(Intent.java:8365)
at android.bluetooth.BluetoothA2dp.doBind(BluetoothA2dp.java:432)
at android.bluetooth.BluetoothA2dp.<init>(BluetoothA2dp.java:405)
at android.bluetooth.BluetoothAdapter.getProfileProxy(BluetoothAdapter.java:3034)
Questions:
Why this permission "INTERACT_ACROSS_USERS" is coming as an issue. (we check for bluetooth permission)
As per https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/bluetooth/BluetoothA2dp.java
boolean doBind() {
Intent intent = new Intent(IBluetoothA2dp.class.getName());
ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
intent.setComponent(comp); ...
It looks like the permission issue is somewhere else - in some system service.
Wondering if someone can explain the issue.
Related
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q) {
RoleManager roleManager = context.getSystemService(RoleManager.class);
// check if the app is having permission to be as default SMS app
boolean isRoleAvailable = roleManager.isRoleAvailable(RoleManager.ROLE_SMS);
if (isRoleAvailable){
// check whether your app is already holding the default SMS app role.
boolean isRoleHeld = roleManager.isRoleHeld(RoleManager.ROLE_SMS);
if (isRoleHeld){
Intent roleRequestIntent = roleManager.createRequestRoleIntent(RoleManager.ROLE_SMS);
((AppCompatActivity)context).startActivityForResult(roleRequestIntent, ConstantsValues.REQUEST_CODES.REQUEST_RESET_SMS_HANDLER);
}
}
}else if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
Intent intent = new Intent(Telephony.Sms.Intents.ACTION_CHANGE_DEFAULT);
intent.putExtra(Telephony.Sms.Intents.EXTRA_PACKAGE_NAME, Custom_SharedPreference.getInstance(context).getDefaultSMSPackage());
((AppCompatActivity)context).startActivityForResult(intent, ConstantsValues.REQUEST_CODES.REQUEST_RESET_SMS_HANDLER);
}
This is working fine when Change SMS App to MyApp default handler but When I change MyApp to again Default SMS App then its not working and activityResult return 0 Activity.Cancle.
This is happend only Android Q other Versions working fine.
In short, it's not possible to revert default SMS app.
As a work-around I decided to open the previous default SMS app using this code:
runIntent = getPackageManager().getLaunchIntentForPackage(newDefaultSmsApp);
Having the same issue, I tried various workaround, like using old method to request a change of default SMS app, however the OS doesn't care at all. Using RoleManager, when requesting to "revert" the role back to default/previous SMS app, the logs shows something like this:
2021-06-18 08:23:06.246 1770-5101/? I/ActivityTaskManager: START u0 {act=android.provider.Telephony.ACTION_CHANGE_DEFAULT cmp=com.google.android.permissioncontroller/com.android.permissioncontroller.role.ui.RequestRoleActivity (has extras)} from uid 10043
2021-06-18 08:23:06.246 1770-5101/? W/PermissionPolicyService: Action Removed: starting Intent { act=android.provider.Telephony.ACTION_CHANGE_DEFAULT cmp=com.google.android.permissioncontroller/com.android.permissioncontroller.role.ui.RequestRoleActivity (has extras) } from ccc71.sb (uid=10043)
Note the Action Removed on second line.
So in summary, it's only possible to request the role for self, but impossible to revert. A real bummer for backup apps that Google is making look bad, like so many other apps these days.
I have a security system in schools, where my tablets are the consoles for each classroom. I've noticed teachers and admin are not restarting the tablets very often (or ever), which has caused issues. I would like to take the task from the clients and program a weekly reboot or shutdown. I have taken a few steps in the right direction:
I have:
Spoken with the Tablet Provider/Scheme Provider, and they have added my app as a privileged app.
Added a whitelist for (what I think are) all required permissions.
Confirmed the privileges exist.
Code to Check Permissions:
public void getGrantedPermissions(final String appPackage) {
List<String> granted = new ArrayList<String>();
try {
PackageInfo pi = getPackageManager().getPackageInfo(appPackage, PackageManager.GET_PERMISSIONS);
for (int i = 0; i < pi.requestedPermissions.length; i++) {
if ((pi.requestedPermissionsFlags[i] & PackageInfo.REQUESTED_PERMISSION_GRANTED) != 0) {
granted.add(pi.requestedPermissions[i]);
}
}
} catch (Exception e) {}
for(int i = 0; i < granted.size(); i++){
Log.e("Permissions", granted.get(i));
}
}
Below is what the log reported. The green permissions are all that I could get on my personal phone. The yellow permissions are what I was able to get, additionally, from the Tablet provider's whitelist. We can confirm by these permissions that I have a privileged app, as well as the shutdown and reboot permissions.
I was able to find a section of code to shutdown the app, but it seems that I can't quite figure out how to use it. Below is the code I have tried, and the error follows:
Intent intent = new Intent("android.intent.action.ACTION_REQUEST_SHUTDOWN");
intent.putExtra("android.intent.extra.KEY_CONFIRM", false);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
Error upon running code:
android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.intent.action.ACTION_REQUEST_SHUTDOWN flg=0x10000000 (has extras) }
"This exception is thrown when a call to Context#startActivity or one of its variants fails because an Activity can not be found to execute the given Intent."
I am assuming that this may require me to modify my manifist.xml, is that correct? If so, I'm unsure how to do so. I feel that I may have to add an to my main activity, where the call is made. Though, I've tried this and it didn't work, or I wrote the code improperly.
Thank you in advance for any assistance!
Figured this one out. I didn't realize a PowerManager existed, but it does, and it works. My solution below. Also, if you didn't read the full question, my app is a privileged/System app, which gives me the authority to manage power. Normal apps will not be able to do this.
Currently running Android 9.0 (might matter, not sure)
try{
PowerManager powerManager = (PowerManager)getSystemService(Context.POWER_SERVICE);
powerManager.reboot(null);
} catch (Exception e){
Toast.makeText(this, "Error performing this action", Toast.LENGTH_LONG).show();
e.printStackTrace();
}
This is the log, I am receving on crash in Samsung running Oero OS:
Fatal Exception: java.lang.SecurityException: Permission Denial:
starting Intent { act=android.intent.action.SEND typ=text/plain
flg=0x80001 pkg=com.google.android.apps.maps
cmp=com.google.android.apps.maps/com.google.android.apps.gmm.sharing.SendTextToClipboardActivity
clip={text/plain T:"XYZ"
Intent share = new Intent(Intent.ACTION_SEND);
share.setType("text/plain");
share.setComponent(new ComponentName(packageName, resolveInfo.activityInfo.name));
share.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
share.putExtra(Intent.EXTRA_TEXT, shareMessage);
share.setPackage(packageName);
Please suggest.
Thanks
You have a couple of options here. You can avoid this crash by specifically filtering out the SendTextToClipboardActivity that Google Maps recently added as an intent-handler. (It looks exactly like the genuine Android "Copy to clipboard" share-target, and is most likely the result of a bug on the part of Google Maps.) Or you can filter out any ResolveInfo where the corresponding Activity is not exported; however, this could result in also filtering out share-targets within your own app that you do want to show to the user, in which case you would need to allow non-exported Activities from your own app package.
For example, suppose you have something like this to obtain a list of providers for your ACTION_SEND intent:
PackageManager packageManager = mActivity.getPackageManager();
List<ResolveInfo> providers = packageManager.queryIntentActivities(sendIntent, 0);
You could then filter out providers that are known to cause problems, and/or providers for which the Activity isn't marked as exported. For example, you could use a check such as the following to build your own list of providers to be displayed to the user:
for (ResolveInfo provider : providers) {
if ("com.google.android.apps.maps".equalsIgnoreCase(provider.activityInfo.packageName)
&& "com.google.android.apps.gmm.sharing.SendTextToClipboardActivity".equalsIgnoreCase(provider.activityInfo.name)) {
continue; // Skip specific Activity you don't want to show
}
if (!BuildConfig.APPLICATION_ID.equalsIgnoreCase(provider.activityInfo.packageName) && !provider.activityInfo.exported) {
continue; // Skip providers where the Activity is not marked with exported=true, unless they're from our own app
}
acceptableProviders.add(provider);
}
How to then go about displaying the acceptableProviders as share options is left as an exercise to the reader. The key is filtering out known bad providers.
Meanwhile, you can also contact Google to complain about the bad behavior of this new intent-handler, which is essentially masquerading as the trusted Android text/plain handler used for the "Copy to clipboard" share-target.
I'm developing an app which connect to android usb device host. When connecting it to an Sony phone and trying to receive the android.hardware.usb.action.USB_DEVICE_ATTACHED by intent filter or directly in the broadcast receiver I receive the next message on Sony Z3 compact device (Android 5.0.2):
Permission Denial: receiving Intent {
act=android.hardware.usb.action.USB_DEVICE_ATTACHED flg=0x10 (has
extras) } to ProcessRecord{***anId**
**anId:my.app.package/u0anId} (pid=xxxxx, uid=xxxxx)
requires com.sonyericsson.permission.BLACKLISTED_USB_DEVICE due to
sender android (uid 1000)
Do I need to call a specific permission? Send a validation number with the request? Is it the usb device that need to send something special?
Can somebody tell me whats the matter?
Thank you for trying to help.
1st UPDATE
Thank's DDPWNAGE for reply... I'm turning arround with the Permission denial... trying to set
<permission
android:name="com.sonyericsson.permission.BLACKLISTED_USB_DEVICE"
android:protectionLevel="signature" />
but this change nothing. I've set the device_filter
<resources>
<usb-device vendor-id="xxxxx" product-id="xxxx"/>
</resources>
with in the manifest
<permission android:name="my.package.USB_PERMISSION" />
<uses-permission android:name="my.package.USB_PERMISSION" />
<uses-feature
android:name="android.hardware.usb.host"
android:required="false" />
I've also trying to set
<permission android:name="my.package.USB_PERMISSION"
android:protectionLevel="signature" />
But I cannot figured out why the device should be in any blacklist of usb
2nd UPDATE
I realized that I also have this message before the Permission Denial :
Calling a method in the system process without a qualified user: android.app.ContextImpl.sendBroadcast:1340 com.android.server.usb.UsbSettingsManager.blacklistedDeviceAttached:757 com.android.server.usb.UsbHostManager.endUsbDeviceAdded:303 com.android.server.usb.UsbHostManager.monitorUsbHostBus:-2 com.android.server.usb.UsbHostManager.access$000:54
When I look up in the UsbHostManager I didn't see any reason why on standard Android devices it works but on Sony devices I've this waring message. In the class we have these 2 methods which check the blacklisted devices :
private boolean isBlackListed(String deviceName) {
int count = mHostBlacklist.length;
for (int i = 0; i < count; i++) {
if (deviceName.startsWith(mHostBlacklist[i])) {
return true;
}
}
return false;
}
/* returns true if the USB device should not be accessible by applications */
private boolean isBlackListed(int clazz, int subClass, int protocol) {
// blacklist hubs
if (clazz == UsbConstants.USB_CLASS_HUB) return true;
// blacklist HID boot devices (mouse and keyboard)
if (clazz == UsbConstants.USB_CLASS_HID &&
subClass == UsbConstants.USB_INTERFACE_SUBCLASS_BOOT) {
return true;
}
return false;
}
My device is not a USB_CLASS_HUB nor a USB_CLASS_HID, so the only things I see is that the device is in mHostBlacklist. But does each constructor have is own host blacklist or is this given by android?
mHostBlacklist = context.getResources().getStringArray(
com.android.internal.R.array.config_usbHostBlacklist);
seems to be from android but is it customizable by contructors? And in this case why did Sony blacklist our usb device?
Somebody from Sony is here to help?
Thank you for your time.
Let me try and dissect that log:
Permission Denial: receiving Intent {
Something's receiving an Intent! What is it?
act=android.hardware.usb.action.USB_DEVICE_ATTACHED flg=0x10 (has extras) }
The action here is android.hardware.usb.action.USB_DEVICE_ATTACHED with flg (flag?) 0x10 (hex for 2), guessing that means it (has extras). Guessing that's the intent the reciever's trying to receive.
to ProcessRecord{***anId**
**anId:my.app.package/u0anID} (pid=xxxxx, uid=xxxxx)
Your app is the receiver of the object... got it.
requires com.sonyericsson.permission.BLACKLISTED_USB_DEVICE due to
sender android (uid 1000)
It seems like here's where your error is. In order to get the USB_DEVICE_ATTACHED event sent to your app, your app needs permission to get it first. Most importantly, it needs the BLACKLISTED_USB_DEVICE permission.
It may also be that your device was "blacklisted", but, why? See if BLACKLISTED_USB_DEVICE is a permission that can be enabled, and try again.
As a further hint: Your crash log begins with Permission Denial.
Since Android Lollipop, we have now an API for accessing apps usage stats. However, your app must be granted those permissions by the user.
I know that for redirecting the user to those settings using Settings.ACTION_USAGE_ACCESS_SETTINGS.
Now, my question is how do you know the user has granted you those permissions so that you can stop redirecting him to the settings.
Thanks!
you can simply query usagestats with daily interval and end time the current time and if nothing is returned this means the user hasn’t granted permissions
#TargetApi(Build.VERSION_CODES.LOLLIPOP)
public boolean doIHavePermission(){
final UsageStatsManager usageStatsManager = (UsageStatsManager) context.getSystemService(Context.USAGE_STATS_SERVICE);
final List<UsageStats> queryUsageStats = usageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, 0, System.currentTimeMillis());
return !queryUsageStats.isEmpty();
}
Daily interval with start date 0 and end date the current time must at least return todays usage.So it will be empty only if permissions are not granted.
Check this answer:
Tomik's answer
If you hurry, here's the solution ;)
#TargetApi(Build.VERSION_CODES.LOLLIPOP)
public static boolean usageAccessGranted(Context context) {
AppOpsManager appOps = (AppOpsManager)context.getSystemService(Context.APP_OPS_SERVICE);
int mode = appOps.checkOpNoThrow(AppOpsManager.OPSTR_GET_USAGE_STATS,
android.os.Process.myUid(), context.getPackageName());
return mode == AppOpsManager.MODE_ALLOWED;
}
I stumbled on the same problem. On Samsung S5 Lollipop usage stats did not work with the following code:
Intent intent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
However usage stats actually exist. With the following code one can open the security settings:
Intent intent = new Intent(Settings.ACTION_SECURITY_SETTINGS);
intent.setComponent(new ComponentName("com.android.settings","com.android.settings.Settings$SecuritySettingsActivity"));
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
An the scroll to the bottom and there is usage stats. I also inspeced logs and by pressing usage stats, you are directed to SubActivity which contains UsageStats fragment. I tried the following code:
Intent intent = new Intent();
intent.setComponent(new ComponentName("com.android.settings", "com.android.settings.SubSettings"));
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
But got security exception. The problem is that they didnt mark SubActivity as exported, so as far as I know its not possible to directly start SubActivity (usage stats window). The only solution is to take user to Securiy settings and them tell him to manually go to usage stats view and enable app.
If someone finds better solution it would be great!
See ActivityNotFoundException in Lollipop when trying to launch activity with intent android.settings.USAGE_ACCESS_SETTINGS
for a better way, since with method we cannot discern whether there are simple no stats for the time interval