Added amazon-fireos platform.
Change to use amazon-fireos as the platform if user agent string contains 'cordova-amazon-fireos'
This commit is contained in:
parent
d49d6ec62f
commit
e5101ba8e1
13
plugin.xml
13
plugin.xml
@ -31,6 +31,19 @@
|
|||||||
<source-file src="src/android/InAppChromeClient.java" target-dir="src/org/apache/cordova/inappbrowser" />
|
<source-file src="src/android/InAppChromeClient.java" target-dir="src/org/apache/cordova/inappbrowser" />
|
||||||
</platform>
|
</platform>
|
||||||
|
|
||||||
|
<!-- amazon-fireos -->
|
||||||
|
<platform name="amazon-fireos">
|
||||||
|
<config-file target="res/xml/config.xml" parent="/*">
|
||||||
|
<feature name="InAppBrowser">
|
||||||
|
<param name="android-package" value="org.apache.cordova.inappbrowser.InAppBrowser"/>
|
||||||
|
</feature>
|
||||||
|
</config-file>
|
||||||
|
|
||||||
|
<source-file src="src/amazon/InAppBrowser.java" target-dir="src/org/apache/cordova/inappbrowser" />
|
||||||
|
<source-file src="src/amazon/InAppChromeClient.java" target-dir="src/org/apache/cordova/inappbrowser" />
|
||||||
|
</platform>
|
||||||
|
|
||||||
|
|
||||||
<!-- ios -->
|
<!-- ios -->
|
||||||
<platform name="ios">
|
<platform name="ios">
|
||||||
<config-file target="config.xml" parent="/*">
|
<config-file target="config.xml" parent="/*">
|
||||||
|
769
src/amazon/InAppBrowser.java
Normal file
769
src/amazon/InAppBrowser.java
Normal file
@ -0,0 +1,769 @@
|
|||||||
|
/*
|
||||||
|
Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
or more contributor license agreements. See the NOTICE file
|
||||||
|
distributed with this work for additional information
|
||||||
|
regarding copyright ownership. The ASF licenses this file
|
||||||
|
to you under the Apache License, Version 2.0 (the
|
||||||
|
"License"); you may not use this file except in compliance
|
||||||
|
with the License. You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing,
|
||||||
|
software distributed under the License is distributed on an
|
||||||
|
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
KIND, either express or implied. See the License for the
|
||||||
|
specific language governing permissions and limitations
|
||||||
|
under the License.
|
||||||
|
*/
|
||||||
|
package org.apache.cordova.inappbrowser;
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
|
import android.app.Dialog;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.text.InputType;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.util.TypedValue;
|
||||||
|
import android.view.Gravity;
|
||||||
|
import android.view.KeyEvent;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.Window;
|
||||||
|
import android.view.WindowManager;
|
||||||
|
import android.view.WindowManager.LayoutParams;
|
||||||
|
import android.view.inputmethod.EditorInfo;
|
||||||
|
import android.view.inputmethod.InputMethodManager;
|
||||||
|
import com.amazon.android.webkit.AmazonWebChromeClient;
|
||||||
|
import com.amazon.android.webkit.AmazonGeolocationPermissions.Callback;
|
||||||
|
import com.amazon.android.webkit.AmazonJsPromptResult;
|
||||||
|
import com.amazon.android.webkit.AmazonWebSettings;
|
||||||
|
import com.amazon.android.webkit.AmazonWebStorage;
|
||||||
|
import com.amazon.android.webkit.AmazonWebView;
|
||||||
|
import com.amazon.android.webkit.AmazonWebViewClient;
|
||||||
|
import com.amazon.android.webkit.AmazonCookieManager;
|
||||||
|
import android.widget.Button;
|
||||||
|
import android.widget.EditText;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
|
import android.widget.RelativeLayout;
|
||||||
|
|
||||||
|
import org.apache.cordova.CallbackContext;
|
||||||
|
import org.apache.cordova.Config;
|
||||||
|
import org.apache.cordova.CordovaArgs;
|
||||||
|
import org.apache.cordova.CordovaPlugin;
|
||||||
|
import org.apache.cordova.CordovaWebView;
|
||||||
|
import org.apache.cordova.LOG;
|
||||||
|
import org.apache.cordova.PluginResult;
|
||||||
|
import org.apache.cordova.CordovaActivity;
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.StringTokenizer;
|
||||||
|
|
||||||
|
@SuppressLint("SetJavaScriptEnabled")
|
||||||
|
public class InAppBrowser extends CordovaPlugin {
|
||||||
|
|
||||||
|
private static final String NULL = "null";
|
||||||
|
protected static final String LOG_TAG = "InAppBrowser";
|
||||||
|
private static final String SELF = "_self";
|
||||||
|
private static final String SYSTEM = "_system";
|
||||||
|
// private static final String BLANK = "_blank";
|
||||||
|
private static final String EXIT_EVENT = "exit";
|
||||||
|
private static final String LOCATION = "location";
|
||||||
|
private static final String HIDDEN = "hidden";
|
||||||
|
private static final String LOAD_START_EVENT = "loadstart";
|
||||||
|
private static final String LOAD_STOP_EVENT = "loadstop";
|
||||||
|
private static final String LOAD_ERROR_EVENT = "loaderror";
|
||||||
|
private static final String CLOSE_BUTTON_CAPTION = "closebuttoncaption";
|
||||||
|
private static final String CLEAR_ALL_CACHE = "clearcache";
|
||||||
|
private static final String CLEAR_SESSION_CACHE = "clearsessioncache";
|
||||||
|
|
||||||
|
private Dialog dialog;
|
||||||
|
private AmazonWebView inAppWebView;
|
||||||
|
private EditText edittext;
|
||||||
|
private CallbackContext callbackContext;
|
||||||
|
private boolean showLocationBar = true;
|
||||||
|
private boolean openWindowHidden = false;
|
||||||
|
private String buttonLabel = "Done";
|
||||||
|
private boolean clearAllCache= false;
|
||||||
|
private boolean clearSessionCache=false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executes the request and returns PluginResult.
|
||||||
|
*
|
||||||
|
* @param action The action to execute.
|
||||||
|
* @param args JSONArry of arguments for the plugin.
|
||||||
|
* @param callbackId The callback id used when calling back into JavaScript.
|
||||||
|
* @return A PluginResult object with a status and message.
|
||||||
|
*/
|
||||||
|
public boolean execute(String action, CordovaArgs args, final CallbackContext callbackContext) throws JSONException {
|
||||||
|
if (action.equals("open")) {
|
||||||
|
this.callbackContext = callbackContext;
|
||||||
|
final String url = args.getString(0);
|
||||||
|
String t = args.optString(1);
|
||||||
|
if (t == null || t.equals("") || t.equals(NULL)) {
|
||||||
|
t = SELF;
|
||||||
|
}
|
||||||
|
final String target = t;
|
||||||
|
final HashMap<String, Boolean> features = parseFeature(args.optString(2));
|
||||||
|
|
||||||
|
Log.d(LOG_TAG, "target = " + target);
|
||||||
|
|
||||||
|
this.cordova.getActivity().runOnUiThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
String result = "";
|
||||||
|
// SELF
|
||||||
|
if (SELF.equals(target)) {
|
||||||
|
Log.d(LOG_TAG, "in self");
|
||||||
|
// load in webview
|
||||||
|
if (url.startsWith("file://") || url.startsWith("javascript:")
|
||||||
|
|| Config.isUrlWhiteListed(url)) {
|
||||||
|
webView.loadUrl(url);
|
||||||
|
}
|
||||||
|
//Load the dialer
|
||||||
|
else if (url.startsWith(AmazonWebView.SCHEME_TEL))
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
Intent intent = new Intent(Intent.ACTION_DIAL);
|
||||||
|
intent.setData(Uri.parse(url));
|
||||||
|
cordova.getActivity().startActivity(intent);
|
||||||
|
} catch (android.content.ActivityNotFoundException e) {
|
||||||
|
LOG.e(LOG_TAG, "Error dialing " + url + ": " + e.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// load in InAppBrowser
|
||||||
|
else {
|
||||||
|
result = showWebPage(url, features);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// SYSTEM
|
||||||
|
else if (SYSTEM.equals(target)) {
|
||||||
|
Log.d(LOG_TAG, "in system");
|
||||||
|
result = openExternal(url);
|
||||||
|
}
|
||||||
|
// BLANK - or anything else
|
||||||
|
else {
|
||||||
|
Log.d(LOG_TAG, "in blank");
|
||||||
|
result = showWebPage(url, features);
|
||||||
|
}
|
||||||
|
|
||||||
|
PluginResult pluginResult = new PluginResult(PluginResult.Status.OK, result);
|
||||||
|
pluginResult.setKeepCallback(true);
|
||||||
|
callbackContext.sendPluginResult(pluginResult);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else if (action.equals("close")) {
|
||||||
|
closeDialog();
|
||||||
|
}
|
||||||
|
else if (action.equals("injectScriptCode")) {
|
||||||
|
String jsWrapper = null;
|
||||||
|
if (args.getBoolean(1)) {
|
||||||
|
jsWrapper = String.format("prompt(JSON.stringify([eval(%%s)]), 'gap-iab://%s')", callbackContext.getCallbackId());
|
||||||
|
}
|
||||||
|
injectDeferredObject(args.getString(0), jsWrapper);
|
||||||
|
}
|
||||||
|
else if (action.equals("injectScriptFile")) {
|
||||||
|
String jsWrapper;
|
||||||
|
if (args.getBoolean(1)) {
|
||||||
|
jsWrapper = String.format("(function(d) { var c = d.createElement('script'); c.src = %%s; c.onload = function() { prompt('', 'gap-iab://%s'); }; d.body.appendChild(c); })(document)", callbackContext.getCallbackId());
|
||||||
|
} else {
|
||||||
|
jsWrapper = "(function(d) { var c = d.createElement('script'); c.src = %s; d.body.appendChild(c); })(document)";
|
||||||
|
}
|
||||||
|
injectDeferredObject(args.getString(0), jsWrapper);
|
||||||
|
}
|
||||||
|
else if (action.equals("injectStyleCode")) {
|
||||||
|
String jsWrapper;
|
||||||
|
if (args.getBoolean(1)) {
|
||||||
|
jsWrapper = String.format("(function(d) { var c = d.createElement('style'); c.innerHTML = %%s; d.body.appendChild(c); prompt('', 'gap-iab://%s');})(document)", callbackContext.getCallbackId());
|
||||||
|
} else {
|
||||||
|
jsWrapper = "(function(d) { var c = d.createElement('style'); c.innerHTML = %s; d.body.appendChild(c); })(document)";
|
||||||
|
}
|
||||||
|
injectDeferredObject(args.getString(0), jsWrapper);
|
||||||
|
}
|
||||||
|
else if (action.equals("injectStyleFile")) {
|
||||||
|
String jsWrapper;
|
||||||
|
if (args.getBoolean(1)) {
|
||||||
|
jsWrapper = String.format("(function(d) { var c = d.createElement('link'); c.rel='stylesheet'; c.type='text/css'; c.href = %%s; d.head.appendChild(c); prompt('', 'gap-iab://%s');})(document)", callbackContext.getCallbackId());
|
||||||
|
} else {
|
||||||
|
jsWrapper = "(function(d) { var c = d.createElement('link'); c.rel='stylesheet'; c.type='text/css'; c.href = %s; d.head.appendChild(c); })(document)";
|
||||||
|
}
|
||||||
|
injectDeferredObject(args.getString(0), jsWrapper);
|
||||||
|
}
|
||||||
|
else if (action.equals("show")) {
|
||||||
|
this.cordova.getActivity().runOnUiThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
dialog.show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
PluginResult pluginResult = new PluginResult(PluginResult.Status.OK);
|
||||||
|
pluginResult.setKeepCallback(true);
|
||||||
|
this.callbackContext.sendPluginResult(pluginResult);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the view navigates.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void onReset() {
|
||||||
|
closeDialog();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called by AccelBroker when listener is to be shut down.
|
||||||
|
* Stop listener.
|
||||||
|
*/
|
||||||
|
public void onDestroy() {
|
||||||
|
closeDialog();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inject an object (script or style) into the InAppBrowser AmazonWebView.
|
||||||
|
*
|
||||||
|
* This is a helper method for the inject{Script|Style}{Code|File} API calls, which
|
||||||
|
* provides a consistent method for injecting JavaScript code into the document.
|
||||||
|
*
|
||||||
|
* If a wrapper string is supplied, then the source string will be JSON-encoded (adding
|
||||||
|
* quotes) and wrapped using string formatting. (The wrapper string should have a single
|
||||||
|
* '%s' marker)
|
||||||
|
*
|
||||||
|
* @param source The source object (filename or script/style text) to inject into
|
||||||
|
* the document.
|
||||||
|
* @param jsWrapper A JavaScript string to wrap the source string in, so that the object
|
||||||
|
* is properly injected, or null if the source string is JavaScript text
|
||||||
|
* which should be executed directly.
|
||||||
|
*/
|
||||||
|
private void injectDeferredObject(String source, String jsWrapper) {
|
||||||
|
final String scriptToInject;
|
||||||
|
if (jsWrapper != null) {
|
||||||
|
org.json.JSONArray jsonEsc = new org.json.JSONArray();
|
||||||
|
jsonEsc.put(source);
|
||||||
|
String jsonRepr = jsonEsc.toString();
|
||||||
|
String jsonSourceString = jsonRepr.substring(1, jsonRepr.length()-1);
|
||||||
|
scriptToInject = String.format(jsWrapper, jsonSourceString);
|
||||||
|
} else {
|
||||||
|
scriptToInject = source;
|
||||||
|
}
|
||||||
|
final String finalScriptToInject = scriptToInject;
|
||||||
|
// This action will have the side-effect of blurring the currently focused element
|
||||||
|
this.cordova.getActivity().runOnUiThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
inAppWebView.loadUrl("javascript:" + finalScriptToInject);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Put the list of features into a hash map
|
||||||
|
*
|
||||||
|
* @param optString
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private HashMap<String, Boolean> parseFeature(String optString) {
|
||||||
|
if (optString.equals(NULL)) {
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
HashMap<String, Boolean> map = new HashMap<String, Boolean>();
|
||||||
|
StringTokenizer features = new StringTokenizer(optString, ",");
|
||||||
|
StringTokenizer option;
|
||||||
|
while(features.hasMoreElements()) {
|
||||||
|
option = new StringTokenizer(features.nextToken(), "=");
|
||||||
|
if (option.hasMoreElements()) {
|
||||||
|
String key = option.nextToken();
|
||||||
|
if (key.equalsIgnoreCase(CLOSE_BUTTON_CAPTION)) {
|
||||||
|
this.buttonLabel = option.nextToken();
|
||||||
|
} else {
|
||||||
|
Boolean value = option.nextToken().equals("no") ? Boolean.FALSE : Boolean.TRUE;
|
||||||
|
map.put(key, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display a new browser with the specified URL.
|
||||||
|
*
|
||||||
|
* @param url The url to load.
|
||||||
|
* @param usePhoneGap Load url in PhoneGap webview
|
||||||
|
* @return "" if ok, or error message.
|
||||||
|
*/
|
||||||
|
public String openExternal(String url) {
|
||||||
|
try {
|
||||||
|
Intent intent = null;
|
||||||
|
intent = new Intent(Intent.ACTION_VIEW);
|
||||||
|
intent.setData(Uri.parse(url));
|
||||||
|
this.cordova.getActivity().startActivity(intent);
|
||||||
|
return "";
|
||||||
|
} catch (android.content.ActivityNotFoundException e) {
|
||||||
|
Log.d(LOG_TAG, "InAppBrowser: Error loading url "+url+":"+ e.toString());
|
||||||
|
return e.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Closes the dialog
|
||||||
|
*/
|
||||||
|
public void closeDialog() {
|
||||||
|
this.cordova.getActivity().runOnUiThread(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
if (dialog != null) {
|
||||||
|
dialog.dismiss();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks to see if it is possible to go back one page in history, then does so.
|
||||||
|
*/
|
||||||
|
private void goBack() {
|
||||||
|
this.cordova.getActivity().runOnUiThread(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
if (InAppBrowser.this.inAppWebView.canGoBack()) {
|
||||||
|
InAppBrowser.this.inAppWebView.goBack();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks to see if it is possible to go forward one page in history, then does so.
|
||||||
|
*/
|
||||||
|
private void goForward() {
|
||||||
|
this.cordova.getActivity().runOnUiThread(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
if (InAppBrowser.this.inAppWebView.canGoForward()) {
|
||||||
|
InAppBrowser.this.inAppWebView.goForward();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Navigate to the new page
|
||||||
|
*
|
||||||
|
* @param url to load
|
||||||
|
*/
|
||||||
|
private void navigate(final String url) {
|
||||||
|
InputMethodManager imm = (InputMethodManager)this.cordova.getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||||
|
imm.hideSoftInputFromWindow(edittext.getWindowToken(), 0);
|
||||||
|
|
||||||
|
this.cordova.getActivity().runOnUiThread(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
if (!url.startsWith("http") && !url.startsWith("file:")) {
|
||||||
|
InAppBrowser.this.inAppWebView.loadUrl("http://" + url);
|
||||||
|
} else {
|
||||||
|
InAppBrowser.this.inAppWebView.loadUrl(url);
|
||||||
|
}
|
||||||
|
InAppBrowser.this.inAppWebView.requestFocus();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Should we show the location bar?
|
||||||
|
*
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
private boolean getShowLocationBar() {
|
||||||
|
return this.showLocationBar;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display a new browser with the specified URL.
|
||||||
|
*
|
||||||
|
* @param url The url to load.
|
||||||
|
* @param jsonObject
|
||||||
|
*/
|
||||||
|
public String showWebPage(final String url, HashMap<String, Boolean> features) {
|
||||||
|
// Determine if we should hide the location bar.
|
||||||
|
showLocationBar = true;
|
||||||
|
openWindowHidden = false;
|
||||||
|
if (features != null) {
|
||||||
|
Boolean show = features.get(LOCATION);
|
||||||
|
if (show != null) {
|
||||||
|
showLocationBar = show.booleanValue();
|
||||||
|
}
|
||||||
|
Boolean hidden = features.get(HIDDEN);
|
||||||
|
if (hidden != null) {
|
||||||
|
openWindowHidden = hidden.booleanValue();
|
||||||
|
}
|
||||||
|
Boolean cache = features.get(CLEAR_ALL_CACHE);
|
||||||
|
if (cache != null) {
|
||||||
|
clearAllCache = cache.booleanValue();
|
||||||
|
} else {
|
||||||
|
cache = features.get(CLEAR_SESSION_CACHE);
|
||||||
|
if (cache != null) {
|
||||||
|
clearSessionCache = cache.booleanValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final CordovaWebView thatWebView = this.webView;
|
||||||
|
|
||||||
|
// Create dialog in new thread
|
||||||
|
Runnable runnable = new Runnable() {
|
||||||
|
/**
|
||||||
|
* Convert our DIP units to Pixels
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
private int dpToPixels(int dipValue) {
|
||||||
|
int value = (int) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP,
|
||||||
|
(float) dipValue,
|
||||||
|
cordova.getActivity().getResources().getDisplayMetrics()
|
||||||
|
);
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void run() {
|
||||||
|
// Let's create the main dialog
|
||||||
|
dialog = new Dialog(cordova.getActivity(), android.R.style.Theme_NoTitleBar);
|
||||||
|
dialog.getWindow().getAttributes().windowAnimations = android.R.style.Animation_Dialog;
|
||||||
|
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||||
|
dialog.setCancelable(true);
|
||||||
|
dialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
|
||||||
|
public void onDismiss(DialogInterface dialog) {
|
||||||
|
closeDialog();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Main container layout
|
||||||
|
LinearLayout main = new LinearLayout(cordova.getActivity());
|
||||||
|
main.setOrientation(LinearLayout.VERTICAL);
|
||||||
|
|
||||||
|
// Toolbar layout
|
||||||
|
RelativeLayout toolbar = new RelativeLayout(cordova.getActivity());
|
||||||
|
//Please, no more black!
|
||||||
|
toolbar.setBackgroundColor(android.graphics.Color.LTGRAY);
|
||||||
|
toolbar.setLayoutParams(new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, this.dpToPixels(44)));
|
||||||
|
toolbar.setPadding(this.dpToPixels(2), this.dpToPixels(2), this.dpToPixels(2), this.dpToPixels(2));
|
||||||
|
toolbar.setHorizontalGravity(Gravity.LEFT);
|
||||||
|
toolbar.setVerticalGravity(Gravity.TOP);
|
||||||
|
|
||||||
|
// Action Button Container layout
|
||||||
|
RelativeLayout actionButtonContainer = new RelativeLayout(cordova.getActivity());
|
||||||
|
actionButtonContainer.setLayoutParams(new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
|
||||||
|
actionButtonContainer.setHorizontalGravity(Gravity.LEFT);
|
||||||
|
actionButtonContainer.setVerticalGravity(Gravity.CENTER_VERTICAL);
|
||||||
|
actionButtonContainer.setId(1);
|
||||||
|
|
||||||
|
// Back button
|
||||||
|
Button back = new Button(cordova.getActivity());
|
||||||
|
RelativeLayout.LayoutParams backLayoutParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
|
||||||
|
backLayoutParams.addRule(RelativeLayout.ALIGN_LEFT);
|
||||||
|
back.setLayoutParams(backLayoutParams);
|
||||||
|
back.setContentDescription("Back Button");
|
||||||
|
back.setId(2);
|
||||||
|
back.setText("<");
|
||||||
|
back.setOnClickListener(new View.OnClickListener() {
|
||||||
|
public void onClick(View v) {
|
||||||
|
goBack();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Forward button
|
||||||
|
Button forward = new Button(cordova.getActivity());
|
||||||
|
RelativeLayout.LayoutParams forwardLayoutParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
|
||||||
|
forwardLayoutParams.addRule(RelativeLayout.RIGHT_OF, 2);
|
||||||
|
forward.setLayoutParams(forwardLayoutParams);
|
||||||
|
forward.setContentDescription("Forward Button");
|
||||||
|
forward.setId(3);
|
||||||
|
forward.setText(">");
|
||||||
|
forward.setOnClickListener(new View.OnClickListener() {
|
||||||
|
public void onClick(View v) {
|
||||||
|
goForward();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Edit Text Box
|
||||||
|
edittext = new EditText(cordova.getActivity());
|
||||||
|
RelativeLayout.LayoutParams textLayoutParams = new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
|
||||||
|
textLayoutParams.addRule(RelativeLayout.RIGHT_OF, 1);
|
||||||
|
textLayoutParams.addRule(RelativeLayout.LEFT_OF, 5);
|
||||||
|
edittext.setLayoutParams(textLayoutParams);
|
||||||
|
edittext.setId(4);
|
||||||
|
edittext.setSingleLine(true);
|
||||||
|
edittext.setText(url);
|
||||||
|
edittext.setInputType(InputType.TYPE_TEXT_VARIATION_URI);
|
||||||
|
edittext.setImeOptions(EditorInfo.IME_ACTION_GO);
|
||||||
|
edittext.setInputType(InputType.TYPE_NULL); // Will not except input... Makes the text NON-EDITABLE
|
||||||
|
edittext.setOnKeyListener(new View.OnKeyListener() {
|
||||||
|
public boolean onKey(View v, int keyCode, KeyEvent event) {
|
||||||
|
// If the event is a key-down event on the "enter" button
|
||||||
|
if ((event.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_ENTER)) {
|
||||||
|
navigate(edittext.getText().toString());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Close button
|
||||||
|
Button close = new Button(cordova.getActivity());
|
||||||
|
RelativeLayout.LayoutParams closeLayoutParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
|
||||||
|
closeLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
|
||||||
|
close.setLayoutParams(closeLayoutParams);
|
||||||
|
forward.setContentDescription("Close Button");
|
||||||
|
close.setId(5);
|
||||||
|
close.setText(buttonLabel);
|
||||||
|
close.setOnClickListener(new View.OnClickListener() {
|
||||||
|
public void onClick(View v) {
|
||||||
|
closeDialog();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// WebView
|
||||||
|
inAppWebView = new AmazonWebView(cordova.getActivity());
|
||||||
|
|
||||||
|
CordovaActivity app = (CordovaActivity) cordova.getActivity();
|
||||||
|
cordova.getFactory().initializeWebView(inAppWebView, 0x00FF00, false, null);
|
||||||
|
|
||||||
|
inAppWebView.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
|
||||||
|
inAppWebView.setWebChromeClient(new InAppChromeClient(thatWebView));
|
||||||
|
AmazonWebViewClient client = new InAppBrowserClient(thatWebView, edittext);
|
||||||
|
inAppWebView.setWebViewClient(client);
|
||||||
|
AmazonWebSettings settings = inAppWebView.getSettings();
|
||||||
|
settings.setJavaScriptEnabled(true);
|
||||||
|
settings.setJavaScriptCanOpenWindowsAutomatically(true);
|
||||||
|
settings.setBuiltInZoomControls(true);
|
||||||
|
settings.setPluginState(com.amazon.android.webkit.AmazonWebSettings.PluginState.ON);
|
||||||
|
|
||||||
|
//Toggle whether this is enabled or not!
|
||||||
|
Bundle appSettings = cordova.getActivity().getIntent().getExtras();
|
||||||
|
boolean enableDatabase = appSettings == null ? true : appSettings.getBoolean("InAppBrowserStorageEnabled", true);
|
||||||
|
if (enableDatabase) {
|
||||||
|
String databasePath = cordova.getActivity().getApplicationContext().getDir("inAppBrowserDB", Context.MODE_PRIVATE).getPath();
|
||||||
|
settings.setDatabasePath(databasePath);
|
||||||
|
settings.setDatabaseEnabled(true);
|
||||||
|
}
|
||||||
|
settings.setDomStorageEnabled(true);
|
||||||
|
|
||||||
|
if (clearAllCache) {
|
||||||
|
AmazonCookieManager.getInstance().removeAllCookie();
|
||||||
|
} else if (clearSessionCache) {
|
||||||
|
AmazonCookieManager.getInstance().removeSessionCookie();
|
||||||
|
}
|
||||||
|
|
||||||
|
inAppWebView.loadUrl(url);
|
||||||
|
inAppWebView.setId(6);
|
||||||
|
inAppWebView.getSettings().setLoadWithOverviewMode(true);
|
||||||
|
inAppWebView.getSettings().setUseWideViewPort(true);
|
||||||
|
inAppWebView.requestFocus();
|
||||||
|
inAppWebView.requestFocusFromTouch();
|
||||||
|
|
||||||
|
// Add the back and forward buttons to our action button container layout
|
||||||
|
actionButtonContainer.addView(back);
|
||||||
|
actionButtonContainer.addView(forward);
|
||||||
|
|
||||||
|
// Add the views to our toolbar
|
||||||
|
toolbar.addView(actionButtonContainer);
|
||||||
|
toolbar.addView(edittext);
|
||||||
|
toolbar.addView(close);
|
||||||
|
|
||||||
|
// Don't add the toolbar if its been disabled
|
||||||
|
if (getShowLocationBar()) {
|
||||||
|
// Add our toolbar to our main view/layout
|
||||||
|
main.addView(toolbar);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add our webview to our main view/layout
|
||||||
|
main.addView(inAppWebView);
|
||||||
|
|
||||||
|
WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
|
||||||
|
lp.copyFrom(dialog.getWindow().getAttributes());
|
||||||
|
lp.width = WindowManager.LayoutParams.MATCH_PARENT;
|
||||||
|
lp.height = WindowManager.LayoutParams.MATCH_PARENT;
|
||||||
|
|
||||||
|
dialog.setContentView(main);
|
||||||
|
dialog.show();
|
||||||
|
dialog.getWindow().setAttributes(lp);
|
||||||
|
// the goal of openhidden is to load the url and not display it
|
||||||
|
// Show() needs to be called to cause the URL to be loaded
|
||||||
|
if(openWindowHidden) {
|
||||||
|
dialog.hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
this.cordova.getActivity().runOnUiThread(runnable);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new plugin success result and send it back to JavaScript
|
||||||
|
*
|
||||||
|
* @param obj a JSONObject contain event payload information
|
||||||
|
*/
|
||||||
|
private void sendUpdate(JSONObject obj, boolean keepCallback) {
|
||||||
|
sendUpdate(obj, keepCallback, PluginResult.Status.OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new plugin result and send it back to JavaScript
|
||||||
|
*
|
||||||
|
* @param obj a JSONObject contain event payload information
|
||||||
|
* @param status the status code to return to the JavaScript environment
|
||||||
|
*/
|
||||||
|
private void sendUpdate(JSONObject obj, boolean keepCallback, PluginResult.Status status) {
|
||||||
|
if (callbackContext != null) {
|
||||||
|
PluginResult result = new PluginResult(status, obj);
|
||||||
|
result.setKeepCallback(keepCallback);
|
||||||
|
callbackContext.sendPluginResult(result);
|
||||||
|
if (!keepCallback) {
|
||||||
|
callbackContext = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The webview client receives notifications about appView
|
||||||
|
*/
|
||||||
|
public class InAppBrowserClient extends AmazonWebViewClient {
|
||||||
|
EditText edittext;
|
||||||
|
CordovaWebView webView;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param mContext
|
||||||
|
* @param edittext
|
||||||
|
*/
|
||||||
|
public InAppBrowserClient(CordovaWebView webView, EditText mEditText) {
|
||||||
|
this.webView = webView;
|
||||||
|
this.edittext = mEditText;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notify the host application that a page has started loading.
|
||||||
|
*
|
||||||
|
* @param view The webview initiating the callback.
|
||||||
|
* @param url The url of the page.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void onPageStarted(AmazonWebView view, String url, Bitmap favicon) {
|
||||||
|
super.onPageStarted(view, url, favicon);
|
||||||
|
String newloc = "";
|
||||||
|
if (url.startsWith("http:") || url.startsWith("https:") || url.startsWith("file:")) {
|
||||||
|
newloc = url;
|
||||||
|
}
|
||||||
|
// If dialing phone (tel:5551212)
|
||||||
|
else if (url.startsWith(AmazonWebView.SCHEME_TEL)) {
|
||||||
|
try {
|
||||||
|
Intent intent = new Intent(Intent.ACTION_DIAL);
|
||||||
|
intent.setData(Uri.parse(url));
|
||||||
|
cordova.getActivity().startActivity(intent);
|
||||||
|
} catch (android.content.ActivityNotFoundException e) {
|
||||||
|
LOG.e(LOG_TAG, "Error dialing " + url + ": " + e.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (url.startsWith("geo:") || url.startsWith(AmazonWebView.SCHEME_MAILTO) || url.startsWith("market:")) {
|
||||||
|
try {
|
||||||
|
Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||||
|
intent.setData(Uri.parse(url));
|
||||||
|
cordova.getActivity().startActivity(intent);
|
||||||
|
} catch (android.content.ActivityNotFoundException e) {
|
||||||
|
LOG.e(LOG_TAG, "Error with " + url + ": " + e.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// If sms:5551212?body=This is the message
|
||||||
|
else if (url.startsWith("sms:")) {
|
||||||
|
try {
|
||||||
|
Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||||
|
|
||||||
|
// Get address
|
||||||
|
String address = null;
|
||||||
|
int parmIndex = url.indexOf('?');
|
||||||
|
if (parmIndex == -1) {
|
||||||
|
address = url.substring(4);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
address = url.substring(4, parmIndex);
|
||||||
|
|
||||||
|
// If body, then set sms body
|
||||||
|
Uri uri = Uri.parse(url);
|
||||||
|
String query = uri.getQuery();
|
||||||
|
if (query != null) {
|
||||||
|
if (query.startsWith("body=")) {
|
||||||
|
intent.putExtra("sms_body", query.substring(5));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
intent.setData(Uri.parse("sms:" + address));
|
||||||
|
intent.putExtra("address", address);
|
||||||
|
intent.setType("vnd.android-dir/mms-sms");
|
||||||
|
cordova.getActivity().startActivity(intent);
|
||||||
|
} catch (android.content.ActivityNotFoundException e) {
|
||||||
|
LOG.e(LOG_TAG, "Error sending sms " + url + ":" + e.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
newloc = "http://" + url;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!newloc.equals(edittext.getText().toString())) {
|
||||||
|
edittext.setText(newloc);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
JSONObject obj = new JSONObject();
|
||||||
|
obj.put("type", LOAD_START_EVENT);
|
||||||
|
obj.put("url", newloc);
|
||||||
|
|
||||||
|
sendUpdate(obj, true);
|
||||||
|
} catch (JSONException ex) {
|
||||||
|
Log.d(LOG_TAG, "Should never happen");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onPageFinished(AmazonWebView view, String url) {
|
||||||
|
super.onPageFinished(view, url);
|
||||||
|
|
||||||
|
try {
|
||||||
|
JSONObject obj = new JSONObject();
|
||||||
|
obj.put("type", LOAD_STOP_EVENT);
|
||||||
|
obj.put("url", url);
|
||||||
|
|
||||||
|
sendUpdate(obj, true);
|
||||||
|
} catch (JSONException ex) {
|
||||||
|
Log.d(LOG_TAG, "Should never happen");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onReceivedError(AmazonWebView view, int errorCode, String description, String failingUrl) {
|
||||||
|
super.onReceivedError(view, errorCode, description, failingUrl);
|
||||||
|
|
||||||
|
try {
|
||||||
|
JSONObject obj = new JSONObject();
|
||||||
|
obj.put("type", LOAD_ERROR_EVENT);
|
||||||
|
obj.put("url", failingUrl);
|
||||||
|
obj.put("code", errorCode);
|
||||||
|
obj.put("message", description);
|
||||||
|
|
||||||
|
sendUpdate(obj, true, PluginResult.Status.ERROR);
|
||||||
|
} catch (JSONException ex) {
|
||||||
|
Log.d(LOG_TAG, "Should never happen");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
128
src/amazon/InAppChromeClient.java
Normal file
128
src/amazon/InAppChromeClient.java
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
package org.apache.cordova.inappbrowser;
|
||||||
|
|
||||||
|
import org.apache.cordova.CordovaWebView;
|
||||||
|
import org.apache.cordova.LOG;
|
||||||
|
import org.apache.cordova.PluginResult;
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONException;
|
||||||
|
|
||||||
|
import com.amazon.android.webkit.AmazonWebChromeClient;
|
||||||
|
import com.amazon.android.webkit.AmazonGeolocationPermissions.Callback;
|
||||||
|
import com.amazon.android.webkit.AmazonJsPromptResult;
|
||||||
|
import com.amazon.android.webkit.AmazonWebStorage;
|
||||||
|
import com.amazon.android.webkit.AmazonWebView;
|
||||||
|
import com.amazon.android.webkit.AmazonWebViewClient;
|
||||||
|
|
||||||
|
public class InAppChromeClient extends AmazonWebChromeClient {
|
||||||
|
|
||||||
|
private CordovaWebView webView;
|
||||||
|
private String LOG_TAG = "InAppChromeClient";
|
||||||
|
private long MAX_QUOTA = 100 * 1024 * 1024;
|
||||||
|
|
||||||
|
public InAppChromeClient(CordovaWebView webView) {
|
||||||
|
super();
|
||||||
|
this.webView = webView;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Handle database quota exceeded notification.
|
||||||
|
*
|
||||||
|
* @param url
|
||||||
|
* @param databaseIdentifier
|
||||||
|
* @param currentQuota
|
||||||
|
* @param estimatedSize
|
||||||
|
* @param totalUsedQuota
|
||||||
|
* @param quotaUpdater
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void onExceededDatabaseQuota(String url, String databaseIdentifier, long currentQuota, long estimatedSize,
|
||||||
|
long totalUsedQuota, AmazonWebStorage.QuotaUpdater quotaUpdater)
|
||||||
|
{
|
||||||
|
LOG.d(LOG_TAG, "onExceededDatabaseQuota estimatedSize: %d currentQuota: %d totalUsedQuota: %d", estimatedSize, currentQuota, totalUsedQuota);
|
||||||
|
|
||||||
|
if (estimatedSize < MAX_QUOTA)
|
||||||
|
{
|
||||||
|
//increase for 1Mb
|
||||||
|
long newQuota = estimatedSize;
|
||||||
|
LOG.d(LOG_TAG, "calling quotaUpdater.updateQuota newQuota: %d", newQuota);
|
||||||
|
quotaUpdater.updateQuota(newQuota);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Set the quota to whatever it is and force an error
|
||||||
|
// TODO: get docs on how to handle this properly
|
||||||
|
quotaUpdater.updateQuota(currentQuota);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instructs the client to show a prompt to ask the user to set the Geolocation permission state for the specified origin.
|
||||||
|
*
|
||||||
|
* @param origin
|
||||||
|
* @param callback
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void onGeolocationPermissionsShowPrompt(String origin, Callback callback) {
|
||||||
|
super.onGeolocationPermissionsShowPrompt(origin, callback);
|
||||||
|
callback.invoke(origin, true, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tell the client to display a prompt dialog to the user.
|
||||||
|
* If the client returns true, WebView will assume that the client will
|
||||||
|
* handle the prompt dialog and call the appropriate JsPromptResult method.
|
||||||
|
*
|
||||||
|
* The prompt bridge provided for the InAppBrowser is capable of executing any
|
||||||
|
* oustanding callback belonging to the InAppBrowser plugin. Care has been
|
||||||
|
* taken that other callbacks cannot be triggered, and that no other code
|
||||||
|
* execution is possible.
|
||||||
|
*
|
||||||
|
* To trigger the bridge, the prompt default value should be of the form:
|
||||||
|
*
|
||||||
|
* gap-iab://<callbackId>
|
||||||
|
*
|
||||||
|
* where <callbackId> is the string id of the callback to trigger (something
|
||||||
|
* like "InAppBrowser0123456789")
|
||||||
|
*
|
||||||
|
* If present, the prompt message is expected to be a JSON-encoded value to
|
||||||
|
* pass to the callback. A JSON_EXCEPTION is returned if the JSON is invalid.
|
||||||
|
*
|
||||||
|
* @param view
|
||||||
|
* @param url
|
||||||
|
* @param message
|
||||||
|
* @param defaultValue
|
||||||
|
* @param result
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean onJsPrompt(AmazonWebView view, String url, String message, String defaultValue, AmazonJsPromptResult result) {
|
||||||
|
// See if the prompt string uses the 'gap-iab' protocol. If so, the remainder should be the id of a callback to execute.
|
||||||
|
if (defaultValue != null && defaultValue.startsWith("gap")) {
|
||||||
|
if(defaultValue.startsWith("gap-iab://")) {
|
||||||
|
PluginResult scriptResult;
|
||||||
|
String scriptCallbackId = defaultValue.substring(10);
|
||||||
|
if (scriptCallbackId.startsWith("InAppBrowser")) {
|
||||||
|
if(message == null || message.length() == 0) {
|
||||||
|
scriptResult = new PluginResult(PluginResult.Status.OK, new JSONArray());
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
scriptResult = new PluginResult(PluginResult.Status.OK, new JSONArray(message));
|
||||||
|
} catch(JSONException e) {
|
||||||
|
scriptResult = new PluginResult(PluginResult.Status.JSON_EXCEPTION, e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.webView.sendPluginResult(scriptResult, scriptCallbackId);
|
||||||
|
result.confirm("");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Anything else with a gap: prefix should get this message
|
||||||
|
LOG.w(LOG_TAG, "InAppBrowser does not support Cordova API calls: " + url + " " + defaultValue);
|
||||||
|
result.cancel();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
6
test/cordova-incl.js
vendored
6
test/cordova-incl.js
vendored
@ -20,7 +20,9 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
var PLAT;
|
var PLAT;
|
||||||
if (/Android/.exec(navigator.userAgent)) {
|
if (/cordova-amazon-fireos/.exec(navigator.userAgent)) {
|
||||||
|
PLAT = 'amazon-fireos';
|
||||||
|
}else if (/Android/.exec(navigator.userAgent)) {
|
||||||
PLAT = 'android';
|
PLAT = 'android';
|
||||||
} else if (/(iPad)|(iPhone)|(iPod)/.exec(navigator.userAgent)) {
|
} else if (/(iPad)|(iPhone)|(iPod)/.exec(navigator.userAgent)) {
|
||||||
PLAT = 'ios';
|
PLAT = 'ios';
|
||||||
@ -61,7 +63,7 @@ if (!window._doNotWriteCordovaScript) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function backHome() {
|
function backHome() {
|
||||||
if (window.device && device.platform && device.platform.toLowerCase() == 'android') {
|
if (window.device && device.platform && (device.platform.toLowerCase() == 'android' || device.platform.toLowerCase() == 'amazon-fireos')) {
|
||||||
navigator.app.backHistory();
|
navigator.app.backHistory();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user