android - 如何删除 android 版本 Pie 上的谷歌帐户?
问题描述
以编程方式,我想从“帐户”部分中删除 google 帐户。以下代码在较低版本的设备上正常工作,但在 Oreo 和更高版本上不工作。但我得到了这个例外
引起:java.lang.SecurityException:uid 10117 无法删除类型的帐户:com.google
这是我的代码:
final AccountManager accountManager = (AccountManager.get(getApplicationContext()));
final Account[] accounts = accountManager.getAccountsByType("com.google");
for (int index = 0; index < accounts.length; index++) {
accountManager.removeAccount(accounts[index], null, null);
// accountManager.removeAccountExplicitly(accounts[finalIndex]); Tried this line code as well.
}
我也给予了以下许可。
<uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" />
<uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" />
<uses-permission android:name="android.permission.USE_CREDENTIALS" />
<uses-permission
android:name="android.permission.ACCOUNT_MANAGER"
tools:ignore="ProtectedPermissions" />
经过研究,我为奥利奥和更高版本的设备添加了此代码,但仍然无法删除 Google 帐户。
public void requestGoogleAccountAccess() throws Exception {
boolean googleAccountAccessGranted = GoogleAuthUtil.requestGoogleAccountsAccess(this);
Log.i("", "googleAccountAccessGranted: " + googleAccountAccessGranted);
}
// exception handler after calling method above
private void handleAuthResult(Throwable e) {
if (e instanceof UserRecoverableAuthException) {
UserRecoverableAuthException authException = (UserRecoverableAuthException) e;
startActivityForResult(authException.getIntent(), 12);
} else {
Log.e("", "Cannot request Google Account Access", e);
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 12) {
Log.i("", "Google Auth Permission Result");
if (resultCode == Activity.RESULT_CANCELED) {
Log.w("", "User Cancelled Play Services Auth Request.");
} else if (resultCode == Activity.RESULT_OK) {
Log.d("", "User accepted Play Services Auth Request.");
// call the following line again on a background thread. the call now returns a boolean instead of throwing an exception
// googleAccountAccessGranted = GoogleAuthUtil.requestGoogleAccountsAccess(this);
}
}
}
我添加了身份验证器
public class Authenticator extends AbstractAccountAuthenticator {
// Simple constructor
public Authenticator(Context context) {
super(context);
}
// Editing properties is not supported
@Override
public Bundle editProperties(
AccountAuthenticatorResponse r, String s) {
throw new UnsupportedOperationException();
}
// Don't add additional accounts
@Override
public Bundle addAccount(
AccountAuthenticatorResponse r,
String s,
String s2,
String[] strings,
Bundle bundle) throws NetworkErrorException {
return null;
}
// Ignore attempts to confirm credentials
@Override
public Bundle confirmCredentials(
AccountAuthenticatorResponse r,
Account account,
Bundle bundle) throws NetworkErrorException {
return null;
}
// Getting an authentication token is not supported
@Override
public Bundle getAuthToken(
AccountAuthenticatorResponse r,
Account account,
String s,
Bundle bundle) throws NetworkErrorException {
throw new UnsupportedOperationException();
}
// Getting a label for the auth token is not supported
@Override
public String getAuthTokenLabel(String s) {
throw new UnsupportedOperationException();
}
// Updating user credentials is not supported
@Override
public Bundle updateCredentials(
AccountAuthenticatorResponse r,
Account account,
String s, Bundle bundle) throws NetworkErrorException {
throw new UnsupportedOperationException();
}
// Checking features for the account is not supported
@Override
public Bundle hasFeatures(
AccountAuthenticatorResponse r,
Account account, String[] strings) throws NetworkErrorException {
throw new UnsupportedOperationException();
}
@Override
public Bundle getAccountRemovalAllowed(AccountAuthenticatorResponse response, Account account) throws NetworkErrorException {
return super.getAccountRemovalAllowed(response, account);
}
}
public class AuthenticatorService extends Service {
// Instance field that stores the authenticator object
private Authenticator mAuthenticator;
@Override
public void onCreate() {
// Create a new authenticator object
mAuthenticator = new Authenticator(this);
}
/*
* When the system binds to this Service to make the RPC call
* return the authenticator's IBinder.
*/
@Override
public IBinder onBind(Intent intent) {
return mAuthenticator.getIBinder();
}
}
// Authenticator.xml
// My App Package Name is "com.accountdemo"
<account-authenticator xmlns:android="http://schemas.android.com/apk/res/android"
android:accountType="com.google"
android:icon="@drawable/abc_vector_test"
android:label="@string/app_name"
android:smallIcon="@drawable/abc_vector_test" />
// Added these lines in Manifest
<service android:name=".AuthenticatorService">
<intent-filter>
<action android:name="android.accounts.AccountAuthenticator" />
</intent-filter>
<meta-data
android:name="android.accounts.AccountAuthenticator"
android:resource="@xml/authenticator" />
</service>
我已经使用系统签名平台密钥测试了这段代码,但它仍然无法正常工作。请有人帮我解决这个问题。谢谢你。
解决方案
推荐阅读
- typescript - 迭代两个对象的键以将一个对象属性设置为另一个 Typescript 的值
- java - ohengine.jdbc.spi.SqlExceptionHelper:错误:运算符不存在:整数 = bytea
- sparql - SPARQL 查询未从 LinkedGeoData 获取任何记录
- stored-procedures - 如何获取存储过程的输出作为雪花中的任务输出
- python - 在 Visual Studio 代码中无法选择内核,findKernel 崩溃:503 Service Unavailable
- wordpress - 在 woocommerce 用户帐户中保存出生日期
- audio - concat 2 个带声音的视频,并与另一个更长或更短的音频循环
- javascript - 在页面加载时打开列表框
- javascript - 粘性导航栏实施失败
- javascript - 将对象传递给此函数时,Meteor.call 的语法应该是什么?