【问题标题】:Camera intent doesn't show in intent chooser相机意图未显示在意图选择器中
【发布时间】:2015-05-22 04:44:49
【问题描述】:
String chooseTitle = activity.getString(R.string.select_or_take_picture);

Intent getIntent = new Intent();
getIntent.setType("image/*");
getIntent.setAction(Intent.ACTION_GET_CONTENT);

Intent galleryIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
galleryIntent.setType("image/*");
PackageManager pm = activity.getApplicationContext().getPackageManager();
for (ResolveInfo ri: pm.queryIntentActivities(galleryIntent, PackageManager.MATCH_DEFAULT_ONLY)) {
  Intent intent = pm.getLaunchIntentForPackage(ri.activityInfo.packageName);
  intent.setAction(Intent.ACTION_PICK);
  intents.add(intent);
}

Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE, photoUri);
for (ResolveInfo ri : pm.queryIntentActivities(cameraIntent, 0)) {
  Intent intent = pm.getLaunchIntentForPackage(ri.activityInfo.packageName);
  intents.add(intent);
}

Intent chooserIntent = Intent.createChooser(getIntent, chooseTitle);
chooserIntent.putExtra(
    Intent.EXTRA_INITIAL_INTENTS,
    intents.toArray(new Parcelable[] {})
);

通过这种方式,选择器显示:

相机意图根本不显示。

但是如果我换行

Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE, photoUri);

Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

效果很好:

但问题是,我真的很想通过photoUri。我该怎么办?

我知道一个可能的替代方法是编写我自己的选择器对话框,但我确实想知道这是否是意图选择器中的错误,或者我没有正确使用它。

附言 @dkarmazi,这是我生成 Uri 的方式:

public Uri generatePhotoUri() {
  String timeStamp = new SimpleDateFormat("yyyyMMdd-HHmmss").format(new Date());
  String imageFileName = "XXX_" + timeStamp + ".jpg";
  File storageDir = Environment.getExternalStoragePublicDirectory(
      Environment.DIRECTORY_PICTURES);
  File imageFile = new File(storageDir, imageFileName);
  return Uri.fromFile(imageFile);
}

这是我的onActivityResult

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
  switch (requestCode) {
    case PICK_PHOTO:
      if (resultCode != Activity.RESULT_OK) {
        break;
      }
      Uri source = data == null ?
          mPhotoUri : // take picture
          data.getData(); // choose from other app
      if (source == null) {
        break;
      }
      // TODO: do with source
      break;
  }
  //....
}

@dkarmazi,我已经调试过了,我确保 resultCode 是 RESULT_CANCELED

【问题讨论】:

    标签: android android-intent camera


    【解决方案1】:

    我最近处理了同样的问题,这是我的解决方案:

    Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri);
    

    然后,一旦用户拍照,您应该可以使用提供的 photoUri 访问它

    这里有一些关于EXTRA_OUTPUT 的文档,您也可以在同一页面上查找 ACTION_IMAGE_CAPTURE。

    意图选择器更新:

    // we create intent chooser by picking one of the intents
    Intent chooserIntent = Intent.createChooser(cameraIntent, getResources().getString(R.string.pick_action_string_for_user));
    // then we add any additional intents
    chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Intent[] { getIntent });
    // chooserIntent is ready
    startActivityForResult(chooserIntent, requestCode);
    

    【讨论】:

    • 我正在尝试这样做,但这是另一个问题。我怎么知道用户是拍了照片还是取消了照片。 resultCode 始终为 RESULT_CANCELED!
    • 一旦用户拍照并成功保存在提供的URI中,在onActivityResult(int requestCode, int resultCode, Intent data)中,resultCode应该是RESULT_OK。您可能不断收到 RESULT_CANCELED 的原因之一是 photoUri 格式错误。您如何实际生成此 URI?能否请您展示一下生成 photoUri 和 onActivityResult 的代码?
    • 我刚刚添加了这些代码。我发现,连图片都抓拍保存了,resultCode是RESULT_CANCELED
    • 我知道你提到你调试了resultCode,但是你如何为chooserIntent启动一个activity呢?你确定它有 requestCode PICK_PHOTO 传递给它吗?
    • 我唯一怀疑的其他地方是:File storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);请尝试切换到 File storageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "")
    【解决方案2】:

    非常感谢@dkarmazi 帮助我调试这个问题。似乎我们没有足够的声誉来一起完善答案,所以我在这里发布解决方案。后来在我们的聊天中,我们找到了一个可能的原因,经过我的实验,现在它起作用了。我如何收集cameraIntents 其实是个问题,所以修改这部分代码

    Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE, photoUri);
    for (ResolveInfo ri : pm.queryIntentActivities(cameraIntent, 0)) {
      Intent intent = pm.getLaunchIntentForPackage(ri.activityInfo.packageName);
      intents.add(intent);
    }
    

    final Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
    for(ResolveInfo ri : pm.queryIntentActivities(cameraIntent, 0)) {
      final String packageName = ri.activityInfo.packageName;
      final Intent intent = new Intent(cameraIntent);
      intent.setComponent(new ComponentName(ri.activityInfo.packageName, ri.activityInfo.name));
      intent.setPackage(packageName);
      intent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri);
      intents.add(intent);
    }
    

    也需要改变

    Intent galleryIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
    galleryIntent.setType("image/*");
    PackageManager pm = activity.getApplicationContext().getPackageManager();
    for (ResolveInfo ri: pm.queryIntentActivities(galleryIntent, PackageManager.MATCH_DEFAULT_ONLY)) {
      Intent intent = pm.getLaunchIntentForPackage(ri.activityInfo.packageName);
      intent.setAction(Intent.ACTION_PICK);
      intents.add(intent);
    }
    

    Intent galleryIntent = new Intent(Intent.ACTION_PICK);
    galleryIntent.setType("image/*");
    PackageManager pm = activity.getApplicationContext().getPackageManager();
    for (ResolveInfo ri: pm.queryIntentActivities(galleryIntent, PackageManager.MATCH_DEFAULT_ONLY)) {
      final String packageName = ri.activityInfo.packageName;
      final Intent intent = new Intent(galleryIntent);
      intent.setComponent(new ComponentName(ri.activityInfo.packageName, ri.activityInfo.name));
      intent.setPackage(packageName);
      intents.add(intent);
    }
    

    我讨厌它的样板,但最终它起作用了。

    【讨论】:

    • 别忘了申请权限WRITE_EXTERNAL_STORAGEREAD_EXTERNAL_STORAGECAMERA
    猜你喜欢
    • 1970-01-01
    • 2018-08-27
    • 2010-12-20
    • 2019-04-07
    • 1970-01-01
    • 2021-08-24
    • 1970-01-01
    • 1970-01-01
    • 2021-02-10
    相关资源
    最近更新 更多