Android7.0之后文件系统禁止向外面公开file://URL路径,必须使用FileProvider通过content://URL
来向外部分享文件
在Android项目的清单列表加入
其中的file_paths需要自己定义
接下来暴露Android方法让js调用
webview.addJavascriptInterface(this, "androidinfo");
拍照的调用
/**
* 拍照
*/
@JavascriptInterface
public void takePhoto() {
File fileUri = new File(Environment.getExternalStorageDirectory().getPath() + "/" + SystemClock.currentThreadTimeMillis() + ".jpg");
imageUri = Uri.fromFile(fileUri);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
imageUri = FileProvider.getUriForFile(MainActivity.this, getPackageName() + ".fileprovider", fileUri);//通过FileProvider创建一个content类型的Uri
}
Intent intentCamera = new Intent();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
intentCamera.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); //添加这一句表示对目标应用临时授权该Uri所代表的文件
}
intentCamera.setAction(MediaStore.ACTION_IMAGE_CAPTURE);
//将拍照结果保存至photo_file的Uri中,不保留在相册中
intentCamera.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
this.startActivityForResult(intentCamera, PHOTO_REQUEST);
}
录像调用
/**
* 录像
*/
@JavascriptInterface
public void recordVideo() {
Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);
//限制时长
intent.putExtra(MediaStore.EXTRA_DURATION_LIMIT, 10);
File fileUri = new File(Environment.getExternalStorageDirectory().getPath() + "/" + SystemClock.currentThreadTimeMillis() + ".mp4");
videoUri = Uri.fromFile(fileUri);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
videoUri = FileProvider.getUriForFile(MainActivity.this, getPackageName() + ".fileprovider", fileUri);//通过FileProvider创建一个content类型的Uri
}
intent.putExtra(MediaStore.EXTRA_OUTPUT, videoUri);
System.out.println(videoUri);
//开启摄像机
startActivityForResult(intent, VIDEO_REQUEST);
}
文件系统调用
//文件选择
@JavascriptInterface
public void intoFileManager() {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("*/*");//无类型限制
// 有类型限制是这样的:
// intent.setType(“image/*”);//选择图片
// intent.setType(“audio/*”); //选择音频
// intent.setType(“video/*”); //选择视频 (mp4 3gp 是android支持的视频格式)
// intent.setType(“video/*;image/*”);//同时选择视频和图片
intent.addCategory(Intent.CATEGORY_OPENABLE);
startActivityForResult(intent, 1);
}
三个调用的后的执行的回调方法是一样的 通过requestCode来判断是照片、视频、文件管理的回调
resultCode为0是失败1是成功 data.getData()打印获取的路径
//执行操作后方法 用requestCode区分结果
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
//拍照
if (requestCode == PHOTO_REQUEST) {
if (resultCode == 0) {
return;
}
System.out.println(imageUri);
ValueCallback stringValueCallback = null;
webview.evaluateJavascript("javascript:addImage('" + imageUri + "')", stringValueCallback);
} else if (requestCode == VIDEO_REQUEST) {
//录像
if (resultCode == 0) {
return;
}
Uri result = data.getData();
ValueCallback stringValueCallback = null;
webview.evaluateJavascript("javascript:addVideo('" + result + "')", stringValueCallback);
} else {
//文件选择
if (data == null) {
return;
}
Uri uri = data.getData();
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT) {//4.4以后
// path = FileChooseUtil.getPath(this, uri);
Log.d("queryfilepath", "返回结果2: " + uri);
}
}
}
java完整代码
import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.SystemClock;
import android.provider.MediaStore;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.webkit.JavascriptInterface;
import android.webkit.ValueCallback;
import android.webkit.WebSettings;
import android.webkit.WebViewClient;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.FileProvider;
import com.github.lzyzsd.jsbridge.BridgeWebView;
import com.github.lzyzsd.jsbridge.DefaultHandler;
import java.io.File;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
private BridgeWebView webview;
private boolean isPermissionRequested;
private final static int PHOTO_REQUEST = 100;
private final static int VIDEO_REQUEST = 120;
private Uri imageUri;
private Uri videoUri;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
webview = findViewById(R.id.webview);
WebSettings settings = webview.getSettings();
webview.setDefaultHandler(new DefaultHandler());
webview.setWebViewClient(new WebViewClient());
settings.setJavaScriptEnabled(true); //设置webview支持javascript
settings.setLoadsImagesAutomatically(true); //支持自动加载图片
settings.setUseWideViewPort(true); //设置webview推荐使用的窗口,使html界面自适应屏幕
settings.setLoadWithOverviewMode(true);
webview.setOnKeyListener(new View.OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_DOWN) {
if (keyCode == KeyEvent.KEYCODE_BACK && webview.canGoBack()) {
//表示按返回键时的操作
webview.goBack();
return true;
}
}
return false;
}
});
webview.addJavascriptInterface(this, "androidinfo");
webview.loadUrl("file:///android_asset/dist/index.html");
requestPermission();
}
/**
* Android6.0之后需要动态申请权限
*/
private void requestPermission() {
if (Build.VERSION.SDK_INT >= 23 && !isPermissionRequested) {
isPermissionRequested = true;
ArrayList permissionsList = new ArrayList<>();
String[] permissions = {
Manifest.permission.ACCESS_NETWORK_STATE,
Manifest.permission.INTERNET,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_WIFI_STATE,
Manifest.permission.CAMERA
};
for (String perm : permissions) {
if (PackageManager.PERMISSION_GRANTED != checkSelfPermission(perm)) {
permissionsList.add(perm);
// 进入到这里代表没有权限.
}
}
if (!permissionsList.isEmpty()) {
String[] strings = new String[permissionsList.size()];
requestPermissions(permissionsList.toArray(strings), 0);
}
}
}
/**
* 拍照
*/
@JavascriptInterface
public void takePhoto() {
File fileUri = new File(Environment.getExternalStorageDirectory().getPath() + "/" + SystemClock.currentThreadTimeMillis() + ".jpg");
imageUri = Uri.fromFile(fileUri);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
imageUri = FileProvider.getUriForFile(MainActivity.this, getPackageName() + ".fileprovider", fileUri);//通过FileProvider创建一个content类型的Uri
}
Intent intentCamera = new Intent();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
intentCamera.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); //添加这一句表示对目标应用临时授权该Uri所代表的文件
}
intentCamera.setAction(MediaStore.ACTION_IMAGE_CAPTURE);
//将拍照结果保存至photo_file的Uri中,不保留在相册中
intentCamera.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
this.startActivityForResult(intentCamera, PHOTO_REQUEST);
}
/**
* 录像
*/
@JavascriptInterface
public void recordVideo() {
Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);
//限制时长
intent.putExtra(MediaStore.EXTRA_DURATION_LIMIT, 10);
File fileUri = new File(Environment.getExternalStorageDirectory().getPath() + "/" + SystemClock.currentThreadTimeMillis() + ".mp4");
videoUri = Uri.fromFile(fileUri);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
videoUri = FileProvider.getUriForFile(MainActivity.this, getPackageName() + ".fileprovider", fileUri);//通过FileProvider创建一个content类型的Uri
}
intent.putExtra(MediaStore.EXTRA_OUTPUT, videoUri);
System.out.println(videoUri);
//开启摄像机
startActivityForResult(intent, VIDEO_REQUEST);
}
//执行操作后方法 用requestCode区分结果
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
System.out.println(requestCode);
if (requestCode == PHOTO_REQUEST) {
if (resultCode == 0) {
return;
}
System.out.println(imageUri);
ValueCallback stringValueCallback = null;
webview.evaluateJavascript("javascript:addImage('" + imageUri + "')", stringValueCallback);
} else if (requestCode == VIDEO_REQUEST) {
if (resultCode == 0) {
return;
}
Uri result = data.getData();
ValueCallback stringValueCallback = null;
webview.evaluateJavascript("javascript:addVideo('" + result + "')", stringValueCallback);
} else {
if (data == null) {
return;
}
Uri uri = data.getData();
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT) {//4.4以后
// path = FileChooseUtil.getPath(this, uri);
Log.d("queryfilepath", "返回结果2: " + uri);
}
}
}
//文件选择
@JavascriptInterface
public void intoFileManager() {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("*/*");//无类型限制
// 有类型限制是这样的:
// intent.setType(“image/*”);//选择图片
// intent.setType(“audio/*”); //选择音频
// intent.setType(“video/*”); //选择视频 (mp4 3gp 是android支持的视频格式)
// intent.setType(“video/*;image/*”);//同时选择视频和图片
intent.addCategory(Intent.CATEGORY_OPENABLE);
startActivityForResult(intent, 1);
}
@Override
protected void onDestroy() {
super.onDestroy();
if (webview != null) {
webview.setWebViewClient(null);
webview.setWebChromeClient(null);
webview.loadDataWithBaseURL(null, "", "text/html", "utf-8", null);
webview.clearHistory();
// ((ViewGroup) webView.getParent()).removeView(webView);
webview.destroy();
webview = null;
}
}
}
Vue代码
拍照页面
拍照
返回
录像页面
摄像
返回
文件管理
点击上传
视频效果
文件管理系统