这今天工作需要用到图片上传的功能,遇到了不少问题,特来整理一下。
先来整理下在Android上传图片需要哪些步骤。
1:调用相册
2:得到图片的路径
3:将图片转化为二进制码
4:发送这个二进制码。
先来说得到图片的路径在Android开发的过程中不像开发Windows序可以直接将路径复制到相应的位置。我们通常得到一个图片的方法是先得到一个图片的uri再通过uri得到它的绝对路径。
这里就需要先说一下我遇到的第一个坑了:事实上uri本身是有getPath()这个方法的。并且经过这个方法可以得到一个看上去像是正常的路径,但是实际上这个路径是不对的!!!
然而我翻阅了Android的官方文档,发现这个方法的作用的确是得到解码后的路径,因此如果有大佬知道为什么这个方法不能得到正确的路径的话请务必告诉我。
这个是我通过下面方法和getPath方法得到的同一个图片的路径
I/zsjm: uri 2==/storage/emulated/0/Screenshots/Screenshot_20190426-101422.png
I/zsjm: 得到图片=/external/images/media/1401
然后就是还有第二个坑:那就是当唤起图库列表后,如果不是点击图库得到照片而是点击了诸如最近浏览之类的方法得到照片也是不能得到正确路径的。
下面我会把上传图片的代码贴出来。但是请注意,我只使用了适用于API19以上的代码,如果对所有不同版本都兼容的代码感兴趣可以查看这位大佬的博客.
//首先我们需要调用相册
Intent intent=new Intent(Intent.ACTION_GET_CONTENT);
//从官方文档得知这里面的参数是一个MIME类型的数据,有关MIME数据类型见下
intent.setType("image/*");
//调用onActivityResult方法,这里同样有一个坑
satrtActivityForResult(intent,1);
关于上面的代码我们来分析一下啊,第一行的作用就是调用相册功能。对这些参数有兴趣的可以查看官方文档。
第二行是一个MIME类型的数据,关于MIME的的类型都有哪些可以查看这个网站。
第三行同样有一点需要注意的是第二个请求参数也就是请求码,我看了好多博客都说这个参数可以任意赋值,但是实际上你只能给他一个大于0的数。如果你的请求码小于0的话这个方法就不会唤起onActivityResult。
另外在Android 6之后我们必须开启权限才能调用相簿中的相片。
除此之外还要注意你手机上的app是否已经被允许访问手机文件。
调用了相册后要获得我们点击图片的绝对路径。
通过上面我们唤醒onActivityResult的动作我们可以直接在重写该方法。这样在当前Activity被唤醒后就会调用我们获取路径的方法。
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
final Uri uri=data.getData();
String Url=getUriPath(uri);
}
public String getUriPath(Uri contentUri)
{
String file=null;
//这个this指的是当前的Activity
file=getDataColumn(this,contentUri,null,null);
return file;
}
//这个类的作用就是将uri转换为绝对路径
private static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) {
//创建一个空字符串
String path = null;
//这段其实就是Android中的多媒体运用。可以观看这位博主的文章辅助理解(https://www.jianshu.com/p/ca73161e5509)
String[] projection=new String[]{MediaStore.Images.Media.DATA};
Cursor cursor=null;
cursor=context.getContentResolver().query(uri,projection,selection,selectionArgs,null);
if (cursor!=null&&cursor.moveToFirst()){
int column=cursor.getColumnIndexOrThrow(projection[0]);
path=cursor.getString(column);
}
return path;
}