使用自定義webview呼叫支付寶app支付
正文:webview在載入網頁的時候會預設調起手機自帶的瀏覽器載入網頁,使用者體驗不好。但當用戶設定瀏覽器客戶端(setWebViewClient)設定這樣的監聽事件之後,當請求url的時候就不會開啟手機自帶的瀏覽器。
webview.setWebViewClient(new WebViewClient() { @Override public void onPageStarted(WebView view, String url, Bitmap favicon) { super.onPageStarted(view, url, favicon); } @Override public void onPageFinished(WebView view, String url) { super.onPageFinished(view, url); LoadingDialog.closeDialog(); } });
在此方法中可以監聽瀏覽器開始載入網頁和載入網頁結束。
今天著重講的並不是上邊的兩個方法而是下面的這位
putinmoney_webview.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
}
});
shouldOverrideUrlLoading並不是每次都在onPageStarted之前開始呼叫的,只有在呼叫webview.loadURL的時候才會呼叫。
webview.loadUrl("https://qr.alipay.com/bax05351pgjhc4yegd2y2084");
但發起請求的時候後,webview的連續動作是先後請求兩個url
1.https://mobilecodec.alipay.com/client_download.htm?qrcode=bax05351pgjhc4yegd2y2084
2.https://ds.alipay.com/from=mobilecodec&scheme=alipayqr%3A%2F%2Fplatformapi%2Fstartapp%3FsaId%3D10000007%26clientVersion%3D3.7.0.0718%26qrcode%3Dhttps%253A%252F%252Fqr.alipay.com%252Fbax05351pgjhc4yegd2y2084%253F_s%253Dweb-other
之後返回一個意圖,也是用這個意圖來開啟支付寶app
intent://platformapi/startapp?saId=10000007&clientVersion=3.7.0.0718&qrcode=https%3A%2F%2Fqr.alipay.com%2Fbax05351pgjhc4yegd2y2084%3F_s%3Dwebother&_t=1474448799004#Intent;scheme=alipayqr;package=com.eg.android.AlipayGphone;end
webview.setWebViewClient(new WebViewClient(){
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
// TODO Auto-generated method stub
super.onPageStarted(view, url, favicon);
}
@Override
public void onPageFinished(WebView view, String url) {
// TODO Auto-generated method stub
super.onPageFinished(view, url);
}
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
Log.e(TAG, "訪問的url地址:" + url);
if (parseScheme(url)) {
try {
Uri uri = Uri.parse(url);
Intent intent;
intent = Intent.parseUri(url,
Intent.URI_INTENT_SCHEME);
intent.addCategory("android.intent.category.BROWSABLE");
intent.setComponent(null);
// intent.setSelector(null);
startActivity(intent);
} catch (Exception e) {
}
} else {
view.loadUrl(url);
}
return true;
}
});
關於"android.intent.category.BROWSABLE"參考:
http://blog.csdn.net/gf771115/article/details/7827833
此外要對webview設定下:
WebSettings webSettings = webview.getSettings();
webSettings.setJavaScriptEnabled(true);
// 設定可以訪問檔案
webSettings.setAllowFileAccess(true);
// 設定支援縮放
webSettings.setBuiltInZoomControls(true);
webSettings.setCacheMode(WebSettings.LOAD_NO_CACHE);
// webSettings.setDatabaseEnabled(true);
// 使用localStorage則必須開啟
webSettings.setDomStorageEnabled(true);
webSettings.setGeolocationEnabled(true);
例項下載地址:https://github.com/reachchen/loadurltoali.git
在專案中發現的問題在此修正:
發現一些手機(例如一些升級了7.0的手機)在請求後並沒有返回intent,所以就會出現調不起支付寶的情況。但是用瀏覽器直接開啟是可以的
相容的思路如下:
新建一個執行緒,在使用者發出請求後,如果10秒的時間沒有收到調起的intent,就用瀏覽器直接調起。
程式碼如下:
public boolean parseScheme(String url) {
if (url.contains("platformapi/startapp")){
myHandler.removeCallbacks(runable);
return true;
} else if(url.contains("web-other")){
myHandler.postDelayed(runable, 10000);
return false;
}else {
return false;
}
}
新建的執行緒
myHandler = new Handler();
runable = new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
LoadingDialog.closeDialog();
webview_another.loadUrl(myaliWebUrl.get("code_url"));
}
};
}
完整程式碼:
java:
package com.reachchen.loadurltoalipay; import android.app.Activity; import android.content.Intent; import android.graphics.Bitmap; import android.net.Uri; import android.os.Bundle; import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.View.OnClickListener; import android.webkit.WebSettings; import android.webkit.WebView; import android.webkit.WebViewClient; import android.widget.Button; public class MainActivity extends Activity { private Button btn_startaliapp; private WebView webview; private String TAG = "MainActivity"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btn_startaliapp = (Button) findViewById(R.id.btn_startaliapp); //應用過程中將其隱藏掉效果更佳 webview = (WebView) findViewById(R.id.webview); WebSettings webSettings = webview.getSettings(); webSettings.setJavaScriptEnabled(true); // 設定可以訪問檔案 webSettings.setAllowFileAccess(true); // 設定支援縮放 webSettings.setBuiltInZoomControls(true); webSettings.setCacheMode(WebSettings.LOAD_NO_CACHE); // webSettings.setDatabaseEnabled(true); // 使用localStorage則必須開啟 webSettings.setDomStorageEnabled(true); webSettings.setGeolocationEnabled(true); webview.setWebViewClient(new WebViewClient(){ @Override public void onPageStarted(WebView view, String url, Bitmap favicon) { // TODO Auto-generated method stub super.onPageStarted(view, url, favicon); } @Override public void onPageFinished(WebView view, String url) { // TODO Auto-generated method stub super.onPageFinished(view, url); } @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { Log.e(TAG, "訪問的url地址:" + url); if (parseScheme(url)) { try { Uri uri = Uri.parse(url); Intent intent; intent = Intent.parseUri(url, Intent.URI_INTENT_SCHEME); intent.addCategory("android.intent.category.BROWSABLE"); intent.setComponent(null); // intent.setSelector(null); startActivity(intent); } catch (Exception e) { } } else { view.loadUrl(url); } return true; } }); btn_startaliapp.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub webview.loadUrl("https://qr.alipay.com/bax05351pgjhc4yegd2y2084"); } }); } public boolean parseScheme(String url) { if (url.contains("platformapi/startapp")) { return true; } else { return false; } } }
xml佈局:<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" > <Button android:id="@+id/btn_startaliapp" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="調起支付寶"/> <WebView android:id="@+id/webview" android:layout_below="@+id/btn_startaliapp" android:layout_width="match_parent" android:layout_height="match_parent" /> </RelativeLayout>