日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

关于android webview使用过程中遇到的一些问题总结

發(fā)布時間:2024/1/18 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 关于android webview使用过程中遇到的一些问题总结 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

?

開發(fā)WebView的時候遇到了各種問題,在此總結(jié)一下。

一、webview的使用方法

1.1、layout中添加WebView的視圖。

<WebViewandroid:id="@+id/content"android:layout_width="match_parent"android:layout_height="0dp"android:layout_weight="1"/>


1.2 java代碼

private WebView webview;private String url = ""; @JavascriptInterfaceprivate void initWebView(){webview.getSettings().setJavaScriptEnabled(true);webview.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);webview.getSettings().setDomStorageEnabled(false);webview.getSettings().setCacheMode(WebSettings.LOAD_DEFAULT);webview.getSettings().setPluginState(WebSettings.PluginState.ON);webview.getSettings().setAllowFileAccess(true);webview.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);webview.getSettings().setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NORMAL);webview.setLayerType(View.LAYER_TYPE_SOFTWARE, null);webview.getSettings().setUseWideViewPort(true);webview.getSettings().setLoadWithOverviewMode(true);webview.getSettings().setAllowContentAccess(true);webview.requestFocus();} public void initData() {webview = (WebView) findViewById(R.id.content);initWebView();webview.loadUrl(url);} @Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initData();}

二、下面是使用過程中遇到的一些問題

2.1、橫豎屏切換時,簡單解決webview重新載入問題

<activity android:name=".MainActivity" android:configChanges="keyboardHidden|orientation|screenSize">

2.2 、Java調(diào)用js

2.2.1Java調(diào)用js

webview.getSettings().setJavaScriptEnabled(true); webview.setWebChromeClient(new WebChromeClient());webview.setWebViewClient(new WebViewClient() {@Overridepublic void onPageFinished(WebView view, String url) {super.onPageFinished(view, url);updatePosition();}}); @JavascriptInterfacepublic void updatePosition() {String msg="";String control = "javascript:updatePosition(\""+msg+"\")";webview.loadUrl(control);}

2.2.2 js調(diào)用Java

示例:要實現(xiàn)類似這樣的js語句 onclick="javascript:android.user('1')" // 添加js調(diào)用接口webview.addJavascriptInterface(this, "android"); @JavascriptInterface public void user(String id) { //跳轉(zhuǎn)activityIntent intent = new Intent(this, UserDetailActivity.class);intent.putExtra("id", id);startActivity(intent);}

?

2.3 、android webview點擊返回鍵返回上一個html

@Overridepublic boolean onKeyDown(int keyCode, KeyEvent event) {if ((keyCode == KeyEvent.KEYCODE_BACK) && webview.canGoBack()) {webview.goBack();return true;}return super.onKeyDown(keyCode, event);}

2.4、H5頁面定位手機問題

一、獲取權(quán)限

android 6.0 以后,需要動態(tài)的獲取位置或者存儲權(quán)限,按照各自的愛好放置位置。我是應(yīng)用開啟初始化的時候,放在MainActivity中的OnCreate方法里

if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION)!= PackageManager.PERMISSION_GRANTED|| ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)!= PackageManager.PERMISSION_GRANTED|| ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED) {Toast.makeText(getApplicationContext(),"沒有權(quán)限,請手動開啟定位權(quán)限",Toast.LENGTH_SHORT).show();// 申請一個(或多個)權(quán)限,并提供用于回調(diào)返回的獲取碼(用戶定義)ActivityCompat.requestPermissions(MainActivity.this,new String[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.WRITE_EXTERNAL_STORAGE}, 100);return false;}

二、webview setting 設(shè)置

//webview支持js腳本webview.getSettings().setJavaScriptEnabled(true);//啟用數(shù)據(jù)庫webview.getSettings().setDatabaseEnabled(true);//設(shè)置定位的數(shù)據(jù)庫路徑String dir = this.getApplicationContext().getDir("database", Context.MODE_PRIVATE).getPath();webview.getSettings().setGeolocationDatabasePath(dir);//啟用地理定位webview.getSettings().setGeolocationEnabled(true);//開啟DomStorage緩存webview.getSettings().setDomStorageEnabled(true); /*** 內(nèi)部類*///配置權(quán)限 webView.setWebChromeClient(new WebChromeClient() { @Overridepublic void onReceivedIcon(WebView view, Bitmap icon) { super.onReceivedIcon(view, icon); } @Override public void onGeolocationPermissionsShowPrompt(String origin,Callback callback) { callback.invoke(origin, true, false); super.onGeolocationPermissionsShowPrompt(origin, callback); } });

?

三 、網(wǎng)絡(luò)權(quán)限

<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" /> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />

app的build.gradle 里面一個targetSdkVersion 23 (為什么寫23 高德地圖告訴我的)

然后你的工程地圖能用了。

?

2.5、H5調(diào)用系統(tǒng)文件或圖庫并上傳

?我們在使用WebView這個控件的時候,經(jīng)常需要去寫一些方法供H5頁面調(diào)用,我在開發(fā)的過程中遇到這樣一個需求,通過點擊H5頁面上的按鈕調(diào)用Android手機的圖庫,并且進行上傳圖片。

???通過網(wǎng)上查找資料,找到了WebChromeClient的一個隱藏方法openFileChooser();

/*** 內(nèi)部類*/class MyWebChromeClient extends WebChromeClient {// For Android 3.0+public void openFileChooser(ValueCallback<Uri> uploadMsg,String acceptType) {if (mUploadMessage != null)return;mUploadMessage = uploadMsg;selectImage(RESULT_CODE_PICK_FROM_ALBUM_BELLOW_LOLLILOP);}// For Android < 3.0public void openFileChooser(ValueCallback<Uri> uploadMsg) {openFileChooser(uploadMsg, "");}// For Android > 4.1.1public void openFileChooser(ValueCallback<Uri> uploadMsg,String acceptType, String capture) {openFileChooser(uploadMsg, acceptType);}// For Android 5.0+public boolean onShowFileChooser(WebView webView,ValueCallback<Uri[]> filePathCallback,FileChooserParams fileChooserParams) {mUploadCallbackAboveL = filePathCallback;selectImage(RESULT_CODE_PICK_FROM_ALBUM_ABOVE_LOLLILOP);return true;}@Overridepublic void onProgressChanged(WebView view, int newProgress) {super.onProgressChanged(view, newProgress);}} /**選擇后,回傳值*/@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {super.onActivityResult(requestCode, resultCode, data);if (mUploadMessage == null && mUploadCallbackAboveL == null) {return;}Uri uri = null;switch (requestCode) {case RESULT_CODE_PICK_FROM_ALBUM_BELLOW_LOLLILOP:uri = afterChosePic(data);if (mUploadMessage != null) {mUploadMessage.onReceiveValue(uri);mUploadMessage = null;}break;case RESULT_CODE_PICK_FROM_ALBUM_ABOVE_LOLLILOP:try {uri = afterChosePic(data);if (uri == null) {mUploadCallbackAboveL.onReceiveValue(new Uri[] { });mUploadCallbackAboveL = null;break;}if (mUploadCallbackAboveL != null && uri != null) {mUploadCallbackAboveL.onReceiveValue(new Uri[] { uri });mUploadCallbackAboveL = null;}} catch (Exception e) {mUploadCallbackAboveL = null;e.printStackTrace();}break;}}/*** 選擇照片后結(jié)束*/private Uri afterChosePic(Intent data) {if (data == null) {return null;}String path = getRealFilePath(data.getData());String[] names = path.split("\\.");String endName = null;if (names != null) {endName = names[names.length - 1];}if (endName != null) {compressPath = compressPath.split("\\.")[0] + "." + endName;}File newFile;try {newFile = FileUtils.compressFile(path, compressPath);} catch (Exception e) {newFile = null;}return Uri.fromFile(newFile);}/*** 根據(jù)Uri獲取圖片文件的絕對路徑*/public String getRealFilePath(final Uri uri) {if (null == uri) {return null;}final String scheme = uri.getScheme();String data = null;if (scheme == null) {data = uri.getPath();} else if (ContentResolver.SCHEME_FILE.equals(scheme)) {data = uri.getPath();} else if (ContentResolver.SCHEME_CONTENT.equals(scheme)) {Cursor cursor = getContentResolver().query(uri,new String[] { ImageColumns.DATA }, null, null, null);if (null != cursor) {if (cursor.moveToFirst()) {int index = cursor.getColumnIndexOrThrow(ImageColumns.DATA);if (index > -1) {data = cursor.getString(index);}}cursor.close();}}return data;} /**打開圖庫,同時處理圖片*/private void selectImage(int resultCode) {compressPath = Environment.getExternalStorageDirectory().getPath() + "/QWB/temp";File file = new File(compressPath);if (!file.exists()) {file.mkdirs();}compressPath = compressPath + File.separator + "compress.png";File image = new File(compressPath);if (image.exists()) {image.delete();}Intent intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);startActivityForResult(intent, resultCode);} //返回html頁面@Overridepublic void onBackPressed() {super.onBackPressed();if(webview.canGoBack()){webview.goBack();}else{finish();}}

文件處理工具類:FileUtils.java?

import android.graphics.Bitmap; import android.graphics.Bitmap.CompressFormat; import android.graphics.Bitmap.Config; import android.graphics.BitmapFactory; import android.graphics.Matrix; import android.media.ExifInterface; import android.text.TextUtils; import android.util.Log;import java.io.BufferedOutputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException;/*** Created by zuoan on 2018/3/21.*/public class FileUtils {/*** 把圖片壓縮到200K** @param oldpath* 壓縮前的圖片路徑* @param newPath* 壓縮后的圖片路徑* @return*/public static File compressFile(String oldpath, String newPath) {Bitmap compressBitmap = FileUtils.decodeFile(oldpath);Bitmap newBitmap = ratingImage(oldpath, compressBitmap);ByteArrayOutputStream os = new ByteArrayOutputStream();newBitmap.compress(CompressFormat.PNG, 100, os);byte[] bytes = os.toByteArray();File file = null ;try {file = FileUtils.getFileFromBytes(bytes, newPath);} catch (Exception e) {e.printStackTrace();}finally{if(newBitmap != null ){if(!newBitmap.isRecycled()){newBitmap.recycle();}newBitmap = null;}if(compressBitmap != null ){if(!compressBitmap.isRecycled()){compressBitmap.recycle();}compressBitmap = null;}}return file;}private static Bitmap ratingImage(String filePath, Bitmap bitmap){int degree = readPictureDegree(filePath);return rotaingImageView(degree, bitmap);}/*** 旋轉(zhuǎn)圖片* @param angle* @param bitmap* @return Bitmap*/public static Bitmap rotaingImageView(int angle , Bitmap bitmap) {//旋轉(zhuǎn)圖片 動作Matrix matrix = new Matrix();;matrix.postRotate(angle);System.out.println("angle2=" + angle);// 創(chuàng)建新的圖片Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);return resizedBitmap;}/*** 讀取圖片屬性:旋轉(zhuǎn)的角度* @param path 圖片絕對路徑* @return degree旋轉(zhuǎn)的角度*/public static int readPictureDegree(String path) {int degree = 0;try {ExifInterface exifInterface = new ExifInterface(path);int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);switch (orientation) {case ExifInterface.ORIENTATION_ROTATE_90:degree = 90;break;case ExifInterface.ORIENTATION_ROTATE_180:degree = 180;break;case ExifInterface.ORIENTATION_ROTATE_270:degree = 270;break;}} catch (IOException e) {e.printStackTrace();}return degree;}/*** 把字節(jié)數(shù)組保存為一個文件** @param b* @param outputFile* @return*/public static File getFileFromBytes(byte[] b, String outputFile) {File ret = null;BufferedOutputStream stream = null;try {ret = new File(outputFile);FileOutputStream fstream = new FileOutputStream(ret);stream = new BufferedOutputStream(fstream);stream.write(b);} catch (Exception e) {// log.error("helper:get file from byte process error!");e.printStackTrace();} finally {if (stream != null) {try {stream.close();} catch (IOException e) {// log.error("helper:get file from byte process error!");e.printStackTrace();}}}return ret;}/*** 圖片壓縮** @param fPath* @return*/public static Bitmap decodeFile(String fPath) {BitmapFactory.Options opts = new BitmapFactory.Options();opts.inJustDecodeBounds = true;opts.inDither = false; // Disable Dithering modeopts.inPurgeable = true; // Tell to gc that whether it needs freeopts.inInputShareable = true; // Which kind of reference will be used toBitmapFactory.decodeFile(fPath, opts);final int REQUIRED_SIZE = 200;int scale = 1;if (opts.outHeight > REQUIRED_SIZE || opts.outWidth > REQUIRED_SIZE) {final int heightRatio = Math.round((float) opts.outHeight/ (float) REQUIRED_SIZE);final int widthRatio = Math.round((float) opts.outWidth/ (float) REQUIRED_SIZE);scale = heightRatio < widthRatio ? heightRatio : widthRatio;//}Log.i("scale", "scal ="+ scale);opts.inJustDecodeBounds = false;opts.inSampleSize = scale;Bitmap bm = BitmapFactory.decodeFile(fPath, opts).copy(Config.ARGB_8888, false);return bm;}/*** 創(chuàng)建目錄* @param path*/public static void setMkdir(String path){File file = new File(path);if(!file.exists()){file.mkdirs();Log.e("file", "目錄不存在 創(chuàng)建目錄 ");}else{Log.e("file", "目錄存在");}}/*** 獲取目錄名稱* @param url* @return FileName*/public static String getFileName(String url){int lastIndexStart = url.lastIndexOf("/");if(lastIndexStart!=-1){return url.substring(lastIndexStart+1, url.length());}else{return null;}}/*** 刪除該目錄下的文件** @param path*/public static void delFile(String path) {if (!TextUtils.isEmpty(path)) {File file = new File(path);if (file.exists()) {file.delete();}}} }

關(guān)于H5調(diào)用相機拍照問題

//輔助WebView處理圖片上傳操作 webview.setWebChromeClient(new MyChromeWebClient());

?

private Uri imageUri;//自定義 WebChromeClient 輔助WebView處理圖片上傳操作【<input type=file> 文件上傳標簽】 public class MyChromeWebClient extends WebChromeClient {// For Android 3.0-public void openFileChooser(ValueCallback<Uri> uploadMsg) {Log.d(TAG, "openFileChoose(ValueCallback<Uri> uploadMsg)");mUploadMessage = uploadMsg;if (videoFlag) {recordVideo();} else {takePhoto();}}// For Android 3.0+public void openFileChooser(ValueCallback uploadMsg, String acceptType) {Log.d(TAG, "openFileChoose( ValueCallback uploadMsg, String acceptType )");mUploadMessage = uploadMsg;if (videoFlag) {recordVideo();} else {takePhoto();}}//For Android 4.1public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture) {Log.d(TAG, "openFileChoose(ValueCallback<Uri> uploadMsg, String acceptType, String capture)");mUploadMessage = uploadMsg;if (videoFlag) {recordVideo();} else {takePhoto();}}// For Android 5.0+public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams) {Log.d(TAG, "onShowFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture)");mUploadCallbackAboveL = filePathCallback;if (videoFlag) {recordVideo();} else {takePhoto();}return true;} }/*** 拍照*/ private 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創(chuàng)建一個content類型的UriimageUri = FileProvider.getUriForFile(MainActivity.this, BuildConfig.APPLICATION_ID+".provider",fileUri);}PhotoUtils.takePicture(MainActivity.this, imageUri, PHOTO_REQUEST);// FileProvider.getUriForFile(context.getApplicationContext(), BuildConfig.APPLICATION_ID+".provider",new File(picturePath)) }/*** 錄像*/ private void recordVideo() {Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);//限制時長intent.putExtra(MediaStore.EXTRA_DURATION_LIMIT, 10);//開啟攝像機startActivityForResult(intent, VIDEO_REQUEST); }@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) {super.onActivityResult(requestCode, resultCode, data);if (requestCode == PHOTO_REQUEST) {if (null == mUploadMessage && null == mUploadCallbackAboveL) return;Uri result = data == null || resultCode != RESULT_OK ? null : data.getData();if (mUploadCallbackAboveL != null) {onActivityResultAboveL(requestCode, resultCode, data);} else if (mUploadMessage != null) {mUploadMessage.onReceiveValue(result);mUploadMessage = null;}} else if (requestCode == VIDEO_REQUEST) {if (null == mUploadMessage && null == mUploadCallbackAboveL) return;Uri result = data == null || resultCode != RESULT_OK ? null : data.getData();if (mUploadCallbackAboveL != null) {if (resultCode == RESULT_OK) {mUploadCallbackAboveL.onReceiveValue(new Uri[]{result});mUploadCallbackAboveL = null;} else {mUploadCallbackAboveL.onReceiveValue(new Uri[]{});mUploadCallbackAboveL = null;}} else if (mUploadMessage != null) {if (resultCode == RESULT_OK) {mUploadMessage.onReceiveValue(result);mUploadMessage = null;} else {mUploadMessage.onReceiveValue(Uri.EMPTY);mUploadMessage = null;}}} }@TargetApi(Build.VERSION_CODES.LOLLIPOP) private void onActivityResultAboveL(int requestCode, int resultCode, Intent data) {if (requestCode != PHOTO_REQUEST || mUploadCallbackAboveL == null) {return;}Uri[] results = null;if (resultCode == Activity.RESULT_OK) {if (data == null) {results = new Uri[]{imageUri};} else {String dataString = data.getDataString();ClipData clipData = data.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)};}}mUploadCallbackAboveL.onReceiveValue(results);mUploadCallbackAboveL = null; }Android 7.0 以上手機需添加單獨權(quán)限

首先在AndroidManifest.xml中添加如下代碼

<providerandroid:name="android.support.v4.content.FileProvider"android:authorities="${applicationId}.provider"android:exported="false"android:grantUriPermissions="true"><meta-dataandroid:name="android.support.FILE_PROVIDER_PATHS"android:resource="@xml/file_paths"/> </provider>

然后在res 目錄下xml中添加文件

file_paths.xml

內(nèi)容如下

<?xml version="1.0" encoding="utf-8"?> <paths><external-pathname="external_storage_root"path="." /> ? </paths>

?

?

?

總結(jié)

以上是生活随笔為你收集整理的关于android webview使用过程中遇到的一些问题总结的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。