Android6.0 权限后编辑头像功能

一个简单的小功能,适合初学者,大神路过即可…

点击按钮弹出PopupWindow,打开相机或相册选择头像并裁剪后显示在ImageView上。

编辑用户头像,基本是个APP都要实现的功能,在6.0加入权限后变得稍微麻烦了点。在写项目的时候正好用到,找了下别人写的,改了改,记录下来,方便自己也方便他人。。。
参考文章:
1. http://www.jianshu.com/p/64baf3f9c38f Android 6.0后权限申请工具库的用法
2. http://blog.csdn.net/harvic880925/article/details/43163175 拍照、相册及裁剪的终极实现
3. 感谢两位的文章分享,我只是把两个功能合到一起了^_^

1.在Android6.0以后引入的权限机制,使用没什么难度啊,大神都介绍的很清楚了。要编辑头像,我们从相机或者相册选择,打开相机必须进行权限申请。这里用到了PermissionTools权限申请工具库。
PermissionTools的github地址:https://github.com/Jerey-Jobs/PermissionTools
PermissionTools的使用方法:
1.1 project’s build.gradle (工程下的 build.gradle)

allprojects {
        repositories {
            ...
            maven { url 'https://jitpack.io' }
        }
}

1.2.module’s build.gradle (模块的build.gradle)

dependencies {
            compile 'com.github.Jerey-Jobs:PermissionTools:1.5'
}

正式开始了:
新建项目,这个不用说了哈,在AndroidManifest.xml里面添加如下权限
分别的是 相机权限 及 读写权限

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

activity_main布局文件,就放一个Button用来点击弹出PopupWindow,一个ImageView用来显示选择的图片

<Button
    android:id="@+id/bt_open"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="弹窗" />

<ImageView
   android:id="@+id/imageView"
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
   app:srcCompat="@mipmap/ic_launcher"
   android:layout_weight="0.59" />

既然要弹出PopupWindow,当然要有个PopupWindow的布局啦,两个按钮,分别是打开相机,和从相册选择,新建XML文件view_popupwindow

        <View
            android:layout_width="match_parent"
            android:layout_height="0.1px"
            android:background="#888" />

        <TextView
            android:id="@+id/tv_pick_phone"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:padding="16dp"
            android:text="打开相机"
            android:textColor="#118"
            android:textSize="18sp" />

        <View
            android:layout_width="match_parent"
            android:layout_height="0.1px"
            android:background="#888" />

        <TextView
            android:id="@+id/tv_pick_zone"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:padding="16dp"
            android:text="从手机相册选择"
            android:textColor="#118"
            android:textSize="18sp" />

下面就是MainActivity的代码了onCreate中
初始化控件,不用讲了
下面来用两个Uri,来存放图片

        String path = getSDCardPath();
        File file = new File(path + "/temp.jpg");
        imageUri = Uri.fromFile(file);
        File cropFile = new File(getSDCardPath() + "/temp_crop.jpg");
        imageCropUri = Uri.fromFile(cropFile);
    //getSDCardPath()
    public static String getSDCardPath() {
        String cmd = "cat /proc/mounts";
        Runtime run = Runtime.getRuntime();// 返回与当前 Java 应用程序相关的运行时对象
        try {
            Process p = run.exec(cmd);// 启动另一个进程来执行命令
            BufferedInputStream in = new BufferedInputStream(p.getInputStream());
            BufferedReader inBr = new BufferedReader(new InputStreamReader(in));

            String lineStr;
            while ((lineStr = inBr.readLine()) != null) {
                // 获得命令执行后在控制台的输出信息
                if (lineStr.contains("sdcard")
                        && lineStr.contains(".android_secure")) {
                    String[] strArray = lineStr.split(" ");
                    if (strArray != null && strArray.length >= 5) {
                        String result = strArray[1].replace("/.android_secure",
                                "");
                        return result;
                    }
                }
                // 检查命令是否执行失败。
                if (p.waitFor() != 0 && p.exitValue() == 1) {
                    // p.exitValue()==0表示正常结束,1:非正常结束
                }
            }
            inBr.close();
            in.close();
        } catch (Exception e) {

            return Environment.getExternalStorageDirectory().getPath();
        }

        return Environment.getExternalStorageDirectory().getPath();
    }
//点击弹窗,需要获取用户授权,用户同意后则弹出PopupWindow,原谅我起了个通俗易懂的名字
@Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.bt_open:
            //调用方法,获取权限
                xiangji(v);
                break;
    }
}

//获取权限方法
public void xiangji(final View v) {
        permissionTools = new PermissionTools.Builder(this)
                .setOnPermissionCallbacks(new PermissionCallbacks() {
                //用户同意权限申请,执行此方法
                    @Override
                    public void onPermissionsGranted(int requestCode, List<String> perms) {
                    //权限申请通过,执行方法,弹出PopupWindow
                        openPopupWindow(v);
                    }
                //用户不同意权限申请,执行此方法
                    @Override
                    public void onPermissionsDenied(int requestCode, List<String> perms) {
                      Toast.makeText(MainActivity.this, "权限申请被据绝",Toast.LENGTH_SHORT).show();
                    }
                })
                .setRequestCode(111)
                .build();
//需要申请哪些权限,我这里同时申请了 相机权限 和 读写权限,可以同时多个,也可以单个,“,”隔开
                                               permissionTools.requestPermissions(Manifest.permission.CAMERA,Manifest.permission.WRITE_EXTERNAL_STORAGE);
}
//弹出PopupWindow
private void openPopupWindow(View v) {
        if (popupWindow != null && popupWindow.isShowing()) {
            return;
        }
        //设置PopupWindow的View
        View view = LayoutInflater.from(this).inflate(R.layout.view_popupwindow, null);
        popupWindow = new PopupWindow(view, RelativeLayout.LayoutParams.MATCH_PARENT,
                RelativeLayout.LayoutParams.WRAP_CONTENT);
        //设置背景,这个没什么效果,不添加会报错
        popupWindow.setBackgroundDrawable(new BitmapDrawable());
        //设置点击弹窗外隐藏自身
        popupWindow.setFocusable(true);
        popupWindow.setOutsideTouchable(true);
        //设置动画
        popupWindow.setAnimationStyle(R.style.PopupWindow);
        //设置位置,这里需要用到传过来view了
        //popupWindow.showAtLocation(v, Gravity.BOTTOM, 0, navigationHeight);
        popupWindow.showAtLocation(v, Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, 0, 0);
        //设置消失监听
        popupWindow.setOnDismissListener(this);
        //设置PopupWindow的View点击事件
        setOnPopupViewClick(view);
        //设置背景色
        setBackgroundAlpha(0.5f);
    }
    //弹出动画 style文件中
    <style name="PopupWindow">
        <item name="android:windowEnterAnimation">@anim/window_in</item>
        <item name="android:windowExitAnimation">@anim/window_out</item>
    </style>
  //设置屏幕背景透明效果
    public void setBackgroundAlpha(float alpha) {
        WindowManager.LayoutParams lp = getWindow().getAttributes();
        lp.alpha = alpha;
        getWindow().setAttributes(lp);
    }
    //popupWindow的View点击事件设置
    private void setOnPopupViewClick(View view) {
        TextView tv_pick_phone, tv_pick_zone;
        tv_pick_phone = (TextView) view.findViewById(R.id.tv_pick_phone);
        tv_pick_zone = (TextView) view.findViewById(R.id.tv_pick_zone);
        tv_pick_phone.setOnClickListener(this);
        tv_pick_zone.setOnClickListener(this);
    }
//popupWindow点击事件
 @Override
    public void onClick(View v) {
        switch (v.getId()) {

        //这里是前面弹窗按钮的点击事件...
            //打开相机
            case R.id.tv_pick_phone:
                Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);// 启动系统相机
                        intent.putExtra("return-data", false);
                        intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
                        intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
                        intent.putExtra("noFaceDetection", true);
                        //需要将拍照的相片返回,用startActivityForResult
                        startActivityForResult(intent, 1);
                popupWindow.dismiss();
                break;
                //打开相册
            case R.id.tv_pick_zone:
                Intent i = new Intent(
                        Intent.ACTION_PICK,
                        android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                // 设定结果返回
                startActivityForResult(i, 2);
                popupWindow.dismiss();
                break;
        }
    }
//用来接收返回的照片
@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == RESULT_OK) {
            if (requestCode == 1) {
                //接收到返回的照片之后,启用裁剪功能
                cropImg(imageUri);
            } else if (requestCode == 2) {
                //返回从相册选择的照片
                Uri uri = data.getData();
                cropImg(uri);
            } else if (requestCode == 3) {
                //接收到裁剪过后的照片,设置给imageview
                Bundle extras = data.getExtras();
                if (extras != null) {
                    try {
                        Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(imageCropUri));
                        imageview.setImageBitmap(bitmap);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    //裁剪照片
    public void cropImg(Uri uri) {
        Intent intent = new Intent("com.android.camera.action.CROP");
        intent.setDataAndType(uri, "image/*");
        intent.putExtra("crop", "true");
        intent.putExtra("aspectX", 1);
        intent.putExtra("aspectY", 1);
        intent.putExtra("outputX", 700);
        intent.putExtra("outputY", 700);
        intent.putExtra("return-data", false);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, imageCropUri);
        intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
        intent.putExtra("noFaceDetection", true);
        //裁剪后返回给Activity
        startActivityForResult(intent, 3);
    }
  @Override
    public void onDismiss() {
        setBackgroundAlpha(1);
    }
//申请权限后回调
@Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        permissionTools.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }

代码基本都分段写上去了,下面就不贴完整代码了。给出github地址,需要的可以自己下。
有问题欢迎指导

传送门

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值