您好,登錄后才能下訂單哦!
這篇文章將為大家詳細講解有關怎么在Android中利用webView包安裝WebAPP,文章內容質量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關知識有一定的了解。
首先在 app/src/main/AndroidManifest.xml 里添加權限:
注意本文代碼中的"..."都代表省略的代碼
<manifest ...> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <application ... </application> </manifest>
第一個是允許訪問網絡連接;
第二個是允許程序寫入外部存儲,如SD卡上寫文件;
第三個是允許應用程序從外部存儲讀取;
再是 app/src/main/res/layout/activity_main.xml 添加:
<WebView android:id="@+id/local_webview" android:layout_width="match_parent" android:layout_height="match_parent" android:visibility="gone" />
MainActivety.java:
private WebView webview; //... protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { WebView.setWebContentsDebuggingEnabled(true); } webview = findViewById(R.id.local_webview); WebSettings settings = webview.getSettings(); loading = findViewById(R.id.loadView); settings.setJavaScriptEnabled(true);//必須 settings.setCacheMode(WebSettings.LOAD_DEFAULT);//關閉webview中緩存 settings.setRenderPriority(WebSettings.RenderPriority.HIGH);//提高渲染的優先級 settings.setUseWideViewPort(true);//WebView是否支持HTML的“viewport”標簽或者使用wide viewport。 settings.setAllowContentAccess(true);//是否允許在WebView中訪問內容URL settings.setBuiltInZoomControls(true);//是否使用其內置的變焦機制 settings.setJavaScriptCanOpenWindowsAutomatically(true);//是否允許自動打開彈窗 settings.setDomStorageEnabled(true);//是否開啟DOM存儲API權限 webview.loadUrl("http://www.baidu.com"); webview.setWebChromeClient(new WebChromeClient() { @Override public void onProgressChanged(WebView view, int newProgress) { Log.d("加載", "on page progress changed and progress is " + newProgress); //... } } webview.setWebViewClient(new WebViewClient() { @Override public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) { super.onReceivedError(view, errorCode, description, failingUrl); // 加載網頁失敗時處理 如: view.loadDataWithBaseURL(null, "<span>頁面加載失敗,請確認網絡是否連接</span>", "text/html", "utf-8", null); } @Override public void onPageFinished(WebView view, String url) { if (!webview.getSettings().getLoadsImagesAutomatically()) { webview.getSettings().setLoadsImagesAutomatically(true); } Log.d("加載", "end "); } }); }
這是一個比較簡單的 webView 例子,這里有幾點需要說下:
關于WebSettings:
1.1 需要運行 js 的網頁都需要此設置:setJavaScriptEnabled
1.2 關于setCacheMode,盡量不要設置 LOAD_CACHE_ONLY 該值,設置這個值會在 webkit 類型瀏覽器對短時間內的 ajax 訪問產生Provisional headers are shown問題;
1.3 關于 AllowFileAccess 一般默認值就好,都開了會有安全上的問題;
1.4 WebSettings 的設置內容很多,如果想看更多的話可以進行搜索;
1.5 暫未發現其他問題,待定;
setWebChromeClient 和 setWebViewClient:
2.1 這2個都是 webView 的配置屬性,不過在功能上有所區分:
WebViewClient幫助WebView處理各種通知、請求事件的
WebChromeClient是輔助WebView處理Javascript的對話框,網站圖標,網站title,加載進度等;
js 里面使用 alert 和 confirm 需要在WebChromeClient里面進行修改,提供對話框;
2.2 關于onPageFinished:
如果你的路由里面是異步加載的,如resolve => require(['./routers/XXX'], resolve),那么就要注意,在每進入異步加載的頁面后,都會觸發此函數,所以如果你需要在頁面加載后只執行一次的代碼的話,就放在 setWebChromeClient 的 onProgressChanged 里進行判斷進度是否為100時再執行;
webview.loadUrl():
3.1 這里的加載地址可以有2種,1是 webview.loadUrl("file:///android_asset/index.html"); 訪問本地文件,2是webview.loadUrl("http://www.baidu.com");訪問網絡文件;
各有其優點:若訪問網絡文件,更新服務器內容即可使用最新的功能;而訪問本地資源的話,加載的速度會快一點,而且即使斷網也可以看到默認的東西;
剛剛有說到,進入 APP 的快慢問題,這里我是調用了一個加載的動畫來完成的:
我這邊選擇的動畫時這個:點擊查看
而在 Android studio 里調用插件的方式十分簡單:
打開根目錄下的 build.gradle,在 allprojects 的 repositories 里添加:
maven { url "https://jitpack.io" }
然后打開 app/build.gradle,在 dependencies 里添加:
compile 'com.github.zzz40500:android-shapeLoadingView:1.0.3.2'
這時候先 build 項目,再在 src/main/res/layout/activity_main.xml 里添加代碼:
<android.support.constraint.ConstraintLayout > <com.mingle.widget.LoadingView android:id="@+id/loadView" android:layout_width="fill_parent" android:layout_height="fill_parent" /> ... </android.support.constraint.ConstraintLayout>
這時候可以,這樣 loading 動畫就添加好了,后面只需要在 Java 代碼里顯示和隱藏就行了;
最關鍵的html:input[type="file"]問題,這個問題才是最大的問題,先說好
如果你的webApp不需要上傳文件或者不在意Android 4.2-4.4 版本的話,可以用該方法
MainActivity.java:
先創建變量
public static final int INPUT_FILE_REQUEST_CODE = 1; private ValueCallback<Uri> mUploadMessage; private final static int FILECHOOSER_RESULTCODE = 2; private ValueCallback<Uri[]> mFilePathCallback; private String mCameraPhotoPath;
在setWebChromeClient里添加代碼:
public void openFileChooser(ValueCallback uploadMsg, String acceptType) { Log.d("選擇", "3.0+"); mUploadMessage = uploadMsg; Intent i = new Intent(Intent.ACTION_GET_CONTENT); i.addCategory(Intent.CATEGORY_OPENABLE); i.setType("image/*"); MainActivity.this.startActivityForResult( Intent.createChooser(i, "Image Chooser"), FILECHOOSER_RESULTCODE); } //Android 5.0 public boolean onShowFileChooser( WebView webView, ValueCallback<Uri[]> filePathCallback, WebChromeClient.FileChooserParams fileChooserParams) { Log.d("選擇", "5.0+"); if (mFilePathCallback != null) { mFilePathCallback.onReceiveValue(null); } mFilePathCallback = filePathCallback; Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); if (takePictureIntent.resolveActivity(getPackageManager()) != null) { // Create the File where the photo should go File photoFile = null; try { //設置MediaStore.EXTRA_OUTPUT路徑,相機拍照寫入的全路徑 photoFile = createImageFile(); takePictureIntent.putExtra("PhotoPath", mCameraPhotoPath); } catch (Exception ex) { // Error occurred while creating the File Log.e("WebViewSetting", "Unable to create Image File", ex); } // Continue only if the File was successfully created if (photoFile != null) { mCameraPhotoPath = "file:" + photoFile.getAbsolutePath(); takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile)); System.out.println(mCameraPhotoPath); } else { takePictureIntent = null; } } Intent contentSelectionIntent = new Intent(Intent.ACTION_GET_CONTENT); contentSelectionIntent.addCategory(Intent.CATEGORY_OPENABLE); contentSelectionIntent.setType("image/*"); Intent[] intentArray; if (takePictureIntent != null) { intentArray = new Intent[]{takePictureIntent}; System.out.println(takePictureIntent); } else { intentArray = new Intent[0]; } Intent chooserIntent = new Intent(Intent.ACTION_CHOOSER); chooserIntent.putExtra(Intent.EXTRA_INTENT, contentSelectionIntent); chooserIntent.putExtra(Intent.EXTRA_TITLE, "Image Chooser"); chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray); startActivityForResult(chooserIntent, INPUT_FILE_REQUEST_CODE); return true; } // For Android 3.0+ public void openFileChooser(ValueCallback<Uri> uploadMsg) { Log.d("選擇", "3.0+"); mUploadMessage = uploadMsg; Intent i = new Intent(Intent.ACTION_GET_CONTENT); i.addCategory(Intent.CATEGORY_OPENABLE); i.setType("image/*"); MainActivity.this.startActivityForResult(Intent.createChooser(i, "Image Chooser"), FILECHOOSER_RESULTCODE); } //For Android 4.1 public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture) { Log.d("選擇", "4+"); mUploadMessage = uploadMsg; Intent i = new Intent(Intent.ACTION_GET_CONTENT); i.addCategory(Intent.CATEGORY_OPENABLE); i.setType("image/*"); MainActivity.this.startActivityForResult(Intent.createChooser(i, "Image Chooser"), MainActivity.FILECHOOSER_RESULTCODE); }
在主類中添加:
@SuppressLint("SdCardPath") private File createImageFile() { File file=new File(Environment.getExternalStorageDirectory()+"/","tmp.png"); mCameraPhotoPath=file.getAbsolutePath(); if(!file.exists()) { try { file.createNewFile(); } catch (IOException e) { e.printStackTrace(); } } return file; } @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { Log.d("result", "show"); if (requestCode == FILECHOOSER_RESULTCODE) { if (null == mUploadMessage) return; Uri result = data == null || resultCode != RESULT_OK ? null : data.getData(); if (result != null) { String imagePath = ImageFilePath.getPath(this, result); if (!TextUtils.isEmpty(imagePath)) { result = Uri.parse("file:///" + imagePath); } } mUploadMessage.onReceiveValue(result); mUploadMessage = null; } else if (requestCode == INPUT_FILE_REQUEST_CODE && mFilePathCallback != null) { // 5.0的回調 Uri[] results = null; // Check that the response is a good one if (resultCode == Activity.RESULT_OK) { if (data == null && !TextUtils.isEmpty(data.getDataString())) { // If there is not data, then we may have taken a photo if (mCameraPhotoPath != null) { results = new Uri[]{Uri.parse(mCameraPhotoPath)}; } } else { String dataString = data.getDataString(); if (dataString != null) { results = new Uri[]{Uri.parse(dataString)}; } } } mFilePathCallback.onReceiveValue(results); mFilePathCallback = null; } else { super.onActivityResult(requestCode, resultCode, data); return; } }
關于怎么在Android中利用webView包安裝WebAPP就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。