安卓開發新人,剛着手項目中用html實現應用的某些模塊,在編寫帶webview的Activity時就遇到的問題不斷嘗試,並改進自己的webviewActivity,最後給出自己的源碼,剛接觸webview的童鞋可以參考其中的解決方案。
其中涉及到的問題有:
<p>webview加載頁面的基本配置</p><p>使webview顯示網頁加載進度</p><p>webview的後退、前進、刷新、關閉的實現</p><p>Android通過webview的cookie來傳鍵值對給html端</p><p>使webview支持文件的上傳</p><p>webview中如何給JS提供接口,讓JS能調用Android的方法</p><p>將JS的Alert轉換爲Android的AlertDialog</p><p>調用該activity來加載頁面,只需要用以下片斷即可</p>
<p></span></div><div><span style="font-size:24px;"></span><pre name="code" class="java"><span style="white-space:pre"> </span>intent.setClass(MainActivity_3.this, WebViewActivity.class);</p> intent.putExtra("url", "file:///android_asset/index.html");// FIXME
intent.putExtra("title", "測試");
startActivity(intent);
Activity源碼
public class WebViewActivity extends Activity {
private final static int FINISH_ACTIVITY = 0;
private final static int REQUEST_UPLOAD_FILE_CODE = 2;
private ValueCallback<Uri> mUploadFile;
private final String TAG = "WebViewActivity ";
private WebView webview;
private String url;
private Handler handler = new MyHandler(this);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().requestFeature(Window.FEATURE_PROGRESS);
setContentView(R.layout.activity_webview);
webview = (WebView) findViewById(R.id.webView);
url = getIntent().getStringExtra("url");
getWindow().setFeatureInt(Window.FEATURE_PROGRESS,
Window.PROGRESS_VISIBILITY_ON);
//給頁面的actionBar加上回退按鈕
getActionBar().setDisplayHomeAsUpEnabled(true);
getActionBar().setBackgroundDrawable(
getResources().getDrawable(R.color.deepgrey));
//設置webview的settings和client
configWebview();
setCookie();
// 加載 頁面
loadURL();
}
//給html頁面傳遞的用戶數據都放在cookie中
private void setCookie() {
SharedPreferences userInfoSP = MyApplication.getInstance()
.getUserinfoSharedPreferences();
CookieSyncManager cookieSyncManager = CookieSyncManager
.createInstance(this);
CookieManager cookieManager = CookieManager.getInstance();
cookieManager.setAcceptCookie(true);
String domain = "app.issll.com";
Cookie cname = null;
try {//若不用URLEncoder編碼,中文在某些機型上會出現亂碼
cname = new Cookie(domain, "userName", URLEncoder.encode(
userInfoSP.getString("name", ""), "UTF-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
Cookie cplotid = new Cookie(domain, "plotId",
UserSelectedAddress.plotid);
Cookie cLongtitude = new Cookie(domain, "longtitude",
String.valueOf(UserSelectedAddress.myLongitude));
Cookie cLatitude = new Cookie(domain, "latitude",
String.valueOf(UserSelectedAddress.myLatitude));
Cookie cUserId = new Cookie(domain, "userId", userInfoSP.getString(
"userid", ""));
MyDebugUtils.d(TAG, cplotid.toString());
MyDebugUtils.d(TAG, cUserId.toString());
MyDebugUtils.d(TAG, cname.toString());
cookieManager.removeAllCookie();
cookieManager.setCookie(url, "" + cUserId);
cookieManager.setCookie(url, "" + cname);
cookieManager.setCookie(url, "" + cplotid);
cookieManager.setCookie(url, "" + cLongtitude);
cookieManager.setCookie(url, "" + cLatitude);
cookieSyncManager.startSync();
}
private void setActionbarTitle() {
String title = getIntent().getStringExtra("title");
if (title != null)
getActionBar().setTitle(title);
else
getActionBar().setTitle(R.string.app_name);
}
private void loadURL() {
try {
webview.loadUrl(url);
} catch (Exception e) {
MyDebugUtils.e(TAG + url, e.getLocalizedMessage());
}
}
//友盟SDK的方法
@Override
protected void onResume() {
MobclickAgent.onResume(this);
super.onResume();
}
@Override
protected void onPause() {
MobclickAgent.onPause(this);
super.onPause();
}
@Override
protected void onDestroy() {
webview.destroy();
super.onDestroy();
}
@SuppressWarnings("deprecation")
private void configWebview() {
// 允許javascript代碼執行
WebSettings settings = webview.getSettings();
settings.setJavaScriptEnabled(true);
settings.setDomStorageEnabled(true);
settings.setCacheMode(WebSettings.LOAD_DEFAULT);
settings.setAppCacheMaxSize(8 * 1024 * 1024);
settings.setRenderPriority(RenderPriority.HIGH);
settings.setCacheMode(WebSettings.LOAD_NO_CACHE);
settings.setAppCacheEnabled(true);
settings.setJavaScriptCanOpenWindowsAutomatically(true);
settings.setAllowFileAccess(true);
settings.setAllowFileAccessFromFileURLs(true);
settings.setAllowUniversalAccessFromFileURLs(true);
settings.setDefaultTextEncodingName("utf-8");
// 在當前頁面打開鏈接,而不是啓動用戶手機上安裝的瀏覽器打開
webview.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
webview.loadUrl(url);
return true;
}
});
webview.setWebChromeClient(new WebChromeClient() {
// 使webview可以更新進度條
@Override
public void onProgressChanged(WebView view, int newProgress) {
WebViewActivity.this.setTitle("加載中……");
WebViewActivity.this.setProgress(newProgress * 100);
if (newProgress == 100)
setActionbarTitle();
}
//使JS alert可以以Android的AlertDiaolog形式彈出
@Override
public boolean onJsAlert(WebView view, String url, String message,
final JsResult result) {
AlertDialog.Builder builder = new Builder(WebViewActivity.this)
.setMessage(message).setPositiveButton("確定",
new OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int which) {
result.confirm();
}
});
builder.setCancelable(true);
builder.show();
return true;
}
//html中上傳點擊input type爲file的控件時會調用下列方法,在Android4.4中無效,待修復
// Android 4.1+
@SuppressWarnings("unused")
public void openFileChooser(ValueCallback<Uri> uploadFile,
String acceptType, String capture) {
openFileChooser(uploadFile);
}
// Android 3.0 +
@SuppressWarnings("unused")
public void openFileChooser(ValueCallback<Uri> uploadFile,
String acceptType) {
openFileChooser(uploadFile);
}
// Android 3.0
public void openFileChooser(ValueCallback<Uri> uploadFile) {
mUploadFile = uploadFile;
startActivityForResult(createCameraIntent(),
REQUEST_UPLOAD_FILE_CODE);
}
});
// 在js中用window.injs.方法名來調用InJavaScript類中的方法
webview.addJavascriptInterface(new InJavaScript(), "android");
webview.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}
private Intent createCameraIntent() {
Intent imageIntent = new Intent(Intent.ACTION_GET_CONTENT);// 選擇圖片文件
imageIntent.setType("image/*");
return imageIntent;
}
// 使後退鍵可以達到網頁回退功能,而不是關閉activity
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK && webview.canGoBack()) {
webview.goBack();
return true;
}
return super.onKeyDown(keyCode, event);
}
//添加菜單欄的幾個功能鍵
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.webview, menu);
return super.onCreateOptionsMenu(menu);
}
/**
* 給javascript調用的代碼
*
*/
private final class InJavaScript {
//可以用JS關閉本Activity
@android.webkit.JavascriptInterface
public void finish() {
handler.sendEmptyMessage(FINISH_ACTIVITY);
}
//可以用JS觸發一個分享文本信息的intent
@android.webkit.JavascriptInterface
public void sharelink(String link){
Intent i=new Intent(Intent.ACTION_SEND);
i.setType("text/plain");
i.putExtra(Intent.EXTRA_SUBJECT, "分享");
i.putExtra(Intent.EXTRA_TEXT, "share this:"+link);
startActivity(Intent.createChooser(i, "請選擇分享方式"));
}
}
/*
* (non-Javadoc)左上角回退可以結束本activity,另有前進、後退、刷新
*
* @see android.app.Activity#onOptionsItemSelected(android.view.MenuItem)
*/
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home://關閉頁面
finish();
break;
case R.id.menu_webview_refresh://刷新
webview.reload();
break;
case R.id.menu_webview_back://後退
if (webview.canGoBack())
webview.goBack();
break;
case R.id.menu_webview_forward://前進
if (webview.canGoForward())
webview.goForward();
break;
}
return super.onOptionsItemSelected(item);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
//選擇文件後回調給JS一個URI
if (requestCode == REQUEST_UPLOAD_FILE_CODE && resultCode == RESULT_OK) {
if (null == mUploadFile)
return;
Uri result = (null == data) ? null : data.getData();//注,此處data.getData(),若爲data則僅是contentProvider的地址將不能爲JS識別
if (null != result) {
mUploadFile.onReceiveValue(result);
mUploadFile = null;
}
//如果用戶取消了選擇文件操作,必須回調一個null的URI給JS,否則webview將會死掉
} else if (requestCode == REQUEST_UPLOAD_FILE_CODE &&resultCode == RESULT_CANCELED) {
Uri result = null;
mUploadFile.onReceiveValue(result);
mUploadFile = null;
}
}
//用來處理UI操作的handler,可擴展,暫無太大用處……
private static class MyHandler extends Handler {
WeakReference<WebViewActivity> weakReference;
public MyHandler(WebViewActivity webViewActivity) {
weakReference = new WeakReference<WebViewActivity>(webViewActivity);
}
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case FINISH_ACTIVITY:
weakReference.get().finish();
break;
default:
break;
}
super.handleMessage(msg);
}
}
}