商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。 For commercial use, please contact the author for authorization. For non commercial use, please indicate the source. 協議(Lice ...
商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。
For commercial use, please contact the author for authorization. For non-commercial use, please indicate the source.
協議(License):署名-非商業性使用-相同方式共用 4.0 國際 (CC BY-NC-SA 4.0)
作者(Author):
鏈接(URL):https://www.35youth.cn/817.html
來源(Source):搬磚少年
近期團隊接到一個新的項目,企業內部的一個掌上超市項目,最初考慮通過公眾號或者小程式來做,後面說是部署在企業內網,就考慮到做網站應用,由於需要通過運營商分配的apn連接企業內網,所以在打開應用之前需要檢測一下網路,如果是web端的話,那就沒法檢測網路了,所以考慮使用安卓的 webview 封裝一下H5的應用。
1、配置網路連接許可權
在AndroidManifest.xml文件中加上以下配置信息
<uses-permission android:name="android.permission.INTERNET"/>
註: 從Android 9.0(API級別28)開始,預設情況下禁用明文支持。因此http的url均無法在webview中載入 ,所以只配置以上信息可能會導致net::ERR_CLEARTEXT_NOT_PERMITTED報錯,還需要在配置文件的 application中加入下麵的配置。參照文章: net::ERR_CLEARTEXT_NOT_PERMITTED
android:usesCleartextTraffic="true"
webview 網路配置異常
net::ERR_CLEARTEXT_NOT_PERMITTED 配置
2、創建layout文件
使用idea的話,會自動創建MainActivity和對應的layout文件,直接在文件的基礎上修改即可,使用Webview控制項,如果需要使用進度條的話,可以將ProgressBar 的配置打開即可。
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.ctjsoft.jxf.shop.MainActivity">
<WebView android:id="@+id/webview" android:layout_width="match_parent" android:layout_height="match_parent"/>
<!--<ProgressBar android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/progressbar"
style="@android:style/Widget.ProgressBar.Horizontal" android:max="100" android:progress="0"
android:visibility="gone"/>-->
</androidx.constraintlayout.widget.ConstraintLayout>
3、修改 MainActivity 文件
重寫onCreate方法:
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//progressBar = (ProgressBar) findViewById(R.id.progressbar);//進度條
webView = (WebView) findViewById(R.id.webview);
webView.getSettings().setAllowUniversalAccessFromFileURLs(true);
webView.getSettings().setAllowFileAccessFromFileURLs(true);
// webview的設置中添加如下代碼
try {
if (Build.VERSION.SDK_INT >= 16) {
Class<?> clazz = webView.getSettings().getClass();
Method method = clazz.getMethod("setAllowUniversalAccessFromFileURLs", boolean.class);
if (method != null) {
method.invoke(webView.getSettings(), true);
}
}
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
//webView.loadUrl("http://172.17.1.176:8082/");//載入url
webView.loadUrl(API);
//使用webview顯示html代碼
// webView.loadDataWithBaseURL(null,"<html><head><title> 歡迎您 </title></head>" +
// "<body><h2>使用webview顯示 html代碼</h2></body></html>", "text/html" , "utf-8", null);
webView.addJavascriptInterface(this, "android");//添加js監聽 這樣html就能調用客戶端
webView.setWebChromeClient(webChromeClient);
webView.setWebViewClient(webViewClient);
WebSettings webSettings = webView.getSettings();
/**
* LOAD_CACHE_ONLY: 不使用網路,只讀取本地緩存數據
* LOAD_DEFAULT: (預設)根據cache-control決定是否從網路上取數據。
* LOAD_NO_CACHE: 不使用緩存,只從網路獲取數據.
* LOAD_CACHE_ELSE_NETWORK,只要本地有,無論是否過期,或者no-cache,都使用緩存中的數據。
*/
webSettings.setCacheMode(WebSettings.LOAD_DEFAULT);//不使用緩存,只從網路獲取數據.
webView.getSettings().setTextZoom(100);
webView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);//設置js可以直接打開視窗,如window.open(),預設為false
webView.getSettings().setJavaScriptEnabled(true);//是否允許執行js,預設為false。設置true時,會提醒可能造成XSS漏洞
webView.getSettings().setSupportZoom(true);//是否可以縮放,預設
webView.getSettings().setBuiltInZoomControls(true);//是否顯示縮放按鈕,預設false
webView.getSettings().setUseWideViewPort(true);//設置此屬性,可任意比例縮放。大視圖模式
webView.getSettings().setLoadWithOverviewMode(true);//和setUseWideViewPort(true)一起解決網頁自適應問題
webView.getSettings().setAppCacheEnabled(true);//是否使用緩存
webView.getSettings().setDomStorageEnabled(true);//DOM Storage
}
```
配置WebviewClient
//WebViewClient主要幫助WebView處理各種通知、請求事件
private WebViewClient webViewClient = new WebViewClient() {
@Override
public void onPageFinished(WebView view, String url) {//頁面載入完成
//progressBar.setVisibility(View.GONE);
}
public void onPageStarted(WebView view, String url, Bitmap favicon) {//頁面開始載入
//progressBar.setVisibility(View.VISIBLE);
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
Log.i("ansen", "攔截url:" + request.getUrl());
return super.shouldOverrideUrlLoading(view, request);
}
};
//WebChromeClient主要輔助WebView處理Javascript的對話框、網站圖標、網站title、載入進度等
private WebChromeClient webChromeClient = new WebChromeClient() {
//不支持js的alert彈窗,需要自己監聽然後通過dialog彈窗
public boolean onJsAlert(WebView webView, String url, String message, JsResult result) {
AlertDialog.Builder localBuilder = new AlertDialog.Builder(webView.getContext());
localBuilder.setMessage(message).setPositiveButton("確定", null);
localBuilder.setCancelable(false);
localBuilder.create().show();
//註意:
//必須要這一句代碼:result.confirm()表示:
//處理結果為確定狀態同時喚醒WebCore線程
//否則不能繼續點擊按鈕
result.confirm();
return true;
}
//獲取網頁標題
@Override
public void onReceivedTitle(WebView view, String title) {
super.onReceivedTitle(view, title);
Log.i("ansen", "網頁標題:" + title);
}
//載入進度回調
@Override
public void onProgressChanged(WebView view, int newProgress) {
// progressBar.setProgress(newProgress);
}
};
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
Log.i("ansen", "是否有上一個頁面:" + webView.canGoBack());
if (webView.canGoBack() && keyCode == KeyEvent.KEYCODE_BACK) {//點擊返回按鈕的時候判斷有沒有上一頁
webView.goBack(); // goBack()表示返回webView的上一頁面
return true;
}
return super.onKeyDown(keyCode, event);
}
/**
* JS調用android的方法
*
* @param str
* @return
*/
@JavascriptInterface //仍然必不可少
public void getClient(String str) {
Log.i("ansen", "html調用客戶端:" + str);
}
@Override
protected void onDestroy() {
super.onDestroy();
//釋放資源
webView.destroy();
webView = null;
}
```