【问题标题】:Intent to choose between the camera or the gallery in Android打算在 Android 中的相机或图库之间进行选择
【发布时间】:2014-10-20 21:19:15
【问题描述】:

我正在尝试启动从相机或 android 的图库中选择图像的意图。我检查了THIS 的帖子,目前我的代码可以使用了:

private Intent getPickIntent() {
    final List<Intent> intents = new ArrayList<Intent>();
    if (allowCamera) {
        setCameraIntents(intents, cameraOutputUri);
    }
    if (allowGallery) {
        intents.add(new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI));
    }

    if (intents.isEmpty()) return null;
    Intent result = Intent.createChooser(intents.remove(0), null);
    if (!intents.isEmpty()) {
        result.putExtra(Intent.EXTRA_INITIAL_INTENTS, intents.toArray(new Parcelable[] {}));
    }
    return result;
}

private void setCameraIntents(List<Intent> cameraIntents, Uri output) {
    final Intent captureIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
    final PackageManager packageManager = context.getPackageManager();
    final List<ResolveInfo> listCam = packageManager.queryIntentActivities(captureIntent, 0);
    for (ResolveInfo res : listCam) {
        final String packageName = res.activityInfo.packageName;
        final Intent intent = new Intent(captureIntent);
        intent.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
        intent.setPackage(packageName);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, output);
        cameraIntents.add(intent);
    }
}

当我设置allowCamera=true 时,它可以正常工作。

当我设置allowGallery=true 时,它会显示以下选择器:

但如果我设置 allowCamera=true 和 allowGallery =true 显示的选择器是:

如果您选择Android System,则会显示第一个选择器。

我希望选择器类似于:

如何“扩展”Android System 选项?

【问题讨论】:

标签: java android android-intent


【解决方案1】:
            Intent galleryintent = new Intent(Intent.ACTION_GET_CONTENT, null);
            galleryintent.setType("image/*");

            Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);

            Intent chooser = new Intent(Intent.ACTION_CHOOSER);
            chooser.putExtra(Intent.EXTRA_INTENT, galleryintent);
            chooser.putExtra(Intent.EXTRA_TITLE, "Select from:");

            Intent[] intentArray = { cameraIntent };
            chooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray);
            startActivityForResult(chooser, REQUEST_PIC);

【讨论】:

  • 我只有文件和相机...不是画廊...?那是我错过的东西吗? @spyZip
  • 可能您的图库应用无法解析类型“image/*”
【解决方案2】:

In your linked post你可以找到解决办法。您的代码的不同之处在于画廊意图的创建方式:

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

不是ACTION_PICK,而是ACTION_GET_CONTENT。似乎如果列表中有一个ACTION_PICK(“容器意图”),系统会遍历它以显示选择的内容,但是一旦包含相机意图,它就无法再遍历(因为那里是一种直接意图和一种容器意图)。

在this answer 的评论中你会发现ACTION_PICK 和ACTION_GET_CONTENT 之间的区别。

有一些可用的解决方案建议使用自定义对话框。但是这个对话框没有标准图标(参见开发者文档here)。因此,我建议您继续使用您的解决方案,只解决层次结构问题。

【讨论】:

    【解决方案3】:
    ## Intent to choose between Camera and Gallery Heading and can crop image after capturing from camera ##
    
    
    public void captureImageCameraOrGallery() {
    
            final CharSequence[] options = { "Take photo", "Choose from library",
                    "Cancel" };
            AlertDialog.Builder builder = new AlertDialog.Builder(
                    Post_activity.this);
    
            builder.setTitle("Select");
    
            builder.setItems(options, new DialogInterface.OnClickListener() {
    
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    // TODO Auto-generated method stub
                    if (options[which].equals("Take photo")) {
                        try {
                            Intent cameraIntent = new Intent(
                                    android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
                            startActivityForResult(cameraIntent, TAKE_PICTURE);
                        } catch (ActivityNotFoundException ex) {
                            String errorMessage = "Whoops - your device doesn't support capturing images!";
    
                        }
    
                    } else if (options[which].equals("Choose from library")) {
                        Intent intent = new Intent(
                                Intent.ACTION_PICK,
                                android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                        startActivityForResult(intent, ACTIVITY_SELECT_IMAGE);
                    } else if (options[which].equals("Cancel")) {
                        dialog.dismiss();
    
                    }
    
                }
            });
            dialog = builder.create();
            dialog.getWindow().getAttributes().windowAnimations = R.style.dialog_animation;
    
            dialog.show();
    
        }
    
    public void onActivityResult(int requestcode, int resultcode, Intent intent) {
            super.onActivityResult(requestcode, resultcode, intent);
            if (resultcode == RESULT_OK) {
                if (requestcode == TAKE_PICTURE) {
                    picUri = intent.getData();
                    startCropImage();
                } else if (requestcode == PIC_CROP) {
                    Bitmap photo = (Bitmap) intent.getExtras().get("data");
                    Drawable drawable = new BitmapDrawable(photo);
                    backGroundImageLinearLayout.setBackgroundDrawable(drawable);
                } else if (requestcode == ACTIVITY_SELECT_IMAGE) {
                    Uri selectedImage = intent.getData();
                    String[] filePath = { MediaStore.Images.Media.DATA };
                    Cursor c = getContentResolver().query(selectedImage, filePath,
                            null, null, null);
                    c.moveToFirst();
                    int columnIndex = c.getColumnIndex(filePath[0]);
                    String picturePath = c.getString(columnIndex);
                    c.close();
                    Bitmap thumbnail = (BitmapFactory.decodeFile(picturePath));
                    Drawable drawable = new BitmapDrawable(thumbnail);
                    backGroundImageLinearLayout.setBackgroundDrawable(drawable);
    
                }
            }
        }
    
    private void startCropImage() {
            try {
                Intent cropIntent = new Intent("com.android.camera.action.CROP");
                cropIntent.setDataAndType(picUri, "image/*");
                cropIntent.putExtra("crop", "true");
                cropIntent.putExtra("aspectX", 1);
                cropIntent.putExtra("aspectY", 1);
                // indicate output X and Y
                cropIntent.putExtra("outputX", 256);
                cropIntent.putExtra("outputY", 256);
                // retrieve data on return
                cropIntent.putExtra("return-data", true);
                // start the activity - we handle returning in onActivityResult
                startActivityForResult(cropIntent, PIC_CROP);
            } catch (ActivityNotFoundException anfe) {
                // display an error message
                String errorMessage = "Whoops - your device doesn't support the crop action!";
                Toast toast = Toast
                        .makeText(this, errorMessage, Toast.LENGTH_SHORT);
                toast.show();
            }
        }
    

    【讨论】:

      【解决方案4】:

      您可能需要为此创建一个自定义对话框:

      以下是当用户单击特定按钮时要调用的方法的代码:

      private void ChooseGallerOrCamera() {
          final CharSequence[] items = { "Take Photo", "Choose from Gallery",
                  "Cancel" };
      
          AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
          builder.setTitle("Add Photo!");
          builder.setItems(items, new DialogInterface.OnClickListener() {
              @Override
              public void onClick(DialogInterface dialog, int item) {
                  if (items[item].equals("Take Photo")) {
                      Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                      File f = new File(android.os.Environment
                              .getExternalStorageDirectory(), "MyImage.jpg");
                      intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(f));
                      startActivityForResult(intent, REQUEST_CAMERA);
                  } else if (items[item].equals("Choose from Gallery")) {
                      Intent intent = new Intent(
                              Intent.ACTION_PICK,
                              android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                      intent.setType("image/*");
                      startActivityForResult(
                              Intent.createChooser(intent, "Select File"),
                              SELECT_FILE);
                  } else if (items[item].equals("Cancel")) {
                      dialog.dismiss();
                  }
              }
          });
          builder.show();
      }
      

      以及处理onActivityResult()的代码:

      @Override
      protected void onActivityResult(int requestCode, int resultCode, Intent data) {
          super.onActivityResult(requestCode, resultCode, data);
          if (resultCode == RESULT_OK) {
              Bitmap mBitmap;
              if (requestCode == REQUEST_CAMERA) {
                  File camFile = new File(Environment.getExternalStorageDirectory()
                          .toString());
                  for (File temp : camFile.listFiles()) {
                      if (temp.getName().equals("MyImage.jpg")) {
                          camFile = temp;
                          break;
                      }
                  }
                  try {
      
                      BitmapFactory.Options btmapOptions = new BitmapFactory.Options();
      
                      mBitmap = BitmapFactory.decodeFile(camFile.getAbsolutePath(),
                              btmapOptions);
                      //Here you have the bitmap of the image from camera
      
                  } catch (Exception e) {
                      e.printStackTrace();
                  }
              } else if (requestCode == SELECT_FILE) {
                  Uri selectedImageUri = data.getData();
      
                  String tempPath = getPath(selectedImageUri, MyActivity.this);
                  BitmapFactory.Options btmapOptions = new BitmapFactory.Options();
                  mBitmap = BitmapFactory.decodeFile(tempPath, btmapOptions);
      
                  //Here you have the bitmap of the image from gallery
              }
          }
      }
      
      public String getPath(Uri uri, Activity activity) {
          String[] projection = { MediaColumns.DATA };
          Cursor cursor = activity
                  .managedQuery(uri, projection, null, null, null);
          int column_index = cursor.getColumnIndexOrThrow(MediaColumns.DATA);
          cursor.moveToFirst();
          return cursor.getString(column_index);
      }
      

      编辑: 试试这个:

      private void letUserTakeUserTakePicture() {
      
          Intent pickIntent = new Intent();
          pickIntent.setType("image/*");
          pickIntent.setAction(Intent.ACTION_GET_CONTENT);
          Intent takePhotoIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
      
          takePhotoIntent.putExtra(MediaStore.EXTRA_OUTPUT,
                  Uri.fromFile(getTempFile(getActivity())));
      
          String pickTitle = "Select or take a new Picture"; // Or get from strings.xml
          Intent chooserIntent = Intent.createChooser(pickIntent, pickTitle);
          chooserIntent.putExtra
                  (Intent.EXTRA_INITIAL_INTENTS, new Intent[]{takePhotoIntent});
      
          startActivityForResult(chooserIntent, Values.REQ_CODE_TAKEPICTURE);
      }
      

      【讨论】:

        【解决方案5】:

        您的代码已经非常实现了目标。只需交换画廊和相机添加订单。

        if (allowGallery) {
            intents.add(new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI));
        }
        if (allowCamera) {
            setCameraIntents(intents, cameraOutputUri);
        }
        

        这是我的测试结果。由于我的操作系统是 Android Nougat(7.0),所以外观有所不同

        第一个截图是你的订单,第二个是交换后的截图。就像你说的,在第一种情况下,点击系统标志会显示图库项目。

        【讨论】:

          【解决方案6】:

          在活动选择器中显示相机和视频文件的意图:

              Intent galleryintent = new Intent(Intent.ACTION_GET_CONTENT, null);
              galleryintent.setType("video/*");
          
              Intent cameraIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
          
              Intent chooser = new Intent(Intent.ACTION_CHOOSER);
              chooser.putExtra(Intent.EXTRA_INTENT, galleryintent);
              chooser.putExtra(Intent.EXTRA_TITLE, "Select from:");
          
              Intent[] intentArray = { cameraIntent };
              chooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray);
              startActivityForResult(chooser, REQUEST_VIDEO_CAPTURE);
          

          【讨论】:

            猜你喜欢
            • 2011-09-07
            • 1970-01-01
            • 1970-01-01
            • 2017-04-27
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多