android使用webview上传文件(支持相册和拍照),支持最高6.0安卓系统(改进版)

首先学习 http://blog.csdn.net/woshinia/article/details/19030437 对input file的支持

1.注意

mUploadMessage.onReceiveValue(Uri.parse(""));

必须得到调用,无论用户是否选了图,否则会出现再点击不响应的情况

2.上面的参考由于比较老,不适用于安卓5.0系统,因为谷歌5.0以后对webkit做了改动,

相关API发生了变化,那么5.0的需要参考http://blog.csdn.net/earbao/article/details/50716747

汇总改进后得出我写的:(最高6.0的安卓系统都支持,已测试使用)

package com.fuiou.webviewupload;

import java.io.File;
import java.io.IOException;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.ContentValues;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;
import android.view.KeyEvent;
import android.webkit.ValueCallback;
import android.webkit.WebChromeClient;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Toast;

public class MainActivity extends Activity {
   public static final String TAG = "MainActivity";
   ValueCallback<Uri> mUploadMessage;
   ValueCallback<Uri[]> mFilePathCallback;
   private WebView mWebView;

   @Override
   protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
      initView();
   }

   private void initView() {
      mWebView = (WebView) findViewById(R.id.web_view);
      mWebView.setWebChromeClient(new MyWebChromeClient());

      mWebView.setWebViewClient(new MyWebViewClient(this));
//    webView.loadUrl("file:///android_asset/upload_image.html");
      mWebView.loadUrl("http://192.168.25.38:8001/test/2016/5/2016-5-24/index.html");
   }

   private class MyWebViewClient extends WebViewClient{
      private Context mContext;
      public MyWebViewClient(Context context){
         super();
         mContext = context;
      }

      @Override
      public void onPageStarted(WebView view, String url, Bitmap favicon) {
         Log.d(TAG,"URL地址:" + url);
         super.onPageStarted(view, url, favicon);
      }

      @Override
      public void onPageFinished(WebView view, String url) {
         Log.i(TAG, "onPageFinished");
         super.onPageFinished(view, url);
      }
   }

   public static final int FILECHOOSER_RESULTCODE = 1;
   private static final int REQ_CAMERA = FILECHOOSER_RESULTCODE+1;
   private static final int REQ_CHOOSE = REQ_CAMERA+1;

   private class MyWebChromeClient extends WebChromeClient {

      public boolean onShowFileChooser(
            WebView webView, ValueCallback<Uri[]> filePathCallback,
            WebChromeClient.FileChooserParams fileChooserParams) {
         if (mFilePathCallback != null) return true;
         mFilePathCallback = filePathCallback;
         selectImage();
         return true;
      }
      // For Android 3.0+
         public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType) {
               if (mUploadMessage != null) return;
               mUploadMessage = uploadMsg;
               selectImage();
//               Intent i = new Intent(Intent.ACTION_GET_CONTENT);
//               i.addCategory(Intent.CATEGORY_OPENABLE);
//               i.setType("*/*");
//                   startActivityForResult( Intent.createChooser( i, "File Chooser" ), FILECHOOSER_RESULTCODE );
           }
            // For Android < 3.0
           public void openFileChooser(ValueCallback<Uri> uploadMsg) {
                  openFileChooser( uploadMsg, "" );
           }
           // For Android  > 4.1.1
         public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture) {
                 openFileChooser(uploadMsg, acceptType);
         }

   }

   /**
    * 检查SD卡是否存在
    *
    * @return
    */
   public final boolean checkSDcard() {
      boolean flag = Environment.getExternalStorageState().equals(
            Environment.MEDIA_MOUNTED);
      if (!flag) {
         Toast.makeText(this, "请插入手机存储卡再使用本功能",Toast.LENGTH_SHORT).show();
      }
      return flag;
   }
   String compressPath = "";

   protected final void selectImage() {
      if (!checkSDcard())
         return;
      String[] selectPicTypeStr = { "camera","photo" };
      AlertDialog alertDialog = new AlertDialog.Builder(this)
            .setItems(selectPicTypeStr,
                  new DialogInterface.OnClickListener() {
                     @Override
                     public void onClick(DialogInterface dialog,
                                    int which) {
                        switch (which) {
                           // 相机拍摄
                           case 0:
                              openCarcme();
                              break;
                           // 手机相册
                           case 1:
                              chosePic();
                              break;
                           default:
                              break;
                        }
                        compressPath = Environment
                              .getExternalStorageDirectory()
                              .getPath()
                              + "/fuiou_wmp/temp";
                        new File(compressPath).mkdirs();
                        compressPath = compressPath + File.separator
                              + "compress.jpg";
                     }
                  }).setOnCancelListener(new DialogInterface.OnCancelListener() {
               @Override
               public void onCancel(DialogInterface dialogInterface) {
                  if(mFilePathCallback != null){
                     Uri[] uris = new Uri[1];
                     uris[0] = Uri.parse("");
                     mFilePathCallback.onReceiveValue(uris);
                     mFilePathCallback=null;
                  }else {
                     mUploadMessage.onReceiveValue(Uri.parse(""));
                     mUploadMessage=null;
                  }
               }
            }).show();
   }

   String imagePaths;
   Uri  cameraUri;
   /**
    * 打开照相机
    */
   private void openCarcme() {
      Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

      imagePaths = Environment.getExternalStorageDirectory().getPath()
            + "/fuiou_wmp/temp/"
            + (System.currentTimeMillis() + ".jpg");
      // 必须确保文件夹路径存在,否则拍照后无法完成回调
      File vFile = new File(imagePaths);
      if (!vFile.exists()) {
         File vDirPath = vFile.getParentFile();
         vDirPath.mkdirs();
      } else {
         if (vFile.exists()) {
            vFile.delete();
         }
      }
      cameraUri = Uri.fromFile(vFile);
      intent.putExtra(MediaStore.EXTRA_OUTPUT, cameraUri);
      startActivityForResult(intent, REQ_CAMERA);
   }

   /**
    * 拍照结束后
    */
   private void afterOpenCamera() {
      File f = new File(imagePaths);
      addImageGallery(f);
   }

   /** 解决拍照后在相册中找不到的问题 */
   private void addImageGallery(File file) {
      ContentValues values = new ContentValues();
      values.put(MediaStore.Images.Media.DATA, file.getAbsolutePath());
      values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
      getContentResolver().insert(
            MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
   }

   /**
    * 本地相册选择图片
    */
   private void chosePic() {
      FileUtils.delFile(compressPath);
      Intent innerIntent = new Intent(Intent.ACTION_GET_CONTENT); // "android.intent.action.GET_CONTENT"
      String IMAGE_UNSPECIFIED = "image/*";
      innerIntent.setType(IMAGE_UNSPECIFIED); // 查看类型
      Intent wrapperIntent = Intent.createChooser(innerIntent, null);
      startActivityForResult(wrapperIntent, REQ_CHOOSE);
   }

   /**
    * 选择照片后结束
    *
    * @param data
    */
   private Uri afterChosePic(Intent data) {

      // 获取图片的路径:
      String[] proj = { MediaStore.Images.Media.DATA };
      // 好像是android多媒体数据库的封装接口,具体的看Android文档
      Cursor cursor = managedQuery(data.getData(), proj, null, null, null);
      if(cursor == null ){
         Toast.makeText(this, "上传的图片仅支持png或jpg格式",Toast.LENGTH_SHORT).show();
         return null;
      }
      // 按我个人理解 这个是获得用户选择的图片的索引值
      int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
      // 将光标移至开头 ,这个很重要,不小心很容易引起越界
      cursor.moveToFirst();
      // 最后根据索引值获取图片路径
      String path = cursor.getString(column_index);
      if(path != null && (path.endsWith(".png")||path.endsWith(".PNG")||path.endsWith(".jpg")||path.endsWith(".JPG"))){
         File newFile = FileUtils.compressFile(path, compressPath);
         return Uri.fromFile(newFile);
      }else{
         Toast.makeText(this, "上传的图片仅支持png或jpg格式",Toast.LENGTH_SHORT).show();
      }
      return null;
   }

   /**
    * 返回文件选择
    */
   @Override
   protected void onActivityResult(int requestCode, int resultCode,
         Intent intent) {
//    if (requestCode == FILECHOOSER_RESULTCODE) {
//       if (null == mUploadMessage)
//          return;
//       Uri result = intent == null || resultCode != RESULT_OK ? null
//             : intent.getData();
//       mUploadMessage.onReceiveValue(result);
//       mUploadMessage = null;
//    }

      if (null == mUploadMessage || mFilePathCallback == null)
         return;
      Uri uri = null;
      File file = new File(cameraUri.getPath());
      if(!file.exists()){
         cameraUri = Uri.parse("");
      }
      if(requestCode == REQ_CAMERA ){
         afterOpenCamera();
         uri = cameraUri;
      }else if(requestCode == REQ_CHOOSE){
         uri = afterChosePic(intent);
      }
      if(mFilePathCallback != null){
         Uri[] uris = new Uri[1];
         uris[0] = uri;
         mFilePathCallback.onReceiveValue(uris);
      }else {
         mUploadMessage.onReceiveValue(uri);
      }
      mFilePathCallback = null;
      mUploadMessage = null;
      super.onActivityResult(requestCode, resultCode, intent);
   }

   public boolean onKeyDown(int keyCode, KeyEvent event) {
      if ((keyCode == KeyEvent.KEYCODE_BACK) && mWebView.canGoBack()) {
         mWebView.goBack();
         return true;
      }else{
              finish();
      }
      return super.onKeyDown(keyCode, event);
      }
}
时间: 2024-10-07 00:09:00

android使用webview上传文件(支持相册和拍照),支持最高6.0安卓系统(改进版)的相关文章

android post方式上传文件(模拟表单格式数据提交)

表单提交内容为: POST /upload.php?zp_id=ab46ca6d703e3a1580c1c9b8b3a8fb39 HTTP/1.1Accept: image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-ms-application, application/x-ms-xbap, application/vnd.ms-xpsdocument, application/xaml+xml, application/v

android C#webservice 上传文件

android 端 public String UploadHeadImg(Bitmap bitmap,String fileName ) { String[] arg={"BtyeString","FileName"}; String[] val={bitmaptoString(bitmap),fileName}; return bd.GetWebReturnModel("UploadFile", arg, val); } public Str

Android应用开发中webview上传文件的几种思路

1. 常规方法,重写WebChromeClient 的 openFileChooser 方法 private class MyWebChromeClient extends WebChromeClient { // For Android 3.0+ public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType) { if (mUploadMessage != null) return; mUploadMe

Android 网络编程--上传文件及相应的参数到服务器

之前一直在做SiteCheck的项目,所用到的知识大部分都涉及到网络编程方面,所以现在有时间先把它的使用方法及一些注意事项记录下来.在这里我用两种例子让大家了解它的使用方法: (1)上传图片及相应参数到服务器  (2)上传语音及相应参数到服务器.代码比较多.... 先贴上代码,再解析: UploadFileTask .java : (实现异步上传的执行类) <span style="font-size:14px;">public class UploadFileTask e

android:AndroidAnnotations上传文件,网络接口如此简洁

网络接口如此简洁 使用HttpClient进行文件的上传,可以参考博客:使用HttpClient进行文件上传 如果项目使用AndroidAnnotation,写上传接口就会非常方便,比如之前写POST接口 首先参考之前的博客,使用AndroidAnnotations进行POST请求. 如下是使用AndroidAnnotations进行文件上传的网络接口 @Rest(rootUrl = "http://192.168.31.183:8080/SSHMySql/", converters

Android项目——HttpUrlConnection上传文件(图片)

UI界面设计:     由于博客发布可能附加图片,但是图片(或者任何文件)信息必须放在http请求体的正文之中,这就需要我们使用HttpUrlConnection的时候构建Http正文. 我们先来看一下Http正文格式: 1 POST /api/feed/ HTTP/1.1 2 Accept-Encoding: gzip 3 Content-Length: 225873 4 Content-Type: multipart/form-data; boundary=OCqxMF6-JxtxoMDHm

Android上传图片到PHP服务器并且支持浏览器上传文件(word、图片、音乐等)

暑假已经过了一半了,这才完成计划当中的第二个任务.虽然进度是慢了点.但也算是暑假的收获吧.下面我就把我学习当中的收获记录在此. 还是跟以往一样,先上图片. 操作的步骤:打开程序---->选择上传的照片----->点击返回键------>显示没有选择上传图片的toast------>点击上传的图片----->打印图片的存储的物理路径---->询问是否确认上传选择的图片----->确认则显示上传成功---->取消则退出 php代码: <?php //上传文

【经验记录】Android上传文件到服务器

Android中实现上传文件,其实是很简单的,和在java里面是一样的,基本上都是熟悉操作输出流和输入流!还有一个特别重要的就是需要配置content-type的一些参数!如果这些都弄好了,上传就很简单了,下面是我写的一个上传的工具类: package com.spring.sky.image.upload.network; import java.io.DataOutputStream; import java.io.File; import java.io.FileInputStream;

Android上传文件到服务器(转)

Android中实现上传文件,其实是很简单的,和在java里面是一样的,基本上都是熟悉操作输出流和输入流!还有一个特别重要的就是需要配置content-type的一些参数!如果这些都弄好了,上传就很简单了,下面是我写的一个上传的工具类: package com.spring.sky.image.upload.network; import java.io.DataOutputStream; import java.io.File; import java.io.FileInputStream;