应用场景:h5通知android端拍照,选相册,然后将图片路径上传成功之后,获取到网络路径,将此路径返还给h5界面,并展示出来。 
android与js快速交互 
效果图如下: 
 

1.在Activity类中,通过webview拦截协议,开始拍照或选择相册。

    mWebView = (WebView) findViewById(R.id.wv);
//设置webview可以与js交互
mWebView.getSettings().setJavaScriptEnabled(true);
//设置webview加载本地h5页面
mWebView.loadUrl(“file:///android_asset/choosePic.html”);
//设置监听,获取webview访问的url
mWebView.setWebViewClient(new WebViewClient() {
public boolean shouldOverrideUrlLoading(WebView view, String url) {
// 重写此方法表明点击网页里面的链接还是在当前的webview里跳转,不跳到浏览器那边
if(url.contains(“hgj://take/photo”)){
//js定义的协议,android用webview进行拦截 然后本地调用拍照等功能
showPopupWindow((LinearLayout) findViewById(R.id.act_index));
}else {
view.loadUrl(url);
}
return true;
}
@Override
public void onPageFinished(WebView view, String url) { }
});

2. 注册js接口,JSInterface是自定义的类,里面放的方法必须与js中的方法一致,参数二也是与js协定的,必须与js保持一致。

  mWebView.addJavascriptInterface(new JSInterface(), "hgj");
//js接口类
private class JSInterface { @JavascriptInterface
public void acceptUrl(String imgUrl) {//此方法是将android端获取的url返给js }
@JavascriptInterface
public void fnUrl(String s) {
//js可以调用此方法 将s值传给android端,然后android端进行相应的操作,此参数可以是任意类型的
}
@JavascriptInterface
public void fnId(String received){
//android 调用js js会回传参数
Log.i("received--","---"+received);
} }

3.拍照、上传图片相关方法

  //确认上传图片
private void upload(String path) throws FileNotFoundException {
//此处可以写入上传图片的方法 这里就直接将拍照和选择相册得到的本地路径返回
url=path;
Message msg = new Message();
msg.what = 0;
mHandler1.sendMessage(msg);
}
/*
* 相册或相机
* */
private void showPopupWindow(LinearLayout parent) {
if (popWindow == null) {
View view = LayoutInflater.from(context).inflate(R.layout.pop_select_photo, null);
// 相机/相册/取消选择界面
popWindow = new PopupWindow(view, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT, true);
initPop(view);// 初始化popwindow参数
}
popWindow.setAnimationStyle(android.R.style.Animation_InputMethod);
popWindow.setFocusable(true);
popWindow.setOutsideTouchable(true);
popWindow.setBackgroundDrawable(new BitmapDrawable());
popWindow.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
popWindow.showAtLocation(parent, Gravity.CENTER, 0, 0);
} // 初始化popwindow参数
public void initPop(View view) {
photograph = (TextView) view.findViewById(R.id.photograph);// 拍照
albums = (TextView) view.findViewById(R.id.albums);// 相册
cancel = (LinearLayout) view.findViewById(R.id.cancel);// 取消
// 相机拍照监听
photograph.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
popWindow.dismiss();
photoSaveName = String.valueOf(System.currentTimeMillis()) + ".png";
photoSavePath = Environment.getExternalStorageDirectory() + "/usershg/cache/";
Uri imageUri = null;
Intent openCameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
imageUri = Uri.fromFile(new File(photoSavePath, photoSaveName));
openCameraIntent.putExtra(MediaStore.Images.Media.ORIENTATION, 0);
openCameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
startActivityForResult(openCameraIntent, PHOTOTAKE);
}
});
// 相册获取监听
albums.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
popWindow.dismiss();
Intent openAlbumIntent = new Intent(Intent.ACTION_GET_CONTENT);
openAlbumIntent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
startActivityForResult(openAlbumIntent, PHOTOZOOM);
}
});
// 取消监听
cancel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
popWindow.dismiss(); }
});
} @SuppressLint("NewApi")
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode != RESULT_OK) {
return;
}
Uri uri = null;
switch (requestCode) {
case PHOTOZOOM:// 相册
if (data == null) {
return;
}
uri = data.getData();
path = getImageAbsolutePath(this, uri);
//获取到图片路径,开始上传
try {
upload(path);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
break;
case PHOTOTAKE:// 拍照
path = photoSavePath + photoSaveName;
//获取到图片路径,开始上传
try {
upload(path);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
break;
default:
break;
}
} /**
* 根据Uri获取图片绝对路径,解决Android4.4以上版本Uri转换
*
* @param
* @param imageUri
* @author yaoxing
* @date 2014-10-12
*/
@TargetApi(19)
public static String getImageAbsolutePath(Activity context, Uri imageUri) {
if (context == null || imageUri == null)
return null;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT && DocumentsContract.isDocumentUri(context, imageUri)) {
if (isExternalStorageDocument(imageUri)) {
String docId = DocumentsContract.getDocumentId(imageUri);
String[] split = docId.split(":");
String type = split[0];
if ("primary".equalsIgnoreCase(type)) {
return Environment.getExternalStorageDirectory() + "/" + split[1];
}
} else if (isDownloadsDocument(imageUri)) {
String id = DocumentsContract.getDocumentId(imageUri);
Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
return getDataColumn(context, contentUri, null, null);
} else if (isMediaDocument(imageUri)) {
String docId = DocumentsContract.getDocumentId(imageUri);
String[] split = docId.split(":");
String type = split[0];
Uri contentUri = null;
if ("image".equals(type)) {
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
} else if ("video".equals(type)) {
contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
} else if ("audio".equals(type)) {
contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
}
String selection = MediaStore.Images.Media._ID + "=?";
String[] selectionArgs = new String[]{split[1]};
return getDataColumn(context, contentUri, selection, selectionArgs);
}
} // MediaStore (and general)
else if ("content".equalsIgnoreCase(imageUri.getScheme())) {
// Return the remote address
if (isGooglePhotosUri(imageUri))
return imageUri.getLastPathSegment();
return getDataColumn(context, imageUri, null, null);
}
// File
else if ("file".equalsIgnoreCase(imageUri.getScheme())) {
return imageUri.getPath();
}
return null;
} public static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) {
Cursor cursor = null;
String column = MediaStore.Images.Media.DATA;
String[] projection = {column};
try {
cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null);
if (cursor != null && cursor.moveToFirst()) {
int index = cursor.getColumnIndexOrThrow(column);
return cursor.getString(index);
}
} finally {
if (cursor != null)
cursor.close();
}
return null;
} /**
* @param uri The Uri to check.
* @return Whether the Uri authority is ExternalStorageProvider.
*/
public static boolean isExternalStorageDocument(Uri uri) {
return "com.android.externalstorage.documents".equals(uri.getAuthority());
} /**
* @param uri The Uri to check.
* @return Whether the Uri authority is DownloadsProvider.
*/
public static boolean isDownloadsDocument(Uri uri) {
return "com.android.providers.downloads.documents".equals(uri.getAuthority());
} /**
* @param uri The Uri to check.
* @return Whether the Uri authority is MediaProvider.
*/
public static boolean isMediaDocument(Uri uri) {
return "com.android.providers.media.documents".equals(uri.getAuthority());
} /**
* @param uri The Uri to check.
* @return Whether the Uri authority is Google Photos.
*/
public static boolean isGooglePhotosUri(Uri uri) {
return "com.google.android.apps.photos.content".equals(uri.getAuthority());
}

4.拍照成功获取url后传给js

 //此处将拍照或选择相册返回的url传给js
mWebView.loadUrl("javascript:acceptUrl('" + url + "')");

5. js给android传数据

js只需要调用window.hgj.fnId(received);就可以了。
hgj:是我们之前android和js定的,如mWebView.addJavascriptInterface(new JSInterface(), "hgj");中的最后一个参数
fnId()是方法名,js把参数传进去,我们android端只要写好这个方法,直接loadUrl获取参数就可以了,如wv.loadUrl("javascript:fnId()");

h5页面: 

源码位置:https://download.csdn.net/download/feitailang/10839514
源码项目截图: 

Android与js交互拍照上传资料的更多相关文章

  1. Android与JS交互,json传参问题

    一.JS调用Android的方法 JS调用安卓的方法,并且传递的参数为json格式的字符串(JSONObject.toString()), 例如: var json = {"name&quo ...

  2. Android—android与js交互以及相互传参

    Android中可以通过WebView来实现与js的交互,让用户可以在android客户端看到js写的页面,接下来为大家介绍的就是怎样实现此功能: 首先android项目目录下有“assets”文件夹 ...

  3. Android仿微信图片上传,可以选择多张图片,缩放预览,拍照上传等

    仿照微信,朋友圈分享图片功能 .可以进行图片的多张选择,拍照添加图片,以及进行图片的预览,预览时可以进行缩放,并且可以删除选中状态的图片 .很不错的源码,大家有需要可以下载看看 . 微信 微信 微信 ...

  4. android 拍照上传文件 原生定位

    最近公司需要一个android拍照上传和定位功能的的单一功能页面,一开始选择ionic cordova angular的一套H5框架,但是遇到和上传文件报错的问题,bug找了一天没找到原因,怀疑是io ...

  5. html5调用手机摄像头,实现拍照上传功能

    今天做手机网站,想实现手机扫描二维码功能.首先实现在浏览器中调用手机摄像头,实现拍照功能并且把拍下的照片显示在页面并上传到服务器上,然后再在服务器端进行分析. 首先实现在浏览器中调用摄像头,当然用现在 ...

  6. 【Demo】HTML5 拍照上传

    本文主要讲解 手机浏览器 如何拍照 为什么会有这个需求 最近做一个项目要用到拍照然后上传照片,但是网页拍照一般都是用Flash做的,而我们主要是H5页面,如果在微信里面有权限就可以通过JSSDK调起摄 ...

  7. webAPP如何实现移动端拍照上传(Vue组件示例)?

    摘要:使用HTML5编写移动Web应用,主要是为了尝试一下“一套代码多处运行”,一个webapp几乎可以不加修改的运行在PC/Android/iOS等上面运行.但是写到现在觉得虽然这种方式弊大于利,不 ...

  8. Android4.4 + WebAPI 实现拍照上传

    网上有很多关于拍照上传的实现方法,如果用新版本android去运行有可能会发现根本实现不了.主要原因是android从4.4版本开始通过intent.ACTION_GET_CONTENT打开选择器后, ...

  9. Android基础_一次上传多张图片

    获取权限 <uses-permission android:name="android.permission.CAMERA"/> <uses-permission ...

随机推荐

  1. Book Contents Reviews Notes Errata Articles Talks Downloads Resources Code Formatter Cover of C# in Depth Order now (3rd edition) Implementing the Singleton Pattern in C#

    原文链接地址: http://csharpindepth.com/Articles/General/Singleton.aspx#unsafe Implementing the Singleton P ...

  2. vscode 自动提示Threejs

    转自:https://blog.csdn.net/github_39125824/article/details/82633993 1.首先,你要安装Node.js 2.在vscode的 查看-> ...

  3. 使用whiptail写linux字符界面ssh链接工具2.0

    先看一下效果 选择分组 选择服务器 开始链接 为什么写 之前写过一个字符界面的链接工具,但是看起来比较简陋,他是这个样子的: 看起来十分不好看.后来在网上看到shell中有一个whiptail工具可以 ...

  4. numpy练习题

    1. 导入numpy库并简写为 np import numpy as np 2. 打印numpy的版本和配置说明 print(np.__version__) print(np.show_config( ...

  5. 撩课-Web大前端每天5道面试题-Day1

    1. var的变量提升的底层原理是什么? JS引擎的工作方式是: 1) 先解析代码,获取所有被声明的变量: 2)然后在运行.也就是说分为预处理和执行两个阶段. 变量提升:所有变量的声明语句都会被提升到 ...

  6. 排序算法(10)--Distribution Sorting--分布排序[2]--Radix Sort--基数排序

    1.基本思想 基数排序是通过“分配”和“收集”过程来实现排序 2.实现原理 基数排序(以整形为例),将整形10进制按每位拆分,然后从低位到高位依次比较各个位.主要分为两个过程: (1)分配,先从个位开 ...

  7. 设计模式(17)--Mediator(中介者模式)行为型

    作者QQ:1095737364    QQ群:123300273     欢迎加入! 1.模式定义: 用一个中介者对象封装一系列的对象交互,中介者使各对象不需要显示地相互作用,从而使耦合松散,而且可以 ...

  8. java中return、break、continue的区别

    1.return @Testpublic void testReturn(){ for (int j = 1; j < 3; j++) { for (int i = 1; i < 5; i ...

  9. idea中连接oracle数据库打包

    问题:在使用idea连接oracle数据时发现oracle.jdbc.OracleDriver引用这个包报错,找不到包.解决方法:在idea的terminal命令框中输入如下命令.我的jar包的位置在 ...

  10. css BFC布局及用处

    http://www.cnblogs.com/lhb25/p/inside-block-formatting-ontext.html 这篇文章讲的很简单很实用