Android 调用相机以及从相册中选择图片


调用相机拍照并显示

MainActivity.java:

public class MainActivity extends AppCompatActivity {

    public static final int TAKE_PHOTO = 1;
    public static final int CHOOSE_PHOT0 = 2;
    private Uri imageUri;
    private ImageView picture;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button takePhoto = findViewById(R.id.take_photo);
        picture = findViewById(R.id.picture);
        takePhoto.setOnClickListener(view -> {
            File outputFile = new File(getExternalCacheDir(),"output_image.jpg");
            //getExternalCacheDir()方法得到当前应用缓存数据位置
            try {
                if (outputFile.exists()) {
                    outputFile.delete();
                }
                outputFile.createNewFile();
                imageUri = FileProvider.getUriForFile(this,
                        "com.example.cameraalbumtest.fileprovider",outputFile);
                //启动相机程序
                Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
                intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
                if (intent.resolveActivity(getPackageManager()) != null){
                    startActivityForResult(intent, TAKE_PHOTO);//第二个参数是请求码
                }
                } catch (IOException e) {
                    e.printStackTrace();
            }
        });        
    }
    
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == TAKE_PHOTO && resultCode == RESULT_OK) {
            try {
                Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver()
                        .openInputStream(imageUri));
                picture.setImageBitmap(BitmapFactory.decodeStream(getContentResolver().openInputStream(imageUri)));
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
        }
    }

Android 7.0及以上要求我们用fileprovider,禁止应用将 file:// 开头的Uri共享给其他的应用读写文件,否则会收到FileUriExposedException的异常。FileProvider生成的Uri会使用我们自己配置的的name属性替换真实的文件路径。
在AndroidManifest.xml中添加provider标签:

<application>
	...
	<provider
		android:authorities="com.example.cameraalbumtest.fileprovider"
		android:name="androidx.core.content.FileProvider"
		android:exported="false"
		android:grantUriPermissions="true">
		<!-- 指定Uri的共享路径 -->
		<meta-data
			android:name="android.support.FILE_PROVIDER_PATHS"
			android:resource="@xml/file_paths"/>
	</provider>
	...
</application>

之后在 res/xml 文件夹下创建文件 file_paths.xml:

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

其中 external-cache-path标签对应getExternalCacheDirs()
name就是我们想要替换上去的名称,这样外部应用即使拿到Uri也无法知到具体的存储位置。

说明:
if (intent.resolveActivity(getPackageManager()) != null) 用来判断是否有对应的action来相应这个intent,如果有再startActivity。


选取相册照片显示

public class MainActivity extends AppCompatActivity {

    public static final int CHOOSE_PHOT0 = 2;
    private Uri imageUri;
    private ImageView picture;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        picture = findViewById(R.id.picture);
        Button chooseFromAlbum = findViewById(R.id.choose_from_album);
        chooseFromAlbum.setOnClickListener(view -> {
            //动态申请权限
            if (ContextCompat.checkSelfPermission(MainActivity.this,
                    Manifest.permission.WRITE_EXTERNAL_STORAGE)!= PackageManager.
                            PERMISSION_GRANTED) {
                ActivityCompat.requestPermissions(MainActivity.this,
                        new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
            } else {
                openAlbum();
            }
        });
    }

    private void openAlbum() {
        Intent intent = new Intent("android.intent.action.GET_CONTENT");
        intent.setType("image/*");
        startActivityForResult(intent, CHOOSE_PHOT0);//打开相册
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions,
                                           int[] grantResults) {
        if(requestCode == 1) {
            if (grantResults.length > 0 && grantResults[0]==PackageManager.
                    PERMISSION_GRANTED) {

//                openAlbum();
            } else {
                Log.d("tag",String.valueOf(grantResults[0]));
                Toast.makeText(this,"You denied the permission",
                        Toast.LENGTH_SHORT).show();
            }
        }
    }
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == CHOOSE_PHOT0 && resultCode == RESULT_OK) {
            if (Build.VERSION.SDK_INT >= 19) {
                //4.4及以上系统选取相册中的图片不再返回图片的真实Uri了,而是
                //一个封装过的Uri,需要对这个Uri进行解析。
                handleImageOnKitKat(data);
            } else {
                handleImageBeforeKitKat(data);
            }
        }
    }

    @TargetApi(19)
    private void handleImageOnKitKat(Intent data) {
        //解析封装过的Uri
        String imagePath = null;
        Uri uri = data.getData();
        if (DocumentsContract.isDocumentUri(this ,uri)) {
            //如果是document类型的Uri,则通过document id处理
            String docId = DocumentsContract.getDocumentId(uri);
            if("com.android.providers.media.documents".equals(uri.getAuthority())) {
                String id = docId.split(":")[1];//解析出数字格式的id
                String selection = MediaStore.Images.Media._ID + "=" +id;
                imagePath = getImagePath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                        selection);
            } else if ("com.android.providers.downloads.documents".equals(uri.getAuthority())) {
                Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"),
                        Long.valueOf(docId));
                imagePath = getImagePath(contentUri, null);
            }
        } else if ("content".equalsIgnoreCase(uri.getScheme())) {
            //如果是content类型的Uri,则使用普遍方式处理
            imagePath = getImagePath(uri, null);
        } else if ("file".equalsIgnoreCase(uri.getScheme())) {
            //如果是file类型的Uri,直接获取图片路径即可
            imagePath = uri.getPath();
        }
        displayImage(imagePath);
    }

    private void handleImageBeforeKitKat(Intent data) {
        Uri uri = data.getData();
        String imagePath = getImagePath(uri,null);
        displayImage(imagePath);
    }

    private String getImagePath(Uri uri, String selection) {
        String path=null;
        //通过Uri和selection类获取真实的图片路径
        Cursor cursor = getContentResolver().query(uri,null,selection, null ,null);
        if (cursor != null) {
            if(cursor.moveToFirst()) {
                int index = cursor.getColumnIndex(MediaStore.
                        Images.Media.DATA);
                path = cursor.getString(index);
            }
            cursor.close();
        }
        return path;
    }

    private void displayImage(String imagePath) {
        if (imagePath != null) {
            Bitmap bitmap = BitmapFactory.decodeFile(imagePath);
            picture.setImageBitmap(bitmap);
        } else {
            Toast.makeText(this,"failed to get image", Toast.LENGTH_SHORT).show();
        }
    }
}

在 AndroidManifest.xml 中需要加入权限:

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

在 Android Q 以后采用隔离存储,WRITE_EXTERNAL_STORAGE 只有了对媒体内容进行读写的权限。在本应用的存储沙盒之中读写不需要权限。

  • 4
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
Android Studio 使用 WebView 调用相机相册,需要使用 Android 系统提供的 WebChromeClient 和 WebViewClient 类。具体步骤如下: 1. 首先在 AndroidManifest.xml 文件添加以下权限: ```xml <uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> ``` 2. 在 Activity 创建 WebView,并设置 WebChromeClient 和 WebViewClient: ```java WebView webView = findViewById(R.id.webview); webView.setWebChromeClient(new WebChromeClient() { // 处理打开相机相册的请求 @Override public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams) { // 创建打开相机相册的 Intent Intent intent = fileChooserParams.createIntent(); try { // 启动 Intent startActivityForResult(intent, REQUEST_CODE_FILE_CHOOSER); } catch (ActivityNotFoundException e) { e.printStackTrace(); return false; } return true; } }); webView.setWebViewClient(new WebViewClient() { // 处理网页加载完成事件 @Override public void onPageFinished(WebView view, String url) { super.onPageFinished(view, url); // 在网页注入 JavaScript 代码,用于调用相机相册 view.loadUrl("javascript: function chooseImage() {window.android.chooseImage();}"); } }); ``` 3. 在 Activity 重写 onActivityResult 方法,处理选择图片后的结果: ```java @Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { if (requestCode == REQUEST_CODE_FILE_CHOOSER) { if (resultCode == RESULT_OK && data != null) { // 获取选择图片 Uri Uri uri = data.getData(); if (uri != null) { // 把 Uri 返回给网页 ValueCallback<Uri[]> filePathCallback = mFilePathCallback; if (filePathCallback != null) { filePathCallback.onReceiveValue(new Uri[]{uri}); mFilePathCallback = null; } } } else { // 如果选择图片失败,也要返回结果给网页 ValueCallback<Uri[]> filePathCallback = mFilePathCallback; if (filePathCallback != null) { filePathCallback.onReceiveValue(null); mFilePathCallback = null; } } } } ``` 4. 在 JavaScript 调用 window.android.chooseImage() 方法,用于打开相机相册选择图片: ```javascript function chooseImage() { // 创建 input 元素,用于触发选择图片的操作 var input = document.createElement('input'); input.type = 'file'; input.accept = 'image/*'; input.onchange = function () { // 把选择图片的结果返回给 Android var uri = input.files; if (uri) { window.android.chooseImage(uri); } else { window.android.chooseImage(null); } }; // 触发点击 input 元素的操作,打开相机相册 input.click(); } ``` 以上就是在 Android Studio 使用 WebView 调用相机相册的基本步骤。如果您还有其他问题,请随时提出。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值