WebView上传文件

android webview本身不支持文件上传,因此我们需要重写webview的WebChromeClient,对其中的onShowFileChooser(高版本会调用这个)和openFileChooser(低版本会调用这个)做相应处理,先上代码:

public class MyChromeClient extends WebChromeClient {

	private UrlActivity activity;

	public static final int FILECHOOSER_RESULTCODE = 5173;

	public static String mCameraFilePath = "";

	@SuppressWarnings("deprecation")
	public MyChromeClient(UrlActivity cordova) {

		this.activity = cordova;

	}

	@Override
	public void onProgressChanged(WebView view, int newProgress) {

		super.onProgressChanged(view, newProgress);

	}

	// <input type="file" name="fileField" id="fileField" />

	// Android > 4.1.1

	@Override
	public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback,
			FileChooserParams fileChooserParams) {
		// TODO 自动生成的方法存根
		this.activity.setmUploadMsgList(filePathCallback);
		// UploadMsg2 = filePathCallback;
		this.activity.startActivityForResult(createDefaultOpenableIntent(), this.FILECHOOSER_RESULTCODE);
		// return false;

		// Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
		// intent.addCategory(Intent.CATEGORY_OPENABLE);
		// intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
		// "image/*");
		// this.activity.startActivityForResult(Intent.createChooser(intent,
		// ""), this.FILECHOOSER_RESULTCODE);
		return true;                            //  如果返回false,在选择文件过程中按返回键会崩溃,不知道为啥

	}

	@SuppressWarnings("static-access")
	public void openFileChooser(ValueCallback<Uri> uploadMsg,

			String acceptType, String capture) {

		this.activity.setmUploadMsg(uploadMsg);

		this.activity.startActivityForResult(createDefaultOpenableIntent(), this.FILECHOOSER_RESULTCODE);

	}

	// 3.0 +

	@SuppressWarnings("static-access")
	public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType) {

		this.activity.setmUploadMsg(uploadMsg);

		this.activity.startActivityForResult(createDefaultOpenableIntent(), this.FILECHOOSER_RESULTCODE);

	}

	// Android < 3.0

	@SuppressWarnings("static-access")
	public void openFileChooser(ValueCallback<Uri> uploadMsg) {

		this.activity.setmUploadMsg(uploadMsg);

		this.activity.startActivityForResult(createDefaultOpenableIntent(), this.FILECHOOSER_RESULTCODE);

	}

	private Intent createDefaultOpenableIntent() {

		Intent i = new Intent(Intent.ACTION_GET_CONTENT);

		i.addCategory(Intent.CATEGORY_OPENABLE);

		i.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,

				"image/*");

		Intent chooser = createChooserIntent(createCameraIntent()
		/*
		 * 
		 * ,
		 * 
		 * createCamcorderIntent
		 * 
		 * (),
		 * 
		 * createSoundRecorderIntent
		 * 
		 * ()
		 */);

		chooser.putExtra(Intent.EXTRA_INTENT, i);

		return chooser;

	}

	private Intent createChooserIntent(Intent... intents) {

		Intent chooser = new Intent(Intent.ACTION_CHOOSER);

		chooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, intents);

		chooser.putExtra(Intent.EXTRA_TITLE, "选择图片");

		return chooser;

	}

	@SuppressWarnings("static-access")
	private Intent createCameraIntent() {

		Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

		File externalDataDir = Environment

				.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);

		File cameraDataDir = new File(externalDataDir.getAbsolutePath()

				+ File.separator + "515aaa");

		cameraDataDir.mkdirs();

		String mCameraFilePath = cameraDataDir.getAbsolutePath()

				+ File.separator + System.currentTimeMillis() + ".jpg";

		this.mCameraFilePath = mCameraFilePath;

		cameraIntent.putExtra(MediaStore.Images.Media.ORIENTATION, 0);

		cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT,

				Uri.fromFile(new File(mCameraFilePath)));

		return cameraIntent;

	}

	/*
	 * 
	 * private Intent createCamcorderIntent() { return new
	 * 
	 * Intent(MediaStore.ACTION_VIDEO_CAPTURE); }
	 * 
	 * 
	 * 
	 * private Intent createSoundRecorderIntent() { return new
	 * 
	 * Intent(MediaStore.Audio.Media.RECORD_SOUND_ACTION); }
	 */

	public static Uri getImageContentUri(Context context, java.io.File imageFile) {

		String filePath = imageFile.getAbsolutePath();

		Cursor cursor = context.getContentResolver().query(

				MediaStore.Images.Media.EXTERNAL_CONTENT_URI,

				new String[] { MediaStore.Images.Media._ID },

				MediaStore.Images.Media.DATA + "=? ",

				new String[] { filePath }, null);

		if (cursor != null && cursor.moveToFirst()) {

			int id = cursor.getInt(cursor

					.getColumnIndex(MediaStore.MediaColumns._ID));

			Uri baseUri = Uri.parse("content://media/external/images/media");

			return Uri.withAppendedPath(baseUri, "" + id);

		} else {

			if (imageFile.exists()) {

				ContentValues values = new ContentValues();

				values.put(MediaStore.Images.Media.DATA, filePath);

				return context.getContentResolver().insert(

						MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);

			} else {

				return null;

			}

		}

	}

}


使用时只需要Webview.setWebChromeClient(new MyChromeClient(this));

此时还需要重写加载webview的这个Activity的onActivityResult方法,在这里才是把文件传给web的


	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		switch (requestCode) {
		
		case MyChromeClient.FILECHOOSER_RESULTCODE:
			if (null == mUploadMsg && null == mUploadMsgList) {
				Log.i("webview activity", "UploadMsg =null");
				return;
			}
			Uri result = data == null || resultCode != RESULT_OK ? null : data.getData();
			if (result != null) {
				if (null != mUploadMsg) {
					mUploadMsg.onReceiveValue(result);
				}
				if (null != mUploadMsgList) {
					mUploadMsgList.onReceiveValue(new Uri[] { result });
				}
			} else {
				Log.i("webview activity", "result =null");
				setResultNull();
			}

			break;

		default:
			break;
		}

	}

	private void setResultNull() {
		if (null != mUploadMsg) {
			mUploadMsg.onReceiveValue(null);  
		}
		if (null != mUploadMsgList) {
			mUploadMsgList.onReceiveValue(null);
		}
	}
mUploadMsg.onReceiveValue(null); 和mUploadMsgList.onReceiveValue(null);是必须要有的,比如正在选择图片上传时按返回键,如果不回传null,
web端会一直等待结果,导致你再次点击无响应。


mUploadMsgList是ValueCallback<Uri[]> 的对象,4.1以后的版本都使用的是Uri数组回传,以前是使用Uri即只能传单个文件
 mUploadMsg是ValueCallback<Uri>的对象,这两个变量定义在WebView的activity里面,在 MyChromeClient里面是有相应赋值的。

如此即可。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值