targetSdkVersion 23通过accountManager.getAccounts()返回长度为0的数组 [英] targetSdkVersion 23 returns 0 length array via accountManager.getAccounts()
问题描述
我在真正的Nexus 5设备Android 6.0.1中观察到以下奇怪结果
I observed the following strange outcome in my real Nexus 5 device, Android 6.0.1
在我的应用启动期间,我运行以下简单代码.
I run the following simple code during my app launched.
Pattern emailPattern = Patterns.EMAIL_ADDRESS; // API level 8+
AccountManager accountManager = AccountManager.get(this);
Account[] accounts = accountManager.getAccounts();
如果我将targetSdkVersion
设置为22、21、19,则上面的代码可以正常工作.它返回非空数组.
The above code works fine, if I set my targetSdkVersion
to 22, 21, 19. It returns non empty array.
但是,当我更改targetSdkVersion
并进行测试时
However, when I change targetSdkVersion
and tested with
defaultConfig {
applicationId "org.yccheok.myapplication"
minSdkVersion 19
targetSdkVersion 23
versionCode 1
versionName "1.0"
}
上面的代码返回0个长度的数组!
任何想法,为什么对targetSdkVersion=23
编译时事物都会中断.
Any idea why thing breaks when compiled against targetSdkVersion=23
.
请注意,在产生问题的过程中,每当更改targetSdkVersion
并通过Android Studio运行它时,都需要清除应用数据,清除应用缓存并手动为所有用户卸载.
Note, during to produce the problem, whenever you change the targetSdkVersion
and run it through Android Studio, you need to clear your app data, clear your app cache and uninstall for all users manually.
以下是在Nexus 5设备Android 6.0.1中重现该问题的步骤
Here are steps to reproduce the problem in Nexus 5 device, Android 6.0.1
- 通过File-> New-> New Projetct ...在Android Studio中创建项目
- 选择空白活动"
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.yccheok.myapplication">
<uses-permission android:name="android.permission.GET_ACCOUNTS"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:theme="@style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
build.gradle
apply plugin: 'com.android.application'
android {
compileSdkVersion 23
buildToolsVersion "23.0.1"
defaultConfig {
applicationId "org.yccheok.myapplication"
minSdkVersion 19
targetSdkVersion 23
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.1.1'
compile 'com.android.support:design:23.1.1'
}
MainActivity.java
import android.accounts.Account;
import android.accounts.AccountManager;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Patterns;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import java.util.regex.Pattern;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
int targetSdkVersion = 0;
try {
PackageInfo packageInfo = getPackageManager().getPackageInfo(getPackageName(), 0);
targetSdkVersion = packageInfo.applicationInfo.targetSdkVersion;
}
catch (PackageManager.NameNotFoundException e) {
android.util.Log.i("CHEOK", e.getMessage());
}
Pattern emailPattern = Patterns.EMAIL_ADDRESS; // API level 8+
AccountManager accountManager = AccountManager.get(this);
Account[] accounts = accountManager.getAccounts();
android.util.Log.i("CHEOK", targetSdkVersion + " : numnber of accoutn by ??? = " + accounts.length);
for (Account account : accounts) {
if (emailPattern.matcher(account.name).matches()) {
String possibleEmail = account.name;
android.util.Log.i("CHEOK", "possibleEmail = " + possibleEmail);
}
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
任何想法,为什么targetSdkVersion 23通过accountManager.getAccounts()返回0长度数组
Any idea why targetSdkVersion 23 returns 0 length array via accountManager.getAccounts()
推荐答案
GET_ACCOUNTS是运行时权限,否则将不起作用.
GET_ACCOUNTS is a dangerous permission and when using target sdk 23 needs to be managed with runtime permissions or it will not work.
您实际上需要在运行时从用户请求权限. 例如:
You need to actually request permission from the user at runtime. example:
ActivityCompat.requestPermissions(this, new String[]
{Manifest.permission.GET_ACCOUNTS}, 1);
int permissionCheck = ContextCompat.checkSelfPermission(thisActivity,
Manifest.permission.GET_ACCOUNTS);