我有一个运行时权限的问题,我试图管理它们的棉花糖和更高版本,但我的应用程序仍然崩溃在运行时(而不是当我重启应用程序)这是活动代码:
在清单中:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />这里是活动代码(不是所有的代码,但我认为理解它是必要的)
public class HomeActivityNew extends AppCompatActivity implements AdapterView.OnItemClickListener, View.OnClickListener, SeekBar.OnSeekBarChangeListener {
// here all variables ...
private boolean permissionToRecordAccepted = false;
private boolean permissionToWriteAccepted = false;
private String[] permissions = {"android.permission.RECORD_AUDIO", "android.permission.WRITE_EXTERNAL_STORAGE"}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home_new);
int requestCode = 200;
if (Build.VERSION.SDK_INT >= 23) {
requestPermissions(permissions, requestCode);
}
init();
myHandler = new Handler();
slidingUpPanelLayout.setPanelState(SlidingUpPanelLayout.PanelState.HIDDEN);
SetupToolbar();
SetupPager();
SetupDrawer();
iv_playpause.setTag("pause");
MobileAds.initialize(getApplicationContext(), getResources().getString(R.string.admov_id));
AdView mAdView = (AdView) findViewById(R.id.adView);
AdRequest adRequest = new AdRequest.Builder().build();
mAdView.loadAd(adRequest);
/* SharedPreferences pref = getSharedPreferences("logincheck", Context.MODE_PRIVATE);
SharedPreferences.Editor edit1 = pref.edit();
edit1.putString("login","true");
edit1.apply();*/
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case 200:
if(grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
permissionToRecordAccepted=true;
}
if(grantResults.length > 0 && grantResults[1] == PackageManager.PERMISSION_GRANTED){
permissionToWriteAccepted=true;
}
break;
}
if (!permissionToRecordAccepted) HomeActivityNew.super.finish();
if (!permissionToWriteAccepted) HomeActivityNew.super.finish();
}这就是错误:
java.lang.RuntimeException: Failure delivering result ResultInfo{who=@android:requestPermissions:, request=200, result=0, data=null} to activity {com.mypackage.HomeActivityNew}: java.lang.
Caused by: java.lang.ArrayIndexOutOfBoundsException: length=0; index=0变量grantResults为空!app on runtime显示权限对话框窗口并同时崩溃,但当我重新启动应用程序时,它会等待权限
发布于 2017-11-24 20:08:14
不应在onCreate中调用this.requestPermissions。documentation on requestPermission声明:
此方法可以启动一个活动,允许用户选择授予和拒绝哪些权限。因此,您应该做好准备,您的活动可能会暂停和恢复。此外,授予某些权限可能需要重新启动应用程序。在这种情况下,系统将在将结果传递给onRequestPermissionsResult(int,String[],int[])之前重新创建活动堆栈。
当检查您是否有权限时,应该使用checkSelfPermission(String)。
为已经授予应用程序的权限调用此API将向用户显示UI,以决定应用程序是否仍然可以拥有这些权限。如果您的应用程序使用受权限保护的数据的方式发生了重大变化,这将非常有用。
这些语句中隐含的是,requestPermissions依赖于活动生命周期。因此,您的活动需要能够处理暂停和恢复,甚至在请求权限时重新开始触发。因此,请等待您的活动完全设置好(稍后在onCreate中调用requestPermissions,或在稍后的回调中调用)。
更好的是,你的方法是错误的。根据Android Documentation - Requesting Permissions的说法
注意:从Android6.0(API23级)开始,用户可以随时撤销任何应用程序的权限,即使该应用程序的目标是较低的API级。你应该测试你的应用程序,以验证当它缺少所需的权限时,它是否正常运行,而不管你的应用程序针对的是什么级别。
(强调我的)。
如果您因为缺少权限而终止您的活动,那么您正在创建一个糟糕的用户体验。即时关闭应用程序,并且没有给出任何原因,至少可以说是令人困惑的。而且,即使它确实授予了权限,用户也可以随时撤销它们。
您应该调用AppCompat.requestPermissions(thisActivity, permissions, requestCode),并且您应该在中调用它,而不是在中调用它(在onCreate中,活动没有完全初始化)。
此外,您应该仅在您的应用程序尚未授予权限的情况下调用它。所以你应该在你的应用需要权限的时候调用ActivityCompat.checkSelfPermission。
如果做不到这一点,它应该请求所需的许可。在这样做的时候,它应该检查是否应该显示原理(当用户在过去拒绝权限或在某个时候撤销权限时)。以下是googlesamples/android-runtime-permissions的摘录
private void requestCameraPermission() {
Log.i(TAG, "CAMERA permission has NOT been granted. Requesting permission.");
// BEGIN_INCLUDE(camera_permission_request)
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.CAMERA)) {
// Provide an additional rationale to the user if the permission was not granted
// and the user would benefit from additional context for the use of the permission.
// For example if the user has previously denied the permission.
Log.i(TAG,
"Displaying camera permission rationale to provide additional context.");
Snackbar.make(mLayout, R.string.permission_camera_rationale,
Snackbar.LENGTH_INDEFINITE)
.setAction(R.string.ok, new View.OnClickListener() {
@Override
public void onClick(View view) {
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{Manifest.permission.CAMERA},
REQUEST_CAMERA);
}
})
.show();
} else {
// Camera permission has not been granted yet. Request it directly.
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA},
REQUEST_CAMERA);
}
// END_INCLUDE(camera_permission_request)
}请参阅示例的其余部分(上面的行),以了解通常是如何请求权限的。还有其他方法可以编写代码来获得其他行为,但您应该首先从一个经过验证的有效示例开始,并了解每个调用的原因,然后再开始一个新的方向。
(Developer Samples - Runtime Permissions是上面示例的v7重新实现。我建议您阅读这两篇文章,以了解权限是如何工作的。但是要小心,不要进行不兼容的v4和v7调用,这可能会导致令人沮丧的bug)
让我再次强调一下:用户可以在任何时候撤销权限,即使平台/sdk低于api 23。因此,每当需要权限时,都必须检查权限。
发布于 2017-11-24 20:23:15
像这样写
private String[] permissions = {Manifest.permission.RECORD_AUDIO, Manifest.permission.WRITE_EXTERNAL_STORAGE}的实例
private String[] permissions = {"android.permission.RECORD_AUDIO", "android.permission.WRITE_EXTERNAL_STORAGE"}发布于 2017-11-24 21:11:18
在您的代码中,您使用了
if (Build.VERSION.SDK_INT >= 23) {
requestPermissions(permissions, requestCode);//Call require API level 23 and above
} 所以你没有提到其他情况,你应该为API23级或low.So修正后的代码请求权限:
if(Build.VERSION.SDK_INT > Build.VERSION_CODES.M){
//Call this method for API level 21 and above
requestPermissions(new String[]{Manifest.permission.RECORD_AUDIO},200);
}else{
ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.RECORD_AUDIO},200);
}https://stackoverflow.com/questions/47472676
复制相似问题