android图库中选择照片然后裁剪,完爆目前各种所谓的教学,看不懂你打我。

前阵子是打算做一个选择相册里的照片裁剪并上传的功能。
然后我就看了很多教程,看了网上很多文章,发现这些人都是在抄来抄去,里面很多细节和思路都没有写清楚。真是误人子弟又操蛋。
所以自己琢磨了一下代码,然后写下这篇文章。
首先是说思路:
拍照这个功能先不说,先说选图片裁剪然后上传的思路。
1.首先要选定一个路径,然后在这个路径下面建立一个空白文件;
2.然后选择一张相册里的图,把这个图的内容原封不动的复制到这个新建的空白文件中。
3.然后打开裁剪程序,裁剪这个新建的文件,再把裁剪好的文件重新输出到这个新建的文件中,对,就是替换。
4.上传这个新建的文件。
现在一步一步的说。

1.选定一个路径,新建一个空白文件。这个softtime是我APP的名字,最开始的时候我建立的文件总是找不到,后来发现要下载一个文件浏览器才能看见,系统把它隐藏了。为此纠结了好久。这里面有个函数 System.currenTimeMillis()是获得系统当前时间毫秒数。
关于Environment.getExternalStorageDirectory(),这个函数其实就是获得你手机SD卡的根目录。
(注意:这里currentImageFile 是建的一个全局变量。方便以后调用。)
File dir = new File(Environment.getExternalStorageDirectory(), "pictures/softtime");//存储路径
                if (!dir.exists()) {
                    dir.mkdirs();
                }
                currentImageFile = new File(dir, System.currentTimeMillis()+".jpg");//路径+名称 = 存储文件具体位置
                //文件不存在的话则新建
                if (!currentImageFile.exists()) {
                    try {
                        currentImageFile.createNewFile();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }

2.选择相册里的图,然后输出到这个新建的文件。(注意看一下注释,我认真的写的注释)
//这个Intent是准备打开相册,网上有多种方法,但是只有这样写是管用的。其他的不管用,别信。
Intent intentGet = new Intent("android.intent.action.GET_CONTENT");  
//下面这里其实是设置给那个图库应用看的,这里可以限定图库打开的文件是什么,现在设置的就是图像文件。
intentGet.setType("image/*");
//下面这两行其实并不重要,意义也不明,但是没有却不行。所以就直接照样子写下来就行。
intentGet.putExtra("crop",true);
intentGet.putExtra("scale",true);
//最重要的就是下面这行代码了。一会详细说。
intentGet.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(currentImageFile));
//这个也很重要,一会详细说。
startActivityForResult(intentGet,CROP);//CROP这个常量是我之前已经定义好的。就是个动作代码。
现在详细说两个地方,先说这一行代码
intentGet.putExtra(MediaStore.EXTRA_OUTPUT,Uri.fromFile(currentImageFile));
这一行其实也是写给那个图库应用看的,图库选择到一个图片文件以后,图库会试图把这个图片复制到一个地方,也就是新建的那个文件,其实这行代码可以这么理解    图库输出到哪(“输出”,“打算输出到的那个文件的位置”)。
好了,再上另外一行代码的意思。
startActivityForResult(intent,动作代码)
这个动作你要先去实现一个方法,就是 onActivityResult(int requestCode, int resultCode, Intent data);
这个方法第一个参数是请求动作码,第二个就是结果状态码,第三个就是返回的数据;
这个动作,先启动你要执行的那个intent,然后会有执行结果返回(比如选择一张图片以后返回的值,返回的图片数据什么的)。
返回到哪呢?就是返回到相应的动作码。这样说起来有点模糊,看一下代码吧。
重头戏来了。
@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        switch (requestCode){
                //如果动作代码是CROP,那么当选图完毕以后就执行这个里面的代码。
                case CROP:
                //准备打开系统的裁剪Activity
                Intent intentCrop = new Intent("com.android.camera.action.CROP"); 
               //这data里面其实就是刚才你选的那张照片的Uri。 
                intentCrop.setDataAndType(data.getData(),"image/*");
               //下面这个设置可以告诉裁剪程序:这个图是否可以缩放
                intentCrop.putExtra("scale",true);
                //裁剪后保存到哪里,这也是裁剪程序自己搞定的
                intentCrop.putExtra(MediaStore.EXTRA_OUTPUT,Uri.fromFile(currentImageFile));
                startActivityForResult(intentCrop,UPLOAD);
                break;

            case UPLOAD:
               //这里就写UPLOAD代码就行了。

        }


    }


这样大概就结束了。
其实要掌握好逻辑就可以了。
startActivityForResult这个方法的流程一定要想明白,这个流程大概是这样的:
(activityA,动作码A)其实就是启动activityA,将返回的结果传到onActivityResult方法的相应动作码A的代码块里面。(然后你可以再启动B,将B的结果返回到另外一个代码块里面。)

如果有不懂的可以给我留言。











你可能感兴趣的:(Android学习)