仅在单击按钮后请求相机权限

Posted

技术标签:

【中文标题】仅在单击按钮后请求相机权限【英文标题】:request camera permission only after button is clicked 【发布时间】:2020-10-19 09:18:18 【问题描述】:

我创建了一个应用程序,我可以在其中放置个人资料图片,它看起来如下:

当相机按钮被点击时,有两个选项:

现在,我希望我的应用在用户点击“相机”选项后询问他们是否允许我授予相机权限,但我不知道该怎么做。

目前,应用在用户首次进入此活动时会请求权限。

如何使授予权限仅在单击此 Cemra 按钮后才弹出?

我的代码是:

private void showPictureDialog()
    AlertDialog.Builder pictureDialog = new AlertDialog.Builder(this);
    pictureDialog.setTitle("Select Action");
    String[] pictureDialogItems = "Photo Gallery", "Camera" ;
    pictureDialog.setItems(pictureDialogItems,
            (dialog, which) -> 
                switch (which) 
                    case 0:
                        choosePhotoFromGallary();
                        break;
                    case 1:
                        takePhotoFromCamera();
                        break;
                
             );
    pictureDialog.show();

public void choosePhotoFromGallary() 
    Intent galleryIntent = new Intent(Intent.ACTION_PICK,
            android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);

    startActivityForResult(galleryIntent, AppConstants.GALLERY);


private void takePhotoFromCamera() 
    Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
    startActivityForResult(intent, AppConstants.CAMERA);


@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) 

    super.onActivityResult(requestCode, resultCode, data);
    if (resultCode == RESULT_CANCELED) 
        return;
    
    Bitmap fixBitmap;
    if (requestCode == AppConstants.GALLERY) 
        if (data != null) 
            Uri contentURI = data.getData();
            try 
                DOES SOMETHING
             catch (IOException ignored) 

            
        

     else if (requestCode == AppConstants.CAMERA) 
            DOES SOMETHING
    


@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) 
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if (requestCode == 5) 
        if (grantResults[0] == PackageManager.PERMISSION_GRANTED) 

        

    

谢谢

【问题讨论】:

你把“请求相机权限”代码放在哪里了? 在主类ProfileACtivity扩展了AppCompactActivity,在onCreate之外 请检查我的回答。希望有所帮助:) 【参考方案1】:

您的问题的想法是:您应该在用户单击对话框上的“相机”选项时请求相机权限,而不是在创建活动时

以下是我的解决方案:

首先删除您当前的“请求相机权限”代码

private void showPictureDialog()
    ...
                    case 1:
                        checkPermissionAndOpenCamera();
                        break;
    ...


/**
 * This will check your app camera permission.
 * If its granted, open camera
 * else request camera permission then open it later.
 */
void checkPermissionAndOpenCamera() 
    if (ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.CAMERA)
            == PackageManager.PERMISSION_DENIED) 
        ActivityCompat.requestPermissions(this, new String[] Manifest.permission.CAMERA, 5);
     else 
        takePhotoFromCamera();
    



private void takePhotoFromCamera() 
    Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
    startActivityForResult(intent, AppConstants.CAMERA);


@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) 
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if (requestCode == 5) 
        if (grantResults[0] == PackageManager.PERMISSION_GRANTED) 
            takePhotoFromCamera();
        

    

【讨论】:

它仍然在我进入活动的那一刻问我,而不仅仅是在我点击相机之后。 您是否删除了之前的相机权限检查码?我可以看看你的完整代码吗? 据我了解,它应该在 if (requestCode == AppConstants.CAMERA) 中的某处 我不认为这是我们的问题 :) 因为 onActivityResult 仅在您的相机打开并完成拍照或取消后才会调用。 您能否更新您的onCreate 功能代码。我认为这会导致你的问题:)【参考方案2】:

为了请求权限,我使用了来自 Karumi 的优秀库 Dexter:

https://github.com/Karumi/Dexter

我的情况和你一样,我做的就是这样:

txt_choose_from_gallery.setOnClickListener 
    checkPhotoPermissions 
        choosePictureFromGallery()
    


txt_take_picture.setOnClickListener 
    checkPhotoPermissions 
        takePictureWithCamera()
    


private fun checkPhotoPermissions(onPermissionGranted: () -> Unit) 
        Dexter.withActivity(activity)
            .withPermissions(
                android.Manifest.permission.READ_EXTERNAL_STORAGE,
                android.Manifest.permission.WRITE_EXTERNAL_STORAGE
            )
            .withListener(object : BaseMultiplePermissionsListener() 
                override fun onPermissionsChecked(response: MultiplePermissionsReport) 
                    if (response.areAllPermissionsGranted()) 
                        onPermissionGranted()
                    
                
            )
            .check()
    

你可以很方便的使用转换成Java,只要把高阶函数onPermissionGranted: () -> Unit改成接口,例如:

interface OnPermissionGrantedListner 
    void onPermissionGranted();


private void checkPhotoPermission(OnPermissionGrantedListener listener) 
    // Dexter code for checking permission, invoke listener in overridden onPermissionChecked method in BaseMultiplePermissionsListener
    listener.onPermissionGranted()


private void showPictureDialog()
    AlertDialog.Builder pictureDialog = new AlertDialog.Builder(this);
    pictureDialog.setTitle("Select Action");
    String[] pictureDialogItems = "Photo Gallery", "Camera" ;
    pictureDialog.setItems(pictureDialogItems,
            (dialog, which) -> 
                switch (which) 
                    case 0:
                        checkPhotoPermission(new OnPermissionGrantedListener 
                            @Override
                            void onPermissionGranted() 
                                choosePhotoFromGallery();
                            
                        
                        break;
                    case 1:
                        checkPhotoPermission(new OnPermissionGrantedListener 
                            @Override
                            void onPermissionGranted() 
                                takePhotoFromCamera();
                            
                                                    
                        break;
                
             );
    pictureDialog.show();

【讨论】:

以上是关于仅在单击按钮后请求相机权限的主要内容,如果未能解决你的问题,请参考以下文章

从android中的意图选择器中选择选项(相机或画廊)后请求权限

Flutter 在按下按钮或 onpressed 事件后授予相机和麦克风权限

Navigator.share 仅在 iOS 中工作一次,第二次单击会引发错误“用户代理不允许请求...”

如何在 Flutter 中请求和检查权限

在请求并授予权限后立即执行 ACTION_CALL 意图

Firebase iOS 11 在按钮按下后要求用户通知