2

SDK版本:35

平台(Android/iOS/web/all):Android

我的应用程序正在尝试从用户的相机中获取照片。在调用 ImagePicker.launchCameraAsync 之前,我只需在我的 expo App 中使用此代码

const { status } = await Permissions.askAsync(Permissions.CAMERA, Permissions.CAMERA_ROLL);.
if(status !== ‘granted’) {
    dispatchMsg(‘error’, ‘We need your permission to get photo’);
    return;
}

从用户的角度来看,他们会看到系统两次请求许可

在此处输入图像描述 在此处输入图像描述

问题是……即使用户已经授予了两者的权限,状态仍然是“拒绝”!有趣的是,这只发生在独立的生产应用程序中。如果我没记错的话……这个问题最近才发生。我的应用程序在 Playstore 中已经存在 6 个多月了,最初直到最近才出现问题。

我试图在生产中打印调试消息,结果如下:

  • Permissions.getAsync(Permissions.CAMERA):
    {“status”:“granted”,“expires”:“never”,“permissions”:{“camera”:{“status”:“granted”,“expires”:“never ”}}}

  • Permissions.getAsync(Permissions.CAMERA_ROLL):
    {“status”:“denied”,“expires”:“never”,“permissions”:{“cameraRoll”:{“status”:“denied”,“expires”:“never” ”}}}

我非常确定我选择授予权限......向我报告错误的用户也是如此。就像我在这个问题似乎最近才发生之前告诉你的那样。由于此问题仅发生在我的生产应用程序中,因此有任何解决方法的想法。

编辑:这是我的应用程序权限列表的屏幕截图,来自 Android 设置。似乎没有显示任何错误

在此处输入图像描述

4

3 回答 3

1

检查您的清单文件。

<uses-permission android:name=”android.permission.CAMERA”/>
<uses-permission android:name=”android.permission.WRITE_EXTERNAL_STORAGE”/>
<uses-permission android:name=”android.permission.READ_EXTERNAL_STORAGE”/>

例子。

    lateinit var imageCamera: ImageView
    lateinit var captureBtn: Button

    val REQUEST_IMAGE_CAPTURE = 1


    private val PERMISSION_REQUEST_CODE: Int = 101

    private var mCurrentPhotoPath: String? = null;
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        imageCamera= findViewById(R.id.image)
        captureBtn = findViewById(R.id.captureBtn)
        captureBtn.setOnClickListener(View.OnClickListener {
            if (checkPersmission()) takePicture() else requestPermission()
        })


    }


    override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
        when (requestCode) {
            PERMISSION_REQUEST_CODE -> {

                if ((grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED)
                        && grantResults[1] == PackageManager.PERMISSION_GRANTED) {

                    takePicture()

                } else {
                    Toast.makeText(this, "Permission Denied", Toast.LENGTH_SHORT).show()
                }
                return
            }

            else -> {

            }
        }
    }

    private fun takePicture() {

        val intent: Intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
        val file: File = createFile()

        val uri: Uri = FileProvider.getUriForFile(
                this,
                "com.example.android.fileprovider",
                file
        )
        intent.putExtra(MediaStore.EXTRA_OUTPUT, uri)
        startActivityForResult(intent, REQUEST_IMAGE_CAPTURE)

    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == Activity.RESULT_OK) {

            //To get the File for further usage
            val auxFile = File(mCurrentPhotoPath)


            var bitmap: Bitmap = BitmapFactory.decodeFile(mCurrentPhotoPath)
            imageCamera.setImageBitmap(bitmap)

        }
    }

    private fun checkPersmission(): Boolean {
        return (ContextCompat.checkSelfPermission(this, android.Manifest.permission.CAMERA) ==
                PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(this,
                android.Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED)
    }

    private fun requestPermission() {
        ActivityCompat.requestPermissions(this, arrayOf(READ_EXTERNAL_STORAGE, CAMERA), PERMISSION_REQUEST_CODE)
    }

    @Throws(IOException::class)
    private fun createFile(): File {
        // Create an image file name
        val timeStamp: String = SimpleDateFormat("yyyyMMdd_HHmmss").format(Date())
        val storageDir: File = getExternalFilesDir(Environment.DIRECTORY_PICTURES)
        return File.createTempFile(
                "JPEG_${timeStamp}_", /* prefix */
                ".jpg", /* suffix */
                storageDir /* directory */
        ).apply {
            // Save a file: path for use with ACTION_VIEW intents
            mCurrentPhotoPath = absolutePath
        }
    }
}
于 2020-07-09T19:51:55.420 回答
0

您必须在添加权限、清除缓存和 expo 发布后重新生成 shell-bundle。

于 2020-07-07T04:30:18.213 回答
0

由于我使用的是 Expo,我再次检查了 app.json 中的权限列表,发现 WRITE_EXTERNAL_STORAGE 不存在。在将应用程序部署到 App & Play 商店后,我一开始就发誓,该应用程序运行良好,但似乎在一定时间后问题出现了。由于 app.json 中权限的修改将需要重新提交完整的新版本到播放/应用商店(而不是仅仅将新版本发布到 Expo 进行 OTA 更新),我这样做了,之后我确认问题消失了

于 2020-07-19T10:35:37.673 回答