*****
**图片上传的实现**
[TOC=6]
# 1. 获取图库图片
~~~
Intent intent1 = new Intent(Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent1, LOCAL_CROP);
~~~
# 2. 获取相机拍照图片
~~~
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
startActivityForResult(intent, TAKE_PHOTO);
~~~
# 3. 图片剪裁
~~~
Intent intent = new Intent("com.android.camera.action.CROP");
//添加这一句表示对目标应用临时授权该Uri所代表的文件
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
//可以选择图片类型,如果是*表明所有类型的图片
intent.setDataAndType(uri, "image/*");
// 下面这个crop = true是设置在开启的Intent中设置显示的VIEW可裁剪
intent.putExtra("crop", "true");
// aspectX aspectY 是宽高的比例,这里设置的是正方形(长宽比为1:1)
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
// outputX outputY 是裁剪图片宽高
intent.putExtra("outputX", 500);
intent.putExtra("outputY", 500);
intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
//是否将数据保留在Bitmap中返回,true返回bitmap,false返回uri
intent.putExtra("return-data", false);
~~~
# 4. 图片回传的实现
~~~
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case TAKE_PHOTO: // 拍照
if (resultCode == RESULT_OK) {
// 创建intent用于裁剪图片
Intent intent = new Intent("com.android.camera.action.CROP");
// 设置数据为文件uri,类型为图片格式
intent.setDataAndType(imageUri, "image/*");
// 允许裁剪
intent.putExtra("scale", true);
// 指定输出到文件uri中
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
// 启动intent,开始裁剪
startActivityForResult(intent, CROP_PHOTO);
}
break;
case LOCAL_CROP: // 系统相机
if (resultCode == RESULT_OK) {
// 创建intent用于裁剪图片
Intent intent1 = new Intent("com.android.camera.action.CROP");
// 获取图库所选图片的uri
Uri uri = data.getData();
intent1.setDataAndType(uri, "image/*");
// 设置裁剪图片的宽高
intent1.putExtra("outputX", 300);
intent1.putExtra("outputY", 300);
// 裁剪后返回数据
intent1.putExtra("return-data", true);
// 启动intent,开始裁剪
startActivityForResult(intent1, CROP_PHOTO);
}
case CROP_PHOTO: // 裁剪后
if (resultCode == RESULT_OK) {
try {
// 展示拍照后裁剪的图片
if (imageUri != null) {
// 创建BitmapFactory.Options对象
BitmapFactory.Options option = new BitmapFactory.Options();
// 属性设置,用于压缩bitmap对象
option.inSampleSize = 2;
option.inPreferredConfig = Bitmap.Config.RGB_565;
// 根据文件流解析生成Bitmap对象
Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(imageUri), null, option);
// 展示图片
ivHead.setImageBitmap(bitmap);
imageUri = null;
return;
}
// 展示图库中选择裁剪后的图片
if (data != null) {
// 根据返回的data,获取Bitmap对象
Bitmap bitmap = data.getExtras().getParcelable("data");
// 展示图片
ivHead.setImageBitmap(bitmap);
data = null;
return;
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
~~~
# 5. 侧滑头像上传
关于文件上传功能,现在的移动开发中有很多好的网络框架提供这个功能。早期开发Android时网络框架少,只能靠自己手写。虽然现在不用自己手写,但是弄明白原理还是很有必要的。
~~~
POST请求头
1. Accept:
text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,\*/\*;q=0.8,application/signed-exchange;v=b3
2. Accept-Encoding:
gzip, deflate, br
3. Accept-Language:
zh-CN,zh;q=0.9,en;q=0.8
4. Cache-Control:
max-age=0
5. Connection:
keep-alive
6. Content-Length:
57451
7. Content-Type:
multipart/form-data; boundary=----WebKitFormBoundaryB94bWqqQGVspXSJd
8. Host:
localhost:8080
9. Origin:
http://localhost:8080
10. Referer:
http://localhost:8080/
11. Upgrade-Insecure-Requests:
1
12. User-Agent:
Mozilla/5.0 (Macintosh; Intel Mac OS X 10\_14\_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36
~~~
~~~
请求体
------WebKitFormBoundary6TAB8KxvuJTZYfUn // 第一行,是“--”字符串(不包括引号)和请求头中的boundary拼成的字符串
Content-Disposition: form-data; name="username" // 第二行是固定的Content-Disposition: form-data;和name="请求的参数名称" 二者拼接的字符串
// 这里是空行
sdafdsa //这是请求的参数,就是username的具体值
------WebKitFormBoundary6TAB8KxvuJTZYfUn // 和第一行一样,是“--”字符串(不包括引号)和请求头中的boundary拼成的字符串
Content-Disposition: form-data; name="f"; filename="default_launcher.conf" // 和第二行类似,但是因为是文件,所以多了一个filename参数,是指你上传的文件名
Content-Type: application/octet-stream // 文件的minetype
// 这里有个空行,下面是要上传的文件内容
packageName=com.cy.chineseonline
className=com.cy.chineseonline.activity.MainActivity
// 这里有个空行,上面是要上传的文件内容
------WebKitFormBoundary6TAB8KxvuJTZYfUn-- // 最后一行 --和boundary和--拼接的字符串
~~~
~~~
private static final String nextLine = "\r\n";
private static final String twoHyphens = "--";
//分割线 随便写一个
private static final String boundary = "wk_file_2519775";
new AsyncTask<Void, Void, String>() {
@Override
protected String doInBackground(Void... voids) {
File file = new File(filePath);
HttpURLConnection connection = null;
try {
URL url1 = new URL("http://169.254.78.219:8080/upload");
connection = (HttpURLConnection) url1.openConnection();
connection.setDoOutput(true);
// 设置字符集
connection.setRequestProperty("Charsert", "UTF-8");
//设置接收编码
connection.setRequestProperty("Accept-Charset", "utf-8");
//开启长连接可以持续传输
connection.setRequestProperty("Connection", "keep-alive");
//设置请求参数格式以及boundary分割线
connection.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
//设置接收返回值的格式
connection.setRequestProperty("Accept", "application/json");
OutputStream outputStream = new DataOutputStream(connection.getOutputStream());
//分隔符头部
String header = twoHyphens + boundary + nextLine;
//分隔符参数设置
header += "Content-Disposition: form-data;name=\"file\";" + "filename=\"" + file.getName() + "\"" + nextLine + nextLine;
//写入输出流
outputStream.write(header.getBytes());
//读取文件并写入
FileInputStream inputStream = new FileInputStream(file);
byte[] bytes = new byte[1024];
int length;
while ((length = inputStream.read(bytes)) != -1) {
outputStream.write(bytes, 0, length);
}
//文件写入完成后加回车
outputStream.write(nextLine.getBytes());
//写入结束分隔符
String footer = nextLine + twoHyphens + boundary + twoHyphens + nextLine;
outputStream.write(footer.getBytes());
outputStream.flush();
if (connection.getResponseCode() == 200) {
return CharStreams.toString(new InputStreamReader(connection.getInputStream()));
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(String s) {
Log.i(TAG, "" + s);
}
}.execute();
~~~
- 咨询项目实战
- 第一单元 HTTP协议
- 1.1 OSI七层模型
- 1.2 HTTP协议(重点)
- 1.3 HTTPS协议(了解)
- 1.4 TCP/IP协议扩展
- 1.5 WebService简介及实战(无接口)
- 1.6 课后练习
- 第二单元 HTTPURLConnection
- 2.1 ANR
- 2.2 网络判断
- 2.3 HTTPURLConnection
- 2.4 课后练习
- 第三单元 AsyncTask
- 3.1 AsyncTask概述
- 3.2 AsyncTask基本使用
- 3.3 课后练习
- 第四单元 图片异步加载
- 4.1 图片异步加载概述
- 4.2 LruCache
- 4.3 DiskLRUCache
- 4.4 图片三级缓存概述
- 4.5 封装图片加载缓存框架
- 第五单元 ListView多条目
- 5.1 ListView多条目概述
- 5.2 ListView多条目的使用
- 第六单元 ListView实现下拉刷新上拉加载
- 6.1 下拉刷新和上拉加载更多
- 6.2 XListView概述
- 6.3 XListView的使用
- 第七单元 封装网络框
- 7.1 封装网络框架概述
- 7.2 网络框架的封装
- 第八单元 项目介绍
- 8.1 公司项目团队架构简介
- 8.2 项目文档及项目流程介绍
- 8.3 项目管理
- 8.4 项目开发
- 第九单元 项目框架搭建
- 9.1 基类封装概述
- 9.2 Application中初始化配置
- 9.3 项目中的工具类
- 9.4 封装网络请求框架
- 9.5 封装图片异步缓存框架
- 第十单元 搭建UI框架1
- 10.1 侧滑菜单概述
- 10.2 主界面框架搭建
- 第十一单元 搭建UI框架2
- 11.1 TabLayout的概述
- 11.2 TabLayout的使用
- 第十二单元 图片上传
- 12.1 图片上传概述
- 12.2 图片上传的实现
- 第十三单元 PullToRefresh
- 13.1 PullToRefresh概述
- 13.2 PullToRefresh的使用
- 13.3 缓存业务实现思路
- 第十四单元 事件分发及滑动冲突
- 14.1 事件分发概述
- 14.2 事件分发流程
- 14.3 事件分发的使用
- 第十五单元 传感器的基本使用
- 15.1 传感器概述
- 15.2 传感器的使用
- 第十六单元 HTML与CSS复习
- 16.1 HTML
- 16.2 CSS
- 第十七单元 js复习
- 17.1 js基础语法
- 17.2 js数组和内置对象
- 17.3 js常用事件
- 17.4 js对象模型
- 17.5 js 正则表达式
- 第十八单元 WebView
- 18.1 WebView 概述
- 18.2 WebView的使用
- 18.3 WebView与js交互
- 第十九单元 项目案例
- 项目概述
- 第二十单元 项目答辩
- 周考
- 第一周周考
- 第二周周考
- 第三种周考
- 月考
- 接口文档