Android 拍照或从相册设置头像

今天有点闲,所以来写一篇博客吧~~~

什么功能呢? 就是非常常见的 设置头像的功能..这次写到博客中,以后用的时候就方便了,直接拿来用就可以了,

好了 进入正题.....

思路:

通过startActivityForResult方法,分别传递调用系统相册的Intent和调用相机拍照的Intent来做选择,之后调用Android系统中自带的图片剪裁,实现图片的剪裁并在onActivityResult方法中获取数据。


1.效果图 

本来是想录GIf的 ,可结果 虚拟机不知道怎么了  相机用不了了..所以效果图就放图片了

大概就是这样的一个界面  ,,....我做的是点击头像从屏幕底部弹出dialog,,接下来 我们来先从布局开始

Fragment的布局我就不放了..可以根据个人来设置这个dialog的 弹窗.


dialog的 布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              xmlns:widget="http://schemas.android.com/apk/res-auto"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical">
        <LinearLayout
            style="@style/wrap_layout"
            android:layout_marginTop="0dp"
            >
            <!-- 上圆角-->
            <LinearLayout
                android:id="@+id/ll_takePhoto"
                style="@style/top_layout">

                <TextView
                    style="@style/usertext"
                    android:gravity="center"
                    android:text="拍照"
                    android:textColor="@color/blue"/>
            </LinearLayout>
            <!-- 分割线 -->
            <View style="@style/bg_line"/>
            <!-- 下圆角-->
            <LinearLayout
                android:id="@+id/ll_choosePhoto"
                style="@style/bottom_layout">

                <TextView
                    style="@style/usertext"
                    android:gravity="center"
                    android:text="从相册中选择"
                    android:textColor="@color/blue"/>
            </LinearLayout>
        </LinearLayout>
        <!-- 全圆角-->
        <LinearLayout style="@style/wrap_layout">
            <LinearLayout
                android:id="@+id/ll_cancel"
                style="@style/single_layout">
                <TextView
                    style="@style/usertext"
                    android:gravity="center"
                    android:text="取消"
                    android:textColor="@color/blue"/>
            </LinearLayout>
        </LinearLayout>
</LinearLayout>

详细的布局 去下载demo 去看吧,这里我就不说了

然后我们来看看代码的编写

 先在AndroidManifest文件中 加入读写权限

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

然后进行下一步

1.拍照 调用系统拍照功能

 //调用系统拍照功能
 intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
 // 指定调用相机拍照后照片的储存路径
 intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(tempFile));
startActivityForResult(intent, PHOTO_REQUEST_TAKEPHOTO);

2.调用手机相册

intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
startActivityForResult(intent, PHOTO_REQUEST_GALLERY);

3. onActivityResult方法中获取数据

 这个方法在什么时候调用呢?

 它是在当前界面startActivityForResult(intent)  等intent 对应的界面 返回到原来的Activity的时候调用onActivityResult

就是 ---->A  跳转到 B  然后 又 从B 返回到 A   的时候 

  1. 第一个参数:

    这个整数requestCode提供给onActivityResult,是以便确认返回的数据是从哪个Activity返回的。这个requestCode和startActivityForResult中的requestCode相对应

  2. 第二个参数:
    这整数resultCode是由子Activity通过其setResult()方法返回.

  3. 第三个参数
    一个Intent对象,带有返回的数据.

  @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        switch (requestCode) {
            case PHOTO_REQUEST_TAKEPHOTO:
                crop(Uri.fromFile(tempFile), 150);
                break;

            case PHOTO_REQUEST_GALLERY:
                if (data != null)
                    crop(data.getData(), 150);
                break;

            case PHOTO_REQUEST_CUT:
                if (data != null)
                    setPicToView(data);
                break;
        }
        super.onActivityResult(requestCode, resultCode, data);
    }


4.调用裁剪界面

private void crop(Uri uri, int size) {
        Intent intent = new Intent("com.android.camera.action.CROP");
        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", size);
        intent.putExtra("outputY", size);
        intent.putExtra("return-data", true);

        startActivityForResult(intent, PHOTO_REQUEST_CUT);
    }

5. 设置到ImageView 上

 //将进行剪裁后的图片显示到UI界面上
    private void setPicToView(Intent picdata) {
        Bundle bundle = picdata.getExtras();
        if (bundle != null) {
            Bitmap photo = bundle.getParcelable("data");
            iv_head.setImageBitmap(photo);
        }
    }


最后贴上Activity的完整代码:

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private RoundImagevView iv_head;
    private Dialog dialog;
    private LinearLayout ll_takePhoto, ll_choosePhoto, ll_cancel;
    private static final int PHOTO_REQUEST_TAKEPHOTO = 1;// 拍照
    private static final int PHOTO_REQUEST_GALLERY = 2;// 从相册中选择
    private static final int PHOTO_REQUEST_CUT = 3;// 结果
    // 创建一个以当前时间为名称的文件
    File tempFile = new File(Environment.getExternalStorageDirectory(), getPhotoFileName());

    private Bitmap bitmap;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        iv_head = (RoundImagevView) findViewById(R.id.iv_head);
        iv_head.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        Intent intent;
        switch (v.getId()) {
            case R.id.iv_head:
                showDiaLog();
                break;
            case R.id.ll_takePhoto:
                // 调用系统的拍照功能
                intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                // 指定调用相机拍照后照片的储存路径
                intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(tempFile));
                startActivityForResult(intent, PHOTO_REQUEST_TAKEPHOTO);
                break;

            case R.id.ll_choosePhoto:
                intent = new Intent(Intent.ACTION_PICK, null);
                intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
                startActivityForResult(intent, PHOTO_REQUEST_GALLERY);
                break;
            case R.id.ll_cancel:
                dialog.dismiss();
                break;
        }
    }


    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        // TODO Auto-generated method stub

        switch (requestCode) {
            case PHOTO_REQUEST_TAKEPHOTO:
                crop(Uri.fromFile(tempFile), 150);
                break;

            case PHOTO_REQUEST_GALLERY:
                if (data != null)
                    crop(data.getData(), 150);
                break;

            case PHOTO_REQUEST_CUT:
                if (data != null)
                    setPicToView(data);
                break;
        }
        super.onActivityResult(requestCode, resultCode, data);

    }

    private void crop(Uri uri, int size) {
        Intent intent = new Intent("com.android.camera.action.CROP");
        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", size);
        intent.putExtra("outputY", size);
        intent.putExtra("return-data", true);

        startActivityForResult(intent, PHOTO_REQUEST_CUT);
    }

    //将进行剪裁后的图片显示到UI界面上
    private void setPicToView(Intent picdata) {
        Bundle bundle = picdata.getExtras();
        if (bundle != null) {
            Bitmap photo = bundle.getParcelable("data");
//            Drawable drawable = new BitmapDrawable(photo);
            iv_head.setImageBitmap(photo);
//            sendImage(bitmap);
        }
    }

    // 使用系统当前日期加以调整作为照片的名称
    private String getPhotoFileName() {
        Date date = new Date(System.currentTimeMillis());
        SimpleDateFormat dateFormat = new SimpleDateFormat("'IMG'_yyyyMMdd_HHmmss");
        return dateFormat.format(date) + ".jpg";
    }


    /**
     * 显示dialog
     */
    private void showDiaLog() {
        dialog = new Dialog(this, R.style.dialog);//自定义dialog样式
        View view = LayoutInflater.from(this).inflate(R.layout.dialog_chose_layout, null);
        ll_takePhoto = (LinearLayout) view.findViewById(R.id.ll_takePhoto);
        ll_choosePhoto = (LinearLayout) view.findViewById(R.id.ll_choosePhoto);
        ll_cancel = (LinearLayout) view.findViewById(R.id.ll_cancel);
        ll_takePhoto.setOnClickListener(this);
        ll_choosePhoto.setOnClickListener(this);
        ll_cancel.setOnClickListener(this);
        dialog.setContentView(view);
        Window window = dialog.getWindow();
        window.setGravity(Gravity.BOTTOM);//设置为从底部弹出
        WindowManager.LayoutParams layoutParams = window.getAttributes();
        layoutParams.y = 30;//设置y轴的坐标
        window.setAttributes(layoutParams);
        dialog.show();

    }
}

注:

上传图片的代码在demo中我注释掉了,你用的你的网络框架上传就好了,,,


需要Demo的同学 请点击下面

--->点我点我


周五了...祝大家周末愉快~~~

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值