Android 7.0 拍照使用getUriForFile

项目中修改用户头像会频繁用到,特就对此功能简单封装了一下,记录下来,代码如下:
DialogSelectPhoto 工具类

package com.union.lirenxing.view.ui.dialog;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.v4.app.FragmentActivity;
import android.support.v4.content.FileProvider;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.tandong.bottomview.view.BottomView;
import com.union.lirenxing.tools.BitmapUtil;
import com.union.mymm.R;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

import static android.app.Activity.RESULT_OK;

/**
 * 选择照片弹出框
 *
 * @author xiaobo
 * @version 1.0
 * @date 2016/12/3 10:42
 */
public class DialogSelectPhoto {

    String stupath, shenfenpath;
    private static final int PHOTO_REQUEST_TAKEPHOTO = 11;// 拍照
    private static final int PHOTO_REQUEST_GALLERY = 12;// 从相册中选择
    private static final int PHOTO_REQUEST_CUT = 3;// 结果
    private String path;// 图片全路径
    private String temppath;
    private static final int PERMISSON_REQUESTCODE = 0;
    public static final  String FOLODER = Environment.getExternalStorageDirectory()+"/com.union.mymm/";
    private File sdcardTempFile;

    private static final int REQUEST_CODE_PERMISSION_CAMERA = 1001;
    private static final int REQUEST_CODE_SETTING = 1002;
    private Context context;
    private  int type;

    public void setType(int type) {
        this.type = type;
    }

    public int getType() {
        return type;
    }

    public void getSelectPhoto(final Context context) {
        final BottomView bottomView = new BottomView(context, R.style.BottomViewTheme_Defalut, R.layout.pannel_select_photo);
        this.context = context;
        View view = bottomView.getView();
        TextView tv_take_photograph = (TextView) view.findViewById(R.id.tv_take_photograph);
        TextView tv_get_albums = (TextView) view.findViewById(R.id.tv_get_albums);
        LinearLayout ll_cancel = (LinearLayout) view.findViewById(R.id.ll_cancel);

        tv_take_photograph.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH-mm");
                Date student = new Date();
                String str = sdf.format(student);
                sdcardTempFile = new File(FOLODER, "tmp" + str + ".jpg");
                if(sdcardTempFile.exists()){
                    sdcardTempFile.delete();
                }
                if(!sdcardTempFile.exists()){
                    try {
                        File file = new File(FOLODER);
                        if(!new File(FOLODER).exists()){
                            file.mkdir();
                        }
                        sdcardTempFile.createNewFile();
                        // 调用系统的拍照功能
                        Intent intent3 = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                        // 指定调用相机拍照后照片的储存路径
                        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){
                            intent3.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                            Uri contentUri = FileProvider.getUriForFile(context, "com.union.mymm.provider", sdcardTempFile);
                            intent3.putExtra(MediaStore.EXTRA_OUTPUT, contentUri);
                        }else {
                            intent3.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(sdcardTempFile));
                        }
                        ((FragmentActivity) context).startActivityForResult(intent3, PHOTO_REQUEST_TAKEPHOTO);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }

                bottomView.dismissBottomView();
            }
        });

        tv_get_albums.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent2 = new Intent(Intent.ACTION_PICK, null);
                intent2.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
                ((FragmentActivity) context).startActivityForResult(intent2, PHOTO_REQUEST_GALLERY);
                bottomView.dismissBottomView();
            }
        });

        ll_cancel.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                bottomView.dismissBottomView();
            }
        });
        bottomView.showBottomView(true);
    }


    public String onActivityResult(Context context, int requestCode, int resultCode, Intent data) {
        if (resultCode != RESULT_OK) {
            ((FragmentActivity) context).setResult(Activity.RESULT_CANCELED);
            ((FragmentActivity) context).finish();
            return "";
        }
        Uri uri = null;
        switch (requestCode) {
            case PHOTO_REQUEST_TAKEPHOTO:
                path = sdcardTempFile.getAbsolutePath();
                break;
            case PHOTO_REQUEST_GALLERY:
                if (data == null) {
                    return "";
                }
                uri = data.getData();
                if (uri.toString().toLowerCase().startsWith("file:")) {
                    path = uri.toString().substring(7);
                } else {
                    // startPhotoZoom(data.getData(), 150);
                    // startActivityForResult(data, PHOTO_REQUEST_CUT);
                    Uri originalUri = data.getData(); // 获得图片的uri
                    // bm = MediaStore.Images.Media.getBitmap(resolver,
                    // originalUri); //显得到bitmap图片
                    // 这里开始的第二部分,获取图片的路径:
                    String[] proj = {MediaStore.Images.Media.DATA};
                    // 好像是android多媒体数据库的封装接口,具体的看Android文档
                    @SuppressWarnings("deprecation")
                    Cursor cursor = ((FragmentActivity) context).managedQuery(originalUri, proj, null, null, null);
                    // 按我个人理解 这个是获得用户选择的图片的索引值
                    int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
                    // 将光标移至开头 ,这个很重要,不小心很容易引起越界
                    cursor.moveToFirst();
                    // 最后根据索引值获取图片路径
                    path = cursor.getString(column_index);// 获得图片的uri
                }
                if(this.type == 1){
                    startPhotoZoom(path);
                }
                break;
            case PHOTO_REQUEST_CUT:
                if (data == null) {
                    // ToastUtils.custom("已取消");
                    return "";
                }
                Bundle bundle = data.getExtras();
                if (bundle != null) {
                    Bitmap photo = bundle.getParcelable("data");
                    temppath = BitmapUtil.SavePhoto(photo, 0);
                    ByteArrayOutputStream stream = new ByteArrayOutputStream();
                    photo.compress(Bitmap.CompressFormat.JPEG, 100, stream);//
                    // Drawable drawable = new BitmapDrawable(photo);
                    // int x=2+(int)(Math.random()*2000);
                    // studentpath = "/mnt/sdcard/"+"tmp" + str + ".jpg";;
                    // mAddImgIv.setImageBitmap(photo);
                }
                path = temppath;
                break;
            case 4:
                if(data!=null){
                    path = setPicToView(data);
                }
                break;
            default:
                break;
        }
        return path;
    }


    /**
     * 保存裁剪之后的图片数据
     * @param picdata
     */
    private String setPicToView(Intent picdata) {
        String path="";
        Bundle extras = picdata.getExtras();
        if (extras != null) {
            Bitmap photo = extras.getParcelable("data");
            path = BitmapUtil.SavePhoto(photo,0);

//          BitmapCompress.getSmallBitmap(fileName, new File(fileName));
            /**
             * 下面注释的方法是将裁剪之后的图片以Base64Coder的字符方式上
             * 传到服务器,QQ头像上传采用的方法跟这个类似
             */

            /*ByteArrayOutputStream stream = new ByteArrayOutputStream();
            photo.compress(Bitmap.CompressFormat.JPEG, 60, stream);
            byte[] b = stream.toByteArray();
            // 将图片流以字符串形式存储下来

            tp = new String(Base64Coder.encodeLines(b));
            这个地方大家可以写下给服务器上传图片的实现,直接把tp直接上传就可以了,
            服务器处理的方法是服务器那边的事了,吼吼

            如果下载到的服务器的数据还是以Base64Coder的形式的话,可以用以下方式转换
            为我们可以用的图片类型就OK啦...吼吼
            Bitmap dBitmap = BitmapFactory.decodeFile(tp);
            Drawable drawable = new BitmapDrawable(dBitmap);
            */

        }
        return path;
    }


    /**
     * 裁剪图片方法实现
     * @param
     */
    public void startPhotoZoom(String path) {
        /*
         * 至于下面这个Intent的ACTION是怎么知道的,大家可以看下自己路径下的如下网页
         * yourself_sdk_path/docs/reference/android/content/Intent.html

         */


        Intent intent = new Intent("com.android.camera.action.CROP");
        Uri uri=null;
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){
            intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            uri = FileProvider.getUriForFile(context, "com.union.mymm.provider", new File(path));
        }else {
            uri = Uri.fromFile(new File(path));
        }
        intent.setDataAndType(uri, "image/*");
        //下面这个crop=true是设置在开启的Intent中设置显示的VIEW可裁剪
        intent.putExtra("crop", "true");
        // aspectX aspectY 是宽高的比例
        intent.putExtra("aspectX", 1);
        intent.putExtra("aspectY", 1);
        // outputX outputY 是裁剪图片宽高
        intent.putExtra("outputX", 150);
        intent.putExtra("outputY", 150);
        intent.putExtra("return-data", true);
        ( (FragmentActivity) context).startActivityForResult(intent, 4);
    }
}

添加 BottomView 依赖:

style 样式:

 <style name="BottomViewTheme_Defalut">
        <item name="android:windowFrame">@null</item>
        <item name="android:windowContentOverlay">@null</item>
        <item name="android:windowIsFloating">true</item>
        <item name="android:windowIsTranslucent">false</item>
        <item name="android:windowNoTitle">true</item>
        <item name="android:windowBackground">@android:color/transparent</item>
        <item name="android:backgroundDimEnabled">true</item>
        <item name="android:windowFullscreen">true</item>
    </style>

XML:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/ll_panel_report_bottom"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:background="@android:color/transparent"
    >

    <LinearLayout
        android:layout_marginTop="@dimen/margin_12_dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:layout_marginRight="10dp"
        android:background="@android:color/transparent"
        android:orientation="vertical">


        <TextView
            android:id="@+id/tv_take_photograph"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@mipmap/panel_report_bottom_bg"
            android:gravity="center"
            android:text="拍照"
            android:textColor="@color/color_themeColor"
            android:textSize="@dimen/text_16_sp" />


        <View
            android:layout_width="match_parent"
            android:layout_height="5dp" />

        <TextView
            android:id="@+id/tv_get_albums"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@mipmap/panel_report_bottom_bg"
            android:gravity="center"
            android:text="从手机相册选择"
            android:textColor="@color/color_themeColor"
            android:textSize="@dimen/text_16_sp" />

        <LinearLayout
            android:id="@+id/ll_cancel"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginBottom="@dimen/margin_12_dp"
            android:layout_marginTop="10dp"
            android:background="@mipmap/panel_report_bottom_bg">

            <TextView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="@drawable/selector_common_item_press"
                android:gravity="center"
                android:text="取消"
                android:textSize="@dimen/text_16_sp" />
        </LinearLayout>
    </LinearLayout>
</LinearLayout>

AndroidManifest 配置

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

注意 清单文件中的 @xml/path 路径 如下图

path.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>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值