上传android手机图片到服务器的方法
2012-08-29 10:27
381 查看
最近做微博开发,想实现上传图片的功能。于是写个样式,放上一些按钮和ImageView,在代码中做监听处理,这个具体就不说了。
那么如何实现上传图片的功能呢?这里有两种上传的方式,本地相册上传和拍照上传。
这两种方式都要使用startActivForResult,因为需要使用这种方式获取激活的那个Activity传回的图片地址,这里说地址不确切,实际上是URI。
至于如何激活,使用的是Intent中的action方法,我在项目中用到了两种处理方式:“本地上传”和“拍照上传”,代码如下:
这两个常量的值,必须大于或者等于0,否则,onActivityResult无法执行。我当时因为这个错误,摸索了一下午,更多资料,请移步:
startActivityForResult的用法
下面是onActivityResult:
得到Bitmap之后就可以在你的ImageView控件中显示待上传图片的缩略图了。这样设计比较人性化,因为用户选择了一张图片后,也许改变主意不想上传了,因此这里可以提供上传前的预览。贴一张效果图吧:
关键部分来了,如何把得到的图片上传到服务器呢?
光知道如何获取要上传图片的Bitmap远远不够,因为像新浪微博和腾讯微博这样的开发平台,支持的是url上传方式,那么如何获取到android手机上的或者android虚拟机上的待上传图片的url地址呢?
这里要考虑三个要素,一个是调用startActivityForResult的代码,一个是被激活的其他第三方用于选择图片的activity(如看图大师),还有一个是主调activity和她的onActivityResult方法。
在上面的代码中,对如何在startActivityForResult方法中启动第三方图片查看器和相机已经做了介绍,但是那种方法经过实际测试,只有调用本地相册时可以,调用相机拍照的那些代码无效,无法获取图片的URL地址。这里我也无法提供有效的解决办法,仍在探索中。
那我就说说如何上传从本地上册挑选出的图片吧,这里以发布一条带文字和图片的腾讯微博为例。主要的代码都在onActivityResult方法体中,不多说,直接贴代码了:
经过游标跳转查找后得到的URL地址示例:
很显然,根据path地址,我们就可以在手机或者虚拟机的SD卡中找到这张图片,这个地址就是发布微博时需要上传的参数之一,至于发布微博的代码我就不多啰嗦了,有兴趣的可以加我QQ:676395711,欢迎交流。
现在,我还是不甘心,明明计划实现本地上传和拍照上传的功能。但是,到了拍照上传就卡壳了,我原先使用的代码是这样的,不过这段代码是错的:
虽然是错的,可以看出这段代码表达的意思是,先在SD卡中建立一个文件,文件名是以系统当前时间命名的,以防止重名。然后调用第三方拍照软件,拍完照片后,把照片保存到先前指定的路径。然后在onActivityResult方法中使用如下代码获取path值,当然这段代码也是错误的:
弄了大半天,也没整明白,希望知道如何处理的朋友告诉我一声。
那么,既然我这里得到了拍照上传时的Bitmap数据,那么能不能把bitmap保存成图片到指定的本地路径,然后在把这个路径作为上传的参数呢?
因为图片的路径是自己指定的,图片的名字也是自己指定的,貌似这样是可以的。处理的代码在下面,不过我没有测试,不保证一定能用:
参考资料:
android 拍照上传及本地上传
【Android】本地图片选择(打开媒体库,选择图片)
希望能帮到你
(完)
那么如何实现上传图片的功能呢?这里有两种上传的方式,本地相册上传和拍照上传。
这两种方式都要使用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无法执行。我当时因为这个错误,摸索了一下午,更多资料,请移步:
startActivityForResult的用法
下面是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中实现将图片上传到服务器的问题
android 拍照上传及本地上传【Android】本地图片选择(打开媒体库,选择图片)
希望能帮到你
(完)
相关文章推荐
- Android开发中调用系统相册上传图片到服务器OPPO等部分手机上出现短暂的显示桌面问题的解决方法
- Android使用post方式上传图片到服务器的方法
- Android使用post方式上传图片到服务器的方法
- android小文章——手机照片上传服务器方法
- Android使用post方式上传图片到服务器的方法
- java input 调用手机相机和本地照片上传图片到服务器然后压缩的方法
- android上传手机图片至服务器,服务器进行保存
- android小文章——手机照片上传服务器方法
- Android 手机上传图片至javaweb服务器(servlet)
- Android简单实现将手机图片上传到服务器中
- 微信公众号开发《四》使用微信JS-SDK实现手机图片上传,支持压缩、预览。并下载图片到自身服务器
- android上传图片至服务器
- android上传图片到服务器(使用base64字节流的形式通过 AsyncHttpClient框架传输)
- android上传图片至服务器
- Android——从本地图库上传图片至服务器
- Java乔晓松-android中上传图片到服务器Tomcat(Struts2)
- phpcms上传图片时,点击【上传到服务器上】按钮,显示:缺少图像源地址的解决方法
- android通过Base64往服务器上传图片和对象
- 有些Android手机拍照上传被旋转90度的处理方法
- Android设置网络图片为手机背景图片的方法