关于android 6.0权限问题
2016-08-05 11:29
351 查看
Android6.0相比之前的Android版本有一个很大的不同点,就是动态的获取权限。之前我们需要什么权限只需要在Manifest文件中声明即可,在6.0中,又新增了运行时权限的动态检测。
Android6.0分了两种权限Normal
Permissions(安装时自动授权,用户也不能取消权限) and Dangerous Permissions(详情在文章最后):
如果在 Android 6.0 以前的设备上,我们之前在清单文件中声明权限是没有问题的,但是如果是在 Android 6.0 设备上,并且项目
此时你肯定想到了 如果 targetSdkVersion 值设置的小于23是不是就不会奔溃了,恩,确实如此, 此时即使使用Android6.0的设备,程序也不会奔溃,原因显而易见,Android 的权限机制是 Android M 后才加入的。从 Android M 开始 应用程序申请的权限是在运行时动态赋给用户的。所以就需要我们动态的申请权限了
之所以写这篇文章是因为最近在写一个APP的时候用到了百度定位,之前使用百度定位的SDK好好的,但是换了手机之后开始不行了,折腾半天,才意识到新手机是6.0的系统,搜索一番,有所了解,写下来,权作备份
一个简单的例子,实现点击按钮,屏幕出现当前位置
申请密钥,配置环境就按照官网上面的来,我们按照之前的方法来
我们点击按钮,发现并没有定位成功,查看log,发现如下log
需要
所以我们就需要针对6.0系统做出修改,来动态申请权限了。
修改代码:
04-24
02:29:16.163 6134-6134/cn.lixyz.testpermission D/TTTT: 弹出提示
我们点击“始终允许”之后,退出程序再此进入,则可以定位了,我们如果我们像要在运行了权限之后立即就可以获取到位置信息呢?
Android提供了
public
void
onRequestPermissionsResult(int requestCode, String[] permissions,
int[] grantResults) {
switch
(requestCode) { case
1:
if
(grantResults[0]
== PackageManager.PERMISSION_GRANTED) { mLocationClient.start(); } else
{ Log.d("TTTT",
"啊偶,被拒绝了,少年不哭,站起来撸");
} break;
default:
super.onRequestPermissionsResult(requestCode,
permissions, grantResults); } }
当我们点击禁止按钮的时候,Log提示"啊偶,被拒绝了,少年不哭,站起来撸"
当我们点击允许按钮的时候,定位成功
完整代码如下
public
class
MainActivity
extends
Activity{
private
Button bt; private
TextView tv; public
LocationClient mLocationClient = null;
public
BDLocationListener myListener = new
MyLocationListener(); @Override
protected
void
onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); mLocationClient = new
LocationClient(getApplicationContext()); // 声明LocationClient类
mLocationClient.registerLocationListener(myListener); // 注册监听函数
initLocation(); bt = (Button) findViewById(R.id.bt); tv = (TextView) findViewById(R.id.tv); bt.setOnClickListener(new
View.OnClickListener() { @Override
public
void
onClick(View v)
{
//mLocationClient.start();
startLocation(); } }); } private
void
startLocation()
{
if(Build.VERSION.SDK_INT>=23){
int
checkPermission = ContextCompat.checkSelfPermission(MainActivity.this,
Manifest.permission.ACCESS_COARSE_LOCATION); if
(checkPermission != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(MainActivity.this,
new
String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, 1);
return;
} else
{ mLocationClient.start(); }
}else{
mLocationClient.start();
} }
@Override
public
void
onRequestPermissionsResult(int requestCode, String[] permissions,
int[] grantResults) {
switch
(requestCode) { case
1:
if
(grantResults[0]
== PackageManager.PERMISSION_GRANTED) { mLocationClient.start(); } else
{ Log.d("TTTT",
"啊偶,被拒绝了,少年不哭,站起来撸");
} break;
default:
super.onRequestPermissionsResult(requestCode,
permissions, grantResults); } } private
void
initLocation()
{ LocationClientOption option =
new
LocationClientOption(); option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);//
可选,默认高精度,设置定位模式,高精度,低功耗,仅设备 option.setCoorType("bd09ll");//
可选,默认gcj02,设置返回的定位结果坐标系
int
span = 1000;
option.setScanSpan(span);// 可选,默认0,即仅定位一次,设置发起定位请求的间隔需要大于等于1000ms才是有效的
option.setIsNeedAddress(true);//
可选,设置是否需要地址信息,默认不需要 option.setOpenGps(true);//
可选,默认false,设置是否使用gps option.setLocationNotify(true);//
可选,默认false,设置是否当gps有效时按照1S1次频率输出GPS结果 option.setIsNeedLocationDescribe(true);//
可选,默认false,设置是否需要位置语义化结果,可以在BDLocation.getLocationDescribe里得到,结果类似于“在北京天安门附近” option.setIsNeedLocationPoiList(true);//
可选,默认false,设置是否需要POI结果,可以在BDLocation.getPoiList里得到 option.setIgnoreKillProcess(false);//
可选,默认true,定位SDK内部是一个SERVICE,并放到了独立进程,设置是否在stop的时候杀死这个进程,默认不杀死 option.SetIgnoreCacheException(false);//
可选,默认false,设置是否收集CRASH信息,默认收集 option.setEnableSimulateGps(false);//
可选,默认false,设置是否需要过滤gps仿真结果,默认需要 mLocationClient.setLocOption(option); }
class
MyLocationListener
implements
BDLocationListener {
@Override
public
void
onReceiveLocation(BDLocation location)
{
// Receive Location
StringBuffer sb = new
StringBuffer(256);
sb.append("time : ");
sb.append(location.getTime()); sb.append("\nerror code : ");
sb.append(location.getLocType()); sb.append("\nlatitude : ");
sb.append(location.getLatitude()); sb.append("\nlontitude : ");
sb.append(location.getLongitude()); sb.append("\nradius : ");
sb.append(location.getRadius()); if
(location.getLocType() == BDLocation.TypeGpsLocation) {// GPS定位结果
sb.append("\nspeed : ");
sb.append(location.getSpeed());// 单位:公里每小时
sb.append("\nsatellite : ");
sb.append(location.getSatelliteNumber()); sb.append("\nheight : ");
sb.append(location.getAltitude());// 单位:米
sb.append("\ndirection : ");
sb.append(location.getDirection());// 单位度
sb.append("\naddr : ");
sb.append(location.getAddrStr()); sb.append("\ndescribe : ");
sb.append("gps定位成功");
} else
if
(location.getLocType() == BDLocation.TypeNetWorkLocation) {//
网络定位结果 sb.append("\naddr
: "); sb.append(location.getAddrStr());
// 运营商信息
sb.append("\noperationers : ");
sb.append(location.getOperators()); sb.append("\ndescribe : ");
sb.append("网络定位成功");
} else
if
(location.getLocType() == BDLocation.TypeOffLineLocation) {//
离线定位结果 sb.append("\ndescribe
: "); sb.append("离线定位成功,离线定位结果也是有效的");
} else
if
(location.getLocType() == BDLocation.TypeServerError) { sb.append("\ndescribe
: "); sb.append("服务端网络定位失败,可以反馈IMEI号和大体定位时间到loc-bugs@baidu.com,会有人追查原因");
} else
if
(location.getLocType() == BDLocation.TypeNetWorkException) { sb.append("\ndescribe
: "); sb.append("网络不同导致定位失败,请检查网络是否通畅");
} else
if
(location.getLocType() == BDLocation.TypeCriteriaException) { sb.append("\ndescribe
: "); sb.append("无法获取有效定位依据导致定位失败,一般是由于手机的原因,处于飞行模式下一般会造成这种结果,可以试着重启手机");
} sb.append("\nlocationdescribe : ");
sb.append(location.getLocationDescribe());// 位置语义化信息
List<Poi> list = location.getPoiList();// POI数据
if
(list != null)
{ sb.append("\npoilist size = : ");
sb.append(list.size()); for
(Poi p : list) { sb.append("\npoi= : ");
sb.append(p.getId() + " "
+ p.getName() + " "
+ p.getRank()); } } if
(location.getCity() != null)
{ Message msg = new
Message(); msg.obj = location.getCity(); handler.sendMessage(msg); } } } Handler handler =
new
Handler() { public
void
handleMessage(android.os.Message msg)
{ tv.setText((String) msg.obj); mLocationClient.stop(); } };}
Android6.0分了两种权限Normal
Permissions(安装时自动授权,用户也不能取消权限) and Dangerous Permissions(详情在文章最后):
如果在 Android 6.0 以前的设备上,我们之前在清单文件中声明权限是没有问题的,但是如果是在 Android 6.0 设备上,并且项目
targetSdkVersion你设置的是23,那再像之前那样声明权限,是不起作用的
此时你肯定想到了 如果 targetSdkVersion 值设置的小于23是不是就不会奔溃了,恩,确实如此, 此时即使使用Android6.0的设备,程序也不会奔溃,原因显而易见,Android 的权限机制是 Android M 后才加入的。从 Android M 开始 应用程序申请的权限是在运行时动态赋给用户的。所以就需要我们动态的申请权限了
之所以写这篇文章是因为最近在写一个APP的时候用到了百度定位,之前使用百度定位的SDK好好的,但是换了手机之后开始不行了,折腾半天,才意识到新手机是6.0的系统,搜索一番,有所了解,写下来,权作备份
一个简单的例子,实现点击按钮,屏幕出现当前位置
申请密钥,配置环境就按照官网上面的来,我们按照之前的方法来
package cn.lixyz.testpermission; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.view.View; import android.widget.Button; import android.widget.TextView; import com.baidu.location.BDLocation; import com.baidu.location.BDLocationListener; import com.baidu.location.LocationClient; import com.baidu.location.LocationClientOption; import com.baidu.location.Poi; import java.util.List; public class MainActivity extends Activity /*implements BDLocationListener*/ { private Button bt; private TextView tv; public LocationClient mLocationClient = null; public BDLocationListener myListener = new MyLocationListener(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mLocationClient = new LocationClient(getApplicationContext()); // 声明LocationClient类 mLocationClient.registerLocationListener(myListener); // 注册监听函数 initLocation(); bt = (Button) findViewById(R.id.bt); tv = (TextView) findViewById(R.id.tv); bt.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mLocationClient.start(); } }); } private void initLocation() { LocationClientOption option = new LocationClientOption(); option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);// 可选,默认高精度,设置定位模式,高精度,低功耗,仅设备 option.setCoorType("bd09ll");// 可选,默认gcj02,设置返回的定位结果坐标系 int span = 1000; option.setScanSpan(span);// 可选,默认0,即仅定位一次,设置发起定位请求的间隔需要大于等于1000ms才是有效的 option.setIsNeedAddress(true);// 可选,设置是否需要地址信息,默认不需要 option.setOpenGps(true);// 可选,默认false,设置是否使用gps option.setLocationNotify(true);// 可选,默认false,设置是否当gps有效时按照1S1次频率输出GPS结果 option.setIsNeedLocationDescribe(true);// 可选,默认false,设置是否需要位置语义化结果,可以在BDLocation.getLocationDescribe里得到,结果类似于“在北京天安门附近” option.setIsNeedLocationPoiList(true);// 可选,默认false,设置是否需要POI结果,可以在BDLocation.getPoiList里得到 option.setIgnoreKillProcess(false);// 可选,默认true,定位SDK内部是一个SERVICE,并放到了独立进程,设置是否在stop的时候杀死这个进程,默认不杀死 option.SetIgnoreCacheException(false);// 可选,默认false,设置是否收集CRASH信息,默认收集 option.setEnableSimulateGps(false);// 可选,默认false,设置是否需要过滤gps仿真结果,默认需要 mLocationClient.setLocOption(option); } class MyLocationListener implements BDLocationListener { @Override public void onReceiveLocation(BDLocation location) { // Receive Location StringBuffer sb = new StringBuffer(256); sb.append("time : "); sb.append(location.getTime()); sb.append("\nerror code : "); sb.append(location.getLocType()); sb.append("\nlatitude : "); sb.append(location.getLatitude()); sb.append("\nlontitude : "); sb.append(location.getLongitude()); sb.append("\nradius : "); sb.append(location.getRadius()); if (location.getLocType() == BDLocation.TypeGpsLocation) {// GPS定位结果 sb.append("\nspeed : "); sb.append(location.getSpeed());// 单位:公里每小时 sb.append("\nsatellite : "); sb.append(location.getSatelliteNumber()); sb.append("\nheight : "); sb.append(location.getAltitude());// 单位:米 sb.append("\ndirection : "); sb.append(location.getDirection());// 单位度 sb.append("\naddr : "); sb.append(location.getAddrStr()); sb.append("\ndescribe : "); sb.append("gps定位成功"); } else if (location.getLocType() == BDLocation.TypeNetWorkLocation) {// 网络定位结果 sb.append("\naddr : "); sb.append(location.getAddrStr()); // 运营商信息 sb.append("\noperationers : "); sb.append(location.getOperators()); sb.append("\ndescribe : "); sb.append("网络定位成功"); } else if (location.getLocType() == BDLocation.TypeOffLineLocation) {// 离线定位结果 sb.append("\ndescribe : "); sb.append("离线定位成功,离线定位结果也是有效的"); } else if (location.getLocType() == BDLocation.TypeServerError) { sb.append("\ndescribe : "); sb.append("服务端网络定位失败,可以反馈IMEI号和大体定位时间到loc-bugs@baidu.com,会有人追查原因"); } else if (location.getLocType() == BDLocation.TypeNetWorkException) { sb.append("\ndescribe : "); sb.append("网络不同导致定位失败,请检查网络是否通畅"); } else if (location.getLocType() == BDLocation.TypeCriteriaException) { sb.append("\ndescribe : "); sb.append("无法获取有效定位依据导致定位失败,一般是由于手机的原因,处于飞行模式下一般会造成这种结果,可以试着重启手机"); } sb.append("\nlocationdescribe : "); sb.append(location.getLocationDescribe());// 位置语义化信息 List<Poi> list = location.getPoiList();// POI数据 if (list != null) { sb.append("\npoilist size = : "); sb.append(list.size()); for (Poi p : list) { sb.append("\npoi= : "); sb.append(p.getId() + " " + p.getName() + " " + p.getRank()); } } if (location.getCity() != null) { Message msg = new Message(); msg.obj = location.getCity(); handler.sendMessage(msg); } } } Handler handler = new Handler() { public void handleMessage(android.os.Message msg) { tv.setText((String) msg.obj); mLocationClient.stop(); } }; }
我们点击按钮,发现并没有定位成功,查看log,发现如下log
04-24 02:16:59.994 5329-5354/? W/System.err: java.lang.SecurityException: getAllCellInfo: Neither user 10198 nor current process has android.permission.ACCESS_COARSE_LOCATION. 04-24 02:16:59.994 5329-5354/? W/System.err: at android.app.ContextImpl.enforce(ContextImpl.java:1595) 04-24 02:16:59.994 5329-5354/? W/System.err: at android.app.ContextImpl.enforceCallingOrSelfPermission(ContextImpl.java:1627) 04-24 02:16:59.994 5329-5354/? W/System.err: at android.content.ContextWrapper.enforceCallingOrSelfPermission(ContextWrapper.java:675) 04-24 02:16:59.994 5329-5354/? W/System.err: at android.content.ContextWrapper.enforceCallingOrSelfPermission(ContextWrapper.java:675) 04-24 02:16:59.994 5329-5354/? W/System.err: at com.android.phone.PhoneInterfaceManager.enforceFineOrCoarseLocationPermission(PhoneInterfaceManager.java:1835) 04-24 02:16:59.994 5329-5354/? W/System.err: at com.android.phone.PhoneInterfaceManager.getAllCellInfoUsingSubId(PhoneInterfaceManager.java:1920) 04-24 02:16:59.994 5329-5354/? W/System.err: at com.android.phone.PhoneInterfaceManager.getAllCellInfo(PhoneInterfaceManager.java:1916) 04-24 02:16:59.994 5329-5354/? W/System.err: at com.android.internal.telephony.ITelephony$Stub.onTransact(ITelephony.java:732) 04-24 02:16:59.994 5329-5354/? W/System.err: at android.os.Binder.execTransact(Binder.java:453)
需要
android.permission.ACCESS_COARSE_LOCATION权限,我们在Manifest文件中添加之后再运行,发现还是抛同样的异常,依旧获取不到位置
所以我们就需要针对6.0系统做出修改,来动态申请权限了。
修改代码:
bt.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { startLocation(); } });
private void startLocation() { int checkPermission = ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_COARSE_LOCATION); if (checkPermission != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, 1); Log.d("TTTT", "弹出提示"); return; } else { mLocationClient.start(); } }
04-24
02:29:16.163 6134-6134/cn.lixyz.testpermission D/TTTT: 弹出提示
我们点击“始终允许”之后,退出程序再此进入,则可以定位了,我们如果我们像要在运行了权限之后立即就可以获取到位置信息呢?
Android提供了
onRequestPermissionsResult方法来帮我们实现我们执行了权限规则之后的操作,这个方法和
onActivityResult方法类似
public
void
onRequestPermissionsResult(int requestCode, String[] permissions,
int[] grantResults) {
switch
(requestCode) { case
1:
if
(grantResults[0]
== PackageManager.PERMISSION_GRANTED) { mLocationClient.start(); } else
{ Log.d("TTTT",
"啊偶,被拒绝了,少年不哭,站起来撸");
} break;
default:
super.onRequestPermissionsResult(requestCode,
permissions, grantResults); } }
当我们点击禁止按钮的时候,Log提示"啊偶,被拒绝了,少年不哭,站起来撸"
当我们点击允许按钮的时候,定位成功
完整代码如下
public
class
MainActivity
extends
Activity{
private
Button bt; private
TextView tv; public
LocationClient mLocationClient = null;
public
BDLocationListener myListener = new
MyLocationListener(); @Override
protected
void
onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); mLocationClient = new
LocationClient(getApplicationContext()); // 声明LocationClient类
mLocationClient.registerLocationListener(myListener); // 注册监听函数
initLocation(); bt = (Button) findViewById(R.id.bt); tv = (TextView) findViewById(R.id.tv); bt.setOnClickListener(new
View.OnClickListener() { @Override
public
void
onClick(View v)
{
//mLocationClient.start();
startLocation(); } }); } private
void
startLocation()
{
if(Build.VERSION.SDK_INT>=23){
int
checkPermission = ContextCompat.checkSelfPermission(MainActivity.this,
Manifest.permission.ACCESS_COARSE_LOCATION); if
(checkPermission != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(MainActivity.this,
new
String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, 1);
return;
} else
{ mLocationClient.start(); }
}else{
mLocationClient.start();
} }
@Override
public
void
onRequestPermissionsResult(int requestCode, String[] permissions,
int[] grantResults) {
switch
(requestCode) { case
1:
if
(grantResults[0]
== PackageManager.PERMISSION_GRANTED) { mLocationClient.start(); } else
{ Log.d("TTTT",
"啊偶,被拒绝了,少年不哭,站起来撸");
} break;
default:
super.onRequestPermissionsResult(requestCode,
permissions, grantResults); } } private
void
initLocation()
{ LocationClientOption option =
new
LocationClientOption(); option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);//
可选,默认高精度,设置定位模式,高精度,低功耗,仅设备 option.setCoorType("bd09ll");//
可选,默认gcj02,设置返回的定位结果坐标系
int
span = 1000;
option.setScanSpan(span);// 可选,默认0,即仅定位一次,设置发起定位请求的间隔需要大于等于1000ms才是有效的
option.setIsNeedAddress(true);//
可选,设置是否需要地址信息,默认不需要 option.setOpenGps(true);//
可选,默认false,设置是否使用gps option.setLocationNotify(true);//
可选,默认false,设置是否当gps有效时按照1S1次频率输出GPS结果 option.setIsNeedLocationDescribe(true);//
可选,默认false,设置是否需要位置语义化结果,可以在BDLocation.getLocationDescribe里得到,结果类似于“在北京天安门附近” option.setIsNeedLocationPoiList(true);//
可选,默认false,设置是否需要POI结果,可以在BDLocation.getPoiList里得到 option.setIgnoreKillProcess(false);//
可选,默认true,定位SDK内部是一个SERVICE,并放到了独立进程,设置是否在stop的时候杀死这个进程,默认不杀死 option.SetIgnoreCacheException(false);//
可选,默认false,设置是否收集CRASH信息,默认收集 option.setEnableSimulateGps(false);//
可选,默认false,设置是否需要过滤gps仿真结果,默认需要 mLocationClient.setLocOption(option); }
class
MyLocationListener
implements
BDLocationListener {
@Override
public
void
onReceiveLocation(BDLocation location)
{
// Receive Location
StringBuffer sb = new
StringBuffer(256);
sb.append("time : ");
sb.append(location.getTime()); sb.append("\nerror code : ");
sb.append(location.getLocType()); sb.append("\nlatitude : ");
sb.append(location.getLatitude()); sb.append("\nlontitude : ");
sb.append(location.getLongitude()); sb.append("\nradius : ");
sb.append(location.getRadius()); if
(location.getLocType() == BDLocation.TypeGpsLocation) {// GPS定位结果
sb.append("\nspeed : ");
sb.append(location.getSpeed());// 单位:公里每小时
sb.append("\nsatellite : ");
sb.append(location.getSatelliteNumber()); sb.append("\nheight : ");
sb.append(location.getAltitude());// 单位:米
sb.append("\ndirection : ");
sb.append(location.getDirection());// 单位度
sb.append("\naddr : ");
sb.append(location.getAddrStr()); sb.append("\ndescribe : ");
sb.append("gps定位成功");
} else
if
(location.getLocType() == BDLocation.TypeNetWorkLocation) {//
网络定位结果 sb.append("\naddr
: "); sb.append(location.getAddrStr());
// 运营商信息
sb.append("\noperationers : ");
sb.append(location.getOperators()); sb.append("\ndescribe : ");
sb.append("网络定位成功");
} else
if
(location.getLocType() == BDLocation.TypeOffLineLocation) {//
离线定位结果 sb.append("\ndescribe
: "); sb.append("离线定位成功,离线定位结果也是有效的");
} else
if
(location.getLocType() == BDLocation.TypeServerError) { sb.append("\ndescribe
: "); sb.append("服务端网络定位失败,可以反馈IMEI号和大体定位时间到loc-bugs@baidu.com,会有人追查原因");
} else
if
(location.getLocType() == BDLocation.TypeNetWorkException) { sb.append("\ndescribe
: "); sb.append("网络不同导致定位失败,请检查网络是否通畅");
} else
if
(location.getLocType() == BDLocation.TypeCriteriaException) { sb.append("\ndescribe
: "); sb.append("无法获取有效定位依据导致定位失败,一般是由于手机的原因,处于飞行模式下一般会造成这种结果,可以试着重启手机");
} sb.append("\nlocationdescribe : ");
sb.append(location.getLocationDescribe());// 位置语义化信息
List<Poi> list = location.getPoiList();// POI数据
if
(list != null)
{ sb.append("\npoilist size = : ");
sb.append(list.size()); for
(Poi p : list) { sb.append("\npoi= : ");
sb.append(p.getId() + " "
+ p.getName() + " "
+ p.getRank()); } } if
(location.getCity() != null)
{ Message msg = new
Message(); msg.obj = location.getCity(); handler.sendMessage(msg); } } } Handler handler =
new
Handler() { public
void
handleMessage(android.os.Message msg)
{ tv.setText((String) msg.obj); mLocationClient.stop(); } };}
相关文章推荐
- 关于Android 6.0权限问题的初步了解
- 关于Android 6.0的权限问题这个大坑记录
- android关于6.0权限 ActivityCompat.requestPermissions找不到问题
- 关于Android 6.0 调用 要求使用权限代码报红色问题
- Android 4.0中关于内外置存储卡读写权限问题
- Android中关于Manifest的权限注册问题
- 关于Android 6.0 WebView的两个问题
- Android 6.0权限问题之Dexter库的使用
- Android 6.0权限问题
- 关于android开发中使用系统权限报错的问题
- 血的教训 关于6.0的读取权限问题
- 关于Unity打Android包自动添加权限的问题
- 关于Android23 及以上模拟器处理应用闪退的一些问题(权限相关)
- 关于android读写sdcard的权限问题
- Android 6.0(M) 获得权限请求问题
- 关于Android权限被禁止的问题
- 在android 6.0以上无法获取READ_PHONE_STATE权限的SecurityException的问题
- Android 6.0权限问题
- android 6.0的权限问题