使用ACTION_GET_CONTENT或OPEN_DOCUMENT从Google相册提供者中选择 [英] Pick from Google Photos provider with ACTION_GET_CONTENT or OPEN_DOCUMENT

查看:194
本文介绍了使用ACTION_GET_CONTENT或OPEN_DOCUMENT从Google相册提供者中选择的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不知道为什么会发生这种情况,但是我无法从Google相册提供者中选择图片.在API 27上进行测试.

I have no clue at why this happens, but I am not able to pick images from the Google Photos provider. Testing on API 27.

如果我使用:

val intent = Intent(Intent.ACTION_GET_CONTENT)
intent.addCategory(Intent.CATEGORY_OPENABLE)
intent.type = "image/*"

  • 我可以在提供商中看到Google相册
  • 我可以浏览并选择一些图片
  • 然后,我将直接返回到提供程序列表(而不是我的应用程序),就像提供程序在尝试捕获中崩溃一样
  • 当我打开照片"提供程序并浏览文件夹时,会看到很多这样的文件:

    When I open the Photos provider and navigate through folders I see lots of these:

    2019-03-02 12:04:15.164 17641-13395/? W/NetworkManagementSocketTagger: untagSocket(120) failed with errno -22
    2019-03-02 12:04:22.528 13217-13217/? E/ResourceType: Style contains key with bad entry: 0x01010586
    2019-03-02 12:04:22.535 13217-13217/? W/ResourceType: For resource 0x7f020366, entry index(870) is beyond type entryCount(468)
    

    当我点击图片时,我看到了这些:

    When I click on the picture, I see these:

    2019-03-02 12:04:34.150 13217-13217/? W/ResourceType: For resource 0x7f02036c, entry index(876) is beyond type entryCount(468)
    2019-03-02 12:04:34.151 13217-13217/? W/ResourceType: For resource 0x7f02036c, entry index(876) is beyond type entryCount(468)
    2019-03-02 12:04:34.229 2907-16891/? W/MediaExtractor: FAILED to autodetect media content.
    2019-03-02 12:04:34.569 10839-10839/? W/ResourceType: ResTable_typeSpec entry count inconsistent: given 468, previously 1330
    

    使用ACTION_OPEN_DOCUMENT

    在这种情况下,我什至没有在提供商抽屉中看到Google相册.

    With ACTION_OPEN_DOCUMENT

    In this case I don't even see Google Photos in the providers drawer.

    我该如何解决这个问题,最好是使用ACTION_GET_CONTENT?

    How can I solve this, preferably with ACTION_GET_CONTENT?

    推荐答案

    编辑2

    我认为我找到了解决问题的方法.在 Google文档中提到访问共享文件将为您提供 URI .

    I think i found the solution of the problem. It is mentioned in the Google docs that accessing a shared file will give you the URI.

    服务器应用程序将Intent中的文件内容URI发送回客户端应用程序.该Intent在其onActivityResult()的覆盖范围内传递给客户端应用程序.客户端应用程序具有文件的内容URI后,便可以通过获取其FileDescriptor来访问文件.

    The server app sends the file's content URI back to the client app in an Intent. This Intent is passed to the client app in its override of onActivityResult(). Once the client app has the file's content URI, it can access the file by getting its FileDescriptor.

    以下是我在 onActivityResult 内部使用的更新代码.确保最后调用onActivityResult的 super 方法.

    Below is the updated code i am using inside onActivityResult. Make sure to call the super method of onActivityResult at last.

    super.onActivityResult(requestCode,resultCode,数据)

    super.onActivityResult(requestCode, resultCode, data)

    工作代码

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    data?.data?.let {
        util._log(TAG, it.toString())
    }
    if (data!!.data != null && data.data != null) {
        try {
    
            val stream = if (data.data!!.toString().contains("com.google.android.apps.photos.contentprovider")) {
                val ff = contentResolver.openFileDescriptor(data.data!!, "r")
                FileInputStream(ff?.fileDescriptor)
            } else {
                contentResolver.openInputStream(data.data!!)
            }
            val createFile = createImageFile()
            util.copyInputStreamToFile(stream, createFile)
            selectedImagePath = createFile.absolutePath
    
        } catch (e: Exception) {
            util._log(TAG, Log.getStackTraceString(e))
        }
    }
        super.onActivityResult(requestCode, resultCode, data)
    }
    

    编辑

    也请查看此 stackoverflow帖子

    原始

    我正在Redmi 6 pro手机的Android oreo 8.1.0(API 27)上使用它,并且运行正常.

    I am using it on Android oreo 8.1.0(API 27) on my Redmi 6 pro phone and it is working fine.

    您尚未发布 onActivityResult 方法,这可能是您需要进行一些修改的地方.我都尝试过

    You haven't posted the onActivityResult method may be this is where you need to do some modifications. I have tried it both

    下面是我的代码段

    val pickIntent = Intent(Intent.ACTION_VIEW)
    pickIntent.type = "image/*"
    pickIntent.action = Intent.ACTION_GET_CONTENT
    pickIntent.addCategory(Intent.CATEGORY_OPENABLE)
    
    startActivityForResult(pickIntent, SELECT_PICTURE)
    

    ,并且在 onActivityResult 中,我像这样解析它

    and in onActivityResult i am parsing it like this

    if (data!!.data != null && data.data != null) {
        try {
            //                    CommonUtilities._Log(TAG, "Data Type " + data.getType());
            if (!isFinishing) {
                val inputStream = contentResolver.openInputStream(data.data!!)
                val createFile = createImageFile()
                copyInputStreamToFile(inputStream!!, createFile)
                //                        CommonUtilities._Log(TAG, "File Path " + createFile.getAbsolutePath());
                selectedImagePath = createFile.absolutePath
            }
        } catch (e: IOException) {
            util._log(TAG, Log.getStackTraceString(e))
        }
    }
    

    创建新文件的方法

    @Throws(IOException::class)
    private fun createImageFile(): File {
        // Create an image file name
        val timeStamp = SimpleDateFormat("yyyyMMdd_HHmmss", Locale.ENGLISH).format(Date())
        val imageFileName = "yesqueen_" + timeStamp + "_"
        val storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)
        return File.createTempFile(imageFileName, ".jpg", storageDir)
    }
    

    从输入流读取的方法

    fun copyInputStreamToFile(`in`: InputStream, file: File) {
        var out: OutputStream? = null
        try {
            out = FileOutputStream(file)
            val buf = ByteArray(1024)
            var len: Int = 0
            while (`in`.read(buf).apply { len = this } > 0) {
                out.write(buf, 0, len)
            }
    
            /*while (`in`.read(buf).let {
                        len = it
                        true
                    }) {
                out.write(buf, 0, len)
            }*/
            /* while ((len = `in`.read(buf)) > 0) {
                 out.write(buf, 0, len)
             }*/
        } catch (e: Exception) {
            e.printStackTrace()
        } finally {
            try {
                out?.close()
            } catch (e: Exception) {
                e.printStackTrace()
            }
    
            try {
                `in`.close()
            } catch (e: Exception) {
                e.printStackTrace()
            }
    
        }
    }
    

    这篇关于使用ACTION_GET_CONTENT或OPEN_DOCUMENT从Google相册提供者中选择的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆