2017-01-05 100 views
0

我使用hotchemi PermissionsDispatcher來檢查權限。它完美適用於API> = 23。但是,當我嘗試在API 16的設備上使用相同的代碼時,我得到了一個致命的異常java.lang.StackOverflowError。當我在生成的類中調用MainActivityPermissionsDispatcher時出現錯誤API PermissionsDispatcher API <23

我深入到由PermissionsDispatcher庫生成的類MainActivityPermissionsDispatcher,並找到堆棧溢出發生的原因。當我打電話MainActivityPermissionsDispatcher.showCameraWithCheck(this);它關係到這個方法在產生MainActivityPermissionsDispatcher

static void showCameraWithCheck(MainActivity target) { 
if (PermissionUtils.hasSelfPermissions(target, PERMISSION_SHOWCAMERA)) { 
    target.showCamera(); 
} else { 
    if (PermissionUtils.shouldShowRequestPermissionRationale(target, PERMISSION_SHOWCAMERA)) { 
    target.showRationaleForCamera(new ShowCameraPermissionRequest(target)); 
    } else { 
    ActivityCompat.requestPermissions(target, PERMISSION_SHOWCAMERA, REQUEST_SHOWCAMERA); 
    } 
} 

}

的事情是PermissionUtils.hasSelfPermissions(target, PERMISSION_SHOWCAMERA)始終是真實的,因此被稱爲target.showCamera()這是我的方法誰叫MainActivityPermissionsDispatcher.showCameraWithCheck(this);所以在沒有進入end loop ....我想hasSelfPermissions()方法檢查它是運行時權限(API> = 23)還是舊式權限(< API 23)。

E/AndroidRuntime:致命異常:主 java.lang.StackOverflowError的 在android.os.Parcel.readException(Parcel.java:1376) 在 android.app.ActivityManagerProxy.checkPermission(ActivityManagerNative.java :2874) 在android.app.ContextImpl.checkPermission(ContextImpl.java:1285) 在 android.content.ContextWrapper.checkPermission(ContextWrapper.java:421) 在 android.support.v4.content.PermissionCh ecker.checkPermission(PermissionChecker.java:89) 在 android.support.v4.content.PermissionChecker.checkSelfPermission(PermissionChecker.java:125) 在 permissions.dispatcher.PermissionUtils.hasSelfPermissions(PermissionUtils.java:73) 在 com.example.android.permissionsdispatcherapp.MainActivityPermissionsDispatcher.showCameraWithCheck(MainActivityPermissionsDispatcher.java:20) 在 com.example.android.permissionsdispatcherapp.MainActivity.showCamera(MainActivity.java:52) ......... .............

@RuntimePermissions 
public class MainActivity extends AppCompatActivity { 
private static String LOG_TAG = MainActivity.class.getSimpleName(); 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    try { 

     Button btnShowCamera = (Button) findViewById(R.id.btn_show_camera); 
     btnShowCamera.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View view) { 
       Log.i(LOG_TAG, "Show camera button pressed."); 
       showCamera(); 
      } 

     }); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 

@NeedsPermission(Manifest.permission.CAMERA) 
void showCamera() { 
    // NOTE: delegate the permission handling to generated method 
    // ERROR 
    MainActivityPermissionsDispatcher.showCameraWithCheck(this); 
} 

@Override 
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { 
    super.onRequestPermissionsResult(requestCode, permissions, grantResults); 
    // NOTE: delegate the permission handling to generated method 
    MainActivityPermissionsDispatcher.onRequestPermissionsResult(this, requestCode, grantResults); 
} 

@OnPermissionDenied(Manifest.permission.CAMERA) 
void onCameraDenied() { 
    // NOTE: Deal with a denied permission, e.g. by showing specific UI 
    // or disabling certain functionality 
    Toast.makeText(this, R.string.permission_camera_denied, Toast.LENGTH_LONG).show(); 
} 

@OnNeverAskAgain(Manifest.permission.CAMERA) 
void onCameraNeverAskAgain() { 
    Toast.makeText(this, R.string.permission_camera_never_askagain, Toast.LENGTH_LONG).show(); 
} 

@OnShowRationale(Manifest.permission.CAMERA) 
void showRationaleForCamera(PermissionRequest request) { 
    // NOTE: Show a rationale to explain why the permission is needed, e.g. with a dialog. 
    // Call proceed() or cancel() on the provided PermissionRequest to continue or abort 
    showRationaleDialog(R.string.permission_camera_rationale, request); 
} 

private void showRationaleDialog(@StringRes int messageResId, final PermissionRequest request) { 
    new AlertDialog.Builder(this) 
      .setPositiveButton(R.string.button_allow, new DialogInterface.OnClickListener() { 
       @Override 
       public void onClick(@NonNull DialogInterface dialog, int which) { 
        request.proceed(); 
       } 
      }) 
      .setNegativeButton(R.string.button_deny, new DialogInterface.OnClickListener() { 
       @Override 
       public void onClick(@NonNull DialogInterface dialog, int which) { 
        request.cancel(); 
       } 
      }) 
      .setCancelable(false) 
      .setMessage(messageResId) 
      .show(); 
} 
} 

enter code here 

回答

1

找到了方法。我的代碼錯了。 它不需要調用showCamera()方法,因爲生成的類MainActivityPermissionsDispatcher已經做到了。由於API 16沒有運行時權限,因此無法結束循環。

這是修復:

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    try { 
      Button btnShowCamera = (Button) findViewById(R.id.btn_show_camera); 
      btnShowCamera.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View view) { 
      Log.i(LOG_TAG, "Show camera button pressed."); 
      askForPermission(); 
      } 

     }); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 

void askForPermission() { 
    MainActivityPermissionsDispatcher.showCameraWithCheck(this); 
} 

@NeedsPermission(Manifest.permission.CAMERA) 
void showCamera() { 
    Toast.makeText(this, "Showing camera", Toast.LENGTH_LONG).show(); 
} 
相關問題