/* Copyright 2012-2013, Polyvi Inc. (http://polyvi.github.io/openxface) This program is distributed under the terms of the GNU General Public License. This file is part of xFace. xFace is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. xFace is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with xFace. If not, see <http://www.gnu.org/licenses/>. */ package com.polyvi.xface.view; import org.apache.cordova.CordovaWebView; import org.apache.cordova.LOG; import android.content.Context; import android.view.MotionEvent; import android.view.View; import com.polyvi.xface.app.XApplication; import com.polyvi.xface.core.XISystemContext; import com.polyvi.xface.event.XEvent; import com.polyvi.xface.event.XEventType; import com.polyvi.xface.event.XISystemEventReceiver; import com.polyvi.xface.util.XUtils; /** * application对应的WebView封装,用于显示application */ public class XAppWebView extends CordovaWebView implements XISystemEventReceiver { public static final String CLASS_NAME = "XAppWebView"; public static final int EMPTPY_VIEW_ID = Integer.MAX_VALUE; private int mViewId; /** < view id,每个view的id唯一 */ private XTouchEventHandler mTouchEventHandler; private XWebViewClient mWebViewClient; /** 该视图是否有效 */ private boolean mIsValid; protected XApplication mOwnerApp; protected XISystemContext mSystemCtx; public XAppWebView(XISystemContext systemContext) { super(systemContext.getContext()); mSystemCtx = systemContext; mViewId = XUtils.generateRandomId(); mTouchEventHandler = new XTouchEventHandler(); registerSystemEventReceiver(); getSettings().setUseWideViewPort(true); } private void registerSystemEventReceiver() { mSystemCtx.getEventCenter().registerReceiver(this, XEventType.MSG_RECEIVED); mSystemCtx.getEventCenter().registerReceiver(this, XEventType.CALL_RECEIVED); mSystemCtx.getEventCenter().registerReceiver(this, XEventType.PUSH_MSG_RECEIVED); mSystemCtx.getEventCenter().registerReceiver(this, XEventType.EXTERNAL_MESSAGE_RECEIVED); } private void unRegisterSystemEventReceiver() { mSystemCtx.getEventCenter().unregisterReceiver(this); } @Override public void onReceived(Context context, XEvent evt) { if (evt.getType() == XEventType.MSG_RECEIVED) { String msgs = (String) evt.getData(); handleMsgEvent(msgs); } else if (evt.getType() == XEventType.CALL_RECEIVED) { int callStatus = (Integer) evt.getData(); handleCallReceived(callStatus); } else if (evt.getType() == XEventType.EXTERNAL_MESSAGE_RECEIVED) { String msgs = (String) evt.getData(); handleExternalMessage(msgs); } } /** * 处理短信事件 * * @param msgs */ private void handleMsgEvent(String msgs) { String jsScript = "try{ cordova.require('cordova/channel').onMsgReceived.fire('" + msgs + "');}catch(e){console.log('msg rcv : ' + e);}"; sendJavascript(jsScript); } /** * 处理来电事件 * * @param callStatus */ private void handleCallReceived(int callStatus) { String jsScript = "try{ cordova.require('cordova/channel').onCallReceived.fire('" + callStatus + "');}catch(e){console.log('call rcv : ' + e);}"; sendJavascript(jsScript); } /** * 处理通知事件 * * @param message */ public void handleNotificationReceived(String message) { String jsScript = "try{ cordova.require('com.polyvi.xface.extension.push.PushNotification').fire('" + message + "');}catch(e){console.log('call rcv : ' + e);}"; sendJavascript(jsScript); } /** * 处理外部程序发过来参数的消息 * * @param message */ private void handleExternalMessage(String message) { String jsScript = "try{xFace.require('xFace/app').fireAppEvent('client','" + message + "');}catch(e){console.log('exception in fireAppEvent:' + e);}"; jsScript = jsScript.replaceAll("'", "\\\\'"); jsScript = jsScript.replaceAll("\"", "\\\\\""); sendJavascript(jsScript); } @Override public void loadUrlIntoView(String url, int time) { // If not first page of app, then load immediately // Add support for browser history if we use it. if ((url.startsWith("javascript:")) || this.canGoBack()) { } // If first page, then show splashscreen else { LOG.d(TAG, "loadUrlIntoView(%s, %d)", url, time); // Send message to show splashscreen now if desired if (this instanceof XStartAppView) { this.postMessage("splashscreen", "show"); } } // Load url this.loadUrlIntoView(url); } /** * 处理双击以及多次连击时自动放大的情况 * * @param event * 交互事件 * @return 如果事件被处理了返回true,否则返回false */ @Override public boolean onTouchEvent(MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { mOwnerApp.resetIdleWatcher(); } mTouchEventHandler.handleTouchEvent(event, this); return super.onTouchEvent(event); } public int getViewId() { return mViewId; } @Override public void loadUrl(String url) { super.loadUrl(url); this.setOnLongClickListener(new View.OnLongClickListener() { @Override public boolean onLongClick(View v) { // 重载onLongClick,阻止Android 4.0系统中出现默认text selection行为. // 经过测试,不影响touchstart, touchmove, touchend等events return true; } }); } /** * 设置适配是否完成标志 * * @param adapt * adapt为true则表示适配完成,false表示适配未完成这时不响应双击时将viewport设置为false */ public void setAdapated(boolean adapt) { mTouchEventHandler.setAdapated(adapt); } public void setValid(boolean isValid) { this.mIsValid = isValid; } public boolean isValid() { return mIsValid; } /** * 获取ownerApp * * @return */ public XApplication getOwnerApp() { return mOwnerApp; } public void setOwnerApp(XApplication app) { this.mOwnerApp = app; } public XWebViewClient getWebViewClient() { return mWebViewClient; } /** * 关闭app * * @param viewId * 须要被关闭app对应的viewid */ public void handleCloseApplication(int viewId) { // 调用父类的消息发送 super.postMessage("exit_engine", null); } public void willClosed() { this.postMessage("spinner", "stop"); unRegisterSystemEventReceiver(); } /** * 调用父类的clearHistory,避免super在UI线程的语法错误 */ private void callSuperClearHistory() { super.clearHistory(); } @Override public void clearHistory() { mSystemCtx.getActivity().runOnUiThread(new Runnable() { @Override public void run() { callSuperClearHistory(); } }); } }