我想写一个模块,在点击一个按钮,相机打开,我可以点击和捕捉图像。如果我不喜欢图像,我可以删除它,然后点击另一个图像,然后选择图像,它应该返回并在活动中显示该图像。
当前回答
你可以使用此代码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" />
其他回答
您可以使用自定义相机与缩略图图像。 你可以看看我的项目。
我创建了一个对话框,可以从图库或相机中选择图像。 回调函数为
Uri,如果图像来自图库 字符串作为文件路径,如果图像是从相机捕获。 从相机中选择的图像需要作为多部分文件数据上传到互联网上
首先,我们要在AndroidManifest中定义权限,因为我们需要在创建文件和从画廊读取图像时写入外部存储
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
中创建file_paths xml文件 应用程序/ 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>
然后我们需要定义文件提供者来生成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 Dailog
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 在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());
下面是一个示例活动,它将启动相机应用程序,然后检索图像并显示它。
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);
}
}
}
请注意,相机应用程序本身提供了查看/重拍图像的功能,一旦图像被接受,活动就会显示它。
下面是上面的活动使用的布局。它只是一个包含id为button1的Button和id为imageview1的ImageView的LinearLayout:
<?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。
在活动:
@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.硬件。相机" / >
正如其他人所讨论的,使用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。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等成员的枚举)
推荐文章
- 警告:API ' variable . getjavacompile()'已过时,已被' variable . getjavacompileprovider()'取代
- 安装APK时出现错误
- 碎片中的onCreateOptionsMenu
- TextView粗体通过XML文件?
- 如何使线性布局的孩子之间的空间?
- DSL元素android.dataBinding。enabled'已过时,已被'android.buildFeatures.dataBinding'取代
- ConstraintLayout:以编程方式更改约束
- PANIC: AVD系统路径损坏。检查ANDROID_SDK_ROOT值
- 如何生成字符串类型的buildConfigField
- Recyclerview不调用onCreateViewHolder
- Android API 21工具栏填充
- Android L中不支持操作栏导航模式
- 如何在TextView中添加一个子弹符号?
- PreferenceManager getDefaultSharedPreferences在Android Q中已弃用
- 在Android Studio中创建aar文件