我不知道为什么会发生这种情况,但是我无法从Google相册提供者中选择图片。在API 27上进行测试。
如果我使用:
val intent = Intent(Intent.ACTION_GET_CONTENT)
intent.addCategory(Intent.CATEGORY_OPENABLE)
intent.type = "image/*"
当我打开“照片”提供程序并浏览文件夹时,会看到很多这样的文件:
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)
当我点击图片时,我看到了这些:
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
在这种情况下,我什至没有在提供商抽屉中看到Google相册。
我该如何解决这个问题,最好使用ACTION_GET_CONTENT?
答案 0 :(得分:3)
编辑2
我认为我找到了解决问题的方法。 Google docs中提到访问共享文件将为您提供 URI 。
服务器应用程序将Intent中的文件内容URI发送回客户端应用程序。该Intent在其onActivityResult()的覆盖范围内传递给客户端应用程序。客户端应用拥有文件的内容URI后,便可以通过获取其FileDescriptor来访问文件。
以下是我在 onActivityResult 内部使用的更新代码。确保最后调用onActivityResult的 super 方法。
super.onActivityResult(requestCode,resultCode,数据)
工作代码
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 post
原始
我正在Redmi 6 pro手机的Android oreo 8.1.0(API 27)上使用它,并且运行正常。
您尚未发布 onActivityResult 方法,这可能是您需要进行一些修改的地方。我都尝试过
下面是我的代码段
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 中,我像这样解析它
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()
}
}
}
答案 1 :(得分:0)
ACTION_PICK 将提供选择图像的选项,您可以获取文件路径
Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Image.Media.EXTERNAL_CONTENT_URI);
intent.setType("image/*");
Intent sIntent = new Intent("com.sec.android.app.myfiles.PICK_DATA");
sIntent.addCategory(Intent.CATEGORY_DEFAULT);
sIntent.setType("image/*");
Intent chooserIntent;
if (getPackageManager().resolveActivity(sIntent, 0) != null) {
// it is device with samsung file manager
chooserIntent = Intent.createChooser(sIntent, "Select file");
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Intent[]{intent});
} else {
chooserIntent = Intent.createChooser(intent, "Select file");
}
try {
startActivityForResult(chooserIntent, REQUEST_TAKE_GALLERY_VIDEO);
} catch (android.content.ActivityNotFoundException ex) {
Toast.makeText(getApplicationContext(), "No suitable File Manager was found.", Toast.LENGTH_SHORT).show();
}
答案 2 :(得分:0)
我遇到了同样的问题,我无法以ACTION_GET_CONTENT
的意图从Google相册获取图像URI。问题与我的活动launchMode
有关。我找不到对Android文档的任何引用。但是这样问题就完全解决了:
我有一个活动申请,而我的ACTION_GET_CONTENT
意图是这样的:
val intent = Intent(Intent.ACTION_GET_CONTENT).apply {
type = "image/*"
}
startActivityForResult(intent, GALLERY_RESULT)
问题是AndroidManifest.xml中活动的定义中的singleInstance
启动模式。
<activity
android:name=".ui.MainActivity"
android:configChanges="orientation"
android:launchMode="singleInstance"
android:screenOrientation="portrait"
android:theme="@style/AppTheme"
android:windowSoftInputMode="adjustResize|stateHidden"/>
通过删除android:launchMode行解决了该问题。如果您的活动需要为singleInstance
,那么创建一个虚拟活动将是一个很好的解决方案。在这里,您可以为结果启动一个虚拟活动,然后在其onCreate
内执行Intent任务,然后在setResult()
内进行您请求的活动:
class ImagePickerActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val intent = Intent(Intent.ACTION_GET_CONTENT).apply {
type = "image/*"
}
if (intent.resolveActivity(packageManager!!) != null) {
startActivityForResult(intent, GALLERY_RESULT)
} else {
Toast.makeText(
this,
"No Gallery APP installed",
Toast.LENGTH_LONG
).show()
finish()
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
//here data is resulted URI from ACTION_GET_CONTENT
//and we pass it to our MainActivy using setResult
setResult(resultCode, data)
finish()
}
}
这是您在MainActivity中的代码:
gallery.setOnClickListener {
startActivityForResult(
Intent(requireActivity(), ImagePickerActivity::class.java),
GALLERY_RESULT
)
}