在Android相机拍摄的图像视图中显示图片

时间:2019-03-25 05:28:30

标签: android imageview android-photoview

我正在尝试以下操作:

  1. 用我的Android设备拍照。
  2. 使用在步骤1中拍摄的照片填充“图像视图”

我尝试遵循下面列出的教程

  1. https://developer.android.com/training/camera/photobasics
  2. How to display picture in imageview photo taken by camera in android
  3. display picture in imageview photo taken by camera in android

但是似乎没有任何效果。这是我的代码

精简版图xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="16dp">
      <ImageView
                android:id="@+id/crime_photo"
                android:layout_width="80dp"
                android:layout_height="80dp"
                android:background="@android:color/darker_gray"
                android:contentDescription="@string/show_a_picture"
                android:cropToPadding="true"
                android:scaleType="centerInside" />

      <ImageButton
                android:id="@+id/crime_camera"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:contentDescription="@string/take_a_picture"
                android:src="@android:drawable/ic_menu_camera" />
</LinearLayout>

我将此布局加载到片段中。这是我的片段代码。

public class CrimeFragment extends Fragment {

  private static final String TAG = CrimeFragment.class.getName();


    private ImageView mPhotoView;

    private ImageButton mPhotoButton;

    private File mPhotoFile;

    private String mPhotoPath;

    private static final String ARG_ID = "crime_id";

    static final String DIALOG_PHOTO = "DialogPhoto";

    static final int REQUEST_CAMERA = 3;

    static final int REQUEST_PHOTO = 4;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
                             @Nullable Bundle savedInstanceState)  {
        View view = inflater.inflate(R.layout.fragment_crime, container, false);

        PackageManager packageManager = getActivity().getPackageManager();
    mPhotoButton = (ImageButton) view.findViewById(R.id.crime_camera);
    mPhotoButton.setEnabled(packageManager.hasSystemFeature(
          PackageManager.FEATURE_CAMERA_ANY));

    final Intent captureImage = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
            mPhotoButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
 mPhotoPath = mCrime.getPhotoFilePath();
              mPhotoFile = createTempFile(mPhotoPath);
              CrimeLab.get(getActivity()).updateCrime(mCrime);
              if (mPhotoFile!= null) {
                Uri uri = FileProvider.getUriForFile(getActivity(),
                    "com.myproject.criminalintent.fileprovider", mPhotoFile);
                captureImage.putExtra(MediaStore.EXTRA_OUTPUT, uri);
                getActivity().startActivityForResult(captureImage, REQUEST_CAMERA);
              }
            });

// Populate the image view if it exists.
mPhotoView = view.findViewById(R.id.crime_photo);
mPhotoView.setOnClickListener(new View.OnClickListener() {
  @Override
  public void onClick(View view) {
     updatePhotoView();

  }
});

        return view;
    }

private void updatePhotoView() {
    mPhotoPath = mCrime.getPhotoFilePath();

    if (mPhotoPath == null) {
        mPhotoFile = createTempFile(mCrime.getPhotoFilename());
        mPhotoPath = mPhotoFile.getAbsolutePath();
        mCrime.setPhotoFilePath(mPhotoPath);
        CrimeLab.get(getActivity()).updateCrime(mCrime);

      mPhotoView.setImageDrawable(null);
    } else {
        // Get photo from the gallery to populate the image view.
      if (mPhotoFile == null || !mPhotoFile.exists()) {
        mPhotoFile = createTempFile(mCrime.getPhotoFilename());
      }
      Bitmap bitmap = PictureUtils.getScaledBitmap(mPhotoFile.getAbsolutePath(), getActivity());
      if (bitmap != null) {
        mPhotoView.setImageBitmap(bitmap);
      }
    }

private File createTempFile(String path) {
      try {
        File storageDirectory = getActivity().getExternalFilesDir(Environment.DIRECTORY_PICTURES);
        return File.createTempFile(path, ".jpg", storageDirectory);
      } catch (IOException ioe) {
        Log.e(TAG, "Unable to create temp file : " + mPhotoFile, ioe);
        return null;
      }
    }

  @Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (resultCode != Activity.RESULT_OK ) {
        return;
    }
    if (requestCode == REQUEST_CAMERA) {
      Bundle extras = data.getExtras();
      Bitmap imageBitmap = (Bitmap) extras.get("data");
      mPhotoView.setImageBitmap(imageBitmap);
    }
}

我的Android清单

<provider
            android:name="android.support.v4.content.FileProvider"
            android:authorities="com.myproject.criminalintent.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true">
        <meta-data android:resource="@xml/files" android:name="android.support.FILE_PROVIDER_PATHS"/>
        </provider>

XML文件

<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path
        name="crime_photos"  path="Android/data/com.myproject.criminalintent/files/Pictures" />
</paths>

更新:我已经添加了屏幕截图。

我应该已经指定了,但是当我尝试执行此操作时,控件根本不返回onActivityResult。我不知道。

图片1:返回getActivity().startActivityForResult(captureImage, REQUEST_CAMERA)时的视图

Camera view on an emulator

我通过单击相机图标,然后按返回键来拍照。控件永远不会转到onActivityResult。我不知道为什么会这样。我尝试了该设备和仿真器,并且始终得到相同的结果。当我再次单击按钮时,我看到崩溃如下。

Camera Crash

异常堆栈跟踪如下:

java.lang.SecurityException: Permission Denial: writing android.support.v4.content.FileProvider uri content://com.myproject.criminalintent.fileprovider/crime_photos/IMG_d5d15282-9ac9-4a8d-adea-0ba59d8db7d31012669679698977960.jpg from pid=7201, uid=10074 requires the provider be exported, or grantUriPermission()
        at android.content.ContentProvider.enforceWritePermissionInner(ContentProvider.java:706)
        at android.content.ContentProvider$Transport.enforceWritePermission(ContentProvider.java:515)
        at android.content.ContentProvider$Transport.enforceFilePermission(ContentProvider.java:487)
        at android.content.ContentProvider$Transport.openAssetFile(ContentProvider.java:385)
        at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:251)
        at android.os.Binder.execTransact(Binder.java:731)

已更新##2:像

一样,在拍照后相机没有返回onActivityResult
  1. Camera does not return to OnActivityResult

更新

这是对我有用的解决方案

  private void updatePhotoview() {
    if (mPhotoPath == null) {
      mPhotoPath = mCrime.getPhotoFilePath();
    }
    if (mPhotoPath == null) {
      return;
    }
    final Uri uri = Uri.parse("file://" + mPhotoPath);
    final ViewTreeObserver vo = mPhotoView.getViewTreeObserver();
    vo.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
      @Override
      public void onGlobalLayout() {
        int finalHeight = mPhotoView.getMeasuredHeight();
        int finalWidth = mPhotoView.getMeasuredWidth();
        Bitmap bitmap = PictureUtils.getScaledBitmap(uri, finalHeight, finalWidth, getActivity());
        mPhotoView.setImageBitmap(bitmap);
        CrimeLab.get(getActivity()).updateCrime(mCrime);
        if (Util.isOsVersionGreaterOrEqualTo(Build.VERSION_CODES.JELLY_BEAN)) {
          mPhotoView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
        }
      }
    });
  }


@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode != Activity.RESULT_OK) {
  return;
}
if (requestCode == REQUEST_CAMERA) {
   updatePhotoview();
}
}

2 个答案:

答案 0 :(得分:0)

在XML中:

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.2/css/bootstrap.min.css">
<button type="button" id="save" class="commonButton">
				<i class="fas fa-save"></i>&nbsp;Save
			</button>
<div class="table-responsive">
  <table id="indentTable" class="table table-bordered table-hover ">

  </table>
</div>

在片段中:

<ImageView
    android:id="@+id/profilePic"
    android:layout_width="@dimen/sdp105"
    android:layout_height="@dimen/sdp105"
    android:layout_centerHorizontal="true"
    android:background="@drawable/border"
    android:src="@drawable/ic_profile" />

<ImageButton
    android:id="@+id/crime_camera"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:contentDescription="@string/take_a_picture"
    android:src="@android:drawable/ic_menu_camera" /> 

答案 1 :(得分:0)

只需使用此类。您可以获取许可并获取图像并将其显示在imageview中。 如果需要任何帮助,请回复并发表评论。

 public class CameraFragment extends android.support.v4.app.Fragment  {

    private String imageFilePath;
    private static final int CAMERA_CAPTURE_IMAGE_REQUEST_CODE = 100;
    private static final int REQUEST_PERMISSIONS_REQUEST_CODE = 34;
    private String visitingCard;
    private ImageView visitingCardImage;

    public CameraFragment() {
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        setHasOptionsMenu(true);
        super.onCreate(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        View view = inflater.inflate(R.layout.fragment_fragment_camera, container, false);

        if(checkPermission()){
            openCameraIntent();
        }

        visitingCardImage = view.findViewById(R.id.crime_photo);
        return view;
    }

    public static String getBase64String(Bitmap image) {
        String encodeString = null;
        try {
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            image.compress(Bitmap.CompressFormat.JPEG, 100, byteArrayOutputStream);
            byte[] byteArray = byteArrayOutputStream.toByteArray();
            encodeString = Base64.encodeToString(byteArray, Base64.DEFAULT);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return encodeString;
    }




    BitmapFactory.Options options;
    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        //getActivity();
        String compressedPath = null;
        if (requestCode == CAMERA_CAPTURE_IMAGE_REQUEST_CODE && resultCode == RESULT_OK) {
            try {
                ImageCompressor compressor = new ImageCompressor();
                compressedPath = compressor.compressImage(imageFilePath, getActivity());
                Bitmap bitmap = BitmapFactory.decodeFile(compressedPath);
                visitingCardImage.setImageBitmap(bitmap);
                visitingCard = getBase64String(bitmap);
            } catch (OutOfMemoryError e) {
                try {
                    options = new BitmapFactory.Options();
                    options.inSampleSize = 2;
                    Bitmap bitmap =  BitmapFactory.decodeFile(compressedPath, options);
                    visitingCardImage.setImageBitmap(bitmap);
                    visitingCard = getBase64String(bitmap);
                    //return bitmap;
                } catch(Exception el) {
                    el.printStackTrace();
                }
            }

        } else {
            Toast.makeText(getActivity(), "cancelled image capture", Toast.LENGTH_SHORT).show();
        }

    }

    private void openCameraIntent() {
        Intent pictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        if (pictureIntent.resolveActivity(getActivity().getPackageManager()) != null) {
            File photoFile;
            try {
                photoFile = createImageFile();
            } catch (IOException e) {
                e.printStackTrace();
                return;
            }
            Uri photoUri;
            if (android.os.Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP) {
                photoUri = Uri.fromFile(photoFile);
            } else {
                photoUri = FileProvider.getUriForFile(getActivity(), getActivity().getPackageName() + ".provider", photoFile);
            }
            pictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri);
            startActivityForResult(pictureIntent, CAMERA_CAPTURE_IMAGE_REQUEST_CODE);
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        if (requestCode == REQUEST_PERMISSIONS_REQUEST_CODE) {
            if (grantResults.length <= 0) {
                Log.i(TAG, "User interaction was cancelled.");
            }else if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                openCameraIntent();
            }
        }
    }
    //endregion

    private File createImageFile() throws IOException {
        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date());
        String imageFileName = "IMG_" + timeStamp + "_";
        File storageDir = getActivity().getExternalFilesDir(Environment.DIRECTORY_PICTURES);
        File image = File.createTempFile(imageFileName, ".jpg", storageDir);
        imageFilePath = image.getAbsolutePath();
        return image;
    }

    private boolean checkPermission() {

        if (Build.VERSION.SDK_INT >= 23) {
            if (ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED
                    && ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
                return true;
            } else {
                requestPermissions(new String[]{Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_PERMISSIONS_REQUEST_CODE);
                return false;
            }
        } else {
            return true;
        }

    }

}

在清单文件中添加此

  <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" />