*****
**圖片上傳的實現**
[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交互
- 第十九單元 項目案例
- 項目概述
- 第二十單元 項目答辯
- 周考
- 第一周周考
- 第二周周考
- 第三種周考
- 月考
- 接口文檔