I have an app that uses Android AccountManager (package name: com.mycompany.accounts), that adds accounts to the device and provides a login screen. I have another app (com.mycomp.actualapp), that uses the first app to add/remove accounts.
I can successfully add and remove accounts on Pre Marshmallow devices, using the following permissions in the manifest:
<uses-permission android:name="android.permission.GET_ACCOUNTS"/>
<uses-permission android:name="android.permission.MANAGE_ACCOUNTS"/>
<uses-permission android:name="android.permission.USE_CREDENTIALS"/>
When compiling with sdk 22 and targetting sdk 22, these permissions should be automatically granted. The following code:
accountManager.removeAccount(getAccount(), activity, new AccountManagerCallback<Bundle>() {
#Override
public void run(AccountManagerFuture<Bundle> accountManagerFuture) {
try {
Bundle bundle = accountManagerFuture.getResult();
boolean success = bundle.getBoolean(AccountManager.KEY_BOOLEAN_RESULT);
if (success) {
Toast.makeText(activity, activity.getString(R.string.successfully_loggedout), Toast.LENGTH_LONG).show();
afterLogoutSuccess(activity);
} else {
Toast.makeText(activity.getApplicationContext(), activity.getString(R.string.failed_to_logout), Toast.LENGTH_LONG).show();
}
onLogoutListener.onLogoutFinished(success);
return;
} catch (OperationCanceledException e) {
Log.e(TAG,"Operation cancelled exception:", e);
} catch (IOException e) {
Log.e(TAG, "IOException:", e);
} catch (AuthenticatorException e) {
Log.e(TAG, "AuthenticatorException:", e);
}
onLogoutListener.onLogoutFinished(false);
}
}, null);
Fails with the following exception:
java.lang.SecurityException: uid 10057 cannot remove accounts of type: com.mycompany.accounts
at android.os.Parcel.readException(Parcel.java:1599)
at android.os.Parcel.readException(Parcel.java:1552)
at android.accounts.IAccountManager$Stub$Proxy.removeAccount(IAccountManager.java:897)
at android.accounts.AccountManager$7.doWork(AccountManager.java:900)
at android.accounts.AccountManager$AmsTask.start(AccountManager.java:1888)
at android.accounts.AccountManager.removeAccount(AccountManager.java:897)
at com.mycomp.actualapp.utils.LoginHelper$4.doInBackground(LoginHelper.java:282)
at com.mycomp.actualapputils.LoginHelper$4.doInBackground(LoginHelper.java:242)
at android.os.AsyncTask$2.call(AsyncTask.java:295)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
The strange thing, is that this code runs fine on Pre Marshmallow devices without any issues.
On a side note, I noticed that compiling with sdk 22 and targeting 22: Going to "Settings > Apps > My app(com.mycomp.actualapp) > Permissions" I see only two permissions, "Phone" "Storage".
I noticed that compiling with sdk 23 and targeting 23: I see three permissions, "Phone", "Storage" and "Contacts".
I have tried the following:
Switching to compile with sdk 23 - grant all permissions in app settings, try remove account again. Still fails with the same exception.
Compile with 22 and add the following permissions to the manifest. Make sure all permissions are granted. Still fails with the same exception:
<uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS"/>
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<uses-permission android:name="android.permission.WRITE_CONTACTS"/>
I am able to get the users account username and token without additional permission granting, but the removing of accounts doesn't work.
I would really appreciate any help!
I know this is late to answer but I thought I would share my findings in case anyone else is in the same situation.
I upgraded my build to build with 23 instead of 22 as I couldn't solve it on 22. Then I explicitly asking for the permission at runtime to GET_ACCOUNTS before trying to do anything with them.
https://developer.android.com/training/permissions/requesting.html
https://developer.android.com/reference/android/Manifest.permission.html#GET_ACCOUNTS
Further information for compiling with 23: You don't need to ask permission if the app shares the signature of the authenticator that manages an account. In this case, my signatures didn't match so I did need to request it. If you create an account within your app to be used within your app, you do not need to request permission at runtime.
I suddenly was stuck in the same thing yesterday.
In my case, I defined wrong package name in node.
Just fix it and it will work perfectly.
<account-authenticator>
xmlns:android="http://schemas.android.com/apk/res/android"
android:accountType="Your correct packet name here" + ".accounts"
android:icon="#drawable/ic_launcher"
android:label="xxx"
android:smallIcon="#drawable/ic_launcher"
>
</account-authenticator>
If your package name is:
com.example.android then the account type should be: com.example.android.accounts
Checking in the source code, you can removeAccounts in two cases:
the account is created by your app
your app is a system app
Source: https://android.googlesource.com/platform/frameworks/base/+/05c9ecc/services/core/java/com/android/server/accounts/AccountManagerService.java#1336
Related
Currenty, We are migrating our Android MediaCAS test application to Android-11 from Android-10.
We are running the application in both AVD-29 & AVD-30.
In AVD-29 we didn't observe any issue. While running the same application in AVD-30 we are facing following issue.
java.lang.SecurityException: Permission Denial: getCurrentUser() from pid=8373, uid=10153 requires android.permission.INTERACT_ACROSS_USERS
E/MediaCas: Failed to create plugin: java.lang.SecurityException: You either need MANAGE_USERS or CREATE_USERS permission to: query user
Sample code:
try {
mMediaCas = new MediaCas(0xF6D8);
} catch (Exception e) {
Log.d("MediacasDebug", "Error" +e);
e.printStackTrace();
}
Note: We observed the same behavior in clearkey cas also
As per the google this issue will be resolved in future android release
Pls refer: https://issuetracker.google.com/issues/179694569
I'm trying to comply with the Google requirements to request the permission ACTIVITY_RECOGNITION, for Android 10, but I don't seem to understand why there's no permission popup showing , like with the other permissions (ie, Location, storage,...)
The code I have is:
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACTIVITY_RECOGNITION) != PackageManager.PERMISSION_GRANTED) {
Log.d("TAG", "PERMISSION 'ACTIVITY_RECOGNITION' NOT GRANTED");
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACTIVITY_RECOGNITION},
MY_PERMISSIONS_ACTIVITY_RECOGNITION);
} else
{
Log.d("TAG", "PERMISSION 'ACTIVITY_RECOGNITION' GRANTED");
}
And I'm always ending up on the 'NOT GRANTED' flow, but the ActivityCompat.requestPermissions is not showing no popup!
Is there anything else I'm Missing ?
The manifest contains the
and the app.gradle
minSdkVersion 29
targetSdkVersion 30
Running out of ideas, any help would be welcome.
Just to add, I'm running this on my Pixel 2, with the latest firmware available 10.0.0 (QP1A.191105.004, Nov 2019)
check : Privacy changes in Android 10
From API 29(Android Q, Android 10)
Android App need permission in AndroidManifest.xml
<uses-permission android:name="android.permission.ACTIVITY_RECOGNITION"/>
Before API 29 AndroidManifest.xml
<uses-permission android:name="com.google.android.gms.permission.ACTIVITY_RECOGNITION" />
check : Google Fit APIs
And
If the system-auto grants the android.permission.ACTIVITY_RECOGNITION permission, your app retains the permission after you update your app to target Android 10. However, the user can revoke this permission at any time in system settings.
Thanks.
I'm building a system app (but not a signature app) to run as root in "kiosk mode". This app should install/uninstall third party apk's on runtime, according to the demand.
I need to install the third party app and immediately grant runtime permissions that the apk needs. After some research, I found the method (android.content.pm.PackageInstaller):
/**
* Sets which runtime permissions to be granted to the package at installation.
*
* #param permissions The permissions to grant or null to grant all runtime
* permissions.
*
* #hide
*/
#SystemApi
#RequiresPermission(android.Manifest.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS)
public void setGrantedRuntimePermissions(String[] permissions) {
installFlags |= PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS;
this.grantedRuntimePermissions = permissions;
}
As the annotation says, it can only be called if I declare INSTALL_GRANT_RUNTIME_PERMISSIONS on my app manifest. So, in spite I could not find this permission in (android.Manifest), I added it to manifest:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.xxx"
>
[...]
<uses-permission android:name="android.permission.INSTALL_PACKAGES" />
<uses-permission android:name="android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS"/>
[...]
When I call the method on my code "params.setGrantedRuntimePermissions(new String[]{ Manifest.permission.ACCESS_COARSE_LOCATION });" I immediately receive an error from Android Studio saying that cannot resolve the method. It is easily explained because there's a #hide instruction there, so I tried to workaround, and call the method by Reflection:
String[] permissions = new String[]{ Manifest.permission.ACCESS_COARSE_LOCATION };
Method m = params.getClass().getMethod("setGrantedRuntimePermissions", new Class[] { String[].class } );
m.invoke(params, (Object)permissions);
But, in spite I have added the permission on Manifest, I still receive the security exception at runtime:
java.lang.SecurityException: You need the android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS permission to use the PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS flag
Extra info:
. The app is installed under /system/priv-app
. Compilation details:
android {
compileSdkVersion 26
buildToolsVersion '26.0.2'
defaultConfig {
applicationId "com.xxx"
minSdkVersion 21
targetSdkVersion 26
versionCode 1
}
. I was using this lib (eu.chainfire.libsuperuser.Shell) to grant the permission and it works but I wonder If I can have it done without using shell:
Shell.SU.run("pm grant com.thirdparty.package android.permission.ACCESS_COARSE_LOCATION");
Any thoughts?
I'm trying an application just show Here map on screen. I've followed all of steps in document of Here + provided app_id, app_code, license key + provided 6 permissions in AndroidManifest.xml.
But It got the following issue:
"ERROR: Cannot initialize Map Fragment: MISSING_PERMISSION"
I'm using gradle 2.8, targetSdkVersion 23, compileSdkVersion 23
Android 6 / API 23 has a new permission system, that means you have to request critical permissions from the user.
See Android docs: https://developer.android.com/training/permissions/requesting.html
Just adding the critical permissions to the manifest is not enough anymore.
If you don't want to do this, you can still set traget API level to 22 and work in legacy mode, but to be more future proof, you should implement the new Android6 way of requesting permissions.
The critical permissions in the HERE SDK that you have to request are:
ACCESS_FINE_LOCATION and WRITE_EXTERNAL_STORAGE
Make sure you are using android runtime permission on for location access as from marshmallow onward all the OS need permission to run
UPDATE: To those who asked about which error codes the users are receiving: there are no error codes. It just opens a blank, post-installation page that says "The app was not installed" with a big 'X' next to it. It's possible different versions of Android could have different messages. There is no indication for what went wrong during the installation.
UPDATE 2: Some users reported that they receive error code "-504" when they try to install/update from the Play Store, and the "app not installed" message when manually trying to install the .apk. I don't know what correlation this error has with users being unable to install, but the solutions from the only 2 questions on SO on this topic did not fix anything for me. I've included the updated manifests and build files.
UPDATE 3: It appears as users report this issue in versions after IAB has been successfully installed, which further de-legitimatizes the concept that this issue is caused by introducing IAB.
UPDATE 4: It looks like the problem is with old users trying to update to a new version, and not with new users. With that in mind, there is a high likelihood that this issue is result of INSTALL_FAILED_UID_CHANGED. Looking through the version history, the significant change I made in the problematic version that users cannot update from is removing drawables that I no longer intended of using.
Asking users to go through the procedure to fix this isn't plausible. If there is a solution that I can enforce which would fix it for faulty users, wonderful... if not, the least I can do at this point is damage control and ensure this doesn't happen in the future.
NOTE: Below is the original post speculating that the problem is the result of introducing IAB into the app. Since then, it has become more and more unlikely for that to be the cause. Regardless, the post still has relevant information.
------------------------------------------------------------------------------------------
Original Title: Android App Users Get "App not installed" After Introducing IAB
I recently introduced IAB in my app that was published on Google Play. After a while, I've started to get reports from some users that they get an "installation unsuccessful" error when they try to install or update it.
What makes me think it's caused by introducing IAB is that one particular long-time user e-mailed me that when he's attempting to update to the version with IAB, the installer mentions that new permissions were introduced and requires the user's permission. Once granted, it says that the app failed to install.
I've done some Googling and it appears to be a problem from their end, one user even tried to manually install an .apk with said permissions removed without any success. I wan't to make sure that it's not something I've done wrong, but an inevitability that I have to accept with some users.
Note that the vast majority has no problem of installing the app, and I haven't received any reports of this until after IAB was introduced. It wouldn't bother me so much were it a small amount of lost users, but the problem is, those users hurt my app's rating. Users have also mentioned that they can install apps, excluding my own, perfectly well.
I don't rule out the possibility that users may have been getting these errors even before IAB was introduced, and the linkage could be a mistaken one.
Here is my manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest package = "com.jjsoftware.fullscientificcalculator"
xmlns:android = "http://schemas.android.com/apk/res/android">
<uses-permission android:name = "android.permission.VIBRATE"/>
<uses-permission android:name = "com.android.vending.BILLING"/>
<application
android:allowBackup = "true"
android:fullBackupContent = "true"
android:icon = "#drawable/logo"
android:label = "#string/app_name">
<activity
android:name = ".MainActivity"
android:hardwareAccelerated = "false"
android:label = "#string/app_name"
android:screenOrientation = "portrait"
android:theme="#style/AppTheme">
<intent-filter>
<action android:name = "android.intent.action.MAIN"/>
<category android:name = "android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity
android:name = ".SettingsActivity"
android:theme = "#style/PreferencesTheme">
<intent-filter>
<action android:name = ".SettingsActivity"/>
<category android:name = "android.intent.category.PREFERENCE"/>
</intent-filter>
</activity>
</application>
Here is the Gradle file:
apply plugin: 'com.android.application'
android {
compileSdkVersion 23
buildToolsVersion "23.0.1"
defaultConfig {
applicationId "com.jjsoftware.fullscientificcalculator"
minSdkVersion 14
targetSdkVersion 23
versionCode 102
versionName "1.679"
}
sourceSets { main { assets.srcDirs = ['src/main/assets', 'src/main/assets/'] } }
}
dependencies {
compile 'com.android.support:appcompat-v7:23.1.1'
compile 'com.google.android.gms:play-services-ads:8.4.0'
compile 'com.android.support:gridlayout-v7:23.2.1'
compile files('libs/exp4j-0.4.5.jar')
compile files('libs/EJML-core-0.28.jar')
compile files('libs/EJML-dense64-0.28.jar')
compile files('libs/Jama-1.0.3.jar')
compile files('libs/EJML-simple-0.28.jar')
}
And, if need be, the top-level build:
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:1.5.0'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
jcenter()
}
}
There is a typo in the manifest file on line android:largeHeap="true">>. xml line ends with >>. This may be causing the error.
it could be the phones have a lower version of the Google play services than the minimum you defined in the APK.
There is nothing much you can do if that is the case, other than for the users to upgrade their google services (https://play.google.com/store/apps/details?id=com.google.android.gms&hl=en) or you reduce your version.
also you may need to add the following to your manifest. (i think this is used to compare the versions installed in the phones with the versions required by the apk)
<application ...>
<!-- This meta-data tag is required to use Google Play Services. -->
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
</application>
I got this error while installing on my Android device a new APK for the app I am developing.
I checked the debug log on the device (using "adb -d logcat > log.txt") and found an entry saying "PackageManager: Downgrade detected: Update version code 2 is older than current 10000". Obviously something went wrong with the versioning somehow.
I uninstalled the package and then was able to install the APK with no problems.
Remember that the latest installment of Android (Marshmallow version) has changed the permissions to give more access to permissions to the user. Hence it is not enough to define the permissions in the manifest anymore.
Through code you need to make sure that the billing permission is enabled by the users when they use the app. The simplest way to go around this is to set the target SDK to v-22. This should temporarily solve your issue.
The real solution however is to handle the new permissions introduced in Marshmallow. Here is how to do it:
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch(requestCode) {
case BILLING_REQUEST:
if (canAccessBilling()) {
callBillingPerms();
}
break;
}
}
private void callBillingPerms() {
Toast.makeText(this, "We need your permission to access Billing", Toast.LENGTH_SHORT).show();
}
private boolean canAccessSMS() {
return(hasPermission(Manifest.vending.BILLING));
}
#TargetApi(Build.VERSION_CODES.M)
private boolean hasPermission(String perm) {
return(PackageManager.PERMISSION_GRANTED==this.checkSelfPermission(perm));
}
Hope this helps :)
Perhaps the error is on the user's side.
This article states the following:
Google Play - Error 504
Problem
App could not be downloaded due to an error.
First solution
The usual, please: go to Settings > Apps > All > Google Play Store and Clear cache and Clear data. Also Clear cache and Clear data for Google Services Framework.
Second solution
Try removing your GMail account
This Stack Exchange answer discussed similar ideas.
According to the list of status codes at Wikipedia, a 504 error means the following:
504 Gateway Timeout
The server was acting as a gateway or proxy and did not receive a timely response from the upstream server.
Ask your users if doing the above solves their issue.