1. 程式人生 > >上傳android手機圖片到伺服器的方法

上傳android手機圖片到伺服器的方法

最近做微博開發,想實現上傳圖片的功能。於是寫個樣式,放上一些按鈕和ImageView,在程式碼中做監聽處理,這個具體就不說了。

那麼如何實現上傳圖片的功能呢?這裡有兩種上傳的方式,本地相簿上傳和拍照上傳。

這兩種方式都要使用startActivForResult,因為需要使用這種方式獲取啟用的那個Activity傳回的圖片地址,這裡說地址不確切,實際上是URI。

至於如何啟用,使用的是Intent中的action方法,我在專案中用到了兩種處理方式:“本地上傳”和“拍照上傳”,程式碼如下:

picBtn = (ImageButton) findViewById(R.id.insert_pic_btn);
		picBtn.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {

				final CharSequence[] items = { "本地上傳", "拍照上傳" };
				AlertDialog dialog = new AlertDialog.Builder(Tweet.this)
						.setTitle("選擇上傳方式")
						.setItems(items, new DialogInterface.OnClickListener() {
							public void onClick(DialogInterface dialog, int item) {
								if (item == 0) {
									Log.v(TAG, "本地上傳 ");
									Intent intent = new Intent();
									intent.setType("image/*");
									intent.setAction(Intent.ACTION_GET_CONTENT);
									startActivityForResult(intent,
											GET_PHOTO_BY_GALLERY);
									dialog.cancel();
								} else if (item == 1) {

									Log.v(TAG, "拍照上傳 ");

									Intent intent = new Intent(
											"android.media.action.IMAGE_CAPTURE");

									startActivityForResult(intent,
											GET_PHOTO_BY_CAMERA);

									dialog.cancel();
								}
							}
						}).create();
				dialog.show();
			}
		});
需要強調一下,這裡有個陷阱,就是
private final int GET_PHOTO_BY_CAMERA = 100;
	private final int GET_PHOTO_BY_GALLERY = 200;

這兩個常量的值,必須大於或者等於0,否則,onActivityResult無法執行。我當時因為這個錯誤,摸索了一下午,更多資料,請移步:

下面是onActivityResult:

@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		if (requestCode == GET_PHOTO_BY_GALLERY) {
			uri = data.getData();
			Log.v(TAG, "uri: " + uri.toString());
			ContentResolver cr = getContentResolver();
			try {
				mBitmap = BitmapFactory.decodeStream(cr.openInputStream(uri));
			} catch (FileNotFoundException e) {

				e.printStackTrace();
			}

		} else if (requestCode == GET_PHOTO_BY_CAMERA) {
			Bundle bundle = data.getExtras();
			mBitmap = (Bitmap) bundle.get("data");
			Log.v(TAG, "bundle.size(): " + bundle.size());

		}

		super.onActivityResult(requestCode, resultCode, data);
		
		}
	}

得到Bitmap之後就可以在你的ImageView控制元件中顯示待上傳圖片的縮圖了。這樣設計比較人性化,因為使用者選擇了一張圖片後,也許改變主意不想上傳了,因此這裡可以提供上傳前的預覽。貼一張效果圖吧:

關鍵部分來了,如何把得到的圖片上傳到伺服器呢?

光知道如何獲取要上傳圖片的Bitmap遠遠不夠,因為像新浪微博和騰訊微博這樣的開發平臺,支援的是url上傳方式,那麼如何獲取到android手機上的或者android虛擬機器上的待上傳圖片的url地址呢?

這裡要考慮三個要素,一個是呼叫startActivityForResult的程式碼,一個是被啟用的其他第三方用於選擇圖片的activity(如看圖大師),還有一個是主調activity和她的onActivityResult方法。

在上面的程式碼中,對如何在startActivityForResult方法中啟動第三方圖片檢視器和相機已經做了介紹,但是那種方法經過實際測試,只有呼叫本地相簿時可以,呼叫相機拍照的那些程式碼無效,無法獲取圖片的URL地址。這裡我也無法提供有效的解決辦法,仍在探索中。

那我就說說如何上傳從本地上冊挑選出的圖片吧,這裡以釋出一條帶文字和圖片的騰訊微博為例。主要的程式碼都在onActivityResult方法體中,不多說,直接貼程式碼了:

if (requestCode == GET_PHOTO_BY_GALLERY) {
			uri = data.getData();
			Log.v(TAG, "uri: " + uri.toString());

			String[] proj = { MediaStore.Images.Media.DATA };
			Cursor cursor = managedQuery(uri, proj, null, null, null);
			int column_index = cursor
					.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
			cursor.moveToFirst();
			path = cursor.getString(column_index);
			Log.v(TAG, "path: " + path);

			ContentResolver cr = getContentResolver();
			try {
				mBitmap = BitmapFactory.decodeStream(cr.openInputStream(uri));
			} catch (FileNotFoundException e) {

				e.printStackTrace();
			}

		} else if (requestCode == GET_PHOTO_BY_CAMERA) {
			Bundle bundle = data.getExtras();
			mBitmap = (Bitmap) bundle.get("data");
                        //對於使用相機上傳,我這裡目前只能獲取到Bitmap,無法獲取到URL,歡迎交流

		}
從控制檯打印出來的log可知,uri中的資料示例:
08-29 22:47:17.050: V/Tweet(2740): uri: content://media/external/images/media/23

經過遊標跳轉查詢後得到的URL地址示例:
08-29 22:47:17.060: V/Tweet(2740): path: /mnt/sdcard/DCIM/Camera/C360_2012-05-19-18-22-50.jpg

很顯然,根據path地址,我們就可以在手機或者虛擬機器的SD卡中找到這張圖片,這個地址就是釋出微博時需要上傳的引數之一,至於釋出微博的程式碼我就不多囉嗦了,有興趣的可以加我QQ:676395711,歡迎交流。

現在,我還是不甘心,明明計劃實現本地上傳和拍照上傳的功能。但是,到了拍照上傳就卡殼了,我原先使用的程式碼是這樣的,不過這段程式碼是錯的:

                                                    if (item == 1) {

									// this.TEMP_IMG_DIR.mkdirs();
									File dir = Environment.getExternalStorageDirectory();
									String fileName = String.valueOf(System.currentTimeMillis()) + ".jpg";
									File file = new File(dir, fileName);
									Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
									Uri uri = Uri.fromFile(file);
									intent.putExtra("output", uri);
									startActivityForResult(intent,GET_PHOTO_BY_CAMERA);
									Log.v(TAG, "拍照上傳 ");
									dialog.cancel();
								}

雖然是錯的,可以看出這段程式碼表達的意思是,先在SD卡中建立一個檔案,檔名是以系統當前時間命名的,以防止重名。然後呼叫第三方拍照軟體,拍完照片後,把照片儲存到先前指定的路徑。然後在onActivityResult方法中使用如下程式碼獲取path值,當然這段程式碼也是錯誤的:

 if (requestCode == GET_PHOTO_BY_CAMERA) {
			Bundle bundle = data.getExtras();
			mBitmap = (Bitmap) bundle.get("data");
			uri = data.getData();
			Log.v(TAG, "uri: " + uri.toString());

			String[] proj = { MediaStore.Images.Media.DATA };
			Cursor cursor = managedQuery(uri, proj, null, null, null);
			int column_index = cursor
					.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
			cursor.moveToFirst();
			path = cursor.getString(column_index);
			Log.v(TAG, "path: " + path);

		}
然後就需要說說我控制檯裡打印出的錯誤資訊了:
08-29 22:51:02.040: E/AndroidRuntime(3251): java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=100, result=-1, data=Intent { act=inline-data (has extras) }} to activity {com.example.testphoto/com.example.testphoto.Tweet}: java.lang.NullPointerException
08-29 22:51:02.040: E/AndroidRuntime(3251): 	at android.app.ActivityThread.deliverResults(ActivityThread.java:2653)
08-29 22:51:02.040: E/AndroidRuntime(3251): 	at android.app.ActivityThread.handleSendResult(ActivityThread.java:2695)
08-29 22:51:02.040: E/AndroidRuntime(3251): 	at android.app.ActivityThread.access$2000(ActivityThread.java:123)
08-29 22:51:02.040: E/AndroidRuntime(3251): 	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:969)
08-29 22:51:02.040: E/AndroidRuntime(3251): 	at android.os.Handler.dispatchMessage(Handler.java:99)
08-29 22:51:02.040: E/AndroidRuntime(3251): 	at android.os.Looper.loop(Looper.java:130)
08-29 22:51:02.040: E/AndroidRuntime(3251): 	at android.app.ActivityThread.main(ActivityThread.java:3835)
08-29 22:51:02.040: E/AndroidRuntime(3251): 	at java.lang.reflect.Method.invokeNative(Native Method)
08-29 22:51:02.040: E/AndroidRuntime(3251): 	at java.lang.reflect.Method.invoke(Method.java:507)
08-29 22:51:02.040: E/AndroidRuntime(3251): 	at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858)
08-29 22:51:02.040: E/AndroidRuntime(3251): 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
08-29 22:51:02.040: E/AndroidRuntime(3251): 	at dalvik.system.NativeStart.main(Native Method)
08-29 22:51:02.040: E/AndroidRuntime(3251): Caused by: java.lang.NullPointerException
08-29 22:51:02.040: E/AndroidRuntime(3251): 	at com.example.testphoto.Tweet.onActivityResult(Tweet.java:100)
08-29 22:51:02.040: E/AndroidRuntime(3251): 	at android.app.Activity.dispatchActivityResult(Activity.java:3908)
08-29 22:51:02.040: E/AndroidRuntime(3251): 	at android.app.ActivityThread.deliverResults(ActivityThread.java:2649)

弄了大半天,也沒整明白,希望知道如何處理的朋友告訴我一聲。

那麼,既然我這裡得到了拍照上傳時的Bitmap資料,那麼能不能把bitmap儲存成圖片到指定的本地路徑,然後在把這個路徑作為上傳的引數呢?

因為圖片的路徑是自己指定的,圖片的名字也是自己指定的,貌似這樣是可以的。處理的程式碼在下面,不過我沒有測試,不保證一定能用:

public void saveBitmap(String bitName) throws IOException {
		File f = new File("/sdcard/Note/" + bitName + ".png");
		f.createNewFile();
		FileOutputStream out = null;
		try {
			out = new FileOutputStream(f);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		mBitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
		try {
			out.flush();
		} catch (IOException e) {
			e.printStackTrace();
		}
		try {
			out.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
未完待續~

參考資料:

希望能幫到你

(完)

相關推薦

android手機圖片伺服器方法

最近做微博開發,想實現上傳圖片的功能。於是寫個樣式,放上一些按鈕和ImageView,在程式碼中做監聽處理,這個具體就不說了。 那麼如何實現上傳圖片的功能呢?這裡有兩種上傳的方式,本地相簿上傳和拍照上傳。 這兩種方式都要使用startActivForResult,因為需要使

通過Fckeditor把圖片到獨立圖片伺服器方法

我大概思考了下有如下幾種方法可以解決: 1.在圖片伺服器上開通FTP,人為新增圖片地址即可,但不方便,特別是在可視編輯器中看圖還的多一部操作. 2.在圖片伺服器上開通FTP,並提高IIS執行dosShell訪問ftp,但是不安全. 3.在圖片伺服器上開通IIS,WEB後臺直接訪問(還是存在在編輯器中不方便檢視

struts2多張圖片方法

原文地址 package eao; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; imp

(複習)android 呼叫系統相機 相簿 裁剪-圖片-客服端-伺服器

效果: 客服端程式碼: package com.cn.lxz.zhaopian; import java.io.File; import java.io.IOException; import java.text.SimpleDateFormat;

AndroidAndroid伺服器互動 POST多個圖片檔案、文字內容 GET下載圖片

這裡伺服器端採用的是php解析內容 HTTP請求   HTTP 請求方法有 OPTIONS、GET、HEAD、POST、PUT、DELETE、TRACE、CONNECT 這幾種。用於資料互動的最基本方法一般為GET、POST、PUT、DELETE。對

關於ThinkCMF自帶插件不了圖片的解決方法

.cn 方法 插件 thinkcmf 解決方法 刪除 打開 blog 文件 原因:是因為刪除了存放圖片的文件夾,這是cmf在windows的一個BUG 解決方法: 再到php.ini裏把 這個打開就解決了關於ThinkCMF自帶插件上傳不了圖片的解決方法

Java Springboot結合FastDFS實現檔案以及根據圖片url將圖片圖片伺服器

上一篇文章我們已經講解了如何搭建FastDFS圖片伺服器,環境我們準備好了現在就讓我們開始與Java結合將他應用到實際的專案中吧。本篇文章我們將會展示上傳圖片到FastDFS圖片伺服器以及通過外網的圖片url將圖片上傳至我們自己的圖片伺服器中。 1.建立springbo

用FlashFXP檔案到SSH伺服器,附FlashFXP顯示中文亂碼的解決方法

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

圖片前端的幾種方法

      1.路徑 <img src="balabala/123.jpg"> 2.img標籤指向servlet方法 <img src="/ImgServlet?imgId=00001" alt="picture">

Android客戶端使用OkGo檔案或者圖片,客戶端和服務端程式碼分享

(一)上傳單個檔案或者圖片: 客戶端程式碼: /** * 儲存資料到伺服器 */ private void saveToInternet() { //上傳單個檔案 String url = Constants.USER_NET_ICON;   Fi

java圖片七牛雲伺服器

七牛雲地址 七牛雲官網 註冊首頁 登入首頁 實名認證:上傳身份證資訊等 上傳圖片: 1.物件儲存 2.新建一個儲存空間 3.建好儲存空間後內容管理 4.預設外鏈(將於2018-08-22起改版,一個月有效期,可以在測試環境中使用)

採用AFNetWorking base64的圖片伺服器圖片解析不了。ASIHttpRequest是可以的,請教!

採用AFNetWorking 上傳base64的圖片到伺服器,上傳的圖片解析不了。ASIHttpRequest上傳是可以的,兩種寫法如下,求教,能給個思路嗎? IOS AFNetworking upload pictures to the server.The reques

Android WebView-H5互動檔案(包括圖片)

WebView 在4.4前後的區別非常大, 比如對URL跳轉的格式, 對JS的注入宣告等等, 4.4以後的WebView 已經是chromium核心, 有多強大就無需我贅述. 說這些, 其實也是為了說明也因為WebView的前後變化太大了, 所以在低版本和版本上, Web

Android檔案攜帶引數及伺服器SSM程式碼

一 Android端程式碼package com.xky.recall.network; import com.xky.recall.utils.LogUtils; import java.io.DataOutputStream; import java.io.File; i

java httpclient檔案,springmvc作為伺服器端接收檔案,以及中檔名亂碼的解決方法

最近由於專案中需要一個檔案上傳(基於http)的功能,遇到一些問題,故寫此部落格防止後面遺忘。 檔案上傳功能需要一個客戶端,一個伺服器端,由於客戶端不是在前臺(jsp,html)觸發,而是在java中進行請求,於是採用的org.apache.commons.

Android 頭像(檔案)到伺服器

import android.annotation.TargetApi; import android.content.Context; import android.content.res.Resources; import android.graphics.Bitmap; import android.g

Androidlog資訊到伺服器

Android應用發生ANR或者崩潰的時候比較多,當然你開發的應用特別好除外,我們可以想辦法把崩潰的log資訊傳到伺服器端,那麼就涉及到如何拿到我們應用的錯誤資訊的問題。但請記得一定要過濾log資訊,只取和你應用相關的Log資訊就可以了。 具體看官方文件這裡: dev g

iOS多張圖片多執行緒處理方法(可獲取最後一張狀態後的訊號)

環境重現 1,服務端提供單張上傳的介面。 2,客戶端需求同時提交多張圖片上傳。 3,使用AFNetWorking 或 自封裝的帶有block回撥網路狀態的框架。 思路 1,建立一個管理類。 2,提供一個單例方法。保證管理類唯一 3,提供一個公共

android大檔案到伺服器客戶端和伺服器端程式碼

使用一般的上傳方法一般上傳不能超過2m的檔案,也非常容易中斷和出錯,於是本人打算使用xutils框架進行檔案上傳開發,話不多說直接上原始碼 首先要下載這個類庫的jar包,地址:https://github.com/wyouflf/xUtils android端程式碼: 新增

多張圖片伺服器

/** * 上傳帶圖片的內容,允許多張圖片上傳(URL)POST * * @param url 網路請求地址 * @param images 要上傳的圖片陣列(注意陣列內容需是圖片) * @par