【问题标题】:Capture Image from Camera and Display in Activity从相机捕获图像并在活动中显示
【发布时间】:2011-08-24 21:08:55
【问题描述】:

我想编写一个模块,单击按钮即可打开相机,我可以单击并捕获图像。如果我不喜欢该图像,我可以将其删除并单击另一张图像,然后选择该图像,它应该返回并在活动中显示该图像。

【问题讨论】:

  • 您应该打开相机意图,捕获图像,如果需要将其保存在 SD 卡上,通过内容提供程序获取 id,并在对话框中显示,并带有确定/取消按钮。
  • @jengelsma 我在使用相机时遇到了一个问题,我以纵向模式捕获图像并在图像视图中显示,然后它总是以横向模式显示。你有什么想法吗?否则你能解决这个问题吗。请回复我等一下你的答案。
  • @Harsha M V 如果你得到答案然后回复我。
  • 这个博客可以帮助你。 startandroiddevelopment.blogspot.in/2013/10/…

标签: android image camera capture


【解决方案1】:

您需要阅读有关Camera 的信息。 (我认为要做你想做的事,你必须将当前图像保存到你的应用程序中,在那里进行选择/删除,然后调用相机重试,而不是直接在相机内重试。)

【讨论】:

    【解决方案2】:

    这是一个示例 Activity,它将启动相机应用,然后检索图像并显示它。

    package edu.gvsu.cis.masl.camerademo;
    
    import android.app.Activity;
    import android.content.Intent;
    import android.graphics.Bitmap;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.Button;
    import android.widget.ImageView;
    
    public class MyCameraActivity extends Activity
    {
        private static final int CAMERA_REQUEST = 1888; 
        private ImageView imageView;
        private static final int MY_CAMERA_PERMISSION_CODE = 100;
    
        @Override
        public void onCreate(Bundle savedInstanceState)
        {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
            this.imageView = (ImageView)this.findViewById(R.id.imageView1);
            Button photoButton = (Button) this.findViewById(R.id.button1);
            photoButton.setOnClickListener(new View.OnClickListener()
            {
                @Override
                public void onClick(View v)
                {
                    if (checkSelfPermission(Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED)
                    {
                        requestPermissions(new String[]{Manifest.permission.CAMERA}, MY_CAMERA_PERMISSION_CODE);
                    }
                    else
                    {
                        Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE); 
                        startActivityForResult(cameraIntent, CAMERA_REQUEST);
                    } 
                }
            });
        }
    
        @Override
        public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults)
        {
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
            if (requestCode == MY_CAMERA_PERMISSION_CODE)
            {
                if (grantResults[0] == PackageManager.PERMISSION_GRANTED)
                {
                    Toast.makeText(this, "camera permission granted", Toast.LENGTH_LONG).show();
                    Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE); 
                    startActivityForResult(cameraIntent, CAMERA_REQUEST);
                }
                else
                {
                    Toast.makeText(this, "camera permission denied", Toast.LENGTH_LONG).show();
                }
            }
        }
    
        @Override
        protected void onActivityResult(int requestCode, int resultCode, Intent data)
        {  
            if (requestCode == CAMERA_REQUEST && resultCode == Activity.RESULT_OK)
            {  
                Bitmap photo = (Bitmap) data.getExtras().get("data"); 
                imageView.setImageBitmap(photo);
            }  
        } 
    }
    

    请注意,相机应用程序本身使您能够查看/重新拍摄图像,一旦图像被接受,活动就会显示它。

    这是上述活动使用的布局。它只是一个 LinearLayout,包含一个 ID 为 button1 的 Button 和一个 ID 为 imageview1 的 ImageView:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        >
        <Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/photo"></Button>
        <ImageView android:id="@+id/imageView1" android:layout_height="wrap_content" android:src="@drawable/icon" android:layout_width="wrap_content"></ImageView>
    
    </LinearLayout>
    

    最后一个细节,一定要补充:

    <uses-feature android:name="android.hardware.camera"></uses-feature> 
    

    如果相机对于您的应用功能来说是可选的。确保在权限中将 require 设置为 false。像这样

    <uses-feature android:name="android.hardware.camera" android:required="false"></uses-feature>
    

    到您的 manifest.xml。

    【讨论】:

    • 位图照片 = (位图) data.getExtras().get("data");它给出了一个空指针期望。当我打开应用程序并单击 Capture 时,它​​会转到相机应用程序,2-4 秒后整个事情都崩溃了。
    • 我想为了安全起见,我们应该检查 onActivityResult() 方法中的 resultCode == Activity.RESULT_OK 。至于为什么相机会崩溃,我们必须看到堆栈跟踪。
    • @Harsha M V 这是三星 Galaxy 上的一个已知错误。请看这个答案stackoverflow.com/questions/7031374/…
    • @WillKru 如果该功能不是强制性的,您应该添加带有android:required="false" 属性的&lt;uses-feature/&gt;&lt;uses-feature android:name="android.hardware.camera" android:required="false"&gt;&lt;/uses-feature&gt;
    • 还要注意Bitmap photo = (Bitmap) data.getExtras().get("data"); 不会抓取拍摄的图像。它会抓取所拍摄图像的缩略图。
    【解决方案3】:

    活动中:

    @Override
        protected void onCreate(Bundle savedInstanceState) {
                     image = (ImageView) findViewById(R.id.imageButton);
            image.setOnClickListener(new OnClickListener() {
    
                @Override
                public void onClick(View v) {
                    try {
                    SimpleDateFormat sdfPic = new SimpleDateFormat(DATE_FORMAT);
                    currentDateandTime = sdfPic.format(new Date()).replace(" ", "");
                    File imagesFolder = new File(IMAGE_PATH, currentDateandTime);
                    imagesFolder.mkdirs();
                    Random generator = new Random();
                    int n = 10000;
                    n = generator.nextInt(n);
                    String fname = IMAGE_NAME + n + IMAGE_FORMAT;
                    File file = new File(imagesFolder, fname);
                    outputFileUri = Uri.fromFile(file);
                    cameraIntent= new Intent(
                            android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
                    cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
                                    startActivityForResult(cameraIntent, CAMERA_DATA);
                    }catch(Exception e) {
                        e.printStackTrace();
                    }
    
                }
            });
               @Override
        public void onActivityResult(int requestCode, int resultCode, Intent data) {
            super.onActivityResult(requestCode, resultCode, data);
            switch(requestCode) {
            case CAMERA_DATA :
                    final int IMAGE_MAX_SIZE = 300;
                    try {
                        // Bitmap bitmap;
                        File file = null;
                        FileInputStream fis;
                        BitmapFactory.Options opts;
                        int resizeScale;
                        Bitmap bmp;
                        file = new File(outputFileUri.getPath());
                        // This bit determines only the width/height of the
                        // bitmap
                        // without loading the contents
                        opts = new BitmapFactory.Options();
                        opts.inJustDecodeBounds = true;
                        fis = new FileInputStream(file);
                        BitmapFactory.decodeStream(fis, null, opts);
                        fis.close();
    
                        // Find the correct scale value. It should be a power of
                        // 2
                        resizeScale = 1;
    
                        if (opts.outHeight > IMAGE_MAX_SIZE
                                || opts.outWidth > IMAGE_MAX_SIZE) {
                            resizeScale = (int) Math.pow(2, (int) Math.round(Math.log(IMAGE_MAX_SIZE/ (double) Math.max(opts.outHeight, opts.outWidth)) / Math.log(0.5)));
                        }
    
                        // Load pre-scaled bitmap
                        opts = new BitmapFactory.Options();
                        opts.inSampleSize = resizeScale;
                        fis = new FileInputStream(file);
                        bmp = BitmapFactory.decodeStream(fis, null, opts);
                        Bitmap getBitmapSize = BitmapFactory.decodeResource(
                                getResources(), R.drawable.male);
                        image.setLayoutParams(new RelativeLayout.LayoutParams(
                                200,200));//(width,height);
                        image.setImageBitmap(bmp);
                        image.setRotation(90);
                        fis.close();
    
                        ByteArrayOutputStream baos = new ByteArrayOutputStream();
                        bmp.compress(Bitmap.CompressFormat.JPEG, 70, baos);
                        imageByte = baos.toByteArray();
                        break;
                    } catch (FileNotFoundException e) {
    
                        e.printStackTrace();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
    

    在 layout.xml 中:

    enter code here
    <RelativeLayout
            android:id="@+id/relativeLayout2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content">
    
    
            <ImageView
                android:id="@+id/imageButton"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
    
                                android:src="@drawable/XXXXXXX"
                android:textAppearance="?android:attr/textAppearanceSmall" />
    

    在 manifest.xml 中:

        <uses-permission android:name="android.permission.CAMERA" />   <uses-feature android:name="android.hardware.camera" />
    

    【讨论】:

      【解决方案4】:

      拍摄照片 + 从图库中选择:

              a = (ImageButton)findViewById(R.id.imageButton1);
      
              a.setOnClickListener(new View.OnClickListener() {
      
                  @Override
      
                  public void onClick(View v) {
      
                      selectImage();
      
                  }
      
              });
          }
          private File savebitmap(Bitmap bmp) {
            String extStorageDirectory = Environment.getExternalStorageDirectory().toString();
            OutputStream outStream = null;
           // String temp = null;
              File file = new File(extStorageDirectory, "temp.png");
            if (file.exists()) {
             file.delete();
             file = new File(extStorageDirectory, "temp.png");
      
            }
      
            try {
             outStream = new FileOutputStream(file);
             bmp.compress(Bitmap.CompressFormat.PNG, 100, outStream);
             outStream.flush();
             outStream.close();
      
            } catch (Exception e) {
             e.printStackTrace();
             return null;
            }
            return file;
           }
          @Override
          public boolean onCreateOptionsMenu(Menu menu) {
              // Inflate the menu; this adds items to the action bar if it is present.
              getMenuInflater().inflate(R.menu.main, menu);
              return true;
          }
           private void selectImage() {
      
      
      
                  final CharSequence[] options = { "Take Photo", "Choose from Gallery","Cancel" };
      
      
      
                  AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
      
                  builder.setTitle("Add Photo!");
      
                  builder.setItems(options, new DialogInterface.OnClickListener() {
      
                      @Override
      
                      public void onClick(DialogInterface dialog, int item) {
      
                          if (options[item].equals("Take Photo"))
      
                          {
      
                              Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
      
                              File f = new File(android.os.Environment.getExternalStorageDirectory(), "temp.jpg");
      
                              intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(f));
                              //pic = f;
      
                              startActivityForResult(intent, 1);
      
      
                          }
      
                          else if (options[item].equals("Choose from Gallery"))
      
                          {
      
                              Intent intent = new   Intent(Intent.ACTION_PICK,android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
      
                              startActivityForResult(intent, 2);
      
      
      
                          }
      
                          else if (options[item].equals("Cancel")) {
      
                              dialog.dismiss();
      
                          }
      
                      }
      
                  });
      
                  builder.show();
      
              }
      
      
      
              @Override
      
              protected void onActivityResult(int requestCode, int resultCode, Intent data) {
      
                  super.onActivityResult(requestCode, resultCode, data);
      
                  if (resultCode == RESULT_OK) {
      
                      if (requestCode == 1) {
                          //h=0;
                          File f = new File(Environment.getExternalStorageDirectory().toString());
      
                          for (File temp : f.listFiles()) {
      
                              if (temp.getName().equals("temp.jpg")) {
      
                                  f = temp;
                                  File photo = new File(Environment.getExternalStorageDirectory(), "temp.jpg");
                                 //pic = photo;
                                  break;
      
                              }
      
                          }
      
                          try {
      
                              Bitmap bitmap;
      
                              BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();
      
      
      
                              bitmap = BitmapFactory.decodeFile(f.getAbsolutePath(),
      
                                      bitmapOptions); 
      
      
      
                              a.setImageBitmap(bitmap);
      
      
      
      
                              String path = android.os.Environment
      
                                      .getExternalStorageDirectory()
      
                                      + File.separator
      
                                      + "Phoenix" + File.separator + "default";
                              //p = path;
      
                              f.delete();
      
                              OutputStream outFile = null;
      
                              File file = new File(path, String.valueOf(System.currentTimeMillis()) + ".jpg");
      
                              try {
      
                                  outFile = new FileOutputStream(file);
      
                                  bitmap.compress(Bitmap.CompressFormat.JPEG, 85, outFile);
          //pic=file;
                                  outFile.flush();
      
                                  outFile.close();
      
      
                              } catch (FileNotFoundException e) {
      
                                  e.printStackTrace();
      
                              } catch (IOException e) {
      
                                  e.printStackTrace();
      
                              } catch (Exception e) {
      
                                  e.printStackTrace();
      
                              }
      
                          } catch (Exception e) {
      
                              e.printStackTrace();
      
                          }
      
                      } else if (requestCode == 2) {
      
      
      
                          Uri selectedImage = data.getData();
                         // h=1;
          //imgui = selectedImage;
                          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));
      
      
                          Log.w("path of image from gallery......******************.........", picturePath+"");
      
      
                          a.setImageBitmap(thumbnail);
      
                      }
      
                  }
      

      【讨论】:

      • ResultCode == 1ResultCode == RESULT_OK ?
      • 它是requestCode==1,帮助识别发起请求的人。
      【解决方案5】:

      您可以使用带有缩略图的自定义相机。 你可以看看我的project

      【讨论】:

        【解决方案6】:

        完整代码如下:

        package com.example.cameraa;
        import android.app.Activity;
        import android.content.Intent;
        import android.graphics.Bitmap;
        import android.net.Uri;
        import android.os.Bundle;
        import android.view.View;
        import android.widget.Button;
        import android.widget.ImageView;
        
        public class MainActivity extends Activity {
        
        
        
        
                Button btnTackPic;
                Uri photoPath;
                ImageView ivThumbnailPhoto;
        
                static int TAKE_PICTURE = 1;
        
                @Override
                protected void onCreate(Bundle savedInstanceState) {
                    super.onCreate(savedInstanceState);
                    setContentView(R.layout.activity_main);
        
                    // Get reference to views
        
                    btnTackPic = (Button) findViewById(R.id.bt1);
                    ivThumbnailPhoto = (ImageView) findViewById(R.id.imageView1);
        
        
        
        
             btnTackPic.setOnClickListener(new View.OnClickListener() {
        
                @Override
                public void onClick(View v) {
                    // TODO Auto-generated method stub
        
        
                        Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE); 
                        startActivityForResult(cameraIntent, TAKE_PICTURE); 
                    }
        
        
        
        
            });
        
                } 
        
                @Override
                protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
        
        
                        if (requestCode == TAKE_PICTURE && resultCode == RESULT_OK) {  
                            Bitmap photo = (Bitmap)intent.getExtras().get("data"); 
                           ivThumbnailPhoto.setImageBitmap(photo);
                        ivThumbnailPhoto.setVisibility(View.VISIBLE);
        
        
        
                    }
                }
        }
        

        记得为相机添加权限。

        【讨论】:

          【解决方案7】:

          从相机拍摄照片+从图库中选择图像并将其设置为布局或图像视图的背景。这是示例代码。

          import java.io.File;
          import java.io.FileNotFoundException;
          import java.io.FileOutputStream;
          import java.io.IOException;
          import java.io.OutputStream;
          
          import android.app.Activity;
          import android.app.AlertDialog;
          import android.content.DialogInterface;
          import android.content.Intent;
          import android.database.Cursor;
          import android.graphics.Bitmap;
          import android.graphics.BitmapFactory;
          import android.graphics.drawable.BitmapDrawable;
          import android.graphics.drawable.Drawable;
          import android.net.Uri;
          import android.os.Bundle;
          import android.os.Environment;
          
              import android.provider.MediaStore;
              import android.util.Log;
              import android.view.View;
              import android.view.View.OnClickListener;
              import android.widget.AdapterView;
              import android.widget.AdapterView.OnItemClickListener;
              import android.widget.GridView;
              import android.widget.ImageView;
              import android.widget.LinearLayout;
          
              public class Post_activity extends Activity
              {
                  final int TAKE_PICTURE = 1;
                  final int ACTIVITY_SELECT_IMAGE = 2;
          
                  ImageView openCameraOrGalleryBtn,cancelBtn;
                  LinearLayout backGroundImageLinearLayout;
          
                  public void onCreate(Bundle savedBundleInstance) {
                      super.onCreate(savedBundleInstance);
                      overridePendingTransition(R.anim.slide_up,0);
                      setContentView(R.layout.post_activity);
          
                      backGroundImageLinearLayout=(LinearLayout)findViewById(R.id.background_image_linear_layout);
                      cancelBtn=(ImageView)findViewById(R.id.cancel_icon);
          
                      openCameraOrGalleryBtn=(ImageView)findViewById(R.id.camera_icon);
          
          
          
                      openCameraOrGalleryBtn.setOnClickListener(new OnClickListener() {
          
                          @Override
                          public void onClick(View v) {
                              // TODO Auto-generated method stub
          
                              selectImage();
                          }
                      });
                      cancelBtn.setOnClickListener(new OnClickListener() {
          
                          @Override
                          public void onClick(View v) {
                              // TODO Auto-generated method stub
                          overridePendingTransition(R.anim.slide_down,0);
                          finish();
                          }
                      });
          
                  }
          
              public void selectImage()
                  {
                       final CharSequence[] options = { "Take Photo", "Choose from Gallery","Cancel" };
                       AlertDialog.Builder builder = new AlertDialog.Builder(Post_activity.this);
                          builder.setTitle("Add Photo!");
                          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"))
                                  {
                                      Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE); 
                                      startActivityForResult(cameraIntent, TAKE_PICTURE);
                                  }
                                  else if(options[which].equals("Choose from Gallery"))
                                  {
                                      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();
                                  }
          
                              }
                          });
                          builder.show();
                  }
                  public void onActivityResult(int requestcode,int resultcode,Intent intent)
                  {
                      super.onActivityResult(requestcode, resultcode, intent);
                      if(resultcode==RESULT_OK)
                      {
                          if(requestcode==TAKE_PICTURE)
                          {
                              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);
          
          
                          }
                      }
                  }
          
                  public void onBackPressed() {
                      super.onBackPressed();
                      //overridePendingTransition(R.anim.slide_down,0);
                  }
              }
          
          Add these permission in Androidmenifest.xml file
          
          <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
              <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
              <uses-permission android:name="android.permission.CAMERA"/>
          

          【讨论】:

          • 这已经很老了,但我喜欢你这样做的方式。当我从图库中选择时,图像无法显示。有什么想法吗?
          【解决方案8】:

          更新(2020 年)

          Google 添加了一个新的 ActivityResultRegistry API,“让您处理 startActivityForResult() + onActivityResult() 以及 requestPermissions() + onRequestPermissionsResult() 流,而无需覆盖您的 Activity 或 Fragment 中的方法,带来更多通过ActivityResultContract 进行类型安全,并提供用于测试这些流程的挂钩" - source

          androidx.activity 1.2.0-alpha02androidx.fragment 1.3.0-alpha02 中添加了API。

          所以您现在可以执行以下操作:

          val takePicture = registerForActivityResult(ActivityResultContracts.TakePicture()) { success: Boolean ->
              if (success) {
                  // The image was saved into the given Uri -> do something with it
              }
          }
          
          val imageUri: Uri = ...
          button.setOnClickListener {
              takePicture.launch(imageUri)
          }
          

          查看文档以了解如何使用新的 Activity 结果 API:https://developer.android.com/training/basics/intents/result#kotlin

          有许多内置的ActivityResultContracts 允许您执行不同的操作,例如选择联系人、请求权限、拍照或拍摄视频。您可能对上面显示的ActivityResultContracts.TakePicture 感兴趣。

          请注意,androidx.fragment 1.3.0-alpha04 不推荐使用 Fragment 上的 startActivityForResult() + onActivityResult()requestPermissions() + onRequestPermissionsResult() API。因此,ActivityResultContracts 似乎是从现在开始做事的新方式。


          原始答案(2015 年)

          我花了几个小时才完成这项工作。代码几乎是developer.android.com的复制粘贴,略有不同。

          AndroidManifest.xml 上请求此权限:

          <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
          

          在您的 Activity 上,首先定义以下内容:

          static final int REQUEST_IMAGE_CAPTURE = 1;
          private Bitmap mImageBitmap;
          private String mCurrentPhotoPath;
          private ImageView mImageView;
          

          然后在onClick 中触发这个Intent

          Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
          if (cameraIntent.resolveActivity(getPackageManager()) != null) {
              // Create the File where the photo should go
              File photoFile = null;
              try {
                  photoFile = createImageFile();
              } catch (IOException ex) {
                  // Error occurred while creating the File
                  Log.i(TAG, "IOException");
              }
              // Continue only if the File was successfully created
              if (photoFile != null) {
                  cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));
                  startActivityForResult(cameraIntent, REQUEST_IMAGE_CAPTURE);
              }
          }
          

          添加如下支持方式:

          private File createImageFile() throws IOException {
              // Create an image file name
              String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
              String imageFileName = "JPEG_" + timeStamp + "_";
              File storageDir = Environment.getExternalStoragePublicDirectory(
                      Environment.DIRECTORY_PICTURES);
              File image = File.createTempFile(
                      imageFileName,  // prefix
                      ".jpg",         // suffix
                      storageDir      // directory
              );
          
              // Save a file: path for use with ACTION_VIEW intents
              mCurrentPhotoPath = "file:" + image.getAbsolutePath();
              return image;
          }
          

          然后接收结果:

          @Override
          protected void onActivityResult(int requestCode, int resultCode, Intent data) {
              if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
                  try {
                      mImageBitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), Uri.parse(mCurrentPhotoPath));
                      mImageView.setImageBitmap(mImageBitmap);
                  } catch (IOException e) {
                      e.printStackTrace();
                  }
              }
          }
          

          使它起作用的是MediaStore.Images.Media.getBitmap(this.getContentResolver(), Uri.parse(mCurrentPhotoPath)),它与developer.android.com 的代码不同。原始代码给了我一个FileNotFoundException

          【讨论】:

          • "Uri.parse(mCurrentPhotoPath))" 是解决方案,因为 MediaStore.EXTRA_OUTPUT 导致空意图结果。
          • 我的图片默认是横向模式,我错过了什么吗?
          • 这段代码对我不起作用。我收到android.os.FileUriExposedException: file:///storage/emulated/0/Pictures/JPEG_20180823_102340_722874009725833047.jpg exposed beyond app through ClipData.Item.getUri()。关于如何解决这个问题的任何想法? @AlbertVilaCalvo
          • @AlbertVilaCalvo 我不知道。那么,您对如何解决此问题有任何想法吗?我不知道我能改变什么。我希望你能帮助我,谢谢。
          • 我不得不使用storageDir = Context.getFilesDir(); 代替文件storageDir = Environment.getExternalStoragePublicDirectory( Environment.DIRECTORY_PICTURES);。否则我会收到权限被拒绝错误。
          【解决方案9】:

          这是我用于捕获和保存相机图像然后将其显示到 imageview 的代码。您可以根据需要使用。

          您必须将相机图像保存到特定位置,然后从该位置获取,然后将其转换为字节数组。

          这是打开捕获相机图像活动的方法。

          private static final int CAMERA_PHOTO = 111;
          private Uri imageToUploadUri;
          
          private void captureCameraImage() {
                  Intent chooserIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                  File f = new File(Environment.getExternalStorageDirectory(), "POST_IMAGE.jpg");
                  chooserIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(f));
                  imageToUploadUri = Uri.fromFile(f);
                  startActivityForResult(chooserIntent, CAMERA_PHOTO);
              }
          

          那么你的 onActivityResult() 方法应该是这样的。

          @Override
                  protected void onActivityResult(int requestCode, int resultCode, Intent data) {
                      super.onActivityResult(requestCode, resultCode, data);
          
                      if (requestCode == CAMERA_PHOTO && resultCode == Activity.RESULT_OK) {
                          if(imageToUploadUri != null){
                              Uri selectedImage = imageToUploadUri;
                              getContentResolver().notifyChange(selectedImage, null);
                              Bitmap reducedSizeBitmap = getBitmap(imageToUploadUri.getPath());
                              if(reducedSizeBitmap != null){
                                  ImgPhoto.setImageBitmap(reducedSizeBitmap);
                                  Button uploadImageButton = (Button) findViewById(R.id.uploadUserImageButton);
                                    uploadImageButton.setVisibility(View.VISIBLE);                
                              }else{
                                  Toast.makeText(this,"Error while capturing Image",Toast.LENGTH_LONG).show();
                              }
                          }else{
                              Toast.makeText(this,"Error while capturing Image",Toast.LENGTH_LONG).show();
                          }
                      } 
                  }
          

          这里是 onActivityResult() 中使用的 getBitmap() 方法。在获取相机捕获图像位图时,我已经完成了所有可能的性能改进。

          private Bitmap getBitmap(String path) {
          
                  Uri uri = Uri.fromFile(new File(path));
                  InputStream in = null;
                  try {
                      final int IMAGE_MAX_SIZE = 1200000; // 1.2MP
                      in = getContentResolver().openInputStream(uri);
          
                      // Decode image size
                      BitmapFactory.Options o = new BitmapFactory.Options();
                      o.inJustDecodeBounds = true;
                      BitmapFactory.decodeStream(in, null, o);
                      in.close();
          
          
                      int scale = 1;
                      while ((o.outWidth * o.outHeight) * (1 / Math.pow(scale, 2)) >
                              IMAGE_MAX_SIZE) {
                          scale++;
                      }
                      Log.d("", "scale = " + scale + ", orig-width: " + o.outWidth + ", orig-height: " + o.outHeight);
          
                      Bitmap b = null;
                      in = getContentResolver().openInputStream(uri);
                      if (scale > 1) {
                          scale--;
                          // scale to max possible inSampleSize that still yields an image
                          // larger than target
                          o = new BitmapFactory.Options();
                          o.inSampleSize = scale;
                          b = BitmapFactory.decodeStream(in, null, o);
          
                          // resize to desired dimensions
                          int height = b.getHeight();
                          int width = b.getWidth();
                          Log.d("", "1th scale operation dimenions - width: " + width + ", height: " + height);
          
                          double y = Math.sqrt(IMAGE_MAX_SIZE
                                  / (((double) width) / height));
                          double x = (y / height) * width;
          
                          Bitmap scaledBitmap = Bitmap.createScaledBitmap(b, (int) x,
                                  (int) y, true);
                          b.recycle();
                          b = scaledBitmap;
          
                          System.gc();
                      } else {
                          b = BitmapFactory.decodeStream(in);
                      }
                      in.close();
          
                      Log.d("", "bitmap size - width: " + b.getWidth() + ", height: " +
                              b.getHeight());
                      return b;
                  } catch (IOException e) {
                      Log.e("", e.getMessage(), e);
                      return null;
                  }
              }
          

          希望对你有帮助!

          【讨论】:

          • 我试过这个并将 captureImage() 从 onClickListener 放在 onClick 中,但不起作用。我正在使用 FragmentDialog... 有什么想法吗?
          【解决方案10】:

          我知道这是一个很老的线程,但是所有这些解决方案都没有完成,并且当用户旋转相机时在某些设备上不起作用,因为 onActivityResult 中的数据为空。所以这是我在很多设备上测试过的解决方案,到目前为止还没有遇到任何问题。

          首先在您的活动中声明您的 Uri 变量:

          private Uri uriFilePath;
          

          然后创建您的临时文件夹用于存储捕获的图像并打算通过相机捕获图像:

          PackageManager packageManager = getActivity().getPackageManager();
          if (packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA)) {
              File mainDirectory = new File(Environment.getExternalStorageDirectory(), "MyFolder/tmp");
                   if (!mainDirectory.exists())
                       mainDirectory.mkdirs();
          
                    Calendar calendar = Calendar.getInstance();
          
                    uriFilePath = Uri.fromFile(new File(mainDirectory, "IMG_" + calendar.getTimeInMillis()));
                    intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                    intent.putExtra(MediaStore.EXTRA_OUTPUT, uriFilePath);
                    startActivityForResult(intent, 1);
          }
          

          现在最重要的事情之一来了,您必须将您的 uriFilePath 保存在 onSaveInstanceState 中,因为如果您不这样做并且用户在使用相机时旋转了他的设备,您的 uri 将为空。

          @Override
          protected void onSaveInstanceState(Bundle outState) {
               if (uriFilePath != null)
                   outState.putString("uri_file_path", uriFilePath.toString());
               super.onSaveInstanceState(outState);
          }
          

          之后,您应该始终在 onCreate 方法中恢复您的 uri:

          @Override
          protected void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              if (savedInstanceState != null) {
                   if (uriFilePath == null && savedInstanceState.getString("uri_file_path") != null) {
                       uriFilePath = Uri.parse(savedInstanceState.getString("uri_file_path"));
                   }
              } 
          }
          

          这是让你的 Uri 进入 onActivityResult 的最后一部分:

          @Override
          protected void onActivityResult(int requestCode, int resultCode, Intent data) {    
              if (resultCode == RESULT_OK) {
                   if (requestCode == 1) {
                      String filePath = uriFilePath.getPath(); // Here is path of your captured image, so you can create bitmap from it, etc.
                   }
              }
           }
          

          附:不要忘记为相机和分机添加权限。存储写入您的清单。

          【讨论】:

          • 我正在使用 FragmentDialog。我尝试按照您的方式执行此操作.. 我声明了 Uri,然后在方法“storeCapturedImage”中 - 我输入了 PackageManager 代码,然后我添加了 onSaveInstanceState() - 所有这些都在 onCreate 之前。然后在 onCreateDialog 中,我放置了“恢复您的 uri”代码,然后将 onActivityResult 放置在 onCreate 方法的正上方...请参阅下一条评论,了解我在“恢复您的 uri”代码之后放置的内容
          • AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); LayoutInflater inflater = getActivity().getLayoutInflater();查看 dialogView = inflater.inflate(R.layout.username_dialog, null); ImageView profilePic = dialogView.findViewById(R.id.profile_pic); profilePic.setImageResource(R.drawable.user_placeholder); profilePic.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { storeCapturedImage();} }); builder.setView(dialogView);
          • 我真的很想知道为什么操作系统不向您发送 OnActivityResult 内部意图中的 uri。我希望有一个很好的理由,因为随身携带状态对 IMO 来说总是不是一件好事。
          • 那么onActivityResult回调中的数据有什么用呢?
          【解决方案11】:

          使用以下代码使用您的移动相机拍摄照片。 如果您使用的是高于 Lolipop 版本的 android,您还应该添加权限请求。

          private void cameraIntent()
              {
                    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                    startActivityForResult(intent, REQUEST_CAMERA);
              }
          
          @override
          protected void onActivityResult(int requestCode, int resultCode, Intent data) {  
               if (requestCode == CAMERA_REQUEST && resultCode == Activity.RESULT_OK) {  
                      Bitmap photo = (Bitmap) data.getExtras().get("data"); 
                      imageView.setImageBitmap(photo);
               }  
          } 
          

          【讨论】:

            【解决方案12】:

            您可以在此处打开相机或图库并将所选图像设置为imageview

            private static final String IMAGE_DIRECTORY = "/YourDirectName";
            private Context mContext;
            private CircleImageView circleImageView;  // imageview
            private int GALLERY = 1, CAMERA = 2;
            

            在清单中添加权限

            <uses-permission android:name="android.permission.CAMERA" />
            <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
            <uses-permission android:name="ANDROID.PERMISSION.READ_EXTERNAL_STORAGE" />
            

            在 onCreate() 中

                requestMultiplePermissions(); // check permission 
            
                circleImageView = findViewById(R.id.profile_image);
                circleImageView.setOnClickListener(new View.OnClickListener() {
                    public void onClick(View v) {
                        showPictureDialog();
                    }
                });
            

            显示选项对话框(从相机或图库中选择图像)

            private void showPictureDialog() {
                AlertDialog.Builder pictureDialog = new AlertDialog.Builder(this);
                pictureDialog.setTitle("Select Action");
                String[] pictureDialogItems = {"Select photo from gallery", "Capture photo from camera"};
                pictureDialog.setItems(pictureDialogItems,
                        new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                switch (which) {
                                    case 0:
                                        choosePhotoFromGallary();
                                        break;
                                    case 1:
                                        takePhotoFromCamera();
                                        break;
                                }
                            }
                        });
                pictureDialog.show();
            }
            

            从图库中获取照片

            public void choosePhotoFromGallary() {
                Intent galleryIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                startActivityForResult(galleryIntent, GALLERY);
            }
            

            从相机中获取照片

            private void takePhotoFromCamera() {
                Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
                startActivityForResult(intent, CAMERA);
            }
            

            一旦图像被选中或捕获,

            @Override
            public void onActivityResult(int requestCode, int resultCode, Intent data) {
            
                super.onActivityResult(requestCode, resultCode, data);
                if (resultCode == this.RESULT_CANCELED) {
                    return;
                }
                if (requestCode == GALLERY) {
                    if (data != null) {
                        Uri contentURI = data.getData();
                        try {
                            Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), contentURI);
                            String path = saveImage(bitmap);
                            Toast.makeText(getApplicationContext(), "Image Saved!", Toast.LENGTH_SHORT).show();
                            circleImageView.setImageBitmap(bitmap);
            
                        } catch (IOException e) {
                            e.printStackTrace();
                            Toast.makeText(getApplicationContext(), "Failed!", Toast.LENGTH_SHORT).show();
                        }
                    }
            
                } else if (requestCode == CAMERA) {
                    Bitmap thumbnail = (Bitmap) data.getExtras().get("data");
                    circleImageView.setImageBitmap(thumbnail);
                    saveImage(thumbnail);
                    Toast.makeText(getApplicationContext(), "Image Saved!", Toast.LENGTH_SHORT).show();
                }
            }
            

            现在是时候存储图片了

            public String saveImage(Bitmap myBitmap) {
                ByteArrayOutputStream bytes = new ByteArrayOutputStream();
                myBitmap.compress(Bitmap.CompressFormat.JPEG, 90, bytes);
                File wallpaperDirectory = new File(Environment.getExternalStorageDirectory() + IMAGE_DIRECTORY);
                if (!wallpaperDirectory.exists()) {  // have the object build the directory structure, if needed.
                    wallpaperDirectory.mkdirs();
                }
            
                try {
                    File f = new File(wallpaperDirectory, Calendar.getInstance().getTimeInMillis() + ".jpg");
                    f.createNewFile();
                    FileOutputStream fo = new FileOutputStream(f);
                    fo.write(bytes.toByteArray());
                    MediaScannerConnection.scanFile(this,
                            new String[]{f.getPath()},
                            new String[]{"image/jpeg"}, null);
                    fo.close();
                    Log.d("TAG", "File Saved::---&gt;" + f.getAbsolutePath());
            
                    return f.getAbsolutePath();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
                return "";
            }
            

            请求权限

                private void requestMultiplePermissions() {
                Dexter.withActivity(this)
                        .withPermissions(
                                Manifest.permission.CAMERA,
                                Manifest.permission.WRITE_EXTERNAL_STORAGE,
                                Manifest.permission.READ_EXTERNAL_STORAGE)
                        .withListener(new MultiplePermissionsListener() {
                            @Override
                            public void onPermissionsChecked(MultiplePermissionsReport report) {
                                if (report.areAllPermissionsGranted()) {  // check if all permissions are granted
                                    Toast.makeText(getApplicationContext(), "All permissions are granted by user!", Toast.LENGTH_SHORT).show();
                                }
            
                                if (report.isAnyPermissionPermanentlyDenied()) { // check for permanent denial of any permission
                                    // show alert dialog navigating to Settings
                                    //openSettingsDialog();
                                }
                            }
            
                            @Override
                            public void onPermissionRationaleShouldBeShown(List<PermissionRequest> permissions, PermissionToken token) {
                                token.continuePermissionRequest();
                            }
                        }).
                        withErrorListener(new PermissionRequestErrorListener() {
                            @Override
                            public void onError(DexterError error) {
                                Toast.makeText(getApplicationContext(), "Some Error! ", Toast.LENGTH_SHORT).show();
                            }
                        })
                        .onSameThread()
                        .check();
            }
            

            【讨论】:

              【解决方案13】:

              我创建了一个对话框,其中包含从图库或相机中选择图像的选项。 回调为

              • 如果图片来自图库,则为 Uri
              • 如果图像是从相机捕获的,则作为文件路径的字符串。
              • 图像作为文件从相机中选择的图像需要作为多部分文件数据上传到互联网上

              首先我们在 AndroidManifest 中定义权限,因为我们需要在创建文件和从图库中读取图像时写入外部存储

              <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
              <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
              

              在里面创建一个file_paths xml app/src/main/res/xml/file_paths.xml

              带路径

              <?xml version="1.0" encoding="utf-8"?>
              <paths xmlns:android="http://schemas.android.com/apk/res/android">
                  <external-path name="external_files" path="."/>
              </paths>
              

              然后我们需要定义file provier来生成Content uri来访问存储在外部存储中的文件

              <provider
                  android:name="androidx.core.content.FileProvider"
                  android:authorities="${applicationId}.provider"
                  android:exported="false"
                  android:grantUriPermissions="true">
                  <meta-data
                      android:name="android.support.FILE_PROVIDER_PATHS"
                      android:resource="@xml/file_paths" />
              </provider>
              

              对话布局

              <?xml version="1.0" encoding="utf-8"?>
              <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
                  xmlns:app="http://schemas.android.com/apk/res-auto"
                  xmlns:tools="http://schemas.android.com/tools"
                  android:layout_width="match_parent"
                  android:layout_height="wrap_content">
              
                  <androidx.constraintlayout.widget.Guideline
                      android:id="@+id/guideline2"
                      android:layout_width="wrap_content"
                      android:layout_height="wrap_content"
                      android:orientation="vertical"
                      app:layout_constraintGuide_percent="0.50" />
              
                  <ImageView
                      android:id="@+id/gallery"
                      android:layout_width="48dp"
                      android:layout_height="48dp"
                      android:layout_marginStart="8dp"
                      android:layout_marginTop="32dp"
                      android:layout_marginEnd="8dp"
                      android:layout_marginBottom="32dp"
                      app:layout_constraintBottom_toBottomOf="parent"
                      app:layout_constraintEnd_toEndOf="parent"
                      app:layout_constraintStart_toStartOf="@+id/guideline2"
                      app:layout_constraintTop_toTopOf="parent"
                      app:srcCompat="@drawable/ic_menu_gallery" />
              
                  <ImageView
                      android:id="@+id/camera"
                      android:layout_width="48dp"
                      android:layout_height="0dp"
                      android:layout_marginStart="8dp"
                      android:layout_marginTop="32dp"
                      android:layout_marginEnd="8dp"
                      android:layout_marginBottom="32dp"
                      app:layout_constraintBottom_toBottomOf="parent"
                      app:layout_constraintEnd_toStartOf="@+id/guideline2"
                      app:layout_constraintStart_toStartOf="parent"
                      app:layout_constraintTop_toTopOf="parent"
                      app:srcCompat="@drawable/ic_menu_camera" />
              </androidx.constraintlayout.widget.ConstraintLayout>
              

              ImagePicker 日志

              public class ImagePicker extends BottomSheetDialogFragment {
              ImagePicker.GetImage getImage;
              public ImagePicker(ImagePicker.GetImage getImage, boolean allowMultiple) {
                  this.getImage = getImage;
              }
              File cameraImage;
              @Override
              public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
                  View view = inflater.inflate(R.layout.bottom_sheet_imagepicker, container, false);
                  view.findViewById(R.id.camera).setOnClickListener(new View.OnClickListener() {@
                      Override
                      public void onClick(View view) {
                          if(ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
                              requestPermissions(new String[] {
                                  Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE
                              }, 2000);
                          } else {
                              captureFromCamera();
                          }
                      }
                  });
                  view.findViewById(R.id.gallery).setOnClickListener(new View.OnClickListener() {@
                      Override
                      public void onClick(View view) {
                          if(ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
                              requestPermissions(new String[] {
                                  Manifest.permission.READ_EXTERNAL_STORAGE
                              }, 2000);
                          } else {
                              startGallery();
                          }
                      }
                  });
                  return view;
              }
              public interface GetImage {
                  void setGalleryImage(Uri imageUri);
                  void setCameraImage(String filePath);
                  void setImageFile(File file);
              }@
              Override
              public void onActivityResult(int requestCode, int resultCode, Intent data) {
                  super.onActivityResult(requestCode, resultCode, data);
                  if(resultCode == Activity.RESULT_OK) {
                      if(requestCode == 1000) {
                          Uri returnUri = data.getData();
                          getImage.setGalleryImage(returnUri);
                          Bitmap bitmapImage = null;
                      }
                      if(requestCode == 1002) {
                          if(cameraImage != null) {
                              getImage.setImageFile(cameraImage);
                          }
                          getImage.setCameraImage(cameraFilePath);
                      }
                  }
              }
              private void startGallery() {
                  Intent cameraIntent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                  cameraIntent.setType("image/*");
                  if(cameraIntent.resolveActivity(getActivity().getPackageManager()) != null) {
                      startActivityForResult(cameraIntent, 1000);
                  }
              }
              private String cameraFilePath;
              private File createImageFile() throws IOException {
                  String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
                  String imageFileName = "JPEG_" + timeStamp + "_";
                  File storageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM), "Camera");
                  File image = File.createTempFile(imageFileName, /* prefix */ ".jpg", /* suffix */ storageDir /* directory */ );
                  cameraFilePath = "file://" + image.getAbsolutePath();
                  cameraImage = image;
                  return image;
              }
              private void captureFromCamera() {
                  try {
                      Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                      intent.putExtra(MediaStore.EXTRA_OUTPUT, FileProvider.getUriForFile(getContext(), BuildConfig.APPLICATION_ID + ".provider", createImageFile()));
                      startActivityForResult(intent, 1002);
                  } catch(IOException ex) {
                      ex.printStackTrace();
                  }
              }
              

              }

              像这样在Activity或片段中调用 在 Fragment/Activity 中定义 ImagePicker

              ImagePicker imagePicker;
              

              然后点击按钮调用dailog

                    imagePicker = new ImagePicker(new ImagePicker.GetImage() {
                          @Override
                          public void setGalleryImage(Uri imageUri) {
              
                              Log.i("ImageURI", imageUri + "");
              
                              String[] filePathColumn = {MediaStore.Images.Media.DATA};
              
                              Cursor cursor = getContext().getContentResolver().query(imageUri, filePathColumn, null, null, null);
                              assert cursor != null;
                              cursor.moveToFirst();
              
                              int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
                              mediaPath = cursor.getString(columnIndex);
                              // Set the Image in ImageView for Previewing the Media
                              imagePreview.setImageBitmap(BitmapFactory.decodeFile(mediaPath));
                              cursor.close();
              
                          }
              
                          @Override
                          public void setCameraImage(String filePath) {
              
                              mediaPath =filePath;
                              Glide.with(getContext()).load(filePath).into(imagePreview);
              
                          }
              
                          @Override
                          public void setImageFile(File file) {
              
                              cameraImage = file;
              
                          }
                      }, true);
                      imagePicker.show(getActivity().getSupportFragmentManager(), imagePicker.getTag());
              

              【讨论】:

                【解决方案14】:

                您可以使用此代码来 onClick 监听器(您可以使用 ImageView 或按钮)

                image.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                            Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                            if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
                                startActivityForResult(takePictureIntent, 1);
                            }
                        }
                    });
                

                在你的 imageView 中显示

                @Override
                protected void onActivityResult(int requestCode, int resultCode, Intent data) {
                    if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
                        Bundle extras = data.getExtras();
                        bitmap = (Bitmap) extras.get("data");
                        image.setImageBitmap(bitmap);
                
                    }
                }
                

                注意:将此插入清单

                <uses-feature android:name="android.hardware.camera" android:required="true" />
                

                【讨论】:

                  【解决方案15】:

                  Bitmap photo = (Bitmap) data.getExtras().get("data"); 从摄像头获取缩略图。有一篇关于如何从相机将图片存储在外部存储器中的文章。 useful link

                  【讨论】:

                    【解决方案16】:

                    请通过使用 Kotlin 和 Andoirdx 支持来执行此示例:

                    button1.setOnClickListener{
                            file = getPhotoFile()
                            val uri: Uri = FileProvider.getUriForFile(applicationContext, "com.example.foto_2.filrprovider", file!!)
                            captureImage.putExtra(MediaStore.EXTRA_OUTPUT, uri)
                    
                            val camaraActivities: List<ResolveInfo> = applicationContext.getPackageManager().queryIntentActivities(captureImage, PackageManager.MATCH_DEFAULT_ONLY)
                    
                            for (activity in camaraActivities) {
                                applicationContext.grantUriPermission(activity.activityInfo.packageName, uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
                            }
                    
                            startActivityForResult(captureImage, REQUEST_PHOTO)
                        }
                    

                    以及活动结果:

                    if (requestCode == REQUEST_PHOTO) {
                            val uri = FileProvider.getUriForFile(applicationContext, "com.example.foto_2.filrprovider", file!!)
                            applicationContext.revokeUriPermission(uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
                            imageView1.viewTreeObserver.addOnGlobalLayoutListener {
                                width = imageView1.width
                                height = imageView1.height
                                imageView1.setImageBitmap(getScaleBitmap(file!!.path , width , height))
                            }
                            if(width!=0&&height!=0){
                                imageView1.setImageBitmap(getScaleBitmap(file!!.path , width , height))
                            }else{
                                val size = Point()
                                this.windowManager.defaultDisplay.getSize(size)
                                imageView1.setImageBitmap(getScaleBitmap(file!!.path , size.x , size.y))
                            }
                    
                        }
                    

                    您可以在https://github.com/joelmmx/take_photo_kotlin.git获取更多详细信息

                    希望对你有帮助!

                    【讨论】:

                      【解决方案17】:

                      正如其他人所讨论的,使用data.getExtras().get("data") 只会得到低质量的缩略图

                      解决方案是使用您的 ACTION_IMAGE_CAPTURE 意图传递一个位置,告诉相机在哪里存储完整质量的图像。

                      代码是Kotlin,不需要任何权限。


                      val f = File("${getExternalFilesDir(null)}/imgShot")
                      val photoURI = FileProvider.getUriForFile(this, "${packageName}.fileprovider", f)
                      val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
                              .apply { putExtra(MediaStore.EXTRA_OUTPUT, photoURI) }
                      startActivityForResult(intent, 1234)
                      

                      然后处理拍照后的结果:

                      override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
                          if (requestCode == 1234 && resultCode == Activity.RESULT_OK) {
                              val bitmap = BitmapFactory.decodeFile(
                                      File("${getExternalFilesDir(null)}/imgShot").toString()
                              )
                              // use imageView.setImageBitmap(bitmap) or whatever
                          }
                      }
                      

                      您还需要添加一个外部 FileProvider,如 here 所述。 AndroidManifest.xml

                      <manifest>
                          <application>
                      
                              <provider
                                  android:name="androidx.core.content.FileProvider"
                                  android:authorities="${applicationId}.fileprovider"
                                  android:exported="false"
                                  android:grantUriPermissions="true">
                                  <meta-data
                                      android:name="android.support.FILE_PROVIDER_PATHS"
                                      android:resource="@xml/provide_paths" />
                              </provider>
                      
                          </application>
                      </manifest>
                      

                      添加一个新文件app/src/main/res/xml/provide_paths.xml

                      <?xml version="1.0" encoding="utf-8"?>
                      <paths>
                          <external-path name="external_files" path="." />
                      </paths>
                      

                      最后,您应该用自己的逻辑替换 1234 以跟踪请求代码(通常是带有 RequestCode.CAPTURE_IMAGE 等成员的枚举)

                      【讨论】:

                        【解决方案18】:

                        2021 年 5 月,JAVA

                        在处理了本文后面描述的必要权限后, 在清单中添加:

                        <uses-permission 
                            android:name="android.permission.READ_EXTERNAL_STORAGE" />
                        <uses-permission 
                            android:name="android.permission.WRITE_EXTERNAL_STORAGE"
                            android:maxSdkVersion="18"  />
                        <uses-permission android:name="android.permission.CAMERA" />
                        <uses-feature
                            android:name="android.hardware.camera"
                            android:required="true" />
                        ....
                        
                            <provider
                                android:name="androidx.core.content.FileProvider"
                                android:authorities="${applicationId}.fileprovider"
                                android:exported="false"
                                android:grantUriPermissions="true">
                                <meta-data
                                    android:name="android.support.FILE_PROVIDER_PATHS"
                                    android:resource="@xml/provider_paths" />
                            </provider>
                        ....
                        

                        其中 ${applicationId} 是应用程序的包名,例如my.app.com

                        res->xml->provider_paths.xml

                        <?xml version="1.0" encoding="utf-8"?>
                         <paths>
                          <external-files-path name="my_images" path="Pictures" />
                          <external-path name="external_files" path="."/>
                            <files-path
                            name="files"   path="." />
                            <external-cache-path
                              name="images" path="." />
                         </paths>
                        

                        活动中:

                        private void onClickCaptureButton(View view) {
                            Intent takePictureIntent_ = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                            // Ensure that there's a camera activity to handle the intent
                            if (takePictureIntent_.resolveActivity(getPackageManager()) != null) {
                                // Create the File where the photo should go
                                File photoFile_ = null;
                                try {
                                    photoFile_ = createImageFile();
                                } catch (IOException ex) {
                                }
                                if(photoFile_!=null){
                                    picturePath=photoFile_.getAbsolutePath();
                                }
                                // Continue only if the File was successfully created
                                if (photoFile_ != null) {
                                    Uri photoURI_ = FileProvider.getUriForFile(this,
                                       "my.app.com.fileprovider", photoFile_);
                                    takePictureIntent_.putExtra(MediaStore.EXTRA_OUTPUT, photoURI_);
                                    startActivityForResult(takePictureIntent_, REQUEST_IMAGE_CAPTURE);
                                }
                            }
                        }
                        

                        还有三个动作:

                        ...
                        private static String picturePath;
                        private static final int REQUEST_IMAGE_CAPTURE = 2;
                        ...
                        private File createImageFile() throws IOException {
                            // Create an image file name
                            String timeStamp_ = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new 
                              Date());
                            String imageFileName_ = "JPEG_" + timeStamp_ + "_";
                            File storageDir_ = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
                            File image_ = File.createTempFile(
                                    imageFileName_,  /* prefix */
                                    ".jpg",         /* suffix */
                                    storageDir_      /* directory */
                            );
                        
                            // Save a file: path for use with ACTION_VIEW intents
                            picturePath= image_.getAbsolutePath();
                            return image_;
                        }
                        
                        @Override
                        public void onActivityResult(int requestCode, int resultCode, Intent data) {
                            super.onActivityResult(requestCode, resultCode, data);
                           if(requestCode == REQUEST_IMAGE_CAPTURE && resultCode == Activity.RESULT_OK 
                           ){
                        
                                try {
                                    File file_ = new File(picturePath);
                                    Uri uri_ = FileProvider.getUriForFile(this,
                                            "my.app.com.fileprovider", file_);
                                    rasm.setImageURI(uri_);
                                } catch (/*IO*/Exception e) {
                                    e.printStackTrace();
                                }
                            }
                        }
                        

                        @Override
                        public void onSaveInstanceState(Bundle savedInstanceState) {
                            savedInstanceState.putString("safar", picturePath);
                            // Always call the superclass so it can save the view hierarchy state
                            super.onSaveInstanceState(savedInstanceState);
                        }
                        

                        和:

                         @Override
                         protected void onCreate(Bundle savedInstanceState) {
                            super.onCreate(savedInstanceState);
                            if (savedInstanceState != null) {
                                picturePath = savedInstanceState.getString("safar");
                            }
                         ....
                        }
                        

                        【讨论】:

                          猜你喜欢
                          • 1970-01-01
                          • 2014-11-29
                          • 1970-01-01
                          • 2020-11-08
                          • 2012-10-30
                          • 1970-01-01
                          • 1970-01-01
                          相关资源
                          最近更新 更多