Android 仅抛出 11 个 ActivityResult RESULT_CANCELED
Android 11 ActivityResult throwing only RESULT_CANCELED
我们正在使用此代码选择 image/video 个文件
//Pick an image from storage
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.setType(type); //Can be image/* or video/*
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
activityResultLauncher.launch(Intent.createChooser(intent, "Select Item"));
然后在新的ActivityResult上获取文件UriAPI
protected final ActivityResultLauncher<Intent> activityResultLauncher = registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(),
result -> {
Log.wtf("WTF", result.toString());
if (result.getResultCode() == Activity.RESULT_OK) {
// There are no request codes
Intent data = result.getData();
if (data == null) {
Toast.makeText(getContext(), R.string.unknown_error, Toast.LENGTH_SHORT).show();
return;
}
activityResult(true, data);
}
else
activityResult(false, null);
});
不幸的是,在更新到 Android 11 之后,我们得到的只是 RESULT_CANCELED
。
E/WTF: ActivityResult{resultCode=RESULT_CANCELED, data=null}
正如 Ian 所说,您不应该使用 Intent.createChooser
和 ACTION_OPEN_DOCUMENT
,尽管它在 Android 11.
之前有效
这是一个帮助程序 class,您使用 select image/video/pdf 使用 Activity 结果 API 作为合同 return 您Uri 的列表。它可以配置为单个或多个 selection 文件。
在 android 10 和 11 中测试。
class SelectFileContract : ActivityResultContract<Pair<SELECTION_TYPE, Boolean>, List<Uri>?>() {
var TAG = this.javaClass.simpleName
override fun createIntent(context: Context, input: Pair<SELECTION_TYPE, Boolean>): Intent {
var intent: Intent? = null
intent = when (input.first) {
SELECTION_TYPE.IMAGE -> Intent(
Intent.ACTION_PICK,
MediaStore.Images.Media.EXTERNAL_CONTENT_URI
)
SELECTION_TYPE.VIDEO -> Intent(
Intent.ACTION_PICK,
MediaStore.Video.Media.EXTERNAL_CONTENT_URI
)
SELECTION_TYPE.PDF -> {
Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
type = "application/pdf"
addCategory(Intent.CATEGORY_OPENABLE)
}
}
}
if (input.second == true) {
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true)
}
return intent!!
}
override fun parseResult(resultCode: Int, intent: Intent?): List<Uri>? = when (resultCode) {
Activity.RESULT_OK -> {
val uriList = mutableListOf<Uri>()
/**
* in case of single selection the Uri will be inside [intent.data]
*/
intent?.data?.let { uriList.add(it) }
/**
* in case of multiple selection the Uri will be inside [intent.clipData]
*/
intent?.clipData?.let { clipData: ClipData ->
for (i in 0 until clipData.itemCount) {
uriList.add(clipData.getItemAt(i).uri)
}
}
Log.d(TAG, uriList.toString())
uriList
}
else -> null
}
}
enum class SELECTION_TYPE {
IMAGE,
VIDEO,
PDF
}
然后在activity具体合同:
private val simpleContractRegistration =
registerForActivityResult(SelectFileContract()) { result: List<Uri>? ->
result?.let {
Log.d(TAG, result.toString())
}
}
然后启动注册:
binding.button.setOnClickListener {
simpleContractRegistration.launch(
Pair(
SELECTION_TYPE.IMAGE,
false
)
)
}
我们正在使用此代码选择 image/video 个文件
//Pick an image from storage
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.setType(type); //Can be image/* or video/*
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
activityResultLauncher.launch(Intent.createChooser(intent, "Select Item"));
然后在新的ActivityResult上获取文件UriAPI
protected final ActivityResultLauncher<Intent> activityResultLauncher = registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(),
result -> {
Log.wtf("WTF", result.toString());
if (result.getResultCode() == Activity.RESULT_OK) {
// There are no request codes
Intent data = result.getData();
if (data == null) {
Toast.makeText(getContext(), R.string.unknown_error, Toast.LENGTH_SHORT).show();
return;
}
activityResult(true, data);
}
else
activityResult(false, null);
});
不幸的是,在更新到 Android 11 之后,我们得到的只是 RESULT_CANCELED
。
E/WTF: ActivityResult{resultCode=RESULT_CANCELED, data=null}
正如 Ian 所说,您不应该使用 Intent.createChooser
和 ACTION_OPEN_DOCUMENT
,尽管它在 Android 11.
这是一个帮助程序 class,您使用 select image/video/pdf 使用 Activity 结果 API 作为合同 return 您Uri 的列表。它可以配置为单个或多个 selection 文件。
在 android 10 和 11 中测试。
class SelectFileContract : ActivityResultContract<Pair<SELECTION_TYPE, Boolean>, List<Uri>?>() {
var TAG = this.javaClass.simpleName
override fun createIntent(context: Context, input: Pair<SELECTION_TYPE, Boolean>): Intent {
var intent: Intent? = null
intent = when (input.first) {
SELECTION_TYPE.IMAGE -> Intent(
Intent.ACTION_PICK,
MediaStore.Images.Media.EXTERNAL_CONTENT_URI
)
SELECTION_TYPE.VIDEO -> Intent(
Intent.ACTION_PICK,
MediaStore.Video.Media.EXTERNAL_CONTENT_URI
)
SELECTION_TYPE.PDF -> {
Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
type = "application/pdf"
addCategory(Intent.CATEGORY_OPENABLE)
}
}
}
if (input.second == true) {
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true)
}
return intent!!
}
override fun parseResult(resultCode: Int, intent: Intent?): List<Uri>? = when (resultCode) {
Activity.RESULT_OK -> {
val uriList = mutableListOf<Uri>()
/**
* in case of single selection the Uri will be inside [intent.data]
*/
intent?.data?.let { uriList.add(it) }
/**
* in case of multiple selection the Uri will be inside [intent.clipData]
*/
intent?.clipData?.let { clipData: ClipData ->
for (i in 0 until clipData.itemCount) {
uriList.add(clipData.getItemAt(i).uri)
}
}
Log.d(TAG, uriList.toString())
uriList
}
else -> null
}
}
enum class SELECTION_TYPE {
IMAGE,
VIDEO,
PDF
}
然后在activity具体合同:
private val simpleContractRegistration =
registerForActivityResult(SelectFileContract()) { result: List<Uri>? ->
result?.let {
Log.d(TAG, result.toString())
}
}
然后启动注册:
binding.button.setOnClickListener {
simpleContractRegistration.launch(
Pair(
SELECTION_TYPE.IMAGE,
false
)
)
}