| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508 |
- package com.qingdaofushan.home.weiview;
- import android.Manifest;
- import android.annotation.TargetApi;
- import android.app.Activity;
- import android.content.ClipData;
- import android.content.ContentValues;
- import android.content.Intent;
- import android.content.pm.PackageManager;
- import android.content.pm.ResolveInfo;
- import android.graphics.Bitmap;
- import android.icu.text.SimpleDateFormat;
- import android.net.Uri;
- import android.os.Build;
- import android.os.Bundle;
- import android.os.Environment;
- import android.provider.MediaStore;
- import android.util.Base64;
- import android.util.Log;
- import android.view.KeyEvent;
- import android.webkit.ValueCallback;
- import android.webkit.WebSettings;
- import android.webkit.WebView;
- import android.widget.LinearLayout;
- import android.widget.Toast;
- import androidx.annotation.NonNull;
- import androidx.annotation.Nullable;
- import androidx.appcompat.app.AppCompatActivity;
- import androidx.core.app.ActivityCompat;
- import androidx.core.content.ContextCompat;
- import androidx.core.content.FileProvider;
- import androidx.core.os.EnvironmentCompat;
- import com.just.agentweb.AgentWeb;
- import com.just.agentweb.PermissionInterceptor;
- import com.just.agentweb.WebChromeClient;
- import com.just.agentweb.WebViewClient;
- //import com.king.zxing.CameraScan;
- import com.qingdaofushan.home.activity.CamActivity;
- import com.qingdaofushan.home.event.EventData;
- import com.qingdaofushan.home.R;
- import com.qingdaofushan.home.utils.ToastUtil;
- import com.qingdaofushan.home.utils.Uri2PathUtil;
- import com.qingdaofushan.home.zxing.view.Constant;
- import org.greenrobot.eventbus.EventBus;
- import org.greenrobot.eventbus.Subscribe;
- import org.greenrobot.eventbus.ThreadMode;
- import java.io.File;
- import java.io.FileInputStream;
- import java.io.FileNotFoundException;
- import java.io.IOException;
- import java.io.InputStream;
- import java.util.Date;
- import java.util.List;
- import java.util.Locale;
- /**
- * @Author pwxmax
- * @Date 2020.6.11
- * @Discription 对接H5通用的 Activity
- */
- public class WebViewActivity extends AppCompatActivity {
- LinearLayout linearLayout;
- protected AgentWeb mAgentWeb;
- private String url;
- private int REQUEST_CODE = 200;
- // 拍照的requestCode
- private static final int CAMERA_REQUEST_CODE = 0x00000010;
- // 申请相机权限的requestCode
- private static final int PERMISSION_CAMERA_REQUEST_CODE = 0x00000012;
- /**
- * 用于保存拍照图片的uri
- */
- private Uri mCameraUri;
- /**
- * 用于保存图片的文件路径,Android 10以下使用图片路径访问图片
- */
- private String mCameraImagePath;
- /**
- * 是否是Android 10以上手机
- */
- private boolean isAndroidQ = Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q;
- private ValueCallback<Uri> uploadMessage;
- private ValueCallback<Uri[]> uploadMessageAboveL;
- private final static int FILE_CHOOSER_RESULT_CODE = 10000;
- @Override
- protected void onCreate(@Nullable Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_web);
- EventBus.getDefault().register(this);
- initView();
- }
- private void initView() {
- url = getIntent().getStringExtra("url");
- // url="http://192.168.1.11:8080";
- linearLayout = findViewById(R.id.ll_webview);
- AndroidWebView.assistActivity(this);
- mAgentWeb = AgentWeb.with(this)
- .setAgentWebParent(linearLayout, new LinearLayout.LayoutParams(-1, -1))
- .closeIndicator()
- .setWebChromeClient(mWebChromeClient)
- .setWebViewClient(mWebViewClient)
- // .setPermissionInterceptor(mPermissionInterceptor)
- .createAgentWeb()
- .go(url);
- if (mAgentWeb != null) {
- mAgentWeb.getJsInterfaceHolder().addJavaObject("android", new AndroidInterface(mAgentWeb, this));
- //注入对象
- WebSettings webSettings = mAgentWeb.getAgentWebSettings().getWebSettings();
- webSettings.setUseWideViewPort(true);//关键点
- webSettings.setDomStorageEnabled(true);
- webSettings.setDefaultTextEncodingName("UTF-8");
- webSettings.setAllowContentAccess(true); // 是否可访问Content Provider的资源,默认值 true
- webSettings.setLoadWithOverviewMode(true);
- webSettings.setCacheMode(WebSettings.LOAD_DEFAULT);
- webSettings.setBuiltInZoomControls(false); // 设置显示缩放按钮
- // webSettings.setAppCacheEnabled(true);//是否使用缓存
- webSettings.setSupportZoom(false); // 支持缩放
- webSettings.setAllowFileAccess(true); //允许加载本地文件html file协议, 这可能会造成不安全 , 建议重写关闭
- webSettings.setAllowFileAccessFromFileURLs(true); //通过 file url 加载的 Javascript 读取其他的本地文件 .建议关闭
- webSettings.setAllowUniversalAccessFromFileURLs(true);//允许通过 file url 加载的 Javascript 可以访问其他的源,包括其他的文件和 http,https 等其他的源
- mAgentWeb.getWebCreator().getWebView().setOverScrollMode(WebView.OVER_SCROLL_NEVER);
- }
- }
- protected PermissionInterceptor mPermissionInterceptor = new PermissionInterceptor() {
- /**
- * PermissionInterceptor 能达到 url1 允许授权, url2 拒绝授权的效果。
- * @param url
- * @param permissions
- * @param action
- * @return true 该Url对应页面请求权限进行拦截 ,false 表示不拦截。
- */
- @Override
- public boolean intercept(String url, String[] permissions, String action) {
- //Log.i(TAG, "mUrl:" + url + " permission:" + mGson.toJson(permissions) + " action:" + action);
- return false;
- }
- };
- private WebViewClient mWebViewClient = new WebViewClient() {
- @Override
- public void onPageStarted(WebView view, String url, Bitmap favicon) {
- //do you work
- }
- };
- private WebChromeClient mWebChromeClient = new WebChromeClient() {
- @Override
- public void onProgressChanged(WebView view, int newProgress) {
- //do you work
- }
- // For Android < 3.0
- public void openFileChooser(ValueCallback<Uri> valueCallback) {
- uploadMessage = valueCallback;
- openImageChooserActivity();
- }
- // For Android >= 3.0
- public void openFileChooser(ValueCallback valueCallback, String acceptType) {
- uploadMessage = valueCallback;
- openImageChooserActivity();
- }
- //For Android >= 4.1
- public void openFileChooser(ValueCallback<Uri> valueCallback, String acceptType, String capture) {
- uploadMessage = valueCallback;
- openImageChooserActivity();
- }
- // For Android >= 5.0
- @Override
- public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, WebChromeClient.FileChooserParams fileChooserParams) {
- uploadMessageAboveL = filePathCallback;
- openImageChooserActivity();
- return true;
- }
- };
- // 2.回调方法触发本地选择文件
- private void openImageChooserActivity() {
- // checkPermissionAndCamera();
- Intent i = new Intent(Intent.ACTION_GET_CONTENT);
- i.addCategory(Intent.CATEGORY_OPENABLE);
- i.setType("image/*");//图片上传
- // i.setType("file/*");//文件上传
- // i.setType("*/*");//文件上传
- startActivityForResult(Intent.createChooser(i, "File Chooser"), FILE_CHOOSER_RESULT_CODE);
- }
- @Override
- public boolean onKeyDown(int keyCode, KeyEvent event) {
- if (mAgentWeb.handleKeyEvent(keyCode, event)) {
- return true;
- }
- if (keyCode == KeyEvent.KEYCODE_BACK) {
- }
- return super.onKeyDown(keyCode, event);
- }
- @Override
- protected void onPause() {
- mAgentWeb.getWebLifeCycle().onPause();
- super.onPause();
- }
- // @Override
- // protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
- // super.onActivityResult(requestCode, resultCode, data);
- // /**
- // * 处理二维码扫描结果
- // */
- // if (resultCode == RESULT_OK) {
- // switch (requestCode) {
- // case 200:
- // Bundle bundle = data.getExtras();
- // String scanResult = bundle.getString(Constant.INTENT_EXTRA_KEY_QR_SCAN);
- //// String result = CameraScan.parseScanResult(data);
- // mAgentWeb.getJsAccessEntrace().quickCallJs("QRCode", scanResult);
- // break;
- // case CAMERA_REQUEST_CODE:
- // if (uploadMessageAboveL != null) {
- // Uri[] results = new Uri[]{mCameraUri};
- // uploadMessageAboveL.onReceiveValue(results);
- // uploadMessageAboveL = null;
- //// onActivityResultAboveL(requestCode, resultCode, data);
- // } else if (uploadMessage != null) {
- // uploadMessage.onReceiveValue(mCameraUri);
- // uploadMessage = null;
- // }
- //// String uploadpath = Uri2PathUtil.getRealPathFromUri(this, mCameraUri);
- //// mAgentWeb.getJsAccessEntrace().quickCallJs("Camera", uploadpath);
- // break;
- // }
- // } else {
- // //这里uploadMessage跟uploadMessageAboveL在不同系统版本下分别持有了
- // //WebView对象,在用户取消文件选择器的情况下,需给onReceiveValue传null返回值
- // //否则WebView在未收到返回值的情况下,无法进行任何操作,文件选择器会失效
- // if (uploadMessage != null) {
- // uploadMessage.onReceiveValue(null);
- // uploadMessage = null;
- // } else if (uploadMessageAboveL != null) {
- // uploadMessageAboveL.onReceiveValue(null);
- // uploadMessageAboveL = null;
- // }
- // }
- // }
- //
- // // 3.选择图片后处理
- @Override
- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- super.onActivityResult(requestCode, resultCode, data);
- if (requestCode == FILE_CHOOSER_RESULT_CODE) {
- if (null == uploadMessage && null == uploadMessageAboveL) return;
- Uri result = data == null || resultCode != RESULT_OK ? null : data.getData();
- // Uri result = (((data == null) || (resultCode != RESULT_OK)) ? null : data.getData());
- if (uploadMessageAboveL != null) {
- onActivityResultAboveL(requestCode, resultCode, data);
- } else if (uploadMessage != null) {
- uploadMessage.onReceiveValue(result);
- uploadMessage = null;
- }
- } else {
- //这里uploadMessage跟uploadMessageAboveL在不同系统版本下分别持有了
- //WebView对象,在用户取消文件选择器的情况下,需给onReceiveValue传null返回值
- //否则WebView在未收到返回值的情况下,无法进行任何操作,文件选择器会失效
- if (uploadMessage != null) {
- uploadMessage.onReceiveValue(null);
- uploadMessage = null;
- } else if (uploadMessageAboveL != null) {
- uploadMessageAboveL.onReceiveValue(null);
- uploadMessageAboveL = null;
- }
- }
- }
- // 4. 选择内容回调到Html页面
- @TargetApi(Build.VERSION_CODES.LOLLIPOP)
- private void onActivityResultAboveL(int requestCode, int resultCode, Intent intent) {
- if (requestCode != FILE_CHOOSER_RESULT_CODE || uploadMessageAboveL == null)
- return;
- Uri[] results = null;
- if (resultCode == Activity.RESULT_OK) {
- if (intent != null) {
- String dataString = intent.getDataString();
- ClipData clipData = intent.getClipData();
- if (clipData != null) {
- results = new Uri[clipData.getItemCount()];
- for (int i = 0; i < clipData.getItemCount(); i++) {
- ClipData.Item item = clipData.getItemAt(i);
- results[i] = item.getUri();
- }
- }
- if (dataString != null)
- results = new Uri[]{Uri.parse(dataString)};
- }
- }
- uploadMessageAboveL.onReceiveValue(results);
- uploadMessageAboveL = null;
- }
- @Subscribe(threadMode = ThreadMode.MAIN)
- public void stopServiceEvent(EventData eventData) {
- if (eventData.getCode() == 1) {
- mAgentWeb.getJsAccessEntrace().quickCallJs("StartService", "1");
- } else if (eventData.getCode() == 2) {
- mAgentWeb.getJsAccessEntrace().quickCallJs("StartService", "2");
- } else if (eventData.getCode() == 3) {
- checkPermissionAndCamera();
- }
- }
- /**
- * 检查权限并拍照。
- * 调用相机前先检查权限。
- */
- private void checkPermissionAndCamera() {
- int hasCameraPermission = ContextCompat.checkSelfPermission(getApplication(),
- Manifest.permission.CAMERA);
- if (hasCameraPermission == PackageManager.PERMISSION_GRANTED) {
- //有权限,调起相机拍照。
- openCamera();
- } else {
- //没有权限,申请权限。
- ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA},
- PERMISSION_CAMERA_REQUEST_CODE);
- ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
- PERMISSION_CAMERA_REQUEST_CODE);
- }
- }
- /**
- * 处理权限申请的回调。
- *
- * @param requestCode
- * @param permissions
- * @param grantResults
- */
- @Override
- public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
- if (requestCode == PERMISSION_CAMERA_REQUEST_CODE) {
- if (grantResults.length > 0
- && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
- //允许权限,有调起相机拍照。
- openCamera();
- } else {
- //拒绝权限,弹出提示框。
- Toast.makeText(this, "拍照权限被拒绝", Toast.LENGTH_LONG).show();
- }
- }
- }
- /**
- * 调起相机拍照
- */
- private void openCamera() {
- Intent captureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
- // 判断是否有相机
- if (captureIntent.resolveActivity(getPackageManager()) != null) {
- File photoFile = null;
- Uri photoUri = null;
- if (isAndroidQ) {
- // 适配android 10
- photoUri = createImageUri();
- } else {
- try {
- photoFile = createImageFile();
- } catch (IOException e) {
- e.printStackTrace();
- }
- if (photoFile != null) {
- mCameraImagePath = photoFile.getAbsolutePath();
- System.out.println("path = " + mCameraImagePath);
- photoUri = FileProvider.getUriForFile(WebViewActivity.this,
- "com.qingdaofushan.home.fileprovider", photoFile);
- }
- }
- System.out.println("photoUri = " + photoUri);
- mCameraUri = photoUri;
- if (photoUri != null) {
- if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
- List<ResolveInfo> resInfoList = getPackageManager()
- .queryIntentActivities(captureIntent, PackageManager.MATCH_DEFAULT_ONLY);
- for (ResolveInfo resolveInfo : resInfoList) {
- String packageName = resolveInfo.activityInfo.packageName;
- grantUriPermission(packageName, photoUri,
- Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
- }
- }
- captureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri);
- captureIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
- startActivityForResult(captureIntent, CAMERA_REQUEST_CODE);
- }
- }
- }
- /**
- * 创建图片地址uri,用于保存拍照后的照片 Android 10以后使用这种方法
- *
- * @return 图片的uri
- */
- private Uri createImageUri() {
- //设置保存参数到ContentValues中
- ContentValues contentValues = new ContentValues();
- //设置文件名
- contentValues.put(MediaStore.Images.Media.DISPLAY_NAME, System.currentTimeMillis() + "");
- //兼容Android Q和以下版本
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
- //android Q中不再使用DATA字段,而用RELATIVE_PATH代替
- //TODO RELATIVE_PATH是相对路径不是绝对路径;照片存储的地方为:内部存储/Pictures/preventpro
- contentValues.put(MediaStore.Images.Media.RELATIVE_PATH, "Pictures/preventpro");
- }
- //设置文件类型
- contentValues.put(MediaStore.Images.Media.MIME_TYPE, "image/JPEG");
- //执行insert操作,向系统文件夹中添加文件
- //EXTERNAL_CONTENT_URI代表外部存储器,该值不变
- Uri uri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues);
- return uri;
- }
- /**
- * 创建保存图片的文件
- *
- * @return
- * @throws IOException
- */
- private File createImageFile() throws IOException {
- String imageName = new SimpleDateFormat("yyyyMMdd_HHmmss",
- Locale.getDefault()).format(new Date()) + ".jpg";
- // File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
- // File storageDir = Environment.getExternalStoragePublicDirectory(
- // Environment.DIRECTORY_PICTURES);
- File storageDir = new File(Environment.getExternalStorageDirectory().getAbsolutePath()
- + File.separator + "Pictures" + File.separator + "abc");
- if (!storageDir.exists()) storageDir.mkdirs();
- File tempFile = new File(storageDir, imageName);
- if (!Environment.MEDIA_MOUNTED.equals(EnvironmentCompat.getStorageState(tempFile))) {
- return null;
- }
- return tempFile;
- }
- /**
- * 文件转base64字符串
- *
- * @param file
- * @return
- */
- public String fileToBase64(File file) {
- String base64 = null;
- InputStream in = null;
- try {
- in = new FileInputStream(file);
- byte[] bytes = new byte[in.available()];
- int length = in.read(bytes);
- base64 = Base64.encodeToString(bytes, 0, length, Base64.DEFAULT);
- } catch (FileNotFoundException e) {
- // TODO Auto-generated catch block
- ToastUtil.showToast("文件读取异常");
- } catch (IOException e) {
- // TODO Auto-generated catch block
- ToastUtil.showToast("IO读取异常");
- } finally {
- try {
- if (in != null) {
- in.close();
- }
- } catch (IOException e) {
- // TODO Auto-generated catch block
- ToastUtil.showToast("IO关闭异常");
- }
- }
- return base64;
- }
- @Override
- protected void onResume() {
- mAgentWeb.getWebLifeCycle().onResume();
- super.onResume();
- }
- @Override
- public void onDestroy() {
- super.onDestroy();
- mAgentWeb.getWebLifeCycle().onDestroy();
- EventBus.getDefault().unregister(this);
- }
- }
|