写与H5交互方法的activity,其中方法的传值只能有一个
public class RiskTestActivity extends HtmlActivity implements ReportBannerView {
public static final String PRODUCT_ID = "extra.product_id";
public static final String H5_PARAMETER = "webViewBackFlagNum";
public static final String BANNER_TYPE = "banner_type";
public static final String BANNER_REPORT_ID = "banner_report_id";
public static final String BANNER_ID = "banner_id";
public static final String BANNER_SOURCE = "banner_source";
public static final int LIVT_TYPE = 2;
private static final String APP_ID = BuildConfig.APP_ID;
public static void loadUrl(Context context, String url) {
Intent it = new Intent(context, RiskTestActivity.class);
it.putExtra(EXTRA_URL, url);
context.startActivity(it);
}
public static void loadUrlForNewTask(Context context, String url) {
Intent it = new Intent(context, RiskTestActivity.class);
it.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
it.putExtra(EXTRA_URL, url);
context.startActivity(it);
}
public static void loadUrlForBanner(Context context, String url, int bannerType, int source,
long id) {
Intent it = new Intent(context, RiskTestActivity.class);
it.putExtra(EXTRA_URL, url);
it.putExtra(BANNER_TYPE, bannerType);
it.putExtra(BANNER_SOURCE, source);
it.putExtra(BANNER_ID, id);
context.startActivity(it);
}
public static void loadUrl(Context context, String url, String title) {
Intent it = new Intent(context, RiskTestActivity.class);
it.putExtra(EXTRA_URL, url);
it.putExtra(EXTRA_TITLE, title);
it.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(it);
}
public static void loadUrlWithHeader(Context context, String url, String header) {
Map<String, String> headers = new HashMap<>();
headers.put("xtoken", header);
headers.put(HeadInterceptor.CAANNELNAME, HeadInterceptor.CAANNELVALUE);
headers.put(HeadInterceptor.CHANNELPWD, HeadInterceptor.CHANNELPWDVALUE);
Intent it = new Intent(context, RiskTestActivity.class);
it.putExtra(EXTRA_URL, url);
it.putExtra(EXTRA_HEADERS, (Serializable) headers);
context.startActivity(it);
}
public static void loadUrl(Context context, String data, String mimeType, String encoding) {
Intent it = new Intent(context, RiskTestActivity.class);
it.putExtra(EXTRA_DATA, data);
it.putExtra(EXTRA_MIME_TYPE, mimeType);
it.putExtra(EXTRA_ENCODING, encoding);
context.startActivity(it);
}
public static void loadUrl(Context context, String baseUrl, String data, String mimeType,
String encoding, String historyUrl, Class targetClass) {
Intent it = new Intent(context, targetClass);
it.putExtra(EXTRA_BASE_URL, baseUrl);
it.putExtra(EXTRA_DATA, data);
it.putExtra(EXTRA_MIME_TYPE, mimeType);
it.putExtra(EXTRA_ENCODING, encoding);
it.putExtra(EXTRA_HISTORY_URL, historyUrl);
context.startActivity(it);
}
private String productId;
private boolean canGoBack;
@Inject ReportBannerPresenter presenter;
//上报Id
private BannerId bannerReportId;
private int bannerType;
private int bannerIntentSource;
//banner入库Id
private long bannerId;
@Override protected void onInit(Bundle savedInstanceState) {
super.onInit(savedInstanceState);
DaggerLoanConponent.builder()
.appComponent(Injector.obtain(getApplication()))
.build()
.inject(this);
delegatePresenter(presenter, this);
setDisplayDown(false);
productId = getIntent().getStringExtra(PRODUCT_ID);
bannerType = getIntent().getIntExtra(BANNER_TYPE, 0);
bannerIntentSource = getIntent().getIntExtra(BANNER_SOURCE, 0);
bannerId = getIntent().getLongExtra(BANNER_ID, 0l);
if (bannerType == LIVT_TYPE) {
presenter.reportStartBanner(bannerIntentSource, this, bannerId,
transformType(bannerIntentSource));
}
htmlView.setWebViewClient(new MyWebViewClite());
htmlView.setWebChromeClient(new MyWebChromeClient());
register();
}
@Override protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putParcelable(BANNER_REPORT_ID, bannerReportId);
outState.putString(PRODUCT_ID, productId);
outState.getInt(BANNER_TYPE, bannerType);
outState.putInt(BANNER_SOURCE, bannerIntentSource);
outState.putLong(BANNER_ID, bannerId);
}
@Override protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
bannerReportId = savedInstanceState.getParcelable(BANNER_REPORT_ID);
productId = savedInstanceState.getString(PRODUCT_ID);
bannerType = savedInstanceState.getInt(BANNER_TYPE);
bannerIntentSource = savedInstanceState.getInt(BANNER_SOURCE);
bannerId = savedInstanceState.getLong(BANNER_ID);
}
public void register() {
htmlView.registNativeModule(new NativeModule() {
@Override public String getName() {
return "fiveMine";
}
@ModuleMethod(name = "setUserName")
public void setUserName() {
navigator.navigateToUserName(RiskTestActivity.this);
}
@ModuleMethod(name = "userCertification")
public void userCertification() {
navigator.navigateToIdcard(RiskTestActivity.this);
}
@ModuleMethod(name = "userRate")
public void userRate() {
if (accountManager.isIdentityAuthenticated()) {
navigator.navigateToRiskTest(RiskTestActivity.this,
Flavor.h5Url(RiskTestActivity.this) + Config.RISK_TEST + "1",
accountManager.peekAuthToken(), productId);
finish();
} else {
DialogUtils.showIdentyDialog(RiskTestActivity.this, "实名认证后可测评",
new NotificationDialog.PositiveClickListener() {
@Override public void onPositiveClickListener(View v) {
navigator.navigateToIdcard(RiskTestActivity.this);
}
});
}
}
@ModuleMethod(name = "userShare")
public void userShare() {
if (checkIdentity("分享")) {
SharePopwindow popwindow = new SharePopwindow(RiskTestActivity.this, accountManager);
popwindow.showPop();
}
}
@ModuleMethod(name = "bindBank")
public void bindBank() {
if (checkIdentity("绑卡")) {
navigator.navigateToBankList(RiskTestActivity.this);
}
}
@ModuleMethod(name = "contactInfo")
public void contactInfo() {
if (checkIdentity("添加")) {
navigator.navigateToContacts(RiskTestActivity.this);
}
}
@ModuleMethod(name = "onlineBook")
public void onlineBook() {
navigator.navigateToHome(RiskTestActivity.this, 1);
}
@ModuleMethod(name = "onlineSignature")
public void onlineSignature() {
navigator.navigateToHome(RiskTestActivity.this, 1);
}
@ModuleMethod(name = "callPhone")
public void callPhone(String phone) {
navigator.navigateToCall(RiskTestActivity.this, phone);
}
@ModuleMethod(name = "openLink")
public void openLink(String url) {
if (!Strings.isBlank(url)) {
String linkUrl = url.contains("http") ? url : Flavor.h5Url(RiskTestActivity.this) + url;
RiskTestActivity.loadUrl(RiskTestActivity.this, linkUrl);
}
}
@ModuleMethod(name = "ratingJump")
public void ratingJump(String code) {
//if (code.equals("2")||code.equals("4")) {
// navigator.navigateToProductDetail(RiskTestActivity.this,
// Strings.isBlank(productId) ? 0 : Integer.parseInt(productId),code.equals("2")? 0:1);
//}
RiskTestActivity.this.finish();
}
@ModuleMethod(name = "showIdentityDialog")
public void showIdentityDialog(String tips) {
checkIdentity(tips, true);
}
@ModuleMethod(name = "shareWX")
public void shareWX( String json) {
// String webUrl, String title, String content, Base64 bitmap
if (!Strings.isBlank(json)) {
String webUrl=null;
String title=null;
String content = null;
String bitmap=null;
try {
JSONObject jsonObject = new JSONObject(json);
webUrl = jsonObject.getString("webUrl");
title = jsonObject.getString("title");
content = jsonObject.getString("content");
bitmap = jsonObject.getString("bitmap");
if (Strings.isBlank(webUrl)) {
return;
}
SharePopwindow popwindow = new SharePopwindow(RiskTestActivity.this,RiskTestActivity.this, accountManager,APP_ID,webUrl,title,content,WXShareUtils.stringtoBitmap(bitmap));
popwindow.showPop();
// WXShareUtils.shareWeb(RiskTestActivity.this, APP_ID,
// webUrl, title, content,
// WXShareUtils.stringtoBitmap(bitmap));
} catch (JSONException e) {
e.printStackTrace();
}
}
}
@ModuleMethod(name = "openLive")
public void openLive(String json) {
if (!Strings.isBlank(json)) {
int id;
String url;
try {
JSONObject jsonObject = new JSONObject(json);
id = jsonObject.getInt("idNum");
url = jsonObject.getString("url");
if (Strings.isBlank(url)) {
return;
}
url = url.contains("http") ? url : Flavor.h5Url(RiskTestActivity.this) + url;
RiskTestActivity.loadUrlForBanner(RiskTestActivity.this, url,
RiskTestActivity.LIVT_TYPE,
Constants.LIVE_LIST, id);
} catch (JSONException e) {
e.printStackTrace();
}
}
}
});
}
@Override protected void onDestroy() {
if (htmlView != null) {
ViewGroup parent = (ViewGroup) htmlView.getParent();
if (parent != null) {
parent.removeView(htmlView);
}
htmlView.setWebChromeClient(new WebChromeClient());
htmlView.removeAllViews();
htmlView.destroy();
}
super.onDestroy();
}
@Override protected void onRestart() {
super.onRestart();
if (htmlView != null) {
htmlView.reload();
}
}
@Override public void onResume() {
super.onResume();
}
@Override protected void onHomeAsUp() {
if (canGoBack) {
if (bannerType == LIVT_TYPE && bannerReportId != null) {
presenter.reportEndBanner(bannerIntentSource, this, bannerReportId);
return;
}
finish();
return;
}
if (bannerType == LIVT_TYPE && !htmlView.canGoBack() && bannerReportId != null) {
presenter.reportEndBanner(bannerIntentSource, this, bannerReportId);
return;
}
if (htmlView.canGoBack()) {
htmlView.goBack();
return;
}
super.onHomeAsUp();
}
@Override public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
if (canGoBack) {
if (bannerType == LIVT_TYPE && bannerReportId != null) {
presenter.reportEndBanner(bannerIntentSource, this, bannerReportId);
return true;
}
finish();
return true;
}
if (bannerType == LIVT_TYPE && !htmlView.canGoBack() && bannerReportId != null) {
presenter.reportEndBanner(bannerIntentSource, this, bannerReportId);
return true;
}
if (htmlView.canGoBack()) {
htmlView.goBack();
return true;
}
}
return super.onKeyDown(keyCode, event);
}
@Override public void showId(BannerId bannerId) {
this.bannerReportId = bannerId;
this.bannerReportId.type = transformType(bannerIntentSource);
}
@Override public void modifySuccess() {
finish();
}
@Override public void showLoading() {
showLoadingDialog();
}
@Override public void hideLoading() {
hideLoadingDialog();
}
private class MyWebViewClite extends SampleWebViewClient {
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
final Uri uri = request.getUrl();
if (uri.toString().startsWith("tel:")) {
//Handle telephony Urls
navigator.navigateToCall(RiskTestActivity.this, uri.toString().substring(4));
return true;
}
return super.shouldOverrideUrlLoading(view, request);
}
@Override public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (url.startsWith("tel:")) {
//Handle telephony Urls
navigator.navigateToCall(RiskTestActivity.this, url.substring(4));
return true;
}
return super.shouldOverrideUrlLoading(view, url);
}
@Override public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
if (htmlView != null && isLoadFinish) {
htmlView.invokeJsModule("", "appCallBack");
}
if(!Strings.isBlank(url)){
String parameter = Uri.parse(url).getQueryParameter(H5_PARAMETER);
canGoBack = parameter != null && parameter.equals("1");
}
}
}
private class MyWebChromeClient extends WebChromeClient {
private CustomViewCallback mCustomViewCallback;
// 横屏时,显示视频的view
private View mCustomView;
// 点击全屏按钮时,调用的方法
@Override
public void onShowCustomView(View view, CustomViewCallback callback) {
super.onShowCustomView(view, callback);
//如果view 已经存在,则隐藏
if (mCustomView != null) {
callback.onCustomViewHidden();
return;
}
mCustomView = view;
mCustomView.setVisibility(View.VISIBLE);
mCustomViewCallback = callback;
videoLayout.addView(mCustomView);
videoLayout.setVisibility(View.VISIBLE);
videoLayout.bringToFront();
//设置横屏
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
}
// 取消全屏调用的方法
@Override
public void onHideCustomView() {
super.onHideCustomView();
if (mCustomView == null) {
return;
}
mCustomView.setVisibility(View.GONE);
videoLayout.removeView(mCustomView);
mCustomView = null;
videoLayout.setVisibility(View.GONE);
try {
mCustomViewCallback.onCustomViewHidden();
} catch (Exception e) {
}
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);//竖屏
}
@Override public void onGeolocationPermissionsShowPrompt(String origin,
GeolocationPermissions.Callback callback) {
callback.invoke(origin, true, false);
super.onGeolocationPermissionsShowPrompt(origin, callback);
}
@Override public void onReceivedTitle(WebView view, String t) {
super.onReceivedTitle(view, t);
if (!Strings.isBlank(t) && !t.contains("mintrust")) {
title = t;
setToolbarTitle(t);
}
}
}
/**
* 横竖屏切换监听
*/
@Override
public void onConfigurationChanged(Configuration config) {
super.onConfigurationChanged(config);
switch (config.orientation) {
case Configuration.ORIENTATION_LANDSCAPE:
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
break;
case Configuration.ORIENTATION_PORTRAIT:
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
break;
default:
}
}
private int transformType(int source) {
int type = 0;
switch (source) {
case 5:
type = 1;
break;
case 6:
type = 2;
break;
case 7:
type = 3;
break;
case 8:
type = 4;
break;
default:
}
return type;
}
}
自定义注解
@Target(METHOD) @Retention(RUNTIME)
@Documented
public @interface ModuleMethod {
String name();
}
HTMLActivity
public class HtmlActivity extends BaseActivity {
public static final String EXTRA_TITLE = "extra.html.title";
public static final String EXTRA_URL = "extra.html.url";
public static final String EXTRA_FIRST_URL = "extra.html.first.url";
public static final String EXTRA_DATA = "extra.html.data";
public static final String EXTRA_MIME_TYPE = "extra.html.mime_type";
public static final String EXTRA_ENCODING = "extra.html.encoding";
public static final String EXTRA_BASE_URL = "extra.html.base_url";
public static final String EXTRA_HISTORY_URL = "extra.html.history_url";
public static final String EXTRA_HEADERS = "extra.html.headers";
private static final int FILE_CHOOSER_RESULT_CODE = 0x21;
@BindView(R.id.htmlview) protected CustomHtmlView htmlView;
@BindView(R.id.fl_video) protected FrameLayout videoLayout;
@BindView(R.id.error) protected TextView tvError;
@BindView(R.id.container_tool_bar) protected RelativeLayout layoutTitle;
@BindView(R.id.tv_title_html) protected TextView tvTitle;
public String title;
private String url;
private String firstUrl;
private String currentUrl;
protected String data;
protected String mimeType;
protected String encoding;
private String baseUrl;
private String historyUrl;
private Map<String, String> headers;
private WebViewClient webViewClient;
protected boolean isError, isLoadFinish = false;
private String errorUrl;
private FileChooserModule.FileChoooserCallback fileChoooserCallback;
public static void loadUrl(Context context, String url) {
Intent it = new Intent(context, HtmlActivity.class);
it.putExtra(EXTRA_URL, url);
context.startActivity(it);
}
@Override protected int layoutResId() {
return R.layout.activity_html;
}
@Override protected void onInit(Bundle savedInstanceState) {
DaggerEmptyComponent.builder()
.appComponent(Injector.obtain(getApplication()))
.build()
.inject(this);
isError = false;
errorUrl = null;
firstUrl = "";
currentUrl = "";
htmlView.setWebViewClient(new SampleWebViewClient());
htmlView.setWebChromeClient(new GpsChromeClient());
//htmlView.registNativeModule(fileChooserModule);
htmlView.registNativeModule(new HtmlModule());
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
WebView.setWebContentsDebuggingEnabled(true);
}
if (savedInstanceState != null) {
title = savedInstanceState.getString(EXTRA_TITLE);
firstUrl = savedInstanceState.getString(EXTRA_FIRST_URL);
url = savedInstanceState.getString(EXTRA_URL);
data = savedInstanceState.getString(EXTRA_DATA);
mimeType = savedInstanceState.getString(EXTRA_MIME_TYPE);
encoding = savedInstanceState.getString(EXTRA_ENCODING);
baseUrl = savedInstanceState.getString(EXTRA_BASE_URL);
historyUrl = savedInstanceState.getString(EXTRA_HISTORY_URL);
//noinspection unchecked
headers = (Map<String, String>) savedInstanceState.getSerializable(EXTRA_HEADERS);
} else {
Intent it = getIntent();
title = it.getStringExtra(EXTRA_TITLE);
url = it.getStringExtra(EXTRA_URL);
data = it.getStringExtra(EXTRA_DATA);
mimeType = it.getStringExtra(EXTRA_MIME_TYPE);
encoding = it.getStringExtra(EXTRA_ENCODING);
baseUrl = it.getStringExtra(EXTRA_BASE_URL);
historyUrl = it.getStringExtra(EXTRA_HISTORY_URL);
firstUrl = url;
//noinspection unchecked
headers = (Map<String, String>) it.getSerializableExtra(EXTRA_HEADERS);
}
Timber.i("Load url: " + url);
if (url != null) {
if (headers != null) {
htmlView.loadUrl(url, headers);
} else {
htmlView.loadUrl(url);
}
} else {
if (baseUrl != null) {
htmlView.loadDataWithBaseURL(baseUrl, data, mimeType, encoding, historyUrl);
} else if (data != null) {
htmlView.loadData(data, mimeType, encoding);
}
}
if (!TextUtils.isEmpty(title)) {
setDisplayHomeAsUp(true);
setToolbarTitle(title);
}
}
@Override protected void onResume() {
super.onResume();
htmlView.onResume();
}
@Override protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString(EXTRA_TITLE, title);
outState.putString(EXTRA_URL, url);
outState.putString(EXTRA_FIRST_URL, firstUrl);
outState.putString(EXTRA_DATA, data);
outState.putString(EXTRA_MIME_TYPE, mimeType);
outState.putString(EXTRA_ENCODING, encoding);
outState.putString(EXTRA_BASE_URL, baseUrl);
outState.putString(EXTRA_HEADERS, historyUrl);
outState.putSerializable(EXTRA_HEADERS, (Serializable) headers);
}
@OnClick(R.id.tv_back_html) void back() {
onHomeAsUp();
}
@OnClick(R.id.img_close) void close() {
finish();
}
@Override protected void onDestroy() {
if (null != htmlView) {
ViewGroup viewGroup = (ViewGroup) htmlView.getParent();
if (null != viewGroup) {
viewGroup.removeView(htmlView);
}
}
htmlView.setWebChromeClient(new WebChromeClient());
htmlView.removeAllViews();
htmlView.destroy();
super.onDestroy();
}
public void setWebViewClient(WebViewClient webViewClient) {
this.webViewClient = webViewClient;
if (htmlView != null) {
htmlView.setWebViewClient(new SampleWebViewClient());
}
}
public class SampleWebViewClient extends WebViewClient {
@TargetApi(Build.VERSION_CODES.LOLLIPOP) @Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
final Uri uri = request.getUrl();
if (uri.toString().startsWith("http") || uri.toString().startsWith("https")) {
return super.shouldOverrideUrlLoading(view, request);
}
navigator.navigateToBrowser(HtmlActivity.this, uri.toString());
return true;
}
@Override public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (url.startsWith("http") || url.startsWith("https")) {
return super.shouldOverrideUrlLoading(view, url);
}
navigator.navigateToBrowser(HtmlActivity.this, url);
return true;
}
@Override public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
currentUrl = url;
showLoadingDialog();
if (errorUrl == null || !url.equals(errorUrl)) {
isError = false;
}
if (webViewClient != null) {
webViewClient.onPageStarted(view, url, favicon);
}
}
@SuppressWarnings("deprecation") @Override
public void onReceivedError(WebView view, int errorCode, String description,
String failingUrl) {
super.onReceivedError(view, errorCode, description, failingUrl);
if (errorCode == 612 || errorCode == 401) {
navigator.navigateToLogin(getApplication(), true);
finish();
}
isError = true;
errorUrl = failingUrl;
Timber.e("Html Error:" + errorCode + "----" + description);
if (webViewClient != null) {
webViewClient.onReceivedError(view, errorCode, description, failingUrl);
}
}
@Override
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
super.onReceivedSslError(view, handler, error);
if (webViewClient != null) {
webViewClient.onReceivedSslError(view, handler, error);
}
}
@Override public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
hideLoadingDialog();
if (null != tvError && null != htmlView) {
if (isError) {
isLoadFinish = false;
tvError.setVisibility(View.VISIBLE);
htmlView.setVisibility(View.GONE);
} else {
isLoadFinish = true;
tvError.setVisibility(View.GONE);
htmlView.setVisibility(View.VISIBLE);
}
}
if (webViewClient != null) {
webViewClient.onPageFinished(view, url);
}
}
}
@OnClick(R.id.error) protected void Onclick() {
errorUrl = "";
tvError.setVisibility(View.GONE);
htmlView.reload();
}
@Override public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK && htmlView.canGoBack()) {
htmlView.goBack();
return true;
}
return super.onKeyDown(keyCode, event);
}
@Override protected void onHomeAsUp() {
if (htmlView.canGoBack()) {
htmlView.goBack();
} else {
finish();
}
}
private void openImageChooserActivity() {
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType("image/*");
startActivityForResult(Intent.createChooser(i, "Image Chooser"), FILE_CHOOSER_RESULT_CODE);
}
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
//htmlView.onActivityResult(requestCode, resultCode, data);
}
FileChooserModule fileChooserModule = new FileChooserModule() {
@Override public void onOpenFileChooser(FileChooserModule.FileChooserParams fileChooserParams,
FileChooserModule.FileChoooserCallback mediaPickerCallback) {
fileChoooserCallback = mediaPickerCallback;
openImageChooserActivity();
}
@Override public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (fileChoooserCallback == null) {
return;
}
Uri[] results = null;
if (requestCode == FILE_CHOOSER_RESULT_CODE && resultCode == Activity.RESULT_OK) {
if (data != null) {
String dataString = data.getDataString();
ClipData clipData = null;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) {
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) };
}
}
fileChoooserCallback.invoke(results);
fileChoooserCallback = null;
}
}
};
/**
* h5定位的支持
*/
final class GpsChromeClient extends WebChromeClient {
@Override public void onGeolocationPermissionsShowPrompt(String origin,
GeolocationPermissions.Callback callback) {
callback.invoke(origin, true, false);
super.onGeolocationPermissionsShowPrompt(origin, callback);
}
@Override public void onReceivedTitle(WebView view, String title) {
if (!TextUtils.isEmpty(title) && !title.contains("mintrust")) {
HtmlActivity.this.title = title;
setToolbarTitle(title);
}
}
}
public class HtmlModule extends NativeModule {
@Override public String getName() {
return "fiveMine";
}
@ModuleMethod(name = "goLogin")
public void goLogin() {
accountManager.clear();
activityManager.clear();
navigator.navigateToLogin(HtmlActivity.this, true);
}
@ModuleMethod(name = "openLink")
public void openLink(String url) {
if (!Strings.isBlank(url)) {
String linkUrl = url.contains("http") ? url : Flavor.h5Url(HtmlActivity.this) + url;
RiskTestActivity.loadUrl(HtmlActivity.this, linkUrl);
}
}
@ModuleMethod(name = "showIdentityDialog")
public void showIdentityDialog(String tips) {
checkIdentity(tips, true);
}
@ModuleMethod(name = "callPhone")
public void callPhone(String phone) {
navigator.navigateToCall(HtmlActivity.this, phone);
}
}
}
CustomeHTMLView
public class CustomHtmlView extends BridgeWebView {
private WebSettings webSettings;
public CustomHtmlView(Context context) {
this(context, null);
}
@SuppressLint("SetJavaScriptEnabled") public CustomHtmlView(Context context, AttributeSet attrs) {
super(context, attrs);
webSettings = getSettings();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
webSettings.setLoadsImagesAutomatically(true);
} else {
webSettings.setLoadsImagesAutomatically(false);
}
webSettings.setJavaScriptEnabled(true);
webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
webSettings.setDomStorageEnabled(true);
webSettings.setDatabaseEnabled(true);
webSettings.setAppCacheEnabled(true);
webSettings.setAllowContentAccess(true);
webSettings.setAllowFileAccess(true);
//播放视频准备
webSettings.setLoadWithOverviewMode(true);
webSettings.setUseWideViewPort(true);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
webSettings.setAllowFileAccessFromFileURLs(true);
}
webSettings.setSupportZoom(false);
webSettings.setDisplayZoomControls(false);
webSettings.setCacheMode(WebSettings.LOAD_DEFAULT);
webSettings.setGeolocationEnabled(true);
webSettings.setSupportMultipleWindows(true);
webSettings.setSaveFormData(true);
}
@Override public void setWebViewClient(WebViewClient client) {
super.setWebViewClient(new WebViewClientWrapper(client, webSettings));
}
@Override public void setWebChromeClient(WebChromeClient client) {
super.setWebChromeClient(new WebChromeClientWrapper(client));
}
@Override public boolean onTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
if (this.getScrollY() <= 0) {
this.scrollTo(0, 1);
}
break;
case MotionEvent.ACTION_UP:
// if(this.getScrollY() == 0)
// this.scrollTo(0,-1);
break;
default:
break;
}
return super.onTouchEvent(ev);
}
final class WebViewClientWrapper extends WebViewClient {
final WebViewClient webViewClient;
final WebSettings webSettings;
private WebViewClientWrapper(@NonNull WebViewClient webViewClient,
@NonNull WebSettings webSettings) {
this.webViewClient = webViewClient;
this.webSettings = webSettings;
}
@Override public boolean shouldOverrideUrlLoading(WebView view, String url) {
return webViewClient.shouldOverrideUrlLoading(view, url);
}
@Override public void onPageStarted(WebView view, String url, Bitmap favicon) {
webViewClient.onPageStarted(view, url, favicon);
}
@Override public void onPageFinished(WebView view, String url) {
webViewClient.onPageFinished(view, url);
if (!webSettings.getLoadsImagesAutomatically()) {
webSettings.setLoadsImagesAutomatically(true);
}
}
@Override public void onLoadResource(WebView view, String url) {
webViewClient.onLoadResource(view, url);
}
@TargetApi(Build.VERSION_CODES.M) @Override
public void onPageCommitVisible(WebView view, String url) {
webViewClient.onPageCommitVisible(view, url);
}
@Override public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
return webViewClient.shouldInterceptRequest(view, url);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP) @Override
public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
return webViewClient.shouldInterceptRequest(view, request);
}
@Override public void onTooManyRedirects(WebView view, Message cancelMsg, Message continueMsg) {
webViewClient.onTooManyRedirects(view, cancelMsg, continueMsg);
}
@Override public void onReceivedError(WebView view, int errorCode, String description,
String failingUrl) {
//loadDataWithBaseURL(null, "", "text/html", "utf-8", null);
String data = " ";
loadUrl("javascript:document.body.innerHTML=\"" + data + "\"");
webViewClient.onReceivedError(view, errorCode, description, failingUrl);
}
@TargetApi(Build.VERSION_CODES.M) @Override
public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
webViewClient.onReceivedError(view, request, error);
}
@TargetApi(Build.VERSION_CODES.M) @Override
public void onReceivedHttpError(WebView view, WebResourceRequest request,
WebResourceResponse errorResponse) {
webViewClient.onReceivedHttpError(view, request, errorResponse);
}
@Override public void onFormResubmission(WebView view, Message dontResend, Message resend) {
webViewClient.onFormResubmission(view, dontResend, resend);
}
@Override public void doUpdateVisitedHistory(WebView view, String url, boolean isReload) {
webViewClient.doUpdateVisitedHistory(view, url, isReload);
}
@Override
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
super.onReceivedSslError(view, handler, error);
webViewClient.onReceivedSslError(view, handler, error);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP) @Override
public void onReceivedClientCertRequest(WebView view, ClientCertRequest request) {
webViewClient.onReceivedClientCertRequest(view, request);
}
@Override
public void onReceivedHttpAuthRequest(WebView view, HttpAuthHandler handler, String host,
String realm) {
webViewClient.onReceivedHttpAuthRequest(view, handler, host, realm);
}
@Override public boolean shouldOverrideKeyEvent(WebView view, KeyEvent event) {
return webViewClient.shouldOverrideKeyEvent(view, event);
}
@Override public void onUnhandledKeyEvent(WebView view, KeyEvent event) {
webViewClient.onUnhandledKeyEvent(view, event);
}
@Override public void onScaleChanged(WebView view, float oldScale, float newScale) {
webViewClient.onScaleChanged(view, oldScale, newScale);
}
@Override
public void onReceivedLoginRequest(WebView view, String realm, String account, String args) {
webViewClient.onReceivedLoginRequest(view, realm, account, args);
}
}
final class WebChromeClientWrapper extends WebChromeClient {
final WebChromeClient webChromeClient;
private WebChromeClientWrapper(@NonNull WebChromeClient webChromeClient) {
this.webChromeClient = webChromeClient;
}
@Override public void onProgressChanged(WebView view, int newProgress) {
webChromeClient.onProgressChanged(view, newProgress);
}
@Override public void onReceivedTitle(WebView view, String title) {
webChromeClient.onReceivedTitle(view, title);
}
@Override public void onReceivedIcon(WebView view, Bitmap icon) {
webChromeClient.onReceivedIcon(view, icon);
}
@Override public void onReceivedTouchIconUrl(WebView view, String url, boolean precomposed) {
webChromeClient.onReceivedTouchIconUrl(view, url, precomposed);
}
@Override public void onShowCustomView(View view, CustomViewCallback callback) {
webChromeClient.onShowCustomView(view, callback);
}
@Override
public void onShowCustomView(View view, int requestedOrientation, CustomViewCallback callback) {
webChromeClient.onShowCustomView(view, requestedOrientation, callback);
}
@Override public void onHideCustomView() {
webChromeClient.onHideCustomView();
}
@Override public boolean onCreateWindow(WebView view, boolean isDialog, boolean isUserGesture,
Message resultMsg) {
return webChromeClient.onCreateWindow(view, isDialog, isUserGesture, resultMsg);
}
@Override public void onRequestFocus(WebView view) {
webChromeClient.onRequestFocus(view);
}
@Override public void onCloseWindow(WebView window) {
webChromeClient.onCloseWindow(window);
}
@Override public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
return webChromeClient.onJsAlert(view, url, message, result);
}
@Override
public boolean onJsConfirm(WebView view, String url, String message, JsResult result) {
return webChromeClient.onJsConfirm(view, url, message, result);
}
@Override
public boolean onJsPrompt(WebView view, String url, String message, String defaultValue,
JsPromptResult result) {
return webChromeClient.onJsPrompt(view, url, message, defaultValue, result);
}
@Override
public boolean onJsBeforeUnload(WebView view, String url, String message, JsResult result) {
return webChromeClient.onJsBeforeUnload(view, url, message, result);
}
@Override public void onExceededDatabaseQuota(String url, String databaseIdentifier, long quota,
long estimatedDatabaseSize, long totalQuota, WebStorage.QuotaUpdater quotaUpdater) {
webChromeClient.onExceededDatabaseQuota(url, databaseIdentifier, quota, estimatedDatabaseSize,
totalQuota, quotaUpdater);
}
@Override public void onReachedMaxAppCacheSize(long requiredStorage, long quota,
WebStorage.QuotaUpdater quotaUpdater) {
webChromeClient.onReachedMaxAppCacheSize(requiredStorage, quota, quotaUpdater);
}
@Override public void onGeolocationPermissionsShowPrompt(String origin,
GeolocationPermissions.Callback callback) {
webChromeClient.onGeolocationPermissionsShowPrompt(origin, callback);
}
@Override public void onGeolocationPermissionsHidePrompt() {
webChromeClient.onGeolocationPermissionsHidePrompt();
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP) @Override
public void onPermissionRequest(PermissionRequest request) {
webChromeClient.onPermissionRequest(request);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP) @Override
public void onPermissionRequestCanceled(PermissionRequest request) {
webChromeClient.onPermissionRequestCanceled(request);
}
@Override public boolean onJsTimeout() {
return webChromeClient.onJsTimeout();
}
@Override public void onConsoleMessage(String message, int lineNumber, String sourceID) {
webChromeClient.onConsoleMessage(message, lineNumber, sourceID);
}
@Override public boolean onConsoleMessage(ConsoleMessage consoleMessage) {
return webChromeClient.onConsoleMessage(consoleMessage);
}
@Override public Bitmap getDefaultVideoPoster() {
return webChromeClient.getDefaultVideoPoster();
}
@Override public View getVideoLoadingProgressView() {
return webChromeClient.getVideoLoadingProgressView();
}
@Override public void getVisitedHistory(ValueCallback<String[]> callback) {
webChromeClient.getVisitedHistory(callback);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP) @Override
public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback,
FileChooserParams fileChooserParams) {
return webChromeClient.onShowFileChooser(webView, filePathCallback, fileChooserParams);
}
}
}
BridgeWebView
public class BridgeWebView extends WebView implements JsBridge, OnPageFinishedCallback {
public static final String TAG = "BridgeWebView";
private BridgeDelegate bridgeDelegate;
protected boolean neddRestoreResult = false;
public BridgeWebView(Context context) {
super(context);
init();
}
public BridgeWebView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public BridgeWebView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public BridgeWebView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init();
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public BridgeWebView(Context context, AttributeSet attrs, int defStyleAttr,
boolean privateBrowsing) {
super(context, attrs, defStyleAttr, privateBrowsing);
init();
}
private void init() {
if (isInEditMode()) {
return;
}
bridgeDelegate = new BridgeDelegate(this);
WebSettings settings = getSettings();
settings.setSavePassword(false);
//图片加载
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
settings.setLoadsImagesAutomatically(true);
} else {
settings.setLoadsImagesAutomatically(false);
settings.setBlockNetworkImage(false);
}
if (Build.VERSION.SDK_INT >= 21) {
settings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
}
//js
settings.setJavaScriptEnabled(true);
settings.setJavaScriptCanOpenWindowsAutomatically(true);
//缓存
settings.setDomStorageEnabled(true);
settings.setDatabaseEnabled(true);
settings.setAppCacheEnabled(true);
settings.setCacheMode(WebSettings.LOAD_DEFAULT);
//文件访问
settings.setAllowContentAccess(true);
settings.setAllowFileAccess(true);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
settings.setAllowFileAccessFromFileURLs(true);
}
//显示
settings.setUseWideViewPort(true);
settings.setLoadWithOverviewMode(true);
settings.setSupportZoom(false);
settings.setDisplayZoomControls(false);
settings.setGeolocationEnabled(true);
settings.setSupportMultipleWindows(true);
settings.setSaveFormData(true);
removeJavascriptInterface("searchBoxJavaBridge_");
//允许跨域
SystemUtils.enablecrossdomain(this);
setWebChromeClient(new WebChromeClient());
setWebViewClient(new WebViewClient());
}
@Override public void setWebChromeClient(WebChromeClient client) {
super.setWebChromeClient(new BridgeWebChromeClient(bridgeDelegate, client));
}
@Override public void setWebViewClient(WebViewClient client) {
super.setWebViewClient(new BridgeWebViewClient(this, client));
}
@Override public void onActivityResult(int requestCode, int resultCode, Intent data) {
bridgeDelegate.onActivityResult(requestCode, resultCode, data);
}
@Override public void onRequestPermissionsResult(int requestCode, String[] permissions,
int[] grantResults) {
bridgeDelegate.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
public void onPermissionsGranted(int requestCode, List<String> perms) {
bridgeDelegate.onPermissionsGranted(requestCode, perms);
}
public void onPermissionsDenied(int requestCode, List<String> perms) {
bridgeDelegate.onPermissionsDenied(requestCode, perms);
}
@Override public void handleMessageFromJs(String message) {
bridgeDelegate.handleMessageFromJs(message);
}
@Override public void registNativeModule(NativeModule nativeModule) {
bridgeDelegate.registNativeModule(nativeModule);
}
@Override public <T extends JsModule> T getJsModule(Class<T> jsMTClass) {
return bridgeDelegate.getJsModule(jsMTClass);
}
@Override public void invokeJsModule(String moduleName, String methodName, Object... args) {
bridgeDelegate.invokeJsModule(moduleName, methodName, args);
}
@Override public void invokeJsCallback(String callbackId, JSONArray jsonArray) {
bridgeDelegate.invokeJsCallback(callbackId, jsonArray);
}
public void flusMessageQueue() {
bridgeDelegate.flusMessageQueue();
}
@Override public void enableDebug(boolean debug) {
bridgeDelegate.enableDebug(debug);
}
@Override public void enableQuickInject(boolean quickInject) {
bridgeDelegate.enableQuickInject(quickInject);
}
@Override public void tryInjectJsBridge(boolean reset, boolean forceInject) {
bridgeDelegate.tryInjectJsBridge(reset, forceInject);
}
@Override protected void onRestoreInstanceState(Parcelable state) {
super.onRestoreInstanceState(state);
neddRestoreResult = true;
}
@Override public void onPageFinished(WebView view, String url) {
bridgeDelegate.onPageFinished(view, url);
}
}
JSBridge
public interface JsBridge {
String JS_BRIDGE_NAME = "NativeBridge";
String BRIDGE_JS = "Bridge.js";
String BRIDGE_SCHEME = "jsbridge://";
String QUEUE_HAS_MESSAGE = BRIDGE_SCHEME + "has_message/";
String RETURN_DATA = BRIDGE_SCHEME + "return_data/";
String JS_HANDLE_MESSAGE_FROM_JAVA =
"javascript:window." + JS_BRIDGE_NAME + ".handleMessageFromNative('%s');";
String JS_FETCH_QUEUE = "javascript:window." + JS_BRIDGE_NAME + ".fetchQueue();";
void enableDebug(boolean debug);
/**
* 是否启用快速注入。 如果注入的接口对象可能被h5覆盖可采用慢注入
* @param quickInject 默认true, 如果 false,只会在pageFinish后注入
*/
void enableQuickInject(boolean quickInject);
/**
* 尝试注入bridge。 为保证注入速度和成功率,会在多个时间尝试注入
* @param reset 重置至未注入状态
* @param force 不管是否已注入,强制再次注入
*/
void tryInjectJsBridge(boolean reset, boolean force);
void handleMessageFromJs(String message);
void invokeJsModule(String moduleName, String methodName, Object[] args);
void invokeJsCallback(String callbackId, JSONArray jsonArray);
void registNativeModule(NativeModule bridgeModule);
<T extends JsModule> T getJsModule(Class<T> jsMTClass);
void flusMessageQueue();
void onActivityResult(int requestCode, int resultCode, Intent data);
void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults);
void onPermissionsGranted(int requestCode, List<String> perms);
void onPermissionsDenied(int requestCode, List<String> perms);
}
OnPageFinishedCallback
public interface OnPageFinishedCallback {
void onPageFinished(WebView view, String url);
}