我正在创建一个意图选择器,在手机相机应用程序和画廊/文件管理器之间进行选择。
Intent chooserIntent = Intent.createChooser(clickPhoto(),"Set Image Using");
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS,openGallery());
startActivityForResult.launch(chooserIntent);
点击拍照方法:
private Intent clickPhoto() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
ComponentName componentName = takePictureIntent.resolveActivity(requireActivity().getPackageManager());
if (componentName != null) {
try {
createImageFile();
mimeType = "image/*";
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.DISPLAY_NAME, getNewFileName());
values.put(MediaStore.Images.Media.MIME_TYPE, mimeType);
values.put(MediaStore.Images.Media.RELATIVE_PATH, getImageDirectoryPath());
Uri imageUri = requireActivity().getContentResolver().insert(MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL), values);
if (imageUri != null) {
currentPhotoPath = imageUri.toString();
shareUri = imageUri;
}
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
// initRequestCode(takePictureIntent, requestCode);
} catch (IOException ioException) {
Toast.makeText(requireContext(), ioException.getMessage().toString(), Toast.LENGTH_LONG).show();
}
}
return takePictureIntent;
}
打开图库方法:
private Intent openGallery(){
mimeType = "image/*";
Intent intent = new Intent();
Uri collection = MediaStore.Video.Media.getContentUri(
MediaStore.VOLUME_EXTERNAL);
try {
intent =
new Intent(Intent.ACTION_PICK, collection).setType(mimeType);
intent.resolveActivity(requireActivity().getPackageManager());
// initRequestCode(intent, requestCode);
} catch (ActivityNotFoundException e) {
Toast.makeText(requireContext(), e.getLocalizedMessage(), Toast.LENGTH_LONG).show();
}
return intent;
}
ActivityResultLauncher:
ActivityResultLauncher<Intent> startActivityForResult = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(),
result -> {
if (result.getResultCode() == Activity.RESULT_OK) {
//how to tell which intent the user selected ?
}
});
我如何知道用户是使用相机拍摄的照片还是使用文件选择器选择的图像?
你可以在每个intent返回之前添加一个额外的整数,你可以在result中访问,例如:
全局变量final String SOURCE = "source";
final int SOURCE_CAMERA = 0;
final int SOURCE_GALLERY = 1;
final int SOURCE_UNKNOWN = 2;
相机
...
takePictureIntent.putExtra(SOURCE, SOURCE_CAMERA);
return takePictureIntent;
为画廊
..
intent.putExtra(SOURCE, SOURCE_GALLERY);
return intent;
ActivityResultLauncher
if (result.getResultCode() == Activity.RESULT_OK) {
//Identify source
int mySource = result.getData().getIntExtra(SOURCE, SOURCE_UNKNOWN )
}
你可以这样区分,
如果一个方法是用于相机意图,
private fun openCamera() {
val takePictureIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
if (takePictureIntent.resolveActivity(packageManager) != null) {
cameraImageFile = getTempFile()
cameraImageFile?.let {
val imageUri = FileProvider.getUriForFile(
this,
"${BuildConfig.APPLICATION_ID}.fileprovider",
it
)
cameraLauncher.launch(imageUri)
}
}
}
和另一个方法是用于画廊意图
private fun openGallery() {
galleryLauncher.launch("image/*")
}
然后你可以像下面这样定义activity
//Todo for gallery
private val galleryLauncher = registerForActivityResult(ActivityResultContracts.GetContent()) {
//code here for gallery
}
//Todo for camera
private val cameraLauncher = registerForActivityResult(ActivityResultContracts.TakePicture()) {
//code here for camera
}
就是这样!
声明一些变量
companion object{
private const val CAMERA_ACTION =1
private const val GALLERY_ACTION =2
private const val CHOOSER_INTENT_ACTION =3
}
private var mActionTriggered =0
随后
private fun openCamera() {
mActionTriggered = CAMERA_ACTION
}
private fun openGallery() {
mActionTriggered =GALLERY_ACTION
}
private fun openChooser() {
mActionTriggered =CHOOSER_INTENT_ACTION
}
onResult
private val startActivityForResult = registerForActivityResult(
StartActivityForResult()
) { result: ActivityResult ->
if (result.resultCode == RESULT_OK) {
when (mActionTriggered) {
CAMERA_ACTION -> {
mActionTriggered = 0
//TODO your logics
}
GALLERY_ACTION -> {
mActionTriggered = 0
//TODO your logics
}
else -> {
mActionTriggered = 0
//TODO your logics
}
}
}else{
mActionTriggered = 0
}
}
感觉有点过分,但是您可以使用选择器活动的细化机制。
您需要自己实现细化活动,但是您可以使用选择器传递的EXTRA_RESULT_RECEIVER
来发回结果。
Intent refinementIntent = new Intent(this, RefinementActivity.class);
PendingIntent refinementPendingIntent = PendingIntent.getActivity(this, 0, refinementIntent, 0);
Intent clickPhotoIntent = clickPhoto();
Intent chooserIntent = Intent.createChooser(clickPhoto(),"Set Image Using");
chooserIntent.putExtra(
Intent.EXTRA_CHOOSER_REFINEMENT_INTENT_SENDER, refinementPendingIntent.getIntentSender());
chooserIntent.putExtra(Intent.EXTRA_RESULT_RECEIVER, new ResultReceiver() {
@Override
public void onReceive(int resultCode, Bundle resultData) {
Intent startedIntent = resultData.getParcelable("extra_selected_intent");
// Check which intent was selected.
// Note that this is called when the selection happened, before the
// started activity returned. Probably what you want to do here is
// cache the value in a field and then check it when you get
// the activity result.
}
});
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, openGallery());
startActivityForResult.launch(chooserIntent);
然后在RefinementActivity.java
中,您需要将选定的意图发送回发送者
@Override
public void onCreate(Bundle savedInstanceState) {
Intent selectedIntent = getIntent().getParcelableExtra(Intent.EXTRA_INTENT);
ResultReceiver receiver = getIntent().getParcelableExtra(Intent.EXTRA_RESULT_RECEIVER);
Bundle resultData = new Bundle();
resultData.putParcelable("extra_selected_intent", selectedIntent);
receiver.send(RESULT_OK, resultData);
startActivity(selectedIntent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT));
finish();
}
您可以初始化全局布尔值name isGallery并在openGallery()中设置它为true和falseclickPhoto()
就像下面的代码:
private boolean isGallery ;
private Intent clickPhoto() {
isGallery = false;
}
private Intent openGallery() {
isGallery = true;
}
现在你的ActivityResultLauncher将像这样:
ActivityResultLauncher<Intent> startActivityForResult =
registerForActivityResult(new ActivityResultContracts.StartActivityForResult(),
result -> {
if (result.getResultCode() == Activity.RESULT_OK) {
if (isGallery) {
// user picked an image with the file picker
} else {
// user took a picture using the camera
}
}
});
由于您使用ActivityResultContracts.StartActivityForResult
,回调接收ActivityResult的实例。因此,您可以通过调用result.getData()
来获取意图,如下所示:
ActivityResultLauncher<Intent> startActivityForResult = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(),
result -> {
if (result.getResultCode() == Activity.RESULT_OK) {
Intent intent = result.getData();
}
});
然而,如果你必须创建一些条件来决定应该根据意图做什么,我建议分别创建两个不同的ActivityResultLauncher<Intent>
和launch
,所以你将有两个不同的回调,如:
ActivityResultLauncher<Intent> galleryLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(),
result -> {
if (result.getResultCode() == Activity.RESULT_OK) {
// what you have to do for gallery
}
});
ActivityResultLauncher<Intent> cameraLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(),
result -> {
if (result.getResultCode() == Activity.RESULT_OK) {
// what you have to do for camera
}
});