【问题标题】:requestPermissions() does NOTHINGrequestPermissions() 什么都不做
【发布时间】:2016-12-24 06:05:37
【问题描述】:

问题...

我正在尝试在 Android Marshmallow 中实现运行时权限,同时保持向后兼容性。我以前成功地做到了这一点,我不确定这次有什么不同。我已经在物理 Note 5(运行 Mallow)上对其进行了测试,并使用在 Marshmallow 上设置的模拟器,两者都不起作用。

我意识到“它不起作用”并不是很有帮助,但我不知道还能说什么,没有任何反应。应用程序不会崩溃,它只是在调用 requestPermissions(perms, 222) 后挂起。

我做错了什么?

详情...

我活动的相关部分:

public class HomeActivity extends Activity implements View.OnClickListener {

    @Override
    public void onClick(View v) {
        switch(v.getId()){
            case R.id.btn_home_scancertificate:
                if (ContextCompat.checkSelfPermission(HomeActivity.this, "android.permission.CAMERA") != PackageManager.PERMISSION_GRANTED){
                    showNoPermDialog();
                }else {
                    AppData.ActionType = ActionType.SCAN_CERTIFICATE;
                    intent = new Intent(HomeActivity.this, CaptureActivity.class);
                    startActivity(intent);
                }
                break;
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
        Log.e("HomeActivity", "Permissions results...");

        switch (requestCode) {
            case 222: {

                boolean granted = (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED);
                Log.e("HomeActivity", granted?"granted permission":"denied permission");

                AppData.ActionType = ActionType.SCAN_POSTCARD;
                intent = new Intent(HomeActivity.this, CaptureActivity.class);
                startActivity(intent);
            }
        }
    }

    public void getCamPerm(){
        Log.e("HomeActivity", "Build version: "+Build.VERSION.SDK_INT);
        if (Build.VERSION.SDK_INT >= 23) {
            Log.e("HomeActivity", "Getting permissions");

            String[] perms = new String[]{Manifest.permission.CAMERA};
            requestPermissions(perms, 222);
        }
    }

    public void showNoPermDialog(){
        if (Build.VERSION.SDK_INT >= 23) {
            boolean showRationale = shouldShowRequestPermissionRationale(Manifest.permission.CAMERA);

            String status = showRationale ? "showing rationale" : "skipping rationale";
            Log.e("HomeActivity", status);

            if (showRationale) {
                AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
                alertDialogBuilder.setTitle("Need permission");
                alertDialogBuilder
                    .setMessage("App requires camera permission for the use of the scanner.")
                    .setCancelable(false)
                    .setPositiveButton("Ok", new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int id) {
                            dialog.cancel();
                            getCamPerm();
                        }
                    });
                AlertDialog alertDialog = alertDialogBuilder.create();
                alertDialog.show();
            }else getCamPerm();

        }else {

            AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
            alertDialogBuilder.setTitle("Need permission");
            alertDialogBuilder
                    .setMessage("App requires permission to use the camera. You have disabled camera permission. Please re-enable this permission thru Settings -> Apps -> Our Town -> Permissions.")
                    .setCancelable(false)
                    .setPositiveButton("Ok", new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int id) {
                            dialog.cancel();
                        }
                    });
            AlertDialog alertDialog = alertDialogBuilder.create();
            alertDialog.show();
        }
    }

}

运行时,只记录这些(onRequestPermissionsResult() 根本不会被调用)

E/HomeActivity:跳过理由

E/HomeActivity:构建版本:23

E/HomeActivity:获取权限

清单包括:<uses-permission android:name="android.permission.CAMERA" />

编辑

仅在我第一次单击该按钮时,它才会显示在 Logcat 中,并且似乎是由对 shouldShowRequestPermissionRationale() 的调用触发的

08-17 11:26:36.996 20660-20660/com.ourtownamerica.ourtowntrutrak W/ViewRootImpl: Cancelling event due to no window focus: MotionEvent { action=ACTION_CANCEL, actionButton=0, id[0]=0, x[0]=1035.6592, y[0]=770.2344, toolType[0]=TOOL_TYPE_FINGER, buttonState=0, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, historySize=0, eventTime=8508970, downTime=8506643, deviceId=0, source=0x1002 }
08-17 11:26:36.996 20660-20660/com.ourtownamerica.ourtowntrutrak W/ViewRootImpl: Cancelling event due to no window focus: MotionEvent { action=ACTION_CANCEL, actionButton=0, id[0]=0, x[0]=1035.6592, y[0]=770.2344, toolType[0]=TOOL_TYPE_FINGER, buttonState=0, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, historySize=0, eventTime=8508970, downTime=8506643, deviceId=0, source=0x1002 }
08-17 11:26:36.996 20660-20660/com.ourtownamerica.ourtowntrutrak W/ViewRootImpl: Cancelling event due to no window focus: MotionEvent { action=ACTION_CANCEL, actionButton=0, id[0]=0, x[0]=1035.6592, y[0]=770.2344, toolType[0]=TOOL_TYPE_FINGER, buttonState=0, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, historySize=0, eventTime=8508970, downTime=8506643, deviceId=0, source=0x1002 }
08-17 11:26:36.997 20660-20660/com.ourtownamerica.ourtowntrutrak W/ViewRootImpl: Cancelling event due to no window focus: MotionEvent { action=ACTION_CANCEL, actionButton=0, id[0]=0, x[0]=1035.6592, y[0]=770.2344, toolType[0]=TOOL_TYPE_FINGER, buttonState=0, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, historySize=0, eventTime=8508970, downTime=8506643, deviceId=0, source=0x1002 }

编辑 2

我从它所在的 Activity 中复制了相同的原始代码并将其移至启动 Activity,它在那里工作正常。它现在可以留在那里,但如果有人知道发生了什么,我们仍然很感激。

【问题讨论】:

标签: java android android-6.0-marshmallow runtime-permissions


【解决方案1】:

好吧,尝试使用 Manifest.permission.CAMERA 而不是“android.permission.CAMERA”

还用于代码质量检查 android 是否为 23在按钮中单击本身 R.id.btn_home_scancertificate:

if (Build.VERSION.SDK_INT >= 23 && ContextCompat.checkSelfPermission(activity,
            Manifest.permission.CAMERA)
            != PackageManager.PERMISSION_GRANTED) {

        showNoPermDialog();

    } else {
        AppData.ActionType = ActionType.SCAN_CERTIFICATE;
                intent = new Intent(HomeActivity.this, CaptureActivity.class);
                startActivity(intent);
    }

    //in alertdialog button simply place this for requesting permission
    ActivityCompat.requestPermissions(activity,
            new String[]{Manifest.permission.CAMERA},
            222);

【讨论】:

  • 谢谢。我做了你建议的两个改变,但没有改变。问题是,shouldShowRequestPermissionRationale() 总是返回 false,因为对话框还没有打开,所以我还没有机会拒绝权限。
  • 我已将每次出现的getCamPerm() 替换为对ActivityCompat.requestPermissions() 的调用,但仍然没有帮助。
【解决方案2】:

对于 M 权限,我一直在使用来自 this answer 的以下类:

public class MarshmallowPermission {
    public static final int EXTERNAL_STORAGE_PERMISSION_REQUEST_CODE = 2;
    public static final int CAMERA_PERMISSION_REQUEST_CODE = 3;

    public MarshmallowPermission() {
    }

    public boolean checkPermissionForExternalStorage(Activity activity) {
        if(Build.VERSION.SDK_INT >= 23) {
            int result = ContextCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE);
            if(result == PackageManager.PERMISSION_GRANTED) {
                return true;
            } else {
                return false;
            }
        } else {
            return true;
        }
    }

    public boolean checkPermissionForCamera(Activity activity) {
        if(Build.VERSION.SDK_INT >= 23) {
            int result = ContextCompat.checkSelfPermission(activity, Manifest.permission.CAMERA);
            if(result == PackageManager.PERMISSION_GRANTED) {
                return true;
            } else {
                return false;
            }
        } else {
            return true;
        }
    }

    public void requestPermissionForExternalStorage(Activity activity) {
        if(ActivityCompat.shouldShowRequestPermissionRationale(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
            Toast.makeText(activity,
                    "External Storage permission needed. Please allow in App Settings for additional functionality.",
                    Toast.LENGTH_LONG).show();
        } else {
            ActivityCompat.requestPermissions(activity,
                    new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
                    EXTERNAL_STORAGE_PERMISSION_REQUEST_CODE);
        }
    }

    public void requestPermissionForCamera(Activity activity) {
        if(ActivityCompat.shouldShowRequestPermissionRationale(activity, Manifest.permission.CAMERA)) {
            Toast.makeText(activity,
                    "Camera permission needed. Please allow in App Settings for additional functionality.",
                    Toast.LENGTH_LONG).show();
        } else {
            ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.CAMERA}, CAMERA_PERMISSION_REQUEST_CODE);
        }
    }
}

像这样工作:

        if(marshmallowPermission.checkPermissionForCamera(activity)) {
            // has camera
        } else {
            marshmallowPermission.requestPermissionForCamera(activity);
        }

并在Activity回调中处理

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    // handle request code
}

【讨论】:

  • 感谢您的课程。不用找了。在这一点上,我确信问题与 Logcat 中的警告有关,而不是与实际权限相关的代码有关。我将不得不对它们进行一些研究..
【解决方案3】:

问题可能源于在请求许可之前致电shouldShowRequestPermissionRationale()。有一个针对此的错误 (here) 记录在案,这尤其糟糕,因为 Google 的一些示例/教程遵循这种模式。

要解决它,请检查权限,如果您尚未获得权限,请请求权限。在onRequestPermissionsResult() 中检查您是否应该说明理由。如果用户拒绝了权限并且他们没有选择不再被询问的选项,这只会返回true。

您可能会发现使用 Andele 库更容易使用此指南和推荐的 UX 指南。

【讨论】:

    猜你喜欢
    • 2019-03-08
    • 2017-04-18
    • 2011-08-03
    • 2014-05-11
    • 2014-09-10
    • 1970-01-01
    • 2023-03-29
    • 2013-09-28
    • 2012-05-09
    相关资源
    最近更新 更多