Android應(yīng)用中拍照后獲取照片路徑并上傳的實(shí)例分享
Activity 中的代碼,我只貼出重要的事件部分代碼
public void doPhoto(View view) { destoryBimap(); String state = Environment.getExternalStorageState(); if (state.equals(Environment.MEDIA_MOUNTED)) { Intent intent = new Intent("android.media.action.IMAGE_CAPTURE"); startActivityForResult(intent, 1); } else { Toast.makeText(MainActivity.this, "沒有SD卡", Toast.LENGTH_LONG).show(); } } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { Uri uri = data.getData(); if (uri != null) { this.photo = BitmapFactory.decodeFile(uri.getPath()); } if (this.photo == null) { Bundle bundle = data.getExtras(); if (bundle != null) { this.photo = (Bitmap) bundle.get("data"); } else { Toast.makeText(MainActivity.this, "拍照失敗", Toast.LENGTH_LONG).show(); return; } } FileOutputStream fileOutputStream = null; try { // 獲取 SD 卡根目錄 String saveDir = Environment.getExternalStorageDirectory() + "/meitian_photos"; // 新建目錄 File dir = new File(saveDir); if (! dir.exists()) dir.mkdir(); // 生成文件名 SimpleDateFormat t = new SimpleDateFormat("yyyyMMddssSSS"); String filename = "MT" + (t.format(new Date())) + ".jpg"; // 新建文件 File file = new File(saveDir, filename); // 打開文件輸出流 fileOutputStream = new FileOutputStream(file); // 生成圖片文件 this.photo.compress(Bitmap.CompressFormat.JPEG, 100, fileOutputStream); // 相片的完整路徑 this.picPath = file.getPath(); ImageView imageView = (ImageView) findViewById(R.id.showPhoto); imageView.setImageBitmap(this.photo); } catch (Exception e) { e.printStackTrace(); } finally { if (fileOutputStream != null) { try { fileOutputStream.close(); } catch (Exception e) { e.printStackTrace(); } } } } /** * 銷毀圖片文件 */ private void destoryBimap() { if (photo != null && ! photo.isRecycled()) { photo.recycle(); photo = null; } }
Layout 布局頁面
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <ScrollView android:layout_width="fill_parent" android:layout_height="fill_parent" > <LinearLayout android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <Button android:id="@+id/doPhoto" android:layout_width="fill_parent" android:layout_height="wrap_content" android:padding="10dp" android:layout_marginBottom="10dp" android:text="拍照" android:onClick="doPhoto" /> <TextView android:id="@+id/showContent" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginBottom="10dp" /> <ImageView android:id="@+id/showPhoto" android:layout_width="fill_parent" android:layout_height="250dp" android:scaleType="centerCrop" android:src="@drawable/add" android:layout_marginBottom="10dp" /> </LinearLayout> </ScrollView> </LinearLayout>
其中的上傳工具類我們下面一起來看:
Android 發(fā)送HTTP GET POST 請(qǐng)求以及通過 MultipartEntityBuilder 上傳文件
全部使用新的方式 MultipartEntityBuilder 來處理了。
httpmime-4.3.2.jar
httpcore-4.3.1.jar
下載地址:http://hc.apache.org/downloads.cgi
有些鏡像貌似打不開,頁面上可以可以選擇國內(nèi)的 .cn 后綴的域名鏡像服務(wù)器來下載
直接上代碼了:
ZHttpRequset.java
package com.ai9475.util; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpRequestBase; import org.apache.http.entity.mime.HttpMultipartMode; import org.apache.http.entity.mime.MultipartEntityBuilder; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.params.BasicHttpParams; import org.apache.http.params.HttpConnectionParams; import org.apache.http.params.HttpParams; import org.apache.http.protocol.HTTP; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.nio.charset.Charset; /** * Created by ZHOUZ on 14-2-3. */ public class ZHttpRequest { public final String HTTP_GET = "GET"; public final String HTTP_POST = "POST"; /** * 當(dāng)前請(qǐng)求的 URL */ protected String url = ""; /** * HTTP 請(qǐng)求的類型 */ protected String requsetType = HTTP_GET; /** * 連接請(qǐng)求的超時(shí)時(shí)間 */ protected int connectionTimeout = 5000; /** * 讀取遠(yuǎn)程數(shù)據(jù)的超時(shí)時(shí)間 */ protected int soTimeout = 10000; /** * 服務(wù)端返回的狀態(tài)碼 */ protected int statusCode = -1; /** * 當(dāng)前鏈接的字符編碼 */ protected String charset = HTTP.UTF_8; /** * HTTP GET 請(qǐng)求管理器 */ protected HttpRequestBase httpRequest= null; /** * HTTP 請(qǐng)求的配置參數(shù) */ protected HttpParams httpParameters= null; /** * HTTP 請(qǐng)求響應(yīng) */ protected HttpResponse httpResponse= null; /** * HTTP 客戶端連接管理器 */ protected HttpClient httpClient= null; /** * HTTP POST 方式發(fā)送多段數(shù)據(jù)管理器 */ protected MultipartEntityBuilder multipartEntityBuilder= null; /** * 綁定 HTTP 請(qǐng)求的事件監(jiān)聽器 */ protected OnHttpRequestListener onHttpRequestListener = null; public ZHttpRequest(){} public ZHttpRequest(OnHttpRequestListener listener) { this.setOnHttpRequestListener(listener); } /** * 設(shè)置當(dāng)前請(qǐng)求的鏈接 * * @param url * @return */ public ZHttpRequest setUrl(String url) { this.url = url; return this; } /** * 設(shè)置連接超時(shí)時(shí)間 * * @param timeout 單位(毫秒),默認(rèn) 5000 * @return */ public ZHttpRequest setConnectionTimeout(int timeout) { this.connectionTimeout = timeout; return this; } /** * 設(shè)置 socket 讀取超時(shí)時(shí)間 * * @param timeout 單位(毫秒),默認(rèn) 10000 * @return */ public ZHttpRequest setSoTimeout(int timeout) { this.soTimeout = timeout; return this; } /** * 設(shè)置獲取內(nèi)容的編碼格式 * * @param charset 默認(rèn)為 UTF-8 * @return */ public ZHttpRequest setCharset(String charset) { this.charset = charset; return this; } /** * 獲取當(dāng)前 HTTP 請(qǐng)求的類型 * * @return */ public String getRequestType() { return this.requsetType; } /** * 判斷當(dāng)前是否 HTTP GET 請(qǐng)求 * * @return */ public boolean isGet() { return this.requsetType == HTTP_GET; } /** * 判斷當(dāng)前是否 HTTP POST 請(qǐng)求 * * @return */ public boolean isPost() { return this.requsetType == HTTP_POST; } /** * 獲取 HTTP 請(qǐng)求響應(yīng)信息 * * @return */ public HttpResponse getHttpResponse() { return this.httpResponse; } /** * 獲取 HTTP 客戶端連接管理器 * * @return */ public HttpClient getHttpClient() { return this.httpClient; } /** * 添加一條 HTTP 請(qǐng)求的 header 信息 * * @param name * @param value * @return */ public ZHttpRequest addHeader(String name, String value) { this.httpRequest.addHeader(name, value); return this; } /** * 獲取 HTTP GET 控制器 * * @return */ public HttpGet getHttpGet() { return (HttpGet) this.httpRequest; } /** * 獲取 HTTP POST 控制器 * * @return */ public HttpPost getHttpPost() { return (HttpPost) this.httpRequest; } /** * 獲取請(qǐng)求的狀態(tài)碼 * * @return */ public int getStatusCode() { return this.statusCode; } /** * 通過 GET 方式請(qǐng)求數(shù)據(jù) * * @param url * @return * @throws IOException */ public String get(String url) throws Exception { this.requsetType = HTTP_GET; // 設(shè)置當(dāng)前請(qǐng)求的鏈接 this.setUrl(url); // 新建 HTTP GET 請(qǐng)求 this.httpRequest = new HttpGet(this.url); // 執(zhí)行客戶端請(qǐng)求 this.httpClientExecute(); // 監(jiān)聽服務(wù)端響應(yīng)事件并返回服務(wù)端內(nèi)容 return this.checkStatus(); } /** * 獲取 HTTP POST 多段數(shù)據(jù)提交管理器 * * @return */ public MultipartEntityBuilder getMultipartEntityBuilder() { if (this.multipartEntityBuilder == null) { this.multipartEntityBuilder = MultipartEntityBuilder.create(); // 設(shè)置為瀏覽器兼容模式 multipartEntityBuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE); // 設(shè)置請(qǐng)求的編碼格式 multipartEntityBuilder.setCharset(Charset.forName(this.charset)); } return this.multipartEntityBuilder; } /** * 配置完要 POST 提交的數(shù)據(jù)后, 執(zhí)行該方法生成數(shù)據(jù)實(shí)體等待發(fā)送 */ public void buildPostEntity() { // 生成 HTTP POST 實(shí)體 HttpEntity httpEntity = this.multipartEntityBuilder.build(); this.getHttpPost().setEntity(httpEntity); } /** * 發(fā)送 POST 請(qǐng)求 * * @param url * @return * @throws Exception */ public String post(String url) throws Exception { this.requsetType = HTTP_POST; // 設(shè)置當(dāng)前請(qǐng)求的鏈接 this.setUrl(url); // 新建 HTTP POST 請(qǐng)求 this.httpRequest = new HttpPost(this.url); // 執(zhí)行客戶端請(qǐng)求 this.httpClientExecute(); // 監(jiān)聽服務(wù)端響應(yīng)事件并返回服務(wù)端內(nèi)容 return this.checkStatus(); } /** * 執(zhí)行 HTTP 請(qǐng)求 * * @throws Exception */ protected void httpClientExecute() throws Exception { // 配置 HTTP 請(qǐng)求參數(shù) this.httpParameters = new BasicHttpParams(); this.httpParameters.setParameter("charset", this.charset); // 設(shè)置 連接請(qǐng)求超時(shí)時(shí)間 HttpConnectionParams.setConnectionTimeout(this.httpParameters, this.connectionTimeout); // 設(shè)置 socket 讀取超時(shí)時(shí)間 HttpConnectionParams.setSoTimeout(this.httpParameters, this.soTimeout); // 開啟一個(gè)客戶端 HTTP 請(qǐng)求 this.httpClient = new DefaultHttpClient(this.httpParameters); // 啟動(dòng) HTTP POST 請(qǐng)求執(zhí)行前的事件監(jiān)聽回調(diào)操作(如: 自定義提交的數(shù)據(jù)字段或上傳的文件等) this.getOnHttpRequestListener().onRequest(this); // 發(fā)送 HTTP 請(qǐng)求并獲取服務(wù)端響應(yīng)狀態(tài) this.httpResponse = this.httpClient.execute(this.httpRequest); // 獲取請(qǐng)求返回的狀態(tài)碼 this.statusCode = this.httpResponse.getStatusLine().getStatusCode(); } /** * 讀取服務(wù)端返回的輸入流并轉(zhuǎn)換成字符串返回 * * @throws Exception */ public String getInputStream() throws Exception { // 接收遠(yuǎn)程輸入流 InputStream inStream = this.httpResponse.getEntity().getContent(); // 分段讀取輸入流數(shù)據(jù) ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte[] buf = new byte[1024]; int len = -1; while ((len = inStream.read(buf)) != -1) { baos.write(buf, 0, len); } // 數(shù)據(jù)接收完畢退出 inStream.close(); // 將數(shù)據(jù)轉(zhuǎn)換為字符串保存 return new String(baos.toByteArray(), this.charset); } /** * 關(guān)閉連接管理器釋放資源 */ protected void shutdownHttpClient() { if (this.httpClient != null && this.httpClient.getConnectionManager() != null) { this.httpClient.getConnectionManager().shutdown(); } } /** * 監(jiān)聽服務(wù)端響應(yīng)事件并返回服務(wù)端內(nèi)容 * * @return * @throws Exception */ protected String checkStatus() throws Exception { OnHttpRequestListener listener = this.getOnHttpRequestListener(); String content; if (this.statusCode == HttpStatus.SC_OK) { // 請(qǐng)求成功, 回調(diào)監(jiān)聽事件 content = listener.onSucceed(this.statusCode, this); } else { // 請(qǐng)求失敗或其他, 回調(diào)監(jiān)聽事件 content = listener.onFailed(this.statusCode, this); } // 關(guān)閉連接管理器釋放資源 this.shutdownHttpClient(); return content; } /** * HTTP 請(qǐng)求操作時(shí)的事件監(jiān)聽接口 */ public interface OnHttpRequestListener { /** * 初始化 HTTP GET 或 POST 請(qǐng)求之前的 header 信息配置 或 其他數(shù)據(jù)配置等操作 * * @param request * @throws Exception */ public void onRequest(ZHttpRequest request) throws Exception; /** * 當(dāng) HTTP 請(qǐng)求響應(yīng)成功時(shí)的回調(diào)方法 * * @param statusCode 當(dāng)前狀態(tài)碼 * @param request * @return 返回請(qǐng)求獲得的字符串內(nèi)容 * @throws Exception */ public String onSucceed(int statusCode, ZHttpRequest request) throws Exception; /** * 當(dāng) HTTP 請(qǐng)求響應(yīng)失敗時(shí)的回調(diào)方法 * * @param statusCode 當(dāng)前狀態(tài)碼 * @param request * @return 返回請(qǐng)求失敗的提示內(nèi)容 * @throws Exception */ public String onFailed(int statusCode, ZHttpRequest request) throws Exception; } /** * 綁定 HTTP 請(qǐng)求的監(jiān)聽事件 * * @param listener * @return */ public ZHttpRequest setOnHttpRequestListener(OnHttpRequestListener listener) { this.onHttpRequestListener = listener; return this; } /** * 獲取已綁定過的 HTTP 請(qǐng)求監(jiān)聽事件 * * @return */ public OnHttpRequestListener getOnHttpRequestListener() { return this.onHttpRequestListener; } }
在 Activity 中的使用方法(這里我還是只寫主體部分代碼):
MainActivity.java
public void doClick(View view) { ZHttpRequest get = new ZHttpRequest(); get .setCharset(HTTP.UTF_8) .setConnectionTimeout(5000) .setSoTimeout(5000); get.setOnHttpRequestListener(new ZHttpRequest.OnHttpRequestListener() { @Override public void onRequest(ZHttpRequest request) throws Exception { } @Override public String onSucceed(int statusCode, ZHttpRequest request) throws Exception { return request.getInputStream(); } @Override public String onFailed(int statusCode, ZHttpRequest request) throws Exception { return "GET 請(qǐng)求失?。簊tatusCode "+ statusCode; } }); ZHttpRequest post = new ZHttpRequest(); post .setCharset(HTTP.UTF_8) .setConnectionTimeout(5000) .setSoTimeout(10000); post.setOnHttpRequestListener(new ZHttpRequest.OnHttpRequestListener() { private String CHARSET = HTTP.UTF_8; private ContentType TEXT_PLAIN = ContentType.create("text/plain", Charset.forName(CHARSET)); @Override public void onRequest(ZHttpRequest request) throws Exception { // 設(shè)置發(fā)送請(qǐng)求的 header 信息 request.addHeader("cookie", "abc=123;456=愛就是幸福;"); // 配置要 POST 的數(shù)據(jù) MultipartEntityBuilder builder = request.getMultipartEntityBuilder(); builder.addTextBody("p1", "abc"); builder.addTextBody("p2", "中文", TEXT_PLAIN); builder.addTextBody("p3", "abc中文cba", TEXT_PLAIN); if (picPath != null && ! "".equals(picPath)) { builder.addTextBody("pic", picPath); builder.addBinaryBody("file", new File(picPath)); } request.buildPostEntity(); } @Override public String onSucceed(int statusCode, ZHttpRequest request) throws Exception { return request.getInputStream(); } @Override public String onFailed(int statusCode, ZHttpRequest request) throws Exception { return "POST 請(qǐng)求失?。簊tatusCode "+ statusCode; } }); TextView textView = (TextView) findViewById(R.id.showContent); String content = "初始內(nèi)容"; try { if (view.getId() == R.id.doGet) { content = get.get("http://www.baidu.com"); content = "GET數(shù)據(jù):isGet: " + (get.isGet() ? "yes" : "no") + " =>" + content; } else { content = post.post("http://192.168.1.6/test.php"); content = "POST數(shù)據(jù):isPost" + (post.isPost() ? "yes" : "no") + " =>" + content; } } catch (IOException e) { content = "IO異常:" + e.getMessage(); } catch (Exception e) { content = "異常:" + e.getMessage(); } textView.setText(content); }
其中 picPath 為 SD 卡中的圖片路徑 String 類型,我是直接拍照后進(jìn)行上傳用的
布局頁面
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <ScrollView android:layout_width="fill_parent" android:layout_height="fill_parent" > <LinearLayout android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <Button android:id="@+id/doGet" android:layout_width="fill_parent" android:layout_height="wrap_content" android:padding="10dp" android:layout_marginBottom="10dp" android:text="GET請(qǐng)求" android:onClick="doClick" /> <Button android:id="@+id/doPost" android:layout_width="fill_parent" android:layout_height="wrap_content" android:padding="10dp" android:layout_marginBottom="10dp" android:text="POST請(qǐng)求" android:onClick="doClick" /> <Button android:id="@+id/doPhoto" android:layout_width="fill_parent" android:layout_height="wrap_content" android:padding="10dp" android:layout_marginBottom="10dp" android:text="拍照" android:onClick="doPhoto" /> <TextView android:id="@+id/showContent" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginBottom="10dp" /> <ImageView android:id="@+id/showPhoto" android:layout_width="fill_parent" android:layout_height="250dp" android:scaleType="centerCrop" android:src="@drawable/add" android:layout_marginBottom="10dp" /> </LinearLayout> </ScrollView> </LinearLayout>
至于服務(wù)端我用的 PHP ,只是簡單的輸出獲取到的數(shù)據(jù)而已
<?php echo 'GET:<br>'. "\n"; //print_r(array_map('urldecode', $_GET)); print_r($_GET); echo '<br>'. "\n". 'POST:<br>'. "\n"; //print_r(array_map('urldecode', $_POST)); print_r($_POST); echo '<br>'. "\n". 'FILES:<br>'. "\n"; print_r($_FILES); echo '<br>'. "\n". 'COOKIES:<br>'. "\n"; print_r($_COOKIE);
- Android實(shí)現(xiàn)拍照、選擇圖片并裁剪圖片功能
- Android啟動(dòng)相機(jī)拍照并返回圖片
- Android拍照保存在系統(tǒng)相冊(cè)不顯示的問題解決方法
- Android仿微信發(fā)表說說實(shí)現(xiàn)拍照、多圖上傳功能
- android 拍照和上傳的實(shí)現(xiàn)代碼
- Android實(shí)現(xiàn)調(diào)用攝像頭進(jìn)行拍照功能
- Android選擇圖片或拍照?qǐng)D片上傳到服務(wù)器
- Android拍照得到全尺寸圖片并進(jìn)行壓縮
- Android部分手機(jī)拍照后獲取的圖片被旋轉(zhuǎn)問題的解決方法
- Android快速實(shí)現(xiàn)無預(yù)覽拍照功能
相關(guān)文章
Android實(shí)現(xiàn)倒計(jì)時(shí)的按鈕效果
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)倒計(jì)時(shí)的按鈕效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-12-12Android開發(fā)adb.exe'' and can be executed.錯(cuò)誤解決方法
這篇文章主要介紹了Android開發(fā)adb.exe' and can be executed.錯(cuò)誤解決方法,本文分析了問題的可能原因并給出了排查步驟,需要的朋友可以參考下2015-06-06Android TelephonyManager詳解及實(shí)現(xiàn)代碼
本文主要介紹Android TelephonyManager, 這里整理了關(guān)于Android TelephoneManager的相關(guān)資料,并附有示例代碼和實(shí)現(xiàn)效果圖,有需要的朋友可以參考下2016-08-08mui,h5+中實(shí)現(xiàn)控制頁面load顯示
這篇文章主要介紹了mui,h5+中實(shí)現(xiàn)控制頁面load顯示的相關(guān)代碼寫法和運(yùn)用技巧,需要的朋友參考一下。2017-11-11Android 新手引導(dǎo)蒙層效果實(shí)現(xiàn)代碼示例
本篇文章主要介紹了Android 新手引導(dǎo)蒙層效果實(shí)現(xiàn)代碼示例,具有一定的參考價(jià)值,有興趣的可以了解一下。2017-01-01解決video標(biāo)簽在安卓webview下無法自動(dòng)播放問題
這篇文章主要介紹了video標(biāo)簽在安卓webview下無法自動(dòng)播放問題的解決方法 ,需要的朋友可以參考下2014-03-03內(nèi)存泄露導(dǎo)致Android?中setVisibility()?失效原理
這篇文章主要介紹了內(nèi)存泄露導(dǎo)致Android?中setVisibility()?失效原理,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,感興趣的小伙伴可以參考一下2022-07-07