观心静

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

实现思维路径:

以进入相机拍照的思维路线为例子:

1.进入app

2.判断之前是否保存头像,如果有就显示历史图像 (下面代码中在getOldAvatar();方法中执行这个逻辑)

3.点击更换图像的Button或者布局,启动对话框(下面代码中在dialogueBox();方法执行这个逻辑)

4.系统版本判断授权方式(静态还是动态授权),判断之前是否已经授权 (setPermissions(Permissions_CAMERA_KEY);这个方法执行授权逻辑

5.如果是首次授权,就执行首次授权完成后马上运行的回调方法 onRequestPermissionsResult

5.判断完成不管是否是首次授权还是之前就是授权过了都要执行enterCamera();方法启动相机并且发送携带数据的请求

6.启动相机完成后,并且拍照完成退出相机,都要运行Intent返回数据请求回调方法onActivityResult。将传入的数据传入到cropPhoto(data.getData());方法里去执行图片剪裁。

7.在cropPhoto方法里将携带数据跳转到裁剪界面中裁剪图片,裁剪完成后又要回到onActivityResult回调方法里,执行裁剪完的数据回调工作。

 

8.在onActivityResult回调方法里,裁剪完的图片将运行setPicToView 方法保存图片。保存的图片将在下次启动activity时作为历史头像调用。

 

package com.example.lenovo.mydemoapp;

import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.os.StrictMode;
import android.provider.MediaStore;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import android.Manifest;

import com.example.lenovo.mydemoapp.myAppCompatActivity.MyAppCompatAcitivity;
import com.example.lenovo.mydemoapp.myLayout.TitleLayout;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;


public class PersonalDataModification extends AppCompatActivity{
    private static final String TAG = "PDM";
    private TitleLayout mTitleLayout;
    private TextView mTitleText;
    private LinearLayout mPersonalDataModification_Avatar,mDialog_CameraButton,mDialog_GalleryButton;
    private ImageView mPersonalDataModification_imageView_Avatar;
    //得到外部存储根目录路径
    private String mAvatarPath = Environment.getExternalStorageDirectory() + "/myAvatar/";
    private String mAvatarName = "Avatar.jpg";
    private Bitmap mBitmap;
    /*
    进入相册,相机,照片裁剪的key组
     */
    private static final int ENTER_GALLERY = 1;
    private static final int ENTER_CAMERA = 2;
    private static final int ENTER_CROP_PHOTO = 3;
    //需要在进入相机拍照或者相册选择图像中做区分。所以写了一个KEY来处理不同的Button
    private static final int Permissions_GALLERY_KEY = 1;
    private static final int Permissions_CAMERA_KEY = 2;
    //需要的权限 注意请不要将数组写成 private String mPermissions[] = {"Manifest.permission.WRITE_EXTERNAL_STORAGE"};
    //这样加了引号的是错误的
    private String mPermissions[] = {Manifest.permission.WRITE_EXTERNAL_STORAGE,
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.CAMERA};
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
        StrictMode.setVmPolicy(builder.build());
        builder.detectFileUriExposure();
        setContentView(R.layout.activity_personal_data_modification);
       // 设置标题栏
        setTitle();
        //显示历史头像
        getOldAvatar();
       // 添加对话框
        dialogueBox();
    }
    /*
    对话框
     */
    public void dialogueBox(){
        mPersonalDataModification_Avatar = (LinearLayout)findViewById(R.id.PersonalDataModification_Avatar);
        mPersonalDataModification_Avatar.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //添加对话框
                 AlertDialog.Builder builder = new AlertDialog.Builder(PersonalDataModification.this);
                //创建对话框 注意一定要这样写 在下面的dialog才能执行dismiss();方法
                final AlertDialog dialog = builder.create();
                View view = LayoutInflater.from(getBaseContext()).inflate(R.layout.dialog_layout,null,false);
                //导入视图
                dialog.setView(view);
                mDialog_CameraButton = (LinearLayout)view.findViewById(R.id.PersonalDataModification_Dialog_CameraButton);
                mDialog_GalleryButton = (LinearLayout)view.findViewById(R.id.PersonalDataModification_Dialog_GalleryButton);
                //相机
                mDialog_CameraButton.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        //设置权限
                        setPermissions(Permissions_CAMERA_KEY);
                        //关闭对话框
                        dialog.dismiss();
                    }
                });
                //相册
                mDialog_GalleryButton.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        setPermissions(Permissions_GALLERY_KEY);
                        dialog.dismiss();
                    }
                });
                //创建并且显示
                dialog.show();
            }
        });
    }
    public void setPermissions(int mPermissions_KEY){
        /*
        要添加List原因是想判断数组里如果有个别已经授权的权限,就不需要再添加到List中。添加到List中的权限后续将转成数组去申请权限
         */
        List<String> permissionsList = new ArrayList<>();
        //判断系统版本
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            for (int i = 0; i < mPermissions.length; i++) {
                //判断一个权限是否已经允许授权,如果没有授权就会将单个未授权的权限添加到List里面
                if (ContextCompat.checkSelfPermission(this.getApplicationContext(), mPermissions[i]) != PackageManager.PERMISSION_GRANTED) {
                    permissionsList.add(mPermissions[i]);
                }
            }
            //判断List不是空的,如果有内容就运行获取权限
            if (!permissionsList.isEmpty()) {
                String [] permissions = permissionsList.toArray(new String[permissionsList.size()]);
                for (int j=0;j<permissions.length;j++){
                    Log.e(TAG,permissions[j]);
                }
                Log.e(TAG,"需要授权的权限有:"+permissions.length+"条");
                //执行授权的代码。此处执行后会弹窗授权
                ActivityCompat.requestPermissions(this, permissions, mPermissions_KEY);
            } else { //如果是空的说明全部权限都已经授权了,就不授权了,直接执行进入相机或者图库
                switch (mPermissions_KEY) {
                    case Permissions_CAMERA_KEY:
                        enterCamera();
                        break;
                    case Permissions_GALLERY_KEY:
                        enterGallery();
                        break;
                    default:
                        break;
                }
            }
        }else {
            Toast.makeText(getBaseContext(), "6.0以下的版本无需授权", Toast.LENGTH_SHORT).show();
            Log.e(TAG,"6.0以下的版本无需授权");
            switch (mPermissions_KEY) {
                case Permissions_CAMERA_KEY:
                    enterCamera();
                    break;
                case Permissions_GALLERY_KEY:
                    enterGallery();
                    break;
                default:
                    break;
            }
        }
    }
    /*
    授权完成后马上会运行的回调方法,此处写入首次授权完成后,要运行的内容
     */
    @Override
        public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == Permissions_CAMERA_KEY) {
            if (grantResults.length > 0) { //安全写法,如果小于0,肯定会出错了
                for (int i = 0; i < grantResults.length; i++) {
                    if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
                        Log.e(TAG, "全部权限都成功授权进入相机");
                        enterCamera();
                    } else {
                        finish();
                        Toast.makeText(getBaseContext(), "授权失败", Toast.LENGTH_SHORT).show();
                        Log.e(TAG, "相机授权失败");
                    }
                }
            }
        } else if (requestCode == Permissions_GALLERY_KEY) {
            if (requestCode == Permissions_GALLERY_KEY) {
                if (grantResults.length > 0) {
                    for (int i = 0; i < grantResults.length; i++) {
                        if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
                            Log.e(TAG, "全部权限都成功授权进入相册");
                            enterGallery();
                        } else {
                            finish();
                            Toast.makeText(getBaseContext(), "授权失败", Toast.LENGTH_SHORT).show();
                            Log.e(TAG, "相册授权失败");
                        }
                    }
                }
            }
        }
    }
     /*
       点击后进入相机
      */
    public void enterCamera(){
        //MediaStore 多媒体存储  ACTION行动 IMAGE 图片 CAPTURW捕获
        Intent intentGallery = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        /*   多媒体存储,额外制造   从文件里获取路径(获取外部存储目录 图片名称head.jpg)
		将图片设置名称并且保存到外部存储空间里
		*/
        intentGallery.putExtra(MediaStore.EXTRA_OUTPUT,
                Uri.fromFile(new File(Environment.getExternalStorageDirectory(), mAvatarName)));
        //跳转页面启动相册,携带数据请求码
        startActivityForResult(intentGallery,ENTER_CAMERA);
    }
    /*
    点击后进入相册
     */
    public void  enterGallery(){
        Intent intentCamera = new Intent(Intent.ACTION_PICK,null);
        //设置数据和类型    多媒体存储.图片.媒体.外部.内容.URI   image/*图片格式
        intentCamera.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,"image/*");
        startActivityForResult(intentCamera, ENTER_GALLERY);

    }
    /*
	从Intent中返回请求数据的方法,活动退出后运行这个方法
	*/
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        switch (requestCode){
            /*
            相册选中图片后的数据回调
             */
            case ENTER_GALLERY:
                if(resultCode == RESULT_OK){
                    cropPhoto(data.getData());
                }
                break;
            /*
            拍照完成后的数据回调
             */
            case ENTER_CAMERA:
                if (resultCode == RESULT_OK) {
                    File temp = new File(Environment.getExternalStorageDirectory() + "/"+mAvatarName);
                    cropPhoto(Uri.fromFile(temp));// 裁剪图片  cropPhoto 200行方法
                }
                break;
            /*
            裁剪完成后的数据回调
             */
            case ENTER_CROP_PHOTO:
                if (data.resolveActivity(getPackageManager())!=null) {//判断Intent是否为空
                    Bundle extras = data.getExtras();
                    mBitmap = extras.getParcelable("data");
                    if (mBitmap != null) {
                        setPicToView(mBitmap);// 保存在SD卡中
                        mPersonalDataModification_imageView_Avatar.setImageBitmap(mBitmap);// 用ImageButton显示出来
                    }
                }
                break;
            default:
                break;
        }
        super.onActivityResult(requestCode, resultCode, data);
    }
    /*
    调用系统的裁剪功能,进入裁剪页面
     */
    public void cropPhoto(Uri uri){
        Intent intent = new Intent("com.android.camera.action.CROP");
        intent.setDataAndType(uri,"image/*");
        intent.putExtra("crop","ture");
        intent.putExtra("aspectX", 1);
        intent.putExtra("aspectY", 1);
        // outputX outputY 是裁剪图片宽高
        intent.putExtra("outputX", 250);
        intent.putExtra("outputY", 250);
        intent.putExtra("return-data", true);
        Log.e(TAG,"头像裁剪");
        startActivityForResult(intent, ENTER_CROP_PHOTO);
    }
    /*
    显示默认头像或者历史设置的头像
     */
    public void getOldAvatar(){
        mPersonalDataModification_imageView_Avatar = (ImageView)findViewById(R.id.PersonalDataModification_imageView_Avatar);
        //从文件存储里得到图片
        Bitmap bt = BitmapFactory.decodeFile(mAvatarPath+mAvatarName);
        //判断不是空头像
        if (bt != null){
            Drawable drawable = new BitmapDrawable(getResources(),bt);
            //重新设置头像图片 注意这里使用的是setImageDrawable,不是setImageResource
            mPersonalDataModification_imageView_Avatar.setImageDrawable(drawable);
            Log.e(TAG,"使用历史头像");
        }else {
            //如果没有旧的头像就使用系统默认的
            mPersonalDataModification_imageView_Avatar.setImageResource(R.drawable.ic_woman_default);
            Log.e(TAG,"使用默认头像");
        }
    }
    /*
	保存到sd卡是为了下一次进入apk的时候直接读取图片,
	*/
    private void setPicToView(Bitmap mBitmap) {
        String sdStatus = Environment.getExternalStorageState();
        if (!sdStatus.equals(Environment.MEDIA_MOUNTED)) { // 检测sd是否可用
            return;
        }

        try {
            File dir = new File(mAvatarPath);
            dir.mkdirs();// 创建文件夹
            File file = new File(mAvatarPath, mAvatarName);
            if (!file.exists()) {
                file.createNewFile();
            }
            FileOutputStream b = new FileOutputStream(file);
            mBitmap.compress(Bitmap.CompressFormat.JPEG, 100, b);// 把图片数据写入图片b
            b.flush();  //刷新
            b.close();  //关闭
        }catch(IOException e){
            e.printStackTrace();
        }
        /*
        FileOutputStream b = null;
        File file = new File(mAvatarPath);
        file.mkdirs();// 创建文件夹
        String fileName = mAvatarPath + mAvatarName;// 图片名字
        try {
            b = new FileOutputStream(fileName);
            mBitmap.compress(Bitmap.CompressFormat.JPEG, 100, b);// 把图片数据写入图片b
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } finally {
            try {
                b.flush();  //刷新
                b.close();  //关闭
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        */
    }
}


    

 

posted on 2018-05-22 10:23  观心静  阅读(514)  评论(0编辑  收藏  举报