2017-12-18 4 views
1

사용자에게 Camera, Location, Write Storage, CallPhone 권한을 요청하고 사용자가 권한을 거부하면 경고 대화 상자를 표시하려고합니다.모든 권한을 거부 한 후에 계속할 수 없습니다.

하지만 내 코드는이 예외가 발생합니다 :

E/AndroidRuntime : 치명적인 예외 : 주요 프로세스 : fwt_android.mpermissions를, PID : 4850 java.lang.RuntimeException가 : 실패 제공하는 결과 ResultInfo {사람 = @ android : requestPermissions :, 요청 = 1, 결과 = -1, 데이터 = 의도 {act = android.content.pm.action.REQUEST_PERMISSIONS (엑스트라가 있음)}} 활동 {fwt_android.mpermissions/fwt_android.mpermissions.activities.Splash} : android.content.res.Resources $ NotFoundException : 리소스 ID # 0x0 android.app.ActivityThread.deliverResults (ActivityThread.java:3699) 012 android.app.ActivityThread $ H.handleMessage (ActivityThread.java:1393)에서 android.app.ActivityThread.-wrap16 (ActivityThread.java) 에서 android.app.ActivityThread.handleSendResult (ActivityThread.java:3742) 에서 3,516, android.os.Handler.dispatchMessage (Handler.java:102) android.os.Looper.loop (Looper.java:148)의 android.app.ActivityThread.main (ActivityThread.java:5417)의 에서의 자바 .lang.reflect.Method.invoke (네이티브 메소드) com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run (ZygoteInit.java:726) at com.android.internal.os.ZygoteInit. main (ZygoteInit.java:616) 원인 : android.content.res.Resources $ NotFoundException : 리소스 ID # 0x0 android.content.res.Resources.getValue (Resources.java:1351) android.content. res.Resources.loadXmlResourceParser (Resources.java:2774) android.content.res.Resources.getLayout (Resources.java:1165) android.view.LayoutInflater.inflate (LayoutInflater.java:421) at android. android.support.v7.app.AppCompatDialog.setContent에서 view.LayoutInflater.inflate (LayoutInflater.java:374) android.support.v7.app.AppCompatDelegateImplV9.setContentView (AppCompatDelegateImplV9.java:287)에서 보기 (AppCompatDialog.java:83) at android.support.v7.app.AlertController.installContent (AlertController.java:226) android.support.v7.app.AlertDialog.onCreate (AlertDialog.java:260) at android.app.Dialog.dispatchOnCreate (Dialog.java:394) android.app.Dialog.show의 (Dialog.java:295) at fwt_android.mpermissions.activities.Splash.onRequestPermissionsResult (Splash.java:215) at android.app.Activity.dispatchRequestPermissionsResult (Activity.java:6553) android.app.ActivityTispatchActivityResult (Activity.java:6432)에서 android.app.ActivityThread.deliverResults (ActivityThread.java:369) 5) android.app.ActivityThread.handleSendResult (ActivityThread.java:3742에서 ) android.app.ActivityThread.-wrap16 android.app.ActivityThread $ H.handleMessage에서 (ActivityThread.java) 에서 (ActivityThread.java:1393) android.os.Handler.dispatchMessage (Handler.java:102) at android.os.Looper.loop (Looper.java:148) at android.app.ActivityThread.main (ActivityThread.java : 5417) at java.lang.reflect.Method.invoke (네이티브 메소드) at com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run (ZygoteInit.java:726) at com.android.internal.os

public void checkPermission() { 
    if (ActivityCompat.checkSelfPermission(context, permissionsRequired[0]) != PackageManager.PERMISSION_GRANTED 
      || ActivityCompat.checkSelfPermission(context, permissionsRequired[1]) != PackageManager.PERMISSION_GRANTED 
      || ActivityCompat.checkSelfPermission(context, permissionsRequired[2]) != PackageManager.PERMISSION_GRANTED 
      || ActivityCompat.checkSelfPermission(context, permissionsRequired[3]) != PackageManager.PERMISSION_GRANTED 
      ) { 
     if (ActivityCompat.shouldShowRequestPermissionRationale(Splash.this, permissionsRequired[0]) 
       || ActivityCompat.shouldShowRequestPermissionRationale(Splash.this, permissionsRequired[1]) 
       || ActivityCompat.shouldShowRequestPermissionRationale(Splash.this, permissionsRequired[2]) 
       || ActivityCompat.shouldShowRequestPermissionRationale(Splash.this, permissionsRequired[3])) { 

      //Show Information about why you need the permission 
      AlertDialog.Builder builder = new AlertDialog.Builder(context); 
      builder.setTitle("Need Multiple Permissions"); 
      builder.setMessage("This app needs Camera Location, Storage and Phone permissions."); 
      builder.setPositiveButton("Grant", new DialogInterface.OnClickListener() { 
       @Override 
       public void onClick(DialogInterface dialog, int which) { 
        dialog.dismiss(); 
        ActivityCompat.requestPermissions(Splash.this, permissionsRequired, PERMISSION_CALLBACK_CONSTANT); 
       } 
      }).setNegativeButton("Cancel", new DialogInterface.OnClickListener() { 
       @Override 
       public void onClick(DialogInterface dialog, int which) { 
        dialog.dismiss(); 
        finish(); 
       } 
      }).create().show(); 
     } else if (permissionStatus.getBoolean(permissionsRequired[0], false) 
       || permissionStatus.getBoolean(permissionsRequired[1], false) 
       || permissionStatus.getBoolean(permissionsRequired[2], false) 
       || permissionStatus.getBoolean(permissionsRequired[3], false) 
       ) { 
      //Previously Permission Request was cancelled with 'Dont Ask Again', 
      // Redirect to Settings after showing Information about why you need the permission 
      AlertDialog.Builder builder = new AlertDialog.Builder(context); 
      builder.setTitle("Need Multiple Permissions"); 
      builder.setMessage("This app needs Camera, Location, Storage and Phone permissions."); 
      builder.setPositiveButton("Grant", new DialogInterface.OnClickListener() { 
       @Override 
       public void onClick(DialogInterface dialog, int which) { 
        dialog.cancel(); 
        sentToSettings = true; 
        Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); 
        Uri uri = Uri.fromParts("package", getPackageName(), null); 
        intent.setData(uri); 
        startActivityForResult(intent, REQUEST_PERMISSION_SETTING); 
        // Toast.makeText(getApplicationContext(), "Go to Permissions to Grant Camera and Location", Toast.LENGTH_LONG).show(); 
       } 
      }).setNegativeButton("Cancel", new DialogInterface.OnClickListener() { 
       @Override 
       public void onClick(DialogInterface dialog, int which) { 
        dialog.cancel(); 
        finish(); 
       } 
      }).create().show(); 
     } else { 
      //just request the permission 
      ActivityCompat.requestPermissions(Splash.this, permissionsRequired, PERMISSION_CALLBACK_CONSTANT); 
     } 

     SharedPreferences.Editor editor = permissionStatus.edit(); 
     editor.putBoolean(permissionsRequired[0], false); 
     editor.putBoolean(permissionsRequired[1], false); 
     editor.putBoolean(permissionsRequired[2], false); 
     editor.putBoolean(permissionsRequired[3], false); 
     editor.apply(); 
    } else { 
     //You already have the permission, just go ahead. 
     splashTread.start(); 
    } 
} 
- 여기
private final int PERMISSION_CALLBACK_CONSTANT = 1; 
private final int REQUEST_PERMISSION_SETTING = 1; 
String[] permissionsRequired = new String[]{Manifest.permission.CAMERA, Manifest.permission.ACCESS_FINE_LOCATION, 
     Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CALL_PHONE}; 

검사 권한 '내 코드입니다 - .ZygoteInit.main (ZygoteInit.java:616) 여기

는 확인 권한에 대한 상수는 여기

그리고 17,451,515,콜백 함수입니다 -

@Override 
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { 
    if (requestCode == PERMISSION_CALLBACK_CONSTANT) { 
     //check if all permissions are granted 
     boolean allgranted = false; 
     for (int grantResult : grantResults) { 
      if (grantResult == PackageManager.PERMISSION_GRANTED) { 
       allgranted = true; 
      } else { 
       allgranted = false; 
       break; 
      } 
     } 

     if (allgranted) { 
      splashTread.start(); 
     } else if (ActivityCompat.shouldShowRequestPermissionRationale(Splash.this, permissions[0]) 
       || ActivityCompat.shouldShowRequestPermissionRationale(Splash.this, permissions[1]) 
       || ActivityCompat.shouldShowRequestPermissionRationale(Splash.this, permissions[2]) 
       || ActivityCompat.shouldShowRequestPermissionRationale(Splash.this, permissions[3])) { 

      AlertDialog.Builder builder = new AlertDialog.Builder(context); 
      builder.setTitle("Need Multiple Permissions"); 
      builder.setMessage("This app needs Camera, Location, Storage and Phone permissions."); 
      builder.setPositiveButton("Grant", new DialogInterface.OnClickListener() { 
       @Override 
       public void onClick(DialogInterface dialog, int which) { 
        dialog.cancel(); 
        ActivityCompat.requestPermissions(Splash.this, permissionsRequired, PERMISSION_CALLBACK_CONSTANT); 
       } 
      }).setNegativeButton("Cancel", new DialogInterface.OnClickListener() { 
       @Override 
       public void onClick(DialogInterface dialog, int which) { 
        dialog.cancel(); 
        finish(); 
       } 
      }).create().show(); 
     } else { 
      Toast.makeText(getBaseContext(), "Unable to get Permission", Toast.LENGTH_LONG).show(); 
     } 
    } 
} 

그리고 splashThread() 기능 모든 권한이 올바른 작동되는 부여 할 때 대기의 기능을하지만 난 어떤 권한을 거부 등을 진행 할 때 그 새로운 경고 대화 상자가해야 사용자에게 설정으로 보내지 만 앱이 비정상 종료 될 때 builder.show();

전체 클래스를 디버깅 한 경우에도 왜이 오류가 발생하는지 알 수 없습니다. 오류 및 해결책을 찾는 것을 도와 주시겠습니까?

답변

1

런타임 권한에 대한 Google의 가이드 라인을 다시 확인하여 내 대답에 대한 해결책을 찾았습니다.

ActivityCompat.shouldShowRequestPermissionRationale() 

사용자 응답 스레드를 차단하지 않아야 명시된 there으로 단지 사용자에게 권한 요구 사항에 대한 설명을 표시해야합니다.

그래서 나는 checkPermission() 호출

AlertDialog.Builder builder = new AlertDialog.Builder(context); 
      builder.setTitle("Need Multiple Permissions"); 
      builder.setMessage("This app needs Camera, Location, Storage and Phone permissions."); 
      builder.setPositiveButton("Grant", new DialogInterface.OnClickListener() { 
       @Override 
       public void onClick(DialogInterface dialog, int which) { 
        dialog.cancel(); 
        ActivityCompat.requestPermissions(Splash.this, permissionsRequired, PERMISSION_CALLBACK_CONSTANT); 
       } 
      }).setNegativeButton("Cancel", new DialogInterface.OnClickListener() { 
       @Override 
       public void onClick(DialogInterface dialog, int which) { 
        dialog.cancel(); 
        finish(); 
       } 
      }).create().show(); 

를 대체하여 그것을했다

관련 문제