
/*
1."yellowin camera-chooser" 라는 주석을 찾아서 모두적용.
2.cordova-plugin-camera 설치.
3.AndroidManist.xml 아래 추가(없는경우)
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" android:required="false" />
<uses-feature android:name="android.hardware.camera.front" android:required="false" />
4.res/xml/camera_provider_paths.xml 아래로 수정
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="<http://schemas.android.com/apk/res/android>">
<cache-path name="cache" path="/" />
</paths>
5.기타
- 웹소스의 input file태그에 아래처럼 capture 속성이 꼭 있어야함. 없다면 기존 일반첨부기능으로 동작함.
<input type="file" capture="image">
*/
package org.apache.cordova.inappbrowser;
import android.Manifest;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Looper;
import android.os.Parcelable;
import android.provider.Browser;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.graphics.Color;
import android.net.http.SslError;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.text.InputType;
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 android.webkit.CookieManager;
import android.webkit.HttpAuthHandler;
import android.webkit.JavascriptInterface;
import android.webkit.SslErrorHandler;
import android.webkit.ValueCallback;
import android.webkit.WebChromeClient;
import android.webkit.WebResourceRequest;
import android.webkit.WebResourceResponse;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.DownloadListener;
import android.webkit.WebViewClient;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import org.apache.cordova.CallbackContext;
import org.apache.cordova.Config;
import org.apache.cordova.CordovaArgs;
import org.apache.cordova.CordovaHttpAuthHandler;
import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.CordovaWebView;
import org.apache.cordova.LOG;
import org.apache.cordova.PluginManager;
import org.apache.cordova.PluginResult;
import org.json.JSONException;
import org.json.JSONObject;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.HashMap;
import java.util.Map;
import java.util.StringTokenizer;
import org.apache.cordova.inappbrowser.InAppBrowserDialog;
//yellowin yellowin videoview 풀스크린 처리 관련 라이브러리
import android.widget.FrameLayout;
import android.content.pm.ActivityInfo;
import android.util.Log;
// yellowin yellowin 파일 다중 선택 (selectMultiple)
import android.app.Activity;
import com.amospro.app.R;
import android.annotation.SuppressLint;
import android.view.View;
//yellowin yellowin bottomnavigationviewex 추가 라이브러리 start
import com.ittianyu.bottomnavigationviewex.BottomNavigationViewEx;
import androidx.annotation.IdRes;
import androidx.annotation.NonNull;
import androidx.appcompat.content.res.AppCompatResources;
import static java.lang.Boolean.FALSE;
import static java.lang.Boolean.TRUE;
//yellowin yellowin bottomnavigationviewex 추가 라이브러리 end
import android.view.Menu; // yellowin toolbar menu 선택
import android.view.MenuItem; // yellowin toolbar
import android.view.MotionEvent; //yellowin toolbar
// //yellowin yellowin 배지 연동 - start
// import q.rorbin.badgeview.Badge;
// import q.rorbin.badgeview.QBadgeView;
// //yellowin yellowin 배지 연동 - end
//yellowin yellowin swipeRefreshLayout
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import android.content.DialogInterface; // yellowin yellowin window.open
import android.os.Handler;
import android.app.AlertDialog;
import android.webkit.JsResult;
import static android.os.Looper.getMainLooper;
import android.webkit.WebResourceError;
//yellowin new 새창처리 - start
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.OvalShape;
//yellowin new 새창처리 - end
import java.io.UnsupportedEncodingException; //yellowin url decoding 추가
import java.net.URLDecoder;
import java.net.URLEncoder;
**//yellowin camera-chooser 추가 - start**
import android.Manifest;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import static android.app.Activity.RESULT_OK;
import static android.graphics.ImageFormat.JPEG;
import android.media.MediaScannerConnection;
import android.provider.MediaStore;
import org.apache.cordova.BuildHelper;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
**//yellowin camera-chooser 추가 - end**
//yellowin yellowin 보안처리 - start
import android.os.Debug;
import android.content.pm.ApplicationInfo;
import com.amospro.app.MainActivity;
import com.amospro.app.R;
import com.amospro.app.RootUtil;
import android.app.AlertDialog;
import android.content.DialogInterface;
import com.initialxy.cordova.themeablebrowser.ThemeableBrowser;
//yellowin yellowin 보안처리 - end
@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 EXIT_EVENT = "exit";
private static final String LOCATION = "location";
private static final String ZOOM = "zoom";
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 DOWNLOAD_EVENT = "download";
private static final String MESSAGE_EVENT = "message";
private static final String CLEAR_ALL_CACHE = "clearcache";
private static final String CLEAR_SESSION_CACHE = "clearsessioncache";
private static final String HARDWARE_BACK_BUTTON = "hardwareback";
private static final String MEDIA_PLAYBACK_REQUIRES_USER_ACTION = "mediaPlaybackRequiresUserAction";
private static final String SHOULD_PAUSE = "shouldPauseOnSuspend";
private static final Boolean DEFAULT_HARDWARE_BACK = true;
private static final String USER_WIDE_VIEW_PORT = "useWideViewPort";
private static final String TOOLBAR_COLOR = "toolbarcolor";
private static final String CLOSE_BUTTON_CAPTION = "closebuttoncaption";
private static final String CLOSE_BUTTON_COLOR = "closebuttoncolor";
private static final String LEFT_TO_RIGHT = "lefttoright";
private static final String HIDE_NAVIGATION = "hidenavigationbuttons";
private static final String NAVIGATION_COLOR = "navigationbuttoncolor";
private static final String HIDE_URL = "hideurlbar";
private static final String FOOTER = "footer";
private static final String FOOTER_COLOR = "footercolor";
private static final String BEFORELOAD = "beforeload";
private static final String FULLSCREEN = "fullscreen";
private static final int TOOLBAR_HEIGHT = 48;
private static final List customizableOptions = Arrays.asList(CLOSE_BUTTON_CAPTION, TOOLBAR_COLOR, NAVIGATION_COLOR, CLOSE_BUTTON_COLOR, FOOTER_COLOR);
private InAppBrowserDialog dialog;
private WebView inAppWebView;
private WebView newWebView;
private EditText edittext;
private CallbackContext callbackContext;
private boolean showLocationBar = true;
private boolean showZoomControls = true;
private boolean openWindowHidden = false;
private boolean clearAllCache = false;
private boolean clearSessionCache = false;
private boolean hadwareBackButton = true;
private boolean mediaPlaybackRequiresUserGesture = false;
private boolean shouldPauseInAppBrowser = false;
private boolean useWideViewPort = true;
private ValueCallback<Uri[]> mUploadCallback;
private final static int FILECHOOSER_REQUESTCODE = 1;
private String closeButtonCaption = "";
private String closeButtonColor = "";
private boolean leftToRight = false;
private int toolbarColor = android.graphics.Color.LTGRAY;
private boolean hideNavigationButtons = false;
private String navigationButtonColor = "";
private boolean hideUrlBar = false;
private boolean showFooter = false;
private String footerColor = "";
private String beforeload = "";
private boolean fullscreen = true;
private String[] allowedSchemes;
private InAppBrowserClient currentClient;
// yellowin yellowin videoview 풀스크린 - 비디오 풀스크린 레이아웃변수
private FrameLayout mVideoview;
private BottomNavigationViewEx bnve; // 하단툴바메뉴
// yellowin yellowin toolbar start
// private BottomBar bottomBar;
private View tabView1;
private View tabView2;
private int tabView1_flag = 1;
private int tabView2_flag = 1;
private String cur_url = "first";
private String prv_url = "";
// yellowin yellowin toolbar end
// // yellowin yellowin toolbar 배지 연동 - start
// Badge mBadge1;
// Badge mBadge2;
// Badge mBadge3;
// Badge mBadge4;
// Badge mBadge5;
// // yellowin yellowin toolbar 배지 연동 - end
// yellowin yellowin window.open - yellowin add2
private boolean isFullscreen = false;
private InAppBrowserDialog dialog_child;
// yellowin new 새창처리 - start
private Window window_child;
// yellowin new 새창처리 - end
//yellowin yellowin swipeRefreshLayout
private SwipeRefreshLayout swipeRefreshLayout;
**// yellowin camera-chooser 추가 - start**
private Uri cameraImageUri = null;
public ValueCallback<Uri> filePathCallbackNormal;
public ValueCallback<Uri[]> filePathCallbackLollipop;
public final static int FILECHOOSER_NORMAL_REQ_CODE = 2001;
public final static int FILECHOOSER_LOLLIPOP_REQ_CODE = 2002;
private static final int JPEG = 0; // Take a picture of type JPEG
private static final int PNG = 1; // Take a picture of type PNG
private static final String JPEG_TYPE = "jpg";
private static final String PNG_TYPE = "png";
private static final String JPEG_EXTENSION = "." + JPEG_TYPE;
private static final String PNG_EXTENSION = "." + PNG_TYPE;
private static final String PNG_MIME_TYPE = "image/png";
private static final String JPEG_MIME_TYPE = "image/jpeg";
private static final String HEIC_MIME_TYPE = "image/heic";
private static final String GET_PICTURE = "Get Picture";
private static final String GET_VIDEO = "Get Video";
private static final String GET_All = "Get All";
private static final String CROPPED_URI_KEY = "croppedUri";
private static final String IMAGE_URI_KEY = "imageUri";
private static final String IMAGE_FILE_PATH_KEY = "imageFilePath";
private static final String TAKE_PICTURE_ACTION = "takePicture";
public static final int PERMISSION_DENIED_ERROR = 20;
public static final int TAKE_PIC_SEC = 0;
public static final int SAVE_TO_ALBUM_SEC = 1;
private static final String TIME_FORMAT = "yyyyMMdd_HHmmss";
private int mQuality; // Compression quality hint (0-100: 0=low quality & high compression,
// 100=compress of max quality)
private int targetWidth; // desired width of the image
private int targetHeight; // desired height of the image
private Uri imageUri; // Uri of captured image
private String imageFilePath; // File where the image is stored
private int encodingType; // Type of encoding to use
private int mediaType; // What type of media to retrieve
private int destType; // Source type (needs to be saved for the permission handling)
private int srcType; // Destination type (needs to be saved for permission handling)
private boolean saveToPhotoAlbum; // Should the picture be saved to the device's photo album
private boolean correctOrientation; // Should the pictures orientation be corrected
private boolean orientationCorrected; // Has the picture's orientation been corrected
private boolean allowEdit; // Should we allow the user to crop the image.
private int numPics;
private MediaScannerConnection conn; // Used to update gallery app with newly-written files
private Uri scanMe; // Uri of image to be added to content store
private Uri croppedUri;
private String croppedFilePath;
// private ExifHelper exifData; // Exif data from source
private String applicationId;
private static final int CAMERA_PERMISSION_REQUEST_CODE = 1001;
**// yellowin camera-chooser 추가 - end**
//yellowin yellowin 보안처리 - start
private String detectDebugger_val = "false";
private String detect_threadCpuTimeNanos_val = "false";
// ThemeableBrowser 인스턴스를 저장하기 위한 정적 참조 변수
private static InAppBrowser instance;
//임시URL인경우 2, 실url이면 1
private String service_flag = "1";
// 생성자 또는 초기화 블록에서 인스턴스를 할당
public InAppBrowser() {
instance = this;
}
// 전역적으로 ThemeableBrowser 인스턴스에 접근하여 닫는 메소드
public static void closeGlobalInstance() {
// if (instance != null && instance.webView != null) {
// instance.closeDialog(); // closeDialog()는 ThemeableBrowser 내에서 대화 상자를 닫는 기존 메소드라고 가정
// }
if (instance != null && instance.webView != null) {
Activity activity = instance.cordova.getActivity();
// UI 스레드에서 대화 상자 닫기
if (activity != null) {
activity.runOnUiThread(() -> {
if (!activity.isFinishing() && !activity.isDestroyed()) {
instance.closeDialog(); // closeDialog를 안전하게 실행
}
});
}
}
}
//- debugbble 속성 탐지
public static boolean isDebuggable(Context context){
//디버그모드로 빌드된 앱을 실행했는지 체크
Log.d("","yellowin Security This device isDebuggable() : " + ((context.getApplicationContext().getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0));
return ((context.getApplicationContext().getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0);
// return false;
}
//- 디버거 연결 여부 탐지
public static boolean detectDebugger() {
Log.d("","yellowin Security This device detectDebugger() : " + Debug.isDebuggerConnected() + " | " + Debug.waitingForDebugger());
if(Debug.isDebuggerConnected() || Debug.waitingForDebugger()){
return true;
}else{
return false;
}
// return Debug.isDebuggerConnected() || Debug.waitingForDebugger();
// return Debug.isDebuggerConnected();
}
//- 디버깅(시간에 따른) 감지
static boolean detect_threadCpuTimeNanos(){
long start = Debug.threadCpuTimeNanos();
for(int i=0; i<10000000; ++i)
continue;
long stop = Debug.threadCpuTimeNanos();
if(stop - start < 100000000) {
Log.d("","yellowin Security This device detect_threadCpuTimeNanos() : false");
return false;
}
else {
Log.d("","yellowin Security This device detect_threadCpuTimeNanos() : true");
return true;
}
}
//yellowin yellowin 보안처리 - end
/**
* Executes the request and returns PluginResult.
*
* @param action the action to execute.
* @param args JSONArry of arguments for the plugin.
* @param callbackContext the callbackContext 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, String> 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");
/* This code exists for compatibility between 3.x and 4.x versions of Cordova.
* Previously the Config class had a static method, isUrlWhitelisted(). That
* responsibility has been moved to the plugins, with an aggregating method in
* PluginManager.
*/
Boolean shouldAllowNavigation = null;
if (url.startsWith("javascript:")) {
shouldAllowNavigation = true;
}
if (shouldAllowNavigation == null) {
try {
Method iuw = Config.class.getMethod("isUrlWhiteListed", String.class);
shouldAllowNavigation = (Boolean)iuw.invoke(null, url);
} catch (NoSuchMethodException e) {
LOG.d(LOG_TAG, e.getLocalizedMessage());
} catch (IllegalAccessException e) {
LOG.d(LOG_TAG, e.getLocalizedMessage());
} catch (InvocationTargetException e) {
LOG.d(LOG_TAG, e.getLocalizedMessage());
}
}
if (shouldAllowNavigation == null) {
try {
Method gpm = webView.getClass().getMethod("getPluginManager");
PluginManager pm = (PluginManager)gpm.invoke(webView);
Method san = pm.getClass().getMethod("shouldAllowNavigation", String.class);
shouldAllowNavigation = (Boolean)san.invoke(pm, url);
} catch (NoSuchMethodException e) {
LOG.d(LOG_TAG, e.getLocalizedMessage());
} catch (IllegalAccessException e) {
LOG.d(LOG_TAG, e.getLocalizedMessage());
} catch (InvocationTargetException e) {
LOG.d(LOG_TAG, e.getLocalizedMessage());
}
}
// load in webview
if (Boolean.TRUE.equals(shouldAllowNavigation)) {
LOG.d(LOG_TAG, "loading in webview");
webView.loadUrl(url);
}
//Load the dialer
else if (url.startsWith(WebView.SCHEME_TEL))
{
try {
LOG.d(LOG_TAG, "loading in dialer");
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 {
LOG.d(LOG_TAG, "loading in InAppBrowser");
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("loadAfterBeforeload")) {
if (beforeload == null) {
LOG.e(LOG_TAG, "unexpected loadAfterBeforeload called without feature beforeload=yes");
}
final String url = args.getString(0);
this.cordova.getActivity().runOnUiThread(new Runnable() {
@SuppressLint("NewApi")
@Override
public void run() {
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.O) {
currentClient.waitForBeforeload = false;
inAppWebView.setWebViewClient(currentClient);
} else {
((InAppBrowserClient)inAppWebView.getWebViewClient()).waitForBeforeload = false;
}
inAppWebView.loadUrl(url);
}
});
}
else if (action.equals("injectScriptCode")) {
String jsWrapper = null;
if (args.getBoolean(1)) {
jsWrapper = String.format("(function(){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() {
if (dialog != null && !cordova.getActivity().isFinishing()) {
dialog.show();
}
}
});
PluginResult pluginResult = new PluginResult(PluginResult.Status.OK);
pluginResult.setKeepCallback(true);
this.callbackContext.sendPluginResult(pluginResult);
}
else if (action.equals("hide")) {
this.cordova.getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
if (dialog != null && !cordova.getActivity().isFinishing()) {
dialog.hide();
}
}
});
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 when the system is about to start resuming a previous activity.
*/
@Override
public void onPause(boolean multitasking) {
if (shouldPauseInAppBrowser) {
inAppWebView.onPause();
}
}
/**
* Called when the activity will start interacting with the user.
*/
@Override
public void onResume(boolean multitasking) {
if (shouldPauseInAppBrowser) {
inAppWebView.onResume();
}
}
/**
* 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 WebView.
*
* 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) {
if (inAppWebView!=null) {
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.cordova.getActivity().runOnUiThread(new Runnable() {
@SuppressLint("NewApi")
@Override
public void run() {
inAppWebView.evaluateJavascript(finalScriptToInject, null);
}
});
} else {
LOG.d(LOG_TAG, "Can't inject code into the system browser");
}
}
/**
* Put the list of features into a hash map
*
* @param optString
* @return
*/
private HashMap<String, String> parseFeature(String optString) {
if (optString.equals(NULL)) {
return null;
} else {
HashMap<String, String> map = new HashMap<String, String>();
StringTokenizer features = new StringTokenizer(optString, ",");
StringTokenizer option;
while(features.hasMoreElements()) {
option = new StringTokenizer(features.nextToken(), "=");
if (option.hasMoreElements()) {
String key = option.nextToken();
String value = option.nextToken();
if (!customizableOptions.contains(key)) {
value = value.equals("yes") || value.equals("no") ? value : "yes";
}
map.put(key, value);
}
}
return map;
}
}
/**
* Display a new browser with the specified URL.
*
* @param url the url to load.
* @return "" if ok, or error message.
*/
public String openExternal(String url) {
try {
Intent intent = null;
intent = new Intent(Intent.ACTION_VIEW);
// Omitting the MIME type for file: URLs causes "No Activity found to handle Intent".
// Adding the MIME type to http: URLs causes them to not be handled by the downloader.
Uri uri = Uri.parse(url);
if ("file".equals(uri.getScheme())) {
intent.setDataAndType(uri, webView.getResourceApi().getMimeType(uri));
} else {
intent.setData(uri);
}
intent.putExtra(Browser.EXTRA_APPLICATION_ID, cordova.getActivity().getPackageName());
// CB-10795: Avoid circular loops by preventing it from opening in the current app
this.openExternalExcludeCurrentApp(intent);
return "";
// not catching FileUriExposedException explicitly because buildtools<24 doesn't know about it
} catch (java.lang.RuntimeException e) {
LOG.d(LOG_TAG, "InAppBrowser: Error loading url "+url+":"+ e.toString());
return e.toString();
}
}
/**
* Opens the intent, providing a chooser that excludes the current app to avoid
* circular loops.
*/
private void openExternalExcludeCurrentApp(Intent intent) {
String currentPackage = cordova.getActivity().getPackageName();
boolean hasCurrentPackage = false;
PackageManager pm = cordova.getActivity().getPackageManager();
List<ResolveInfo> activities = pm.queryIntentActivities(intent, 0);
ArrayList<Intent> targetIntents = new ArrayList<Intent>();
for (ResolveInfo ri : activities) {
if (!currentPackage.equals(ri.activityInfo.packageName)) {
Intent targetIntent = (Intent)intent.clone();
targetIntent.setPackage(ri.activityInfo.packageName);
targetIntents.add(targetIntent);
}
else {
hasCurrentPackage = true;
}
}
// If the current app package isn't a target for this URL, then use
// the normal launch behavior
if (hasCurrentPackage == false || targetIntents.size() == 0) {
this.cordova.getActivity().startActivity(intent);
}
// If there's only one possible intent, launch it directly
else if (targetIntents.size() == 1) {
this.cordova.getActivity().startActivity(targetIntents.get(0));
}
// Otherwise, show a custom chooser without the current app listed
else if (targetIntents.size() > 0) {
Intent chooser = Intent.createChooser(targetIntents.remove(targetIntents.size()-1), null);
chooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, targetIntents.toArray(new Parcelable[] {}));
this.cordova.getActivity().startActivity(chooser);
}
}
/**
* Closes the dialog
*/
public void closeDialog() {
//yellowin yellowin 보안처리 - start
if (dialog != null && dialog.isShowing()) { // Dialog가 열려 있을 때만 닫기
dialog.dismiss();
// Clean up.
dialog = null;
}
//yellowin yellowin 보안처리 - end
this.cordova.getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
final WebView childView = inAppWebView;
// The JS protects against multiple calls, so this should happen only when
// closeDialog() is called by other native code.
if (childView == null) {
return;
}
childView.setWebViewClient(new WebViewClient() {
// NB: wait for about:blank before dismissing
public void onPageFinished(WebView view, String url) {
if (dialog != null && !cordova.getActivity().isFinishing()) {
dialog.dismiss();
dialog = null;
}
}
});
// NB: From SDK 19: "If you call methods on WebView from any thread
// other than your app's UI thread, it can cause unexpected results."
// <http://developer.android.com/guide/webapps/migrating.html#Threads>
childView.loadUrl("about:blank");
try {
JSONObject obj = new JSONObject();
obj.put("type", EXIT_EVENT);
sendUpdate(obj, false);
} catch (JSONException ex) {
LOG.d(LOG_TAG, "Should never happen");
}
}
});
}
/**
* Checks to see if it is possible to go back one page in history, then does so.
*/
public void goBack() {
if (this.inAppWebView.canGoBack()) {
//this.inAppWebView.goBack();
this.inAppWebView.loadUrl("javascript:gfn_historyBack();");
webView.loadUrl("javascript:onBackKeyDown_new();");
}else{
webView.loadUrl("javascript:exitApp();");
}
// // if (inAppWebView.canGoBack()) {
// LOG.d(LOG_TAG, "yellowin yellowin inappbrowser >>>>>>>>> onBackKeyDown()");
// webView.loadUrl("javascript:onBackKeyDown();");
// // } else {
// // LOG.d(LOG_TAG, "yellowin yellowin inappbrowser >>>>>>>>> exitApp()");
// // webView.loadUrl("javascript:exitApp();");
// // }
}
/**
* Can the web browser go back?
* @return boolean
*/
public boolean canGoBack() {
return this.inAppWebView.canGoBack();
}
/**
* Has the user set the hardware back button to go back
* @return boolean
*/
public boolean hardwareBack() {
return hadwareBackButton;
}
/**
* Checks to see if it is possible to go forward one page in history, then does so.
*/
private void goForward() {
if (this.inAppWebView.canGoForward()) {
this.inAppWebView.goForward();
}
}
/**
* Navigate to the new page
*
* @param url to load
*/
private void navigate(String url) {
InputMethodManager imm = (InputMethodManager)this.cordova.getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(edittext.getWindowToken(), 0);
if (!url.startsWith("http") && !url.startsWith("file:")) {
this.inAppWebView.loadUrl("http://" + url);
} else {
this.inAppWebView.loadUrl(url);
}
this.inAppWebView.requestFocus();
}
/**
* Should we show the location bar?
*
* @return boolean
*/
private boolean getShowLocationBar() {
return this.showLocationBar;
}
private InAppBrowser getInAppBrowser() {
return this;
}
/**
* Display a new browser with the specified URL.
*
* @param url the url to load.
* @param features jsonObject
*/
public String showWebPage(final String url, HashMap<String, String> features) {
// Determine if we should hide the location bar.
showLocationBar = true;
showZoomControls = true;
openWindowHidden = false;
mediaPlaybackRequiresUserGesture = false;
if (features != null) {
String show = features.get(LOCATION);
if (show != null) {
showLocationBar = show.equals("yes") ? true : false;
}
if(showLocationBar) {
String hideNavigation = features.get(HIDE_NAVIGATION);
String hideUrl = features.get(HIDE_URL);
if(hideNavigation != null) hideNavigationButtons = hideNavigation.equals("yes") ? true : false;
if(hideUrl != null) hideUrlBar = hideUrl.equals("yes") ? true : false;
}
String zoom = features.get(ZOOM);
if (zoom != null) {
showZoomControls = zoom.equals("yes") ? true : false;
}
String hidden = features.get(HIDDEN);
if (hidden != null) {
openWindowHidden = hidden.equals("yes") ? true : false;
}
String hardwareBack = features.get(HARDWARE_BACK_BUTTON);
if (hardwareBack != null) {
hadwareBackButton = hardwareBack.equals("yes") ? true : false;
} else {
hadwareBackButton = DEFAULT_HARDWARE_BACK;
}
String mediaPlayback = features.get(MEDIA_PLAYBACK_REQUIRES_USER_ACTION);
if (mediaPlayback != null) {
mediaPlaybackRequiresUserGesture = mediaPlayback.equals("yes") ? true : false;
}
String cache = features.get(CLEAR_ALL_CACHE);
if (cache != null) {
clearAllCache = cache.equals("yes") ? true : false;
} else {
cache = features.get(CLEAR_SESSION_CACHE);
if (cache != null) {
clearSessionCache = cache.equals("yes") ? true : false;
}
}
String shouldPause = features.get(SHOULD_PAUSE);
if (shouldPause != null) {
shouldPauseInAppBrowser = shouldPause.equals("yes") ? true : false;
}
String wideViewPort = features.get(USER_WIDE_VIEW_PORT);
if (wideViewPort != null ) {
useWideViewPort = wideViewPort.equals("yes") ? true : false;
}
String closeButtonCaptionSet = features.get(CLOSE_BUTTON_CAPTION);
if (closeButtonCaptionSet != null) {
closeButtonCaption = closeButtonCaptionSet;
}
String closeButtonColorSet = features.get(CLOSE_BUTTON_COLOR);
if (closeButtonColorSet != null) {
closeButtonColor = closeButtonColorSet;
}
String leftToRightSet = features.get(LEFT_TO_RIGHT);
leftToRight = leftToRightSet != null && leftToRightSet.equals("yes");
String toolbarColorSet = features.get(TOOLBAR_COLOR);
if (toolbarColorSet != null) {
toolbarColor = android.graphics.Color.parseColor(toolbarColorSet);
}
String navigationButtonColorSet = features.get(NAVIGATION_COLOR);
if (navigationButtonColorSet != null) {
navigationButtonColor = navigationButtonColorSet;
}
String showFooterSet = features.get(FOOTER);
if (showFooterSet != null) {
showFooter = showFooterSet.equals("yes") ? true : false;
}
String footerColorSet = features.get(FOOTER_COLOR);
if (footerColorSet != null) {
footerColor = footerColorSet;
}
if (features.get(BEFORELOAD) != null) {
beforeload = features.get(BEFORELOAD);
}
String fullscreenSet = features.get(FULLSCREEN);
if (fullscreenSet != null) {
fullscreen = fullscreenSet.equals("yes") ? true : false;
}
}
final CordovaWebView thatWebView = this.webView;
// Create dialog in new thread
Runnable runnable = new Runnable() {
// yellowin yellowin videoview 풀스크린
private void enableFullScreen(Activity activity, Window window) {
// inFullScreen = true; // yellowin yellowin window.open
WindowManager.LayoutParams attrs = window.getAttributes();
attrs.flags |= WindowManager.LayoutParams.FLAG_FULLSCREEN;
attrs.flags |= WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
window.setAttributes(attrs);
if (android.os.Build.VERSION.SDK_INT >= 14) {
// noinspection all
int flags = View.SYSTEM_UI_FLAG_LOW_PROFILE;
if (android.os.Build.VERSION.SDK_INT >= 16) {
flags = View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_IMMERSIVE;
}
window.getDecorView().setSystemUiVisibility(flags);
}
}
// yellowin yellowin videoview 풀스크린
private void disableFullScreen(Activity activity, Window window) {
// inFullScreen = false; // yellowin yellowin window.open
WindowManager.LayoutParams attrs = window.getAttributes();
attrs.flags &= ~WindowManager.LayoutParams.FLAG_FULLSCREEN;
attrs.flags &= ~WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
window.setAttributes(attrs);
if (android.os.Build.VERSION.SDK_INT >= 14) {
// noinspection all
window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
dialog.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
}
/**
* 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;
}
private View createCloseButton(int id) {
View _close;
Resources activityRes = cordova.getActivity().getResources();
if (closeButtonCaption != "") {
// Use TextView for text
TextView close = new TextView(cordova.getActivity());
close.setText(closeButtonCaption);
close.setTextSize(20);
if (closeButtonColor != "") close.setTextColor(android.graphics.Color.parseColor(closeButtonColor));
close.setGravity(android.view.Gravity.CENTER_VERTICAL);
close.setPadding(this.dpToPixels(10), 0, this.dpToPixels(10), 0);
_close = close;
}
else {
ImageButton close = new ImageButton(cordova.getActivity());
int closeResId = activityRes.getIdentifier("ic_action_remove", "drawable", cordova.getActivity().getPackageName());
Drawable closeIcon = activityRes.getDrawable(closeResId);
if (closeButtonColor != "") close.setColorFilter(android.graphics.Color.parseColor(closeButtonColor));
close.setImageDrawable(closeIcon);
close.setScaleType(ImageView.ScaleType.FIT_CENTER);
close.getAdjustViewBounds();
_close = close;
}
RelativeLayout.LayoutParams closeLayoutParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
if (leftToRight) closeLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
else closeLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
_close.setLayoutParams(closeLayoutParams);
_close.setBackground(null);
_close.setContentDescription("Close Button");
_close.setId(Integer.valueOf(id));
_close.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
closeDialog();
}
});
return _close;
}
@SuppressLint("NewApi")
public void run() {
// CB-6702 InAppBrowser hangs when opening more than one instance
if (dialog != null) {
dialog.dismiss();
};
// Let's create the main dialog
dialog = new InAppBrowserDialog(cordova.getActivity(), android.R.style.Theme_NoTitleBar);
dialog.getWindow().getAttributes().windowAnimations = android.R.style.Animation_Dialog;
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
if (fullscreen) {
dialog.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
dialog.setCancelable(true);
dialog.setInAppBroswer(getInAppBrowser());
// yellowin 추가
dialog.setContentView(R.layout.activity_main); /* 레이아웃 로드 */
// yellowin yellowin 인앱브라우져 상단 상태바 컬러 변경하기 - start
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
dialog.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
dialog.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
dialog.getWindow().setStatusBarColor(Color.parseColor("#ffffff"));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
dialog.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
}
// yellowin yellowin 인앱브라우져 상단 상태바 컬러 변경하기 - end
// // Main container layout
// LinearLayout main = new LinearLayout(cordova.getActivity());
// main.setOrientation(LinearLayout.VERTICAL);
// yellowin Main container layout
RelativeLayout main = new RelativeLayout(cordova.getActivity());
RelativeLayout fullScreenMain = new RelativeLayout(cordova.getActivity());
fullScreenMain.setLayoutParams(
new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
LinearLayout browserMain = new LinearLayout(cordova.getActivity());
browserMain.setOrientation(LinearLayout.VERTICAL);
browserMain.setLayoutParams(
new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
// yellowin Main container layout
// Toolbar layout
RelativeLayout toolbar = new RelativeLayout(cordova.getActivity());
//Please, no more black!
toolbar.setBackgroundColor(toolbarColor);
toolbar.setLayoutParams(new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, this.dpToPixels(TOOLBAR_HEIGHT)));
toolbar.setPadding(this.dpToPixels(2), this.dpToPixels(2), this.dpToPixels(2), this.dpToPixels(2));
if (leftToRight) {
toolbar.setHorizontalGravity(Gravity.LEFT);
} else {
toolbar.setHorizontalGravity(Gravity.RIGHT);
}
toolbar.setVerticalGravity(Gravity.TOP);
// Action Button Container layout
RelativeLayout actionButtonContainer = new RelativeLayout(cordova.getActivity());
RelativeLayout.LayoutParams actionButtonLayoutParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
if (leftToRight) actionButtonLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
else actionButtonLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
actionButtonContainer.setLayoutParams(actionButtonLayoutParams);
actionButtonContainer.setHorizontalGravity(Gravity.LEFT);
actionButtonContainer.setVerticalGravity(Gravity.CENTER_VERTICAL);
actionButtonContainer.setId(leftToRight ? Integer.valueOf(5) : Integer.valueOf(1));
// Back button
ImageButton back = new ImageButton(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(Integer.valueOf(2));
Resources activityRes = cordova.getActivity().getResources();
int backResId = activityRes.getIdentifier("ic_action_previous_item", "drawable", cordova.getActivity().getPackageName());
Drawable backIcon = activityRes.getDrawable(backResId);
if (navigationButtonColor != "") back.setColorFilter(android.graphics.Color.parseColor(navigationButtonColor));
back.setBackground(null);
back.setImageDrawable(backIcon);
back.setScaleType(ImageView.ScaleType.FIT_CENTER);
back.setPadding(0, this.dpToPixels(10), 0, this.dpToPixels(10));
back.getAdjustViewBounds();
back.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
goBack();
}
});
// Forward button
ImageButton forward = new ImageButton(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(Integer.valueOf(3));
int fwdResId = activityRes.getIdentifier("ic_action_next_item", "drawable", cordova.getActivity().getPackageName());
Drawable fwdIcon = activityRes.getDrawable(fwdResId);
if (navigationButtonColor != "") forward.setColorFilter(android.graphics.Color.parseColor(navigationButtonColor));
forward.setBackground(null);
forward.setImageDrawable(fwdIcon);
forward.setScaleType(ImageView.ScaleType.FIT_CENTER);
forward.setPadding(0, this.dpToPixels(10), 0, this.dpToPixels(10));
forward.getAdjustViewBounds();
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(Integer.valueOf(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;
}
});
// Header Close/Done button
int closeButtonId = leftToRight ? 1 : 5;
View close = createCloseButton(closeButtonId);
toolbar.addView(close);
// Footer
RelativeLayout footer = new RelativeLayout(cordova.getActivity());
int _footerColor;
if(footerColor != "") {
_footerColor = Color.parseColor(footerColor);
} else {
_footerColor = android.graphics.Color.LTGRAY;
}
footer.setBackgroundColor(_footerColor);
RelativeLayout.LayoutParams footerLayout = new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, this.dpToPixels(TOOLBAR_HEIGHT));
footerLayout.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, RelativeLayout.TRUE);
footer.setLayoutParams(footerLayout);
if (closeButtonCaption != "") footer.setPadding(this.dpToPixels(8), this.dpToPixels(8), this.dpToPixels(8), this.dpToPixels(8));
footer.setHorizontalGravity(Gravity.LEFT);
footer.setVerticalGravity(Gravity.BOTTOM);
View footerClose = createCloseButton(7);
footer.addView(footerClose);
// yellowin WebView
inAppWebView = (WebView) dialog.findViewById(R.id.webView); /* 인앱브라우져 /layout/active_main.xml 로드/연결 */
//yellowin yellowin swipeRefreshLayout
swipeRefreshLayout = dialog.findViewById(R.id.swipeRefreshLayout);
//// yellowin yellowin videoview 풀스크린 - 비디오 풀스크린 뷰
mVideoview = dialog.findViewById(R.id.videoview);
//yellowin yellowin swipeRefreshLayout
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
// Implement your refresh logic here
// For example, reload the current URL in the WebView
inAppWebView.reload();
}
});
// // WebView
// inAppWebView = new WebView(cordova.getActivity());
// inAppWebView.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
// inAppWebView.setId(Integer.valueOf(6));
// File Chooser Implemented ChromeClient
inAppWebView.setWebChromeClient(new InAppChromeClient(thatWebView) {
// yellowin yellowin videoview 풀스크린
@Override
public void onHideCustomView() {
Activity activity = cordova.getActivity();
Window window = dialog.getWindow();
Log.d("yellowin", "yellowin mVideoview disableFullScreen~~ onHideCustomView 1111");
disableFullScreen(activity, window);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
}
mVideoview.setVisibility(View.GONE);
// 하단툴바 메뉴 표시
// bnve.setVisibility(View.VISIBLE);
}
// yellowin yellowin videoview 풀스크린
@Override
public void onShowCustomView(View view, CustomViewCallback callback) {
// Enter fullscreen mode
// super.onShowCustomView(view, callback);
// You may need to handle the view and callback to exit fullscreen later
// 하단툴바 메뉴 숨김 (bnve 객체명으로 하단툴바가 있는경우에만 사용)
// bnve.setVisibility(View.GONE);
mVideoview.addView(view);
mVideoview.setVisibility(View.VISIBLE);
mVideoview.bringToFront();
Activity activity = cordova.getActivity();
Window window = dialog.getWindow();
Log.d("yellowin", "yellowin mVideoview enableFullScreen~~ onShowCustomView 1111");
enableFullScreen(activity, window);
// activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);
}
}
public boolean onShowFileChooser (WebView webView, ValueCallback<Uri[]> filePathCallback, WebChromeClient.FileChooserParams fileChooserParams)
{
LOG.d(LOG_TAG, "File Chooser 5.0+");
// Callback 초기화 (중요!) //input file태그를 다시 눌렀을때 정상 작동되도록 함.
// If callback exists, finish it.
if (filePathCallbackLollipop != null) {
filePathCallbackLollipop.onReceiveValue(null);
filePathCallbackLollipop = null;
}
filePathCallbackLollipop = filePathCallback;
boolean isCapture = fileChooserParams.isCaptureEnabled();
String acceptType = Arrays.toString(fileChooserParams.getAcceptTypes());
Log.i("---", "---");
Log.w("//===========//", "================================================");
Log.i("", "\\n" + "[A_Main >> onShowFileChooser() :: 웹 브라우저 갤러리 호출 수행 실시]");
Log.i("", "\\n" + "[filePathCallback :: " + String.valueOf(filePathCallback.toString()) + "]");
Log.i("", "\\n" + "[fileChooserParams :: " + Arrays.toString(fileChooserParams.getAcceptTypes())
+ "]");
Log.w("//===========//", "================================================");
Log.i("---", "---");
// 카메라만 호출여부 체크
// 아래 Input 태그의 속성중 capture란 속성이 들어가있다면 isCapture=true 임.
// <input type="file" name="upfile_1" id="upfile_1" accept="image/jpeg,
// image/png, image/jpg;" capture="image">
Log.d("onShowFileChooser", "yellowin yellowin onShowFileChooser inapp view : 000000");
Log.d("onShowFileChooser", "yellowin yellowin onShowFileChooser 1111 : " + String.valueOf(isCapture));
Log.d("onShowFileChooser", "yellowin yellowin onShowFileChooser 2222 : " + String.valueOf(acceptType));
// yellowin multi
//////////// yellowin yellowin 멀티 업로드 추가 수정 시작 11
Boolean selectMultiple = false;
if (fileChooserParams.getMode() == WebChromeClient.FileChooserParams.MODE_OPEN_MULTIPLE) {
selectMultiple = true;
}
if (isCapture) {
// (isCapture = true인경우 카메라만 띄울수 있음)
yellowinChooser(isCapture, selectMultiple, acceptType);
} else if (!acceptType.contains("*/*")) {
Log.d("yellowin : ", "yellowin 카메라,갤러리 호출");
// 카메라 및 갤러리 선택 호출
yellowinChooser(false, selectMultiple, acceptType);
} else {
Log.d("yellowin : ", "yellowin 갤러리 일반 호출");
// 갤러리만 호출 일반파일 선택 호출(기존소스임)
// Create File Chooser Intent
Intent content = new Intent(Intent.ACTION_GET_CONTENT);
content.addCategory(Intent.CATEGORY_OPENABLE);
content.setType("*/*");
content.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, selectMultiple);
//////////// yellowin multi upload 추가 수정 끝 11
// Run cordova startActivityForResult
cordova.startActivityForResult(InAppBrowser.this,
Intent.createChooser(content, "Select File"), FILECHOOSER_REQUESTCODE);
// }
}
return true;
}
// yellowin yellowin window.open 사용시 앱내에서 새로운 자식팝업뷰로 뜨게 처리함. - start
public boolean onCreateWindow(WebView view, boolean isDialog, boolean isUserGesture,
android.os.Message resultMsg) {
newWebView = new WebView(view.getContext());
// WebView newWebView = new VideoEnabledWebView(cordova.getActivity());
Log.d("yellowin", "onCreateWindow yellowin window.open ~~~~~");
newWebView.setLayoutParams(
new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
newWebView.setId(Integer.valueOf(6));
WebSettings settings = newWebView.getSettings();
settings.setJavaScriptEnabled(true);
settings.setJavaScriptCanOpenWindowsAutomatically(true);
settings.setSupportMultipleWindows(true);
// bnve.setVisibility(View.GONE);
// Log.d("yellowin","yellowin bnve bnve.setVisibility(View.GONE) 1111");
// yellowin 상단 기본 인앱코드 카피 - start
// yellowin yellowin window.open 글자크기 고정
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.ICE_CREAM_SANDWICH)
settings.setTextZoom(100);
// yellowin mixed content errors 방지
// settings.setMixedContentMode(android.webkit.WebSettings.MIXED_CONTENT_COMPATIBILITY_MODE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
settings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
}
// // yellowin yellowin net::ERR_CACHE_MISS
// settings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
settings.setJavaScriptEnabled(true);
settings.setJavaScriptCanOpenWindowsAutomatically(true);
settings.setBuiltInZoomControls(showZoomControls);
// yellowin //줌 컨트롤을 숨김
settings.setDisplayZoomControls(false);
settings.setPluginState(android.webkit.WebSettings.PluginState.ON);
// yellowin yellowin window.open 세로 scroll 제거
newWebView.setHorizontalScrollBarEnabled(false);
// yellowin yellowin window.open 가로 scroll 제거
newWebView.setVerticalScrollBarEnabled(false);
// yellwoin 웹뷰 배경 흰색
newWebView.setBackgroundColor(Color.parseColor("#ffffff"));
// Add postMessage interface
class JsObject {
@JavascriptInterface
// public void postMessage(String data) {
// try {
// JSONObject obj = new JSONObject();
// obj.put("type", MESSAGE_EVENT);
// obj.put("data", new JSONObject(data));
// sendUpdate(obj, true);
// } catch (JSONException ex) {
// LOG.e(LOG_TAG, "data object passed to postMessage has caused a JSON error.");
// }
// }
public void postMessage(String data) {
try {
JSONObject obj = new JSONObject();
obj.put("type", MESSAGE_EVENT);
// 데이터가 JSON 문자열인지 확인
if (isJSONValid(data)) {
obj.put("data", new JSONObject(data)); // JSON 문자열 처리
} else {
throw new IllegalArgumentException("Invalid JSON data received: " + data);
}
sendUpdate(obj, true);
} catch (JSONException ex) {
LOG.e(LOG_TAG, "JSON parsing error in postMessage: " + ex.getMessage());
} catch (Exception ex) {
LOG.e(LOG_TAG, "Unexpected error in postMessage: " + ex.getMessage());
}
}
/**
* Helper method to validate if a string is a valid JSON.
*/
private boolean isJSONValid(String data) {
try {
new JSONObject(data); // JSON으로 변환 시도
return true;
} catch (JSONException ex) {
return false;
}
}
}
settings.setMediaPlaybackRequiresUserGesture(mediaPlaybackRequiresUserGesture);
newWebView.addJavascriptInterface(new JsObject(), "firebase");
newWebView.addJavascriptInterface(new JsObject(), "cordova_iab");
String overrideUserAgent = preferences.getString("OverrideUserAgent", null);
String appendUserAgent = preferences.getString("AppendUserAgent", null);
if (overrideUserAgent != null) {
settings.setUserAgentString(overrideUserAgent);
}
if (appendUserAgent != null) {
settings.setUserAgentString(settings.getUserAgentString() + appendUserAgent);
}
//
//
// // 기존 User-Agent 가져오기
// String defaultUserAgent = settings.getUserAgentString();
//
// // 새로운 User-Agent 추가 (Yellowin 추가 : /APTRACK_ANDROID => GA팀에서 추가요청으로 추가)
// String customUserAgent = defaultUserAgent + " mobileapp androidapp amospro/APTRACK_ANDROID";
// settings.setUserAgentString(customUserAgent);
// 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) {
CookieManager.getInstance().removeAllCookie();
} else if (clearSessionCache) {
CookieManager.getInstance().removeSessionCookie();
}
// Enable Thirdparty Cookies
CookieManager.getInstance().setAcceptThirdPartyCookies(newWebView, true);
// yellowin 상단 기본 인앱코드 카피 - end
if (dialog_child != null) {
dialog_child.dismiss();
}
;
// yellowin new 새창처리 - start
// 새 창의 전체 레이아웃을 위한 RelativeLayout 생성
RelativeLayout fullScreenLayout = new RelativeLayout(cordova.getContext());
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
fullScreenLayout.setLayoutParams(layoutParams);
// fullScreenLayout.setBackgroundColor(Color.WHITE); // 전체 배경을 흰색으로 설정
fullScreenLayout.setBackgroundColor(Color.TRANSPARENT); // 전체 배경을 투명으로 설정
// "닫기" 이미지 버튼 생성 및 설정
ImageButton closeButton = new ImageButton(cordova.getContext());
closeButton.setId(View.generateViewId()); // 닫기 버튼에 고유 ID 할당
closeButton.setImageResource(R.drawable.ic_close); // 이미지 리소스 설정
closeButton.setScaleType(ImageView.ScaleType.CENTER_INSIDE); // 이미지가 버튼 중앙에 위치하도록 설정
// 동그란 모양의 배경을 설정하기 위한 ShapeDrawable
ShapeDrawable circleDrawable = new ShapeDrawable(new OvalShape());
circleDrawable.getPaint().setColor(Color.WHITE); // 동그란 배경의 색상을 흰색으로 설정
circleDrawable.getPaint().setAntiAlias(true); // 안티알리아싱 적용
// 이미지 버튼에 동그란 배경 설정
closeButton.setBackground(circleDrawable);
// closeButton.setBackgroundColor(Color.TRANSPARENT); // 배경색을 투명으로 설정
// closeButton.setOnClickListener(v -> dialog_child.dismiss());
closeButton.setColorFilter(Color.BLACK); // 이미지 색상을 검은색으로 변경
closeButton.setScaleType(ImageView.ScaleType.FIT_CENTER); // 이미지를 버튼 크기에 맞게 조정
closeButton.setPadding(15, 15, 15, 15); // x이미지 여백
// 이미지 버튼 크기 조정
int buttonSize = 35; // 버튼 크기를 80dp로 설정
float scale = cordova.getContext().getResources().getDisplayMetrics().density;
int dpAsPixels = (int) (buttonSize * scale + 0.5f);
RelativeLayout.LayoutParams buttonParams = new RelativeLayout.LayoutParams(dpAsPixels,
dpAsPixels);
// RelativeLayout.LayoutParams buttonParams = new
// RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT,
// LayoutParams.WRAP_CONTENT);
buttonParams.addRule(RelativeLayout.ALIGN_PARENT_TOP);
buttonParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
// 닫기 버튼에 마진을 추가하여 상단에 여백을 만듦
buttonParams.setMargins(0, 25, 30, 25); // 마진 추가로 상단에 여백을 만듦
closeButton.setLayoutParams(buttonParams);
// RelativeLayout에 "닫기" 이미지 버튼 추가
fullScreenLayout.addView(closeButton);
// WebView 설정 및 추가
RelativeLayout.LayoutParams webViewParams = new RelativeLayout.LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
webViewParams.addRule(RelativeLayout.BELOW, closeButton.getId()); // WebView가 닫기 버튼 아래에 위치하도록 설정
fullScreenLayout.addView(newWebView, webViewParams);
// 대화 상자(dialog) 설정 및 표시
if (dialog_child != null) {
dialog_child.dismiss();
}
dialog_child = new InAppBrowserDialog(cordova.getActivity(), android.R.style.Theme_NoTitleBar);
// 대화 상자의 윈도우 배경을 투명하게 설정
window_child = dialog_child.getWindow();
if (window_child != null) {
// window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); // 윈도우
// 배경을 투명하게
window_child.setBackgroundDrawable(new ColorDrawable(Color.argb(128, 0, 0, 0))); // 50% 투명도의
// 검은색
// 슬라이드 애니메이션 설정 (res/anim/slide_in_bottom.xml, res/anim/slide_out_bottom.xml,
// stay_in_place.xml 파일이 있어야함. res/values/styles.xml 파일에 DialogSlideAnim,
// DialogSlideAnimClose style이 정의되어 있어야함.)
window_child.setWindowAnimations(R.style.DialogSlideAnim);
window_child.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window_child.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
window_child.setStatusBarColor(Color.TRANSPARENT);
// 상태바 아이콘과 텍스트 색상을 검정색으로 설정 (API 23+)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
window_child.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
}
}
// "닫기" 버튼 클릭 이벤트 설정
closeButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 애니메이션으로 닫기 (res/anim/slide_in_bottom.xml, res/anim/slide_out_bottom.xml,
// stay_in_place.xml 파일이 있어야함. res/values/styles.xml 파일에 DialogSlideAnim,
// DialogSlideAnimClose style이 정의되어 있어야함.)
window_child.setWindowAnimations(R.style.DialogSlideAnimClose); // 슬라이드 아웃 애니메이션 설정
// Handler를 사용하여 애니메이션의 지속 시간 후에 dialog_child.dismiss()를 호출
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
newWebView.destroy();
dialog_child.dismiss();
}
}, 100); // 여기서 300은 애니메이션의 duration과 일치해야 합니다.
}
});
dialog_child.setContentView(fullScreenLayout);
WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
lp.copyFrom(dialog_child.getWindow().getAttributes());
lp.width = LayoutParams.MATCH_PARENT;
lp.height = LayoutParams.MATCH_PARENT;
window_child.setAttributes(lp);
dialog_child.show();
// yellowin new 새창처리 - end
dialog_child.setOnKeyListener(new DialogInterface.OnKeyListener() {
@Override
public boolean onKey(DialogInterface dialog_ch, int keyCode, KeyEvent event) {
LOG.d("yellowin", "yellowin dialog_child back~~~~!!!!!! ");
if (keyCode == KeyEvent.KEYCODE_BACK) {
// yellowin yellowin window.open - video 풀스크린 화면에서 백버튼을 눌렀을때의 처리(풀스크린 해제된 화면으로
// 표시)
if (isFullscreen) {
Activity activity = cordova.getActivity();
Window window = dialog_child.getWindow();
// if (!fullScreenFeature) {
disableFullScreen(activity, window);
// }
Log.d("yellowin", "yellowin bnve disableFullScreen~~ 0000");
// //1초후에 실행되도록 지연시간을 주어야 함.
new Handler(getMainLooper()).postDelayed(new Runnable() {
@Override
public void run() {
isFullscreen = false;
// newWebView.loadUrl("javascript:document.exitFullscreen();");
}
}, 1000);
// activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT);
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
// newWebView.setVisibility(View.GONE);
isFullscreen = false;
return true;
} else {
if (newWebView.canGoBack()) {
newWebView.goBack();
} else {
// yellowin new 새창처리 - start
// 애니메이션으로 닫기 (res/anim/slide_in_bottom.xml, res/anim/slide_out_bottom.xml,
// stay_in_place.xml 파일이 있어야함. res/values/styles.xml 파일에 DialogSlideAnim,
// DialogSlideAnimClose style이 정의되어 있어야함.)
window_child.setWindowAnimations(R.style.DialogSlideAnimClose); // 슬라이드 아웃
// 애니메이션 설정
// Handler를 사용하여 애니메이션의 지속 시간 후에 dialog_child.dismiss()를 호출
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
newWebView.destroy();
dialog_child.dismiss();
}
}, 100); // 여기서 300은 애니메이션의 duration과 일치해야 합니다.
// yellowin new 새창처리 - end
// yellowin new 새창처리 - start
// 아래는 기존 코드로 주석처리 해야함.
// newWebView.destroy();
// dialog_ch.dismiss();
// yellowin new 새창처리 - end
}
return true;
}
} else {
return false;
}
}
});
newWebView.setWebChromeClient(new InAppChromeClient(thatWebView) {
public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback,
WebChromeClient.FileChooserParams fileChooserParams) {
LOG.d(LOG_TAG, "yellowin yellowin newWebview File Chooser 5.0+");
// If callback exists, finish it.
if (mUploadCallback != null) {
mUploadCallback.onReceiveValue(null);
}
mUploadCallback = filePathCallback;
// Create File Chooser Intent
Intent content = new Intent(Intent.ACTION_GET_CONTENT);
content.addCategory(Intent.CATEGORY_OPENABLE);
content.setType("*/*");
// yellowin multi upload 추가 start
Boolean selectMultiple = false;
if (fileChooserParams
.getMode() == WebChromeClient.FileChooserParams.MODE_OPEN_MULTIPLE) {
selectMultiple = true;
}
// yellowin multi upload 추가 end
// Run cordova startActivityForResult
cordova.startActivityForResult(InAppBrowser.this,
Intent.createChooser(content, "Select File"),
FILECHOOSER_REQUESTCODE);
return true;
}
@Override
public void onCloseWindow(WebView window) {
// bnve.setVisibility(View.VISIBLE);
Log.d("yellowin", "yellowin bnve onCloseWindow bnve.setVisibility(View.VISIBLE) 1111");
newWebView.destroy();
dialog_child.dismiss();
}
@Override
public boolean onJsAlert(WebView view, String url, String message, final JsResult result) {
final AlertDialog.Builder builder = new AlertDialog.Builder(view.getContext(),
AlertDialog.THEME_DEVICE_DEFAULT_LIGHT);
// builder.setTitle("alert title - inAppChromeClient.JAVA");
builder.setMessage(message);
builder.setPositiveButton(android.R.string.ok, null);
// Do not need to bind the key events
// Mask keycode is equal to 84 and the like button
builder.setOnKeyListener(new DialogInterface.OnKeyListener() {
public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
// Log.v ("onJsAlert", "keyCode ==" + keyCode + "event =" + event);
return true;
}
});
// Disable response back key event
builder.setCancelable(false);
AlertDialog dialog = builder.create();
dialog.show();
result.confirm(); // bind the event because there is no need to force confirm, otherwise
// the page will turn black can not display content.
return true;
}
@Override
public boolean onJsConfirm(WebView view, String url, String message,
final JsResult result) {
final AlertDialog.Builder builder = new AlertDialog.Builder(view.getContext(),
AlertDialog.THEME_DEVICE_DEFAULT_LIGHT);
// builder.setTitle("confirm title - inAppChromeClient.JAVA");
builder.setMessage(message);
// builder.setPositiveButton("ok", null);
builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
result.confirm();
}
});
builder.setNegativeButton(android.R.string.cancel,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
result.cancel();
}
});
// Disable response back key event
builder.setCancelable(false);
AlertDialog dialog = builder.create();
dialog.show();
return true;
}
});
WebViewClient client_child = new InAppBrowserClient(thatWebView, edittext, beforeload);
// newWebView.setWebViewClient(client_child);
newWebView.setWebViewClient(new MyWebViewClient(view.getContext()));
WebView.WebViewTransport transport = (WebView.WebViewTransport) resultMsg.obj;
transport.setWebView(newWebView);
resultMsg.sendToTarget();
return true;
}
@Override
public void onCloseWindow(WebView window) {
Log.d("yellowin", "yellowin bnve onCloseWindow bnve.setVisibility(View.VISIBLE) 000");
Log.e(getClass().getName(), "onCloseWindow");
window.setVisibility(View.GONE);
window.destroy();
super.onCloseWindow(window);
}
// yellowin yellowin window.open 사용시 앱내에서 새로운 자식팝업뷰로 뜨게 처리함. - end
});
// currentClient = new InAppBrowserClient(thatWebView, edittext, beforeload);
// inAppWebView.setWebViewClient(currentClient);
// yellowin yellowin edit
WebViewClient client = new InAppBrowserClient(thatWebView, edittext, beforeload);
inAppWebView.setWebViewClient(client);
WebSettings settings = inAppWebView.getSettings();
// yellowin 글자크기 고정
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.ICE_CREAM_SANDWICH)
settings.setTextZoom(100);
// yellowin mixed content errors 방지
// settings.setMixedContentMode(android.webkit.WebSettings.MIXED_CONTENT_COMPATIBILITY_MODE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
settings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
}
// // yellowin yellowin net::ERR_CACHE_MISS
// settings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
settings.setJavaScriptEnabled(true);
settings.setJavaScriptCanOpenWindowsAutomatically(true);
settings.setBuiltInZoomControls(showZoomControls);
// yellowin //줌 컨트롤을 숨김
settings.setDisplayZoomControls(false);
settings.setPluginState(android.webkit.WebSettings.PluginState.ON);
// yellowin 세로 scroll 제거
inAppWebView.setHorizontalScrollBarEnabled(false);
// yellowin 가로 scroll 제거
inAppWebView.setVerticalScrollBarEnabled(false);
// yellwoin 웹뷰 배경 흰색
inAppWebView.setBackgroundColor(Color.parseColor("#ffffff"));
// download event
inAppWebView.setDownloadListener(
new DownloadListener(){
public void onDownloadStart(
String url, String userAgent, String contentDisposition, String mimetype, long contentLength
){
try{
JSONObject succObj = new JSONObject();
succObj.put("type", DOWNLOAD_EVENT);
succObj.put("url",url);
succObj.put("userAgent",userAgent);
succObj.put("contentDisposition",contentDisposition);
succObj.put("mimetype",mimetype);
succObj.put("contentLength",contentLength);
sendUpdate(succObj, true);
}
catch(Exception e){
LOG.e(LOG_TAG,e.getMessage());
}
}
}
);
// Add postMessage interface
class JsObject {
@JavascriptInterface
// public void postMessage(String data) {
// try {
// JSONObject obj = new JSONObject();
// obj.put("type", MESSAGE_EVENT);
// obj.put("data", new JSONObject(data));
// sendUpdate(obj, true);
// } catch (JSONException ex) {
// LOG.e(LOG_TAG, "data object passed to postMessage has caused a JSON error.");
// }
// }
public void postMessage(String data) {
try {
JSONObject obj = new JSONObject();
obj.put("type", MESSAGE_EVENT);
// 데이터가 JSON 문자열인지 확인
if (isJSONValid(data)) {
obj.put("data", new JSONObject(data)); // JSON 문자열 처리
} else {
throw new IllegalArgumentException("Invalid JSON data received: " + data);
}
sendUpdate(obj, true);
} catch (JSONException ex) {
LOG.e(LOG_TAG, "JSON parsing error in postMessage: " + ex.getMessage());
} catch (Exception ex) {
LOG.e(LOG_TAG, "Unexpected error in postMessage: " + ex.getMessage());
}
}
/**
* Helper method to validate if a string is a valid JSON.
*/
private boolean isJSONValid(String data) {
try {
new JSONObject(data); // JSON으로 변환 시도
return true;
} catch (JSONException ex) {
return false;
}
}
}
settings.setMediaPlaybackRequiresUserGesture(mediaPlaybackRequiresUserGesture);
inAppWebView.addJavascriptInterface(new JsObject(), "firebase");
inAppWebView.addJavascriptInterface(new JsObject(), "cordova_iab");
// WebView 설정 코드
inAppWebView.getSettings().setJavaScriptEnabled(true); // JavaScript 활성화
AnalyticsWebInterface analyticsWebInterface = new AnalyticsWebInterface(cordova.getContext());
inAppWebView.addJavascriptInterface(analyticsWebInterface, "AnalyticsWebInterface");
String overrideUserAgent = preferences.getString("OverrideUserAgent", null);
String appendUserAgent = preferences.getString("AppendUserAgent", null);
if (overrideUserAgent != null) {
settings.setUserAgentString(overrideUserAgent);
}
if (appendUserAgent != null) {
settings.setUserAgentString(settings.getUserAgentString() + " " + appendUserAgent);
}
//
// // 기존 User-Agent 가져오기
// String defaultUserAgent = settings.getUserAgentString();
//
// // 새로운 User-Agent 추가 (Yellowin 추가 : /APTRACK_ANDROID => GA팀에서 추가요청으로 추가)
// String customUserAgent = defaultUserAgent + " mobileapp androidapp amospro/APTRACK_ANDROID";
// settings.setUserAgentString(customUserAgent);
//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) {
CookieManager.getInstance().removeAllCookie();
} else if (clearSessionCache) {
CookieManager.getInstance().removeSessionCookie();
}
// Enable Thirdparty Cookies
CookieManager.getInstance().setAcceptThirdPartyCookies(inAppWebView,true);
inAppWebView.loadUrl(url);
inAppWebView.setId(Integer.valueOf(6));
inAppWebView.getSettings().setLoadWithOverviewMode(true);
inAppWebView.getSettings().setUseWideViewPort(useWideViewPort);
// Multiple Windows set to true to mitigate Chromium security bug.
// See: <https://bugs.chromium.org/p/chromium/issues/detail?id=1083819>
inAppWebView.getSettings().setSupportMultipleWindows(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 if they haven't been disabled
if (!hideNavigationButtons) toolbar.addView(actionButtonContainer);
if (!hideUrlBar) toolbar.addView(edittext);
// 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
// RelativeLayout webViewLayout = new RelativeLayout(cordova.getActivity());
// webViewLayout.addView(inAppWebView);
// main.addView(webViewLayout);
// // Don't add the footer unless it's been enabled
// if (showFooter) {
// webViewLayout.addView(footer);
// }
// WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
// lp.copyFrom(dialog.getWindow().getAttributes());
// lp.width = WindowManager.LayoutParams.MATCH_PARENT;
// lp.height = WindowManager.LayoutParams.MATCH_PARENT;
// yellowin yellowin start
LayoutParams lp = new LayoutParams();
lp.copyFrom(dialog.getWindow().getAttributes());
lp.width = LayoutParams.MATCH_PARENT;
lp.height = LayoutParams.MATCH_PARENT;
// yellowin yellowin end
if (dialog != null) {
// dialog.setContentView(main); // yellowin yellowin
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 != null) {
dialog.hide();
}
}
};
this.cordova.getActivity().runOnUiThread(runnable);
return "";
}
public class AnalyticsWebInterface {
private Context context;
public AnalyticsWebInterface(Context context) {
this.context = context;
}
@JavascriptInterface
public void logEvent(String name, String jsonParams) {
Log.d("AnalyticsWebInterface", "logEvent called: name=" + name + ", params=" + jsonParams);
//
// // 메인 스레드에서 loadUrl 실행
// new Handler(Looper.getMainLooper()).post(() -> {
// webView.loadUrl("javascript:call_logEvent(name,jsonParams);");
// });
// JavaScript로 JSON 그대로 전달
new Handler(Looper.getMainLooper()).post(() -> {
String javascript = String.format("javascript:call_logEvent('%s', %s);", name, jsonParams);
webView.loadUrl(javascript);
});
}
@JavascriptInterface
public void setUserProperty(String name, String value) {
Log.d("AnalyticsWebInterface", "setUserProperty called: name=" + name + ", value=" + value);
new Handler(Looper.getMainLooper()).post(() -> {
String javascript = String.format("javascript:call_setUserProperty('%s', '%s');", name, value);
webView.loadUrl(javascript);
});
}
@JavascriptInterface
public void setUserId(String id) {
Log.d("AnalyticsWebInterface", "setUserId called: id=" + id);
new Handler(Looper.getMainLooper()).post(() -> {
String javascript = String.format("javascript:call_setUserId('%s');", id);
webView.loadUrl(javascript);
});
}
}
// yellowin yellowin window.open popupview WebViewClient선언 - start
public class MyWebViewClient extends WebViewClient {
private String TAG = "MyWebViewClient";
private Context mApplicationContext = null;
String beforeload;
boolean waitForBeforeload;
public MyWebViewClient(Context _applicationContext) {
mApplicationContext = _applicationContext;
}
@Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
// MyLog.i(TAG,"shouldOverrideUrlLoading(view:"+view+ ", request:"+request+")");
// return super.shouldOverrideUrlLoading(view, request);
return shouldOverrideUrlLoading(request.getUrl().toString(), request.getMethod());
}
public boolean shouldOverrideUrlLoading(String url, String method) {
boolean override = false;
boolean useBeforeload = false;
String errorMessage = null;
LOG.d(LOG_TAG, "yellowin yellowin window.open >>>> url 11111 : " + url);
// yellowin yellowin 외부 브라우져로 url 열기 시작
if( url.contains("systempop=") ) {
String[] array;
array = url.split("systempop=");
String url2 = array[1];
LOG.d(LOG_TAG, "yellowin url window.open external link URL : " + url);
try {
Intent intent = null;
Uri uri = Uri.parse(url2);
intent = new Intent(Intent.ACTION_VIEW, uri);
cordova.getActivity().startActivity(intent);
override = true;
} catch (android.content.ActivityNotFoundException e) {
//e.printStackTrace(); //code break
override = false;
}
} else
if (url.startsWith(WebView.SCHEME_TEL)) {
try {
Intent intent = new Intent(Intent.ACTION_DIAL);
intent.setData(Uri.parse(url));
cordova.getActivity().startActivity(intent);
override = true;
} catch (android.content.ActivityNotFoundException e) {
LOG.e(LOG_TAG, "Error dialing " + url + ": " + e.toString());
}
} else if (url.startsWith("geo:") || url.startsWith(WebView.SCHEME_MAILTO)) {
try {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse(url));
cordova.getActivity().startActivity(intent);
override = true;
} 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);
override = true;
} catch (android.content.ActivityNotFoundException e) {
LOG.e(LOG_TAG, "Error sending sms " + url + ":" + e.toString());
}
} else if ((!url.startsWith("http:")
&& !url.startsWith("https:")
&& url.matches("^[A-Za-z0-9+.-]*://.*?$"))
|| url.startsWith("market:")
|| url.startsWith("intent:")
|| url.startsWith("bandapp:")// 네이버 밴드
|| url.startsWith("kakaotalk:")// 카카오톡
|| url.startsWith("storylink:")
|| url.startsWith("kakaoplus:")
|| url.startsWith("kakaokompassauth:")
|| url.startsWith("storykompassauth:")
|| url.startsWith("kakaolink:")
|| url.startsWith("kakaotalk-5.9.7:")
|| url.startsWith("kakaostory-2.9.0:")
|| url.startsWith("naversearchapp:")// 네이버앱
|| url.startsWith("nidlogin:")
|| url.startsWith("naversearchthirdlogin:")
|| url.startsWith("daumapps:")// 다음
|| url.startsWith("googlechromes:")// 크롬
|| url.startsWith("fb:")// 페이스북
// 본인인증
|| url.startsWith("tauthlink:")
|| url.startsWith("ktauthexternalcall:")
|| url.startsWith("upluscorporation:")
// 결제
|| url.contains("com.kftc.bankpay.android://")
|| url.contains("com.lotte.lottesmartpay://")
|| url.contains("com.ahnlab.v3mobileplus://")
|| url.contains("hanaansim://")
|| url.contains("vguard://")
|| url.contains("droidxantivirus://")
|| url.contains("smshinhancardusim://")
|| url.contains("smartwall://")
|| url.contains("appfree://")
|| url.contains("kb-acp://")
|| url.contains("lguthepay://")
|| url.contains("v3mobile://")
|| url.contains("kakaopay://")
|| url.contains("kftc-bankpay://")
|| url.contains("ispmobile://")
|| url.contains("hdcardappcardansimclick://")
|| url.contains("smhyundaiansimclick://")
|| url.contains("shinhan-sr-ansimclick://")
|| url.contains("smshinhanansimclick://")
|| url.contains("nonghyupcardansimclick://")
|| url.contains("kb-acp://")
|| url.contains("mpocket.online.ansimclick://")
|| url.contains("ansimclickscard://")
|| url.contains("ansimclickipcollect://")
|| url.contains("vguardstart://")
|| url.contains("samsungpay://")
|| url.contains("scardcertiapp://")
|| url.contains("lottesmartpay://")
|| url.contains("lotteappcard://")
|| url.contains("cloudpay://")
|| url.contains("nhappvardansimclick://")
|| url.contains("nhappcardansimclick://")
|| url.contains("nhallonepayansimclick://")
|| url.contains("citispay://")
|| url.contains("citimobileapp://")
|| url.contains("citicardappkr://")
|| url.contains("payco://")
|| url.contains("paypin://")
|| url.contains("paycoapplogin://")
|| url.contains("tswansimclick://")
|| url.contains("bankwallet://")
|| url.contains("uppay://")
|| url.contains("kpay://")
|| url.contains("smilepayapp://")
|| url.contains("maps://")
|| url.contains("citymapper://")
|| url.contains("comgooglemaps://")
|| url.contains("navigon://")
|| url.contains("transit://")
|| url.contains("waze://")
|| url.contains("yandexnavi://")
|| url.contains("uber://")
|| url.contains("tomtomhome://")
|| url.contains("com.sygic.aura://")
|| url.contains("here-route://")
|| url.contains("moovit://")
|| url.contains("lyft://")
|| url.contains("mapsme://")
|| url.contains("cabify://")
|| url.contains("baidumap://")
|| url.contains("lguthepay://")
|| url.contains("smartxpay-transfer://")
|| url.contains("smilepay://")
|| url.contains("supertoss://")
|| url.contains("hanawalletmembers://")
|| url.contains("wooripay://")
|| url.contains("shinsegaeeasypayment://")
|| url.contains("lpayapp://")
|| url.contains("lmslpay://")
|| url.contains("chai://")
|| url.contains("intmoney://")
|| url.contains("hanaskcardmobileportal://")
|| url.contains("ukbanksmartbanknonloginpay://")
|| url.contains("kdb-bankpay://")
|| url.contains("ibk-bankpay://")
|| url.contains("kb-bankpay://")
|| url.contains("keb-bankpay://")
|| url.contains("sh-bankpay://")
|| url.contains("nhb-bankpay://")
|| url.contains("nh-bankpay://")
|| url.contains("wr-bankpay://")
|| url.contains("sc-bankpay://")
|| url.contains("s-bankpay://")
|| url.contains("ct-bankpay://")
|| url.contains("dg-bankpay://")
|| url.contains("bnk-bankpay://")
|| url.contains("kj-bankpay://")
|| url.contains("jj-bankpay://")
|| url.contains("kn-bankpay://")
|| url.contains("kp-bankpay://")
|| url.contains("cu-bankpay://")
|| url.contains("mg-bankpay://")
|| url.contains("kbn-bankpa://y")
|| url.contains("kkb-bankpay://")
//|| url.contains("ansimclick")
//|| (url.contains("ansimclick") && !url.equals("ansimclick.hyundiacard.com"))
|| url.contains("market://details?id=com.shcard.smartpay")
|| url.contains("<http://m.ahnlab.com/kr/site/download>")
|| url.endsWith(".apk")
//본인인증
|| url.contains("tauthlink://")
|| url.contains("ktauthexternalcall://")
|| url.contains("upluscorporation://")
|| url.contains("line://")//라인
|| url.contains("bandapp://")//네이버 밴드
|| url.contains("kakaotalk://")//카카오톡
|| url.contains("storylink://")
|| url.contains("kakaoplus://")
|| url.contains("kakaokompassauth://")
|| url.contains("storykompassauth://")
|| url.contains("kakaolink://")
|| url.contains("kakaotalk-5.9.7://")
|| url.contains("kakaostory-2.9.0://")
|| url.contains("naversearchapp")//네이버앱
|| url.contains("naversearchthirdlogin")
|| (url.contains("nidlogin") && !url.contains("naver.com"))
|| url.contains("daumapps://open")//다음
|| url.contains("googlechromes://")//크롬
|| url.contains("fb://")//페이스북
|| url.contains("fbapi://")
|| url.contains("fb-messenger-api://")
|| url.contains("fbauth2://")
|| url.contains("fbshareextension://")
) {
LOG.d(LOG_TAG, "yellowin window.open >>>> url scheme 11111 " + url);
try {
Intent intent = null;
// Intent intent = new Intent();
try {
intent = Intent.parseUri(url, Intent.URI_INTENT_SCHEME);
LOG.d(LOG_TAG, "yellowin window.open >>>> url scheme aaaaaaa " + url);
} catch (java.net.URISyntaxException ex) {
//ex.printStackTrace(); //code break
LOG.d(LOG_TAG, "yellowin window.open >>>> url scheme eeeeeee " + ex.getMessage());
override = false;
}
try {
cordova.getActivity().startActivity(intent);
override = true;
} catch (android.content.ActivityNotFoundException e) {
// chrome Version type
LOG.d(LOG_TAG, "yellowin window.open >>>> url scheme bbbbbb " + e.getMessage());
if (cordova.getActivity().getPackageManager().resolveActivity(intent, 0) == null) {
LOG.d(LOG_TAG, "yellowin window.open >>>> url scheme 33333 " + url);
String packagename = intent.getPackage();
// LOG.d(LOG_TAG, "yellowin url scheme 33333 packagename : " + packagename);
if (packagename != null) {
// Uri uri = Uri.parse("market://search?q=pname:" + packagename);
Uri uri = Uri.parse("market://details?id=" + packagename);
intent = new Intent(Intent.ACTION_VIEW, uri);
cordova.getActivity().startActivity(intent);
override = true;
}
} else {
LOG.d(LOG_TAG, "yellowin window.open >>>> url scheme 44444 " + url);
intent.addCategory(Intent.CATEGORY_BROWSABLE);
intent.setComponent(null);
try {
if (cordova.getActivity().startActivityIfNeeded(intent, -1)) {
override = true;
}
} catch (android.content.ActivityNotFoundException ex) {
override = false;
}
}
LOG.d(LOG_TAG, "yellowin window.open >>>> url scheme 44444 " + url);
override = true;
}
} catch (android.content.ActivityNotFoundException e) {
// Log.e("error ===>", e.getMessage());
LOG.e("yellowin url", "yellowin window.open >>>> url scheme ssssssss ");
//e.printStackTrace(); //code break
override = false;
}
}
else if (url.contains("amoshair.co.kr")
// 본인인증
|| url.contains("checkplus.co.kr")
|| url.contains("safe.ok-name.co.kr")
|| url.contains("mobile-ok.com")
|| url.contains("teledit.com")
|| url.contains("kcp.co.kr") // 결제 & 본인인증
// tags.bluekai.com
|| url.contains("tags.bluekai.com")
|| url.contains("astg.widerplanet.com")
// <https://pf.kakao.com>
// || url.contains("pf.kakao.com") // 카카오 채널...
|| url.contains("nid.naver.com")
|| url.contains("accounts.kakao.com")
|| url.contains("kauth.kakao.com")
|| url.contains("api.twitter.com")
|| (url.contains("facebook.com") && url.contains("oauth"))
|| url.contains("accounts.google.com")
|| url.contains("account/login")
) {
LOG.d(LOG_TAG, "yellowin window.open yes url :::::::: " + url);
override = false;
} else if (url != null) {
try {
Intent intent = null;
try {
intent = Intent.parseUri(url, Intent.URI_INTENT_SCHEME);
} catch (Exception e) {
//e.printStackTrace(); //code break
}
Uri uri = Uri.parse(url);
intent = new Intent(Intent.ACTION_VIEW, uri);
cordova.getActivity().startActivity(intent);
override = true;
} catch (android.content.ActivityNotFoundException e) {
//e.printStackTrace(); //code break
override = false;
}
// 외부 브라우져로 열리는 url이면 창 닫기 0.3초후에 실행되도록 지연시간을 주어야 함.
new Handler(getMainLooper()).postDelayed(new Runnable() {
@Override
public void run() {
newWebView.destroy();
dialog_child.dismiss();
}
}, 300);
LOG.d(LOG_TAG, "yellowin window.open no url :::::::: " + url);
}
if (useBeforeload) {
this.waitForBeforeload = true;
}
return override;
}
private boolean sendBeforeLoad(String url, String method) {
try {
JSONObject obj = new JSONObject();
obj.put("type", BEFORELOAD);
obj.put("url", url);
if (method != null) {
obj.put("method", method);
}
sendUpdate(obj, true);
return true;
} catch (JSONException ex) {
LOG.e(LOG_TAG, "URI passed in has caused a JSON error.");
}
return false;
}
/**
* New (added in API 21)
* For Android 5.0 and above.
*
* @param view
* @param request
*/
@Override
public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
return shouldInterceptRequest(request.getUrl().toString(), super.shouldInterceptRequest(view, request),
request.getMethod());
}
public WebResourceResponse shouldInterceptRequest(String url, WebResourceResponse response, String method) {
return response;
}
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
// MyLog.i(TAG,"onPageStarted(view:"+view+ ", url:"+url+ ",
// favicon:"+favicon+")");
}
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
// MyLog.i(TAG,"onPageFinished(view:"+view+ ", url:"+url+")");
}
@Override
public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
super.onReceivedError(view, request, error);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
// Log.i(TAG, "onReceivedError() " + error.getErrorCode() + " ---> " +
// error.getDescription());
onReceivedError(error.getErrorCode(), String.valueOf(error.getDescription()));
}
}
@Override
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
super.onReceivedError(view, errorCode, description, failingUrl);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
// Log.i(TAG, "onReceivedError() " + errorCode + " ---> " + description);
onReceivedError(errorCode, description);
}
}
private void onReceivedError(int errorCode, String description) {
// MyLog.i(getClass().getName(), "onReceivedError() " + errorCode + " ---> " +
// description);
switch (errorCode) {
case WebViewClient.ERROR_TIMEOUT: // 연결 시간 초과
case WebViewClient.ERROR_CONNECT: // 서버로 연결 실패
// case WebViewClient.ERROR_UNKNOWN: // 일반 오류
case WebViewClient.ERROR_FILE_NOT_FOUND: // 404
case WebViewClient.ERROR_HOST_LOOKUP:
case WebViewClient.ERROR_UNSUPPORTED_AUTH_SCHEME:
case WebViewClient.ERROR_AUTHENTICATION:
case WebViewClient.ERROR_PROXY_AUTHENTICATION:
case WebViewClient.ERROR_IO:
case WebViewClient.ERROR_REDIRECT_LOOP:
case WebViewClient.ERROR_UNSUPPORTED_SCHEME:
case WebViewClient.ERROR_FAILED_SSL_HANDSHAKE:
case WebViewClient.ERROR_BAD_URL:
case WebViewClient.ERROR_FILE:
case WebViewClient.ERROR_TOO_MANY_REQUESTS:
case WebViewClient.ERROR_UNSAFE_RESOURCE:
// MyLog.toastMakeTextShow(mApplicationContext,getClass().getName(),"WebViewClient,onReceivedError("+errorCode+")
// 에러 발생 " );;
// MyLog.e(TAG,"WebViewClient,onReceivedError("+errorCode+") 에러 발생 " );
break;
}
}
}
// yellowin yellowin window.open popupview WebViewClient선언 - end
**// yellowin camera-chooser 추가 - start**
// 카메라,갤러리 선택 호출 기능 구현
private void yellowinChooser_tmp(boolean _isCapture, boolean _selectMultiple, String _acceptType) {
LOG.d("yellowin", "yellowin yellowinChooser 000000");
LOG.d("yellowin", "yellowin yellowinChooser 000000 _isCapture : " + _isCapture);
LOG.d("yellowin", "yellowin yellowinChooser 000000 _selectMultiple : " + _selectMultiple);
LOG.d("yellowin", "yellowin yellowinChooser 000000 _acceptType : " + _acceptType);
Intent intentCamera = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
Intent intentCamera_video = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
this.applicationId = (String) BuildHelper.getBuildConfigValue(cordova.getActivity(), "APPLICATION_ID");
this.applicationId = preferences.getString("applicationId", this.applicationId);
File photo = createCaptureFile(1);
// File video = createCaptureFile(2);
this.imageFilePath = photo.getAbsolutePath();
// this.videoFilePath = video.getAbsolutePath();
this.imageUri = androidx.core.content.FileProvider.getUriForFile(cordova.getActivity(),
applicationId + ".cordova.plugin.camera.provider", photo);
// => 카메라 플러그인을 설치해야함. cordova plugin add cordova-plugin-camera
intentCamera.putExtra(MediaStore.EXTRA_OUTPUT, this.imageUri);
// We can write to this URI, this will hopefully allow us to write files to get
// to the next step
intentCamera.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
Boolean chooser_sel = true; // 카메라/갤러리 모두 선택할수 있는창 : true, 카메라 바로 실행이면 false
if (_isCapture) {
LOG.d("yellowin", "yellowin yellowinChooser 11111");
LOG.d("yellowin", "yellowin _isCapture true 1111");
// 바로 카메라 실행..
cordova.startActivityForResult(InAppBrowser.this, intentCamera, FILECHOOSER_LOLLIPOP_REQ_CODE);
}else{ // 선택팝업 카메라, 갤러리 둘다 띄우고 싶을 때
LOG.d("yellowin","yellowin _isCapture false 1111");
Intent pickIntent = new Intent(Intent.ACTION_PICK);
pickIntent.setType(MediaStore.Images.Media.CONTENT_TYPE);
pickIntent.setData(MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
//yellowin multi
//////////// yellowin yellowin 멀티 업로드 추가 수정 시작 22
pickIntent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, _selectMultiple);
//////////// yellowin multi upload 추가 수정 끝 22
String pickTitle = "사진 가져올 방법을 선택하세요.";
Intent chooserIntent = Intent.createChooser(pickIntent, pickTitle);
// 카메라 intent 포함시키기..
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Parcelable[]{intentCamera});
// chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS,new Parcelable[]{intentCamera_video});
// cordova.startActivityForResult((CordovaPlugin) this,chooserIntent, FILECHOOSER_LOLLIPOP_REQ_CODE);
if(_selectMultiple){
//갤러리 이미지 multi 선택이라면, 기존 방식으로 결과 리턴로직 타도록 함.
cordova.startActivityForResult((CordovaPlugin) this,chooserIntent, FILECHOOSER_REQUESTCODE);
// cordova.startActivityForResult(InAppBrowser.this, Intent.createChooser(content, "Select File"), FILECHOOSER_REQUESTCODE);
}else{
cordova.startActivityForResult((CordovaPlugin) this,chooserIntent, FILECHOOSER_LOLLIPOP_REQ_CODE);
}
}
}
private void yellowinChooser(boolean _isCapture, boolean _selectMultiple, String _acceptType) {
LOG.d("yellowin", "yellowin yellowinChooser 000000");
// 권한 확인
if (ContextCompat.checkSelfPermission(cordova.getActivity(), Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
// 권한이 없으면 권한 요청
LOG.d("yellowin", "yellowin yellowinChooser 000000 권한 체크~~~~");
ActivityCompat.requestPermissions(
cordova.getActivity(),
new String[]{Manifest.permission.CAMERA},
CAMERA_PERMISSION_REQUEST_CODE
);
if (filePathCallbackLollipop != null) { // resultCode에 RESULT_OK가 들어오지 않으면 null 처리 한다.(이렇게 하지 않으면
// 다음부터 input 태그를 클릭해도 반응하지 않음)
Log.d("onActivityResult() ",
"FILECHOOSER_LOLLIPOP_REQ_CODE 의 if문의 filePathCallbackLollipop이 null이 아니면");
filePathCallbackLollipop.onReceiveValue(null);
filePathCallbackLollipop = null;
}
return; // 권한 요청 후 바로 리턴하여 카메라 호출을 막음
}
// 여기서부터는 권한이 허용된 경우에만 실행
Intent intentCamera = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
Intent intentCamera_video = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
this.applicationId = (String) BuildHelper.getBuildConfigValue(cordova.getActivity(), "APPLICATION_ID");
this.applicationId = preferences.getString("applicationId", this.applicationId);
File photo = createCaptureFile(1);
this.imageFilePath = photo.getAbsolutePath();
this.imageUri = androidx.core.content.FileProvider.getUriForFile(
cordova.getActivity(),
applicationId + ".cordova.plugin.camera.provider",
photo
);
intentCamera.putExtra(MediaStore.EXTRA_OUTPUT, this.imageUri);
intentCamera.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
Boolean chooser_sel = true;
if (_isCapture) {
LOG.d("yellowin", "yellowin yellowinChooser 11111");
cordova.startActivityForResult(InAppBrowser.this, intentCamera, FILECHOOSER_LOLLIPOP_REQ_CODE);
} else {
LOG.d("yellowin","yellowin _isCapture false 1111");
Intent pickIntent = new Intent(Intent.ACTION_PICK);
pickIntent.setType(MediaStore.Images.Media.CONTENT_TYPE);
pickIntent.setData(MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
pickIntent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, _selectMultiple);
String pickTitle = "사진 가져올 방법을 선택하세요.";
Intent chooserIntent = Intent.createChooser(pickIntent, pickTitle);
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Parcelable[]{intentCamera});
if (_selectMultiple) {
cordova.startActivityForResult((CordovaPlugin) this, chooserIntent, FILECHOOSER_REQUESTCODE);
} else {
cordova.startActivityForResult((CordovaPlugin) this, chooserIntent, FILECHOOSER_LOLLIPOP_REQ_CODE);
}
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
if (requestCode == CAMERA_PERMISSION_REQUEST_CODE) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// 권한이 허용되었을 때, 카메라를 다시 호출
yellowinChooser(true, false, "image/*"); // 예시로 기본 파라미터 설정
} else {
// 권한이 거부된 경우 사용자에게 알림을 표시하거나 다른 처리를 수행할 수 있음
LOG.d("yellowin", "Camera permission denied");
}
}
cordova.getActivity().onRequestPermissionsResult(requestCode, permissions, grantResults);
}
**// yellowin camera-chooser 추가 - end
// yellowin camera-chooser 추가 - start**
private File createCaptureFile(int encodingType) {
return createCaptureFile(encodingType, "");
}
private File createCaptureFile(int encodingType, String fileName) {
if (fileName.isEmpty()) {
// 아래 라이브러리를 상단에 추가해야함
// import java.text.SimpleDateFormat;
// import java.util.Date;
String timeStamp = new SimpleDateFormat(TIME_FORMAT).format(new Date());
fileName = timeStamp;
// Append the current time in milliseconds for empty filename to differentiate
// between multiple files selected via gallery
fileName = "Pic_" + System.currentTimeMillis();
}
if (encodingType == JPEG) {
fileName = fileName + JPEG_EXTENSION;
} else if (encodingType == PNG) {
fileName = fileName + PNG_EXTENSION;
} else if (encodingType == 2) {
LOG.d("yellowin", "yellowin filename encodingType : " + Integer.toString(encodingType));
fileName = fileName + ".mp4";
} else {
throw new IllegalArgumentException("Invalid Encoding Type: " + encodingType);
}
LOG.d("yellowin", "yellowin filename fileName : " + fileName);
return new File(getTempDirectoryPath(), fileName);
}
private String getTempDirectoryPath() {
File cache = cordova.getActivity().getCacheDir();
// Create the cache directory if it doesn't exist
cache.mkdirs();
return cache.getAbsolutePath();
}
**// yellowin camera-chooser 추가 - end**
/**
* 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;
}
}
}
**// yellowin camera-chooser 추가 - start
//기존** onActivityResult 메소드를 아래로 대체해야함.
/**
* Receive File Data from File Chooser
*
* @param requestCode the requested code from chromeclient
* @param resultCode the result code returned from android system
* @param intent the data from android file chooser
*/
public void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.d("onActivityResult() ",
"requestCode = " + Integer.toString(requestCode) + " / resultCode = " + Integer.toString(resultCode));
switch (requestCode) {
case FILECHOOSER_NORMAL_REQ_CODE:
if (resultCode == Activity.RESULT_OK) {
if (filePathCallbackNormal == null)
return;
Uri result = (data == null || resultCode != RESULT_OK) ? null : data.getData();
// onReceiveValue 로 파일을 전송한다.
filePathCallbackNormal.onReceiveValue(result);
filePathCallbackNormal = null;
}
break;
case FILECHOOSER_LOLLIPOP_REQ_CODE:
Log.d("onActivityResult() ",
"FILECHOOSER_LOLLIPOP_REQ_CODE = " + Integer.toString(FILECHOOSER_LOLLIPOP_REQ_CODE));
if (resultCode == Activity.RESULT_OK) {
Log.d("onActivityResult() ", "FILECHOOSER_LOLLIPOP_REQ_CODE 의 if문 RESULT_OK 안에 들어옴");
if (filePathCallbackLollipop == null)
return;
if (data == null) {
data = new Intent();
}
if (data.getData() == null) {
// data.setData(cameraImageUri);
data.setData(this.imageUri);
}
filePathCallbackLollipop
.onReceiveValue(WebChromeClient.FileChooserParams.parseResult(resultCode, data));
filePathCallbackLollipop = null;
} else {
Log.d("onActivityResult() ", "FILECHOOSER_LOLLIPOP_REQ_CODE 의 if문의 else문 안으로~");
if (filePathCallbackLollipop != null) { // resultCode에 RESULT_OK가 들어오지 않으면 null 처리하지 한다.(이렇게 하지 않으면
// 다음부터 input 태그를 클릭해도 반응하지 않음)
Log.d("onActivityResult() ",
"FILECHOOSER_LOLLIPOP_REQ_CODE 의 if문의 filePathCallbackLollipop이 null이 아니면");
filePathCallbackLollipop.onReceiveValue(null);
filePathCallbackLollipop = null;
}
if (filePathCallbackNormal != null) {
filePathCallbackNormal.onReceiveValue(null);
filePathCallbackNormal = null;
}
}
break;
default:
// 기본 파일첨부 처리(기존방식)
//////////// yellowin yellowin 멀티 업로드 추가 수정 시작 22
// mUploadCallback.onReceiveValue(WebChromeClient.FileChooserParams.parseResult(resultCode,
//////////// intent));
// mUploadCallback = null;
Uri[] result = WebChromeClient.FileChooserParams.parseResult(resultCode, data);
LOG.d(LOG_TAG, "yellowin Receive file chooser URL: " + result);
// Uri[] result = null;
if (resultCode == Activity.RESULT_OK && data != null) {
if (data.getClipData() != null) {
// handle multiple-selected files
final int numSelectedFiles = data.getClipData().getItemCount();
result = new Uri[numSelectedFiles];
for (int i = 0; i < numSelectedFiles; i++) {
result[i] = data.getClipData().getItemAt(i).getUri();
LOG.d(LOG_TAG, "Receive file chooser URL: " + result[i]);
}
} else if (data.getData() != null) {
// handle single-selected file
result = WebChromeClient.FileChooserParams.parseResult(resultCode, data);
LOG.d(LOG_TAG, "yellowin Receive file chooser URL: " + result);
}
} else {
Log.d("onActivityResult() ",
"FILECHOOSER_LOLLIPOP_REQ_CODE = " + Integer.toString(FILECHOOSER_LOLLIPOP_REQ_CODE));
if (resultCode == Activity.RESULT_OK)
// if (resultCode == 0)
{
Log.d("onActivityResult() ", "FILECHOOSER_LOLLIPOP_REQ_CODE 의 if문 RESULT_OK 안에 들어옴");
if (filePathCallbackLollipop == null)
return;
if (data == null) {
data = new Intent();
}
if (data.getData() == null) {
// data.setData(cameraImageUri);
data.setData(this.imageUri);
}
filePathCallbackLollipop
.onReceiveValue(WebChromeClient.FileChooserParams.parseResult(resultCode, data));
filePathCallbackLollipop = null;
} else {
Log.d("onActivityResult() ", "FILECHOOSER_LOLLIPOP_REQ_CODE 의 if문의 else문 안으로~");
if (filePathCallbackLollipop != null) { // resultCode에 RESULT_OK가 들어오지 않으면 null 처리하지 한다.(이렇게 하지
// 않으면 다음부터 input 태그를 클릭해도 반응하지 않음)
Log.d("onActivityResult() ",
"FILECHOOSER_LOLLIPOP_REQ_CODE 의 if문의 filePathCallbackLollipop이 null이 아니면");
filePathCallbackLollipop.onReceiveValue(null);
filePathCallbackLollipop = null;
}
if (filePathCallbackNormal != null) {
filePathCallbackNormal.onReceiveValue(null);
filePathCallbackNormal = null;
}
}
break;
}
//////////// filePathsCallback.onReceiveValue(result);
filePathCallbackLollipop.onReceiveValue(result);
filePathCallbackLollipop = null;
// yellowin multi upload 추가 수정 끝 22
break;
}
super.onActivityResult(requestCode, resultCode, data);
}
**// yellowin camera-chooser 추가 - end**
/**
* The webview client receives notifications about appView
*/
public class InAppBrowserClient extends WebViewClient {
EditText edittext;
CordovaWebView webView;
String beforeload;
boolean waitForBeforeload;
/**
* Constructor.
*
* @param webView
* @param mEditText
*/
public InAppBrowserClient(CordovaWebView webView, EditText mEditText, String beforeload) {
this.webView = webView;
this.edittext = mEditText;
this.beforeload = beforeload;
this.waitForBeforeload = beforeload != null;
}
/**
* Override the URL that should be loaded
*
* Legacy (deprecated in API 24)
* For Android 6 and below.
*
* @param webView
* @param url
*/
@SuppressWarnings("deprecation")
@Override
public boolean shouldOverrideUrlLoading(WebView webView, String url) {
return shouldOverrideUrlLoading(url, null);
}
/**
* Override the URL that should be loaded
*
* New (added in API 24)
* For Android 7 and above.
*
* @param webView
* @param request
*/
@TargetApi(Build.VERSION_CODES.N)
@Override
public boolean shouldOverrideUrlLoading(WebView webView, WebResourceRequest request) {
return shouldOverrideUrlLoading(request.getUrl().toString(), request.getMethod());
}
/**
* Override the URL that should be loaded
*
* This handles a small subset of all the URIs that would be encountered.
*
* @param url
* @param method
*/
public boolean shouldOverrideUrlLoading(String url, String method) {
boolean override = false;
boolean useBeforeload = false;
String errorMessage = null;
if (beforeload.equals("yes") && method == null) {
useBeforeload = true;
} else if(beforeload.equals("yes")
//TODO handle POST requests then this condition can be removed:
&& !method.equals("POST"))
{
useBeforeload = true;
} else if(beforeload.equals("get") && (method == null || method.equals("GET"))) {
useBeforeload = true;
} else if(beforeload.equals("post") && (method == null || method.equals("POST"))) {
//TODO handle POST requests
errorMessage = "beforeload doesn't yet support POST requests";
}
// On first URL change, initiate JS callback. Only after the beforeload event, continue.
if (useBeforeload && this.waitForBeforeload) {
if(sendBeforeLoad(url, method)) {
return true;
}
}
if(errorMessage != null) {
try {
LOG.e(LOG_TAG, errorMessage);
JSONObject obj = new JSONObject();
obj.put("type", LOAD_ERROR_EVENT);
obj.put("url", url);
obj.put("code", -1);
obj.put("message", errorMessage);
sendUpdate(obj, true, PluginResult.Status.ERROR);
} catch(Exception e) {
LOG.e(LOG_TAG, "Error sending loaderror for " + url + ": " + e.toString());
}
}
// yellowin yellowin 외부 브라우져로 url 열기 시작
if( url.contains("systempop=") ) {
String[] array;
array = url.split("systempop=");
String url2 = array[1];
LOG.d(LOG_TAG, "yellowin url window.open external link URL : " + url);
try {
Intent intent = null;
Uri uri = Uri.parse(url2);
intent = new Intent(Intent.ACTION_VIEW, uri);
cordova.getActivity().startActivity(intent);
override = true;
} catch (android.content.ActivityNotFoundException e) {
//e.printStackTrace(); //code break
override = false;
}
} else
if (url.startsWith(WebView.SCHEME_TEL)) {
try {
Intent intent = new Intent(Intent.ACTION_DIAL);
intent.setData(Uri.parse(url));
cordova.getActivity().startActivity(intent);
override = true;
} catch (android.content.ActivityNotFoundException e) {
LOG.e(LOG_TAG, "Error dialing " + url + ": " + e.toString());
}
} else if (url.startsWith("geo:") || url.startsWith(WebView.SCHEME_MAILTO)) {
try {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse(url));
cordova.getActivity().startActivity(intent);
override = true;
} 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);
override = true;
} catch (android.content.ActivityNotFoundException e) {
LOG.e(LOG_TAG, "Error sending sms " + url + ":" + e.toString());
}
}
else if (url.startsWith("market:")
|| url.startsWith("intent:")
|| url.startsWith("bandapp:")// 네이버 밴드
|| url.startsWith("kakaotalk:")// 카카오톡
|| url.startsWith("storylink:")
|| url.startsWith("kakaoplus:")
|| url.startsWith("kakaokompassauth:")
|| url.startsWith("storykompassauth:")
|| url.startsWith("kakaolink:")
|| url.startsWith("kakaotalk-5.9.7:")
|| url.startsWith("kakaostory-2.9.0:")
|| url.startsWith("naversearchapp:")// 네이버앱
|| url.startsWith("nidlogin:")
|| url.startsWith("naversearchthirdlogin:")
|| url.startsWith("daumapps:")// 다음
|| url.startsWith("googlechromes:")// 크롬
|| url.startsWith("fb:")// 페이스북
// 본인인증
|| url.startsWith("tauthlink:")
|| url.startsWith("ktauthexternalcall:")
|| url.startsWith("upluscorporation:")
// 결제
|| url.contains("com.kftc.bankpay.android://")
|| url.contains("com.lotte.lottesmartpay://")
|| url.contains("com.ahnlab.v3mobileplus://")
|| url.contains("hanaansim://")
|| url.contains("vguard://")
|| url.contains("droidxantivirus://")
|| url.contains("smshinhancardusim://")
|| url.contains("smartwall://")
|| url.contains("appfree://")
|| url.contains("kb-acp://")
|| url.contains("lguthepay://")
|| url.contains("v3mobile://")
|| url.contains("kakaopay://")
|| url.contains("kftc-bankpay://")
|| url.contains("ispmobile://")
|| url.contains("hdcardappcardansimclick://")
|| url.contains("smhyundaiansimclick://")
|| url.contains("shinhan-sr-ansimclick://")
|| url.contains("smshinhanansimclick://")
|| url.contains("nonghyupcardansimclick://")
|| url.contains("kb-acp://")
|| url.contains("mpocket.online.ansimclick://")
|| url.contains("ansimclickscard://")
|| url.contains("ansimclickipcollect://")
|| url.contains("vguardstart://")
|| url.contains("samsungpay://")
|| url.contains("scardcertiapp://")
|| url.contains("lottesmartpay://")
|| url.contains("lotteappcard://")
|| url.contains("cloudpay://")
|| url.contains("nhappvardansimclick://")
|| url.contains("nhappcardansimclick://")
|| url.contains("nhallonepayansimclick://")
|| url.contains("citispay://")
|| url.contains("citimobileapp://")
|| url.contains("citicardappkr://")
|| url.contains("payco://")
|| url.contains("paypin://")
|| url.contains("paycoapplogin://")
|| url.contains("tswansimclick://")
|| url.contains("bankwallet://")
|| url.contains("uppay://")
|| url.contains("kpay://")
|| url.contains("smilepayapp://")
|| url.contains("maps://")
|| url.contains("citymapper://")
|| url.contains("comgooglemaps://")
|| url.contains("navigon://")
|| url.contains("transit://")
|| url.contains("waze://")
|| url.contains("yandexnavi://")
|| url.contains("uber://")
|| url.contains("tomtomhome://")
|| url.contains("com.sygic.aura://")
|| url.contains("here-route://")
|| url.contains("moovit://")
|| url.contains("lyft://")
|| url.contains("mapsme://")
|| url.contains("cabify://")
|| url.contains("baidumap://")
|| url.contains("lguthepay://")
|| url.contains("smartxpay-transfer://")
|| url.contains("smilepay://")
|| url.contains("supertoss://")
|| url.contains("hanawalletmembers://")
|| url.contains("wooripay://")
|| url.contains("shinsegaeeasypayment://")
|| url.contains("lpayapp://")
|| url.contains("lmslpay://")
|| url.contains("chai://")
|| url.contains("intmoney://")
|| url.contains("hanaskcardmobileportal://")
|| url.contains("ukbanksmartbanknonloginpay://")
|| url.contains("kdb-bankpay://")
|| url.contains("ibk-bankpay://")
|| url.contains("kb-bankpay://")
|| url.contains("keb-bankpay://")
|| url.contains("sh-bankpay://")
|| url.contains("nhb-bankpay://")
|| url.contains("nh-bankpay://")
|| url.contains("wr-bankpay://")
|| url.contains("sc-bankpay://")
|| url.contains("s-bankpay://")
|| url.contains("ct-bankpay://")
|| url.contains("dg-bankpay://")
|| url.contains("bnk-bankpay://")
|| url.contains("kj-bankpay://")
|| url.contains("jj-bankpay://")
|| url.contains("kn-bankpay://")
|| url.contains("kp-bankpay://")
|| url.contains("cu-bankpay://")
|| url.contains("mg-bankpay://")
|| url.contains("kbn-bankpa://y")
|| url.contains("kkb-bankpay://")
//|| url.contains("ansimclick")
//|| (url.contains("ansimclick") && !url.equals("ansimclick.hyundiacard.com"))
|| url.contains("market://details?id=com.shcard.smartpay")
|| url.contains("<http://m.ahnlab.com/kr/site/download>")
|| url.endsWith(".apk")
//본인인증
|| url.contains("tauthlink://")
|| url.contains("ktauthexternalcall://")
|| url.contains("upluscorporation://")
|| url.contains("line://")//라인
|| url.contains("bandapp://")//네이버 밴드
|| url.contains("kakaotalk://")//카카오톡
|| url.contains("storylink://")
|| url.contains("kakaoplus://")
|| url.contains("kakaokompassauth://")
|| url.contains("storykompassauth://")
|| url.contains("kakaolink://")
|| url.contains("kakaotalk-5.9.7://")
|| url.contains("kakaostory-2.9.0://")
|| url.contains("naversearchapp")//네이버앱
|| url.contains("naversearchthirdlogin")
|| (url.contains("nidlogin") && !url.contains("naver.com"))
|| url.contains("daumapps://open")//다음
|| url.contains("googlechromes://")//크롬
|| url.contains("fb://")//페이스북
|| url.contains("fbapi://")
|| url.contains("fb-messenger-api://")
|| url.contains("fbauth2://")
|| url.contains("fbshareextension://")
) {
try {
Intent intent = null;
// Intent intent = new Intent();
try {
intent = Intent.parseUri(url, Intent.URI_INTENT_SCHEME);
LOG.d(LOG_TAG, "yellowin url scheme aaaaaaa " + url);
} catch (java.net.URISyntaxException ex) {
//ex.printStackTrace(); //code break
LOG.d(LOG_TAG, "yellowin url scheme eeeeeee " + ex.getMessage());
override = false;
}
try {
cordova.getActivity().startActivity(intent);
override = true;
} catch (android.content.ActivityNotFoundException e) {
// chrome Version type
LOG.d(LOG_TAG, "yellowin url scheme bbbbbb " + e.getMessage());
if (cordova.getActivity().getPackageManager().resolveActivity(intent, 0) == null) {
LOG.d(LOG_TAG, "yellowin url scheme 33333 " + url);
String packagename = intent.getPackage();
if (packagename != null) {
Uri uri = Uri.parse("market://search?q=pname:" + packagename);
intent = new Intent(Intent.ACTION_VIEW, uri);
cordova.getActivity().startActivity(intent);
override = true;
}
} else {
LOG.d(LOG_TAG, "yellowin url scheme 44444 " + url);
intent.addCategory(Intent.CATEGORY_BROWSABLE);
intent.setComponent(null);
try {
if (cordova.getActivity().startActivityIfNeeded(intent, -1)) {
override = true;
}
} catch (android.content.ActivityNotFoundException ex) {
override = false;
}
}
override = true;
}
} catch (android.content.ActivityNotFoundException e) {
// Log.e("error ===>", e.getMessage());
LOG.e("yellowin url", "yellowin url scheme ssssssss ");
////e.printStackTrace(); //code break //code break
override = false;
}
}
// Test for whitelisted custom scheme names like mycoolapp:// or twitteroauthresponse:// (Twitter Oauth Response)
else if (!url.startsWith("http:") && !url.startsWith("https:") && url.matches("^[A-Za-z0-9+.-]*://.*?$")) {
if (allowedSchemes == null) {
String allowed = preferences.getString("AllowedSchemes", null);
if(allowed != null) {
allowedSchemes = allowed.split(",");
}
}
if (allowedSchemes != null) {
for (String scheme : allowedSchemes) {
if (url.startsWith(scheme)) {
try {
JSONObject obj = new JSONObject();
obj.put("type", "customscheme");
obj.put("url", url);
sendUpdate(obj, true);
override = true;
} catch (JSONException ex) {
LOG.e(LOG_TAG, "Custom Scheme URI passed in has caused a JSON error.");
}
}
}
}
}
else if (url.startsWith("<https://devfo.amoshair.co.kr>")
|| url.startsWith("<http://devfo.amoshair.co.kr>")
|| url.startsWith("<https://stgfo.amoshair.co.kr>")
|| url.startsWith("<http://stgfo.amoshair.co.kr>")
|| url.startsWith("<https://amospro.amoshair.co.kr>")
|| url.startsWith("<http://amospro.amoshair.co.kr>")
|| url.contains("amoshair.co.kr")
// 본인인증
|| url.contains("checkplus.co.kr")
|| url.contains("safe.ok-name.co.kr")
|| url.contains("mobile-ok.com")
|| url.contains("teledit.com")
|| url.contains("kcp.co.kr") // 결제 & 본인인증
// tags.bluekai.com
|| url.contains("tags.bluekai.com")
|| url.contains("astg.widerplanet.com")
// <https://pf.kakao.com>
// || url.contains("pf.kakao.com") // 카카오 채널...
|| url.contains("nid.naver.com")
|| url.contains("accounts.kakao.com")
|| url.contains("kauth.kakao.com")
|| url.contains("api.twitter.com")
|| (url.contains("facebook.com") && url.contains("oauth"))
|| url.contains("accounts.google.com")
|| url.contains("account/login")
// 결제
|| url.contains("drmobile.inicis.com")
|| url.contains("mobilians.co.kr")
|| url.contains("alipay.com")
|| url.contains("allpayx.com")
|| url.contains("fcmobile.inicis.com")
|| url.contains("<http://aio.best>")
|| url.contains("smpay.kcp.co.kr")
|| url.contains("kcp.co.kr")
|| url.contains("ansimclick.hyundiacard.com")
|| url.contains("allatpay.com")
|| url.contains("xpay.lgdacom.net")
|| url.contains("pg-web.kakao.com") // 카카오
// || url.contains("kakao.com")
|| url.contains("shinhancard.com")
|| url.contains("hyundaicard.com")
|| url.contains("ssgpay.com")
|| url.contains("payco.com")
|| url.contains("lpay.com")
|| url.contains("inicis.com")
|| url.contains("vpay.co.kr")
|| url.contains("bootpay.co.kr")
|| url.contains("allatpay.com")
|| url.contains("smilepay.co.kr")
|| url.contains("nicepay.co.kr")
|| url.contains("teledit.com")
|| url.contains("eximbay.com")
|| url.contains("paypal.com")
|| url.contains("paypalobjects.com")
|| url.contains("tpay.co.kr")
|| url.contains("uplus.co.kr")
|| url.contains("bankpay.or.kr")
|| url.contains("ksmobile.inicis.com")
// || url.contains("kftc-bankpay")
|| url.contains("allthegate.com")
|| url.contains("iamport.kr")
|| url.contains("pay.toss")
|| url.contains("samsungcard.co.kr")
|| url.contains("samsungcard.com")
|| url.contains("samsungcard-ad.com")
|| url.contains("nonghyup.com")
|| url.contains("pay.tosspayments.com/card")
|| url.contains("acs.hanacard.co.kr")
|| url.contains("tosspayments.com")
|| url.contains("pay.naver.com")
|| url.contains("pstatic.net")
|| url.contains("paymentwall.com")
|| url.contains("pay.kakao.com")
|| url.contains("welcomepayments.co.kr")
|| url.contains("payletter.com")
|| url.contains("easypay.co.kr")
|| url.contains("citibank.co.kr")
|| url.contains("godo.co.kr")
|| url.contains("godomall.com")
|| url.contains("chai.finance")
|| url.contains("payapp.kr")
|| url.contains("payprotocol.io") // 페이코인
|| url.contains("yeskey.or.kr") // 현대카드 핀번호 결제
|| url.contains("billgate.net")
|| url.contains("passcall.co.kr")
|| url.contains("cnspay.co.kr") // 스마일페이
|| url.contains("mysmilepay.com")
|| url.contains("e-ncp.com")
) {
LOG.d(LOG_TAG, "yellowin yellowin inappbrowser yes url :::::::: " + url);
override = false;
} else if (url != null) {
try {
Intent intent = null;
try {
intent = Intent.parseUri(url, Intent.URI_INTENT_SCHEME);
} catch (Exception e) {
//e.printStackTrace(); //code break
}
Uri uri = Uri.parse(url);
intent = new Intent(Intent.ACTION_VIEW, uri);
cordova.getActivity().startActivity(intent);
override = true;
} catch (android.content.ActivityNotFoundException e) {
//e.printStackTrace(); //code break
override = false;
}
LOG.d(LOG_TAG, "yellowin yellowin inappbrowser no url :::::::: " + url);
}
if (useBeforeload) {
this.waitForBeforeload = true;
}
return override;
}
private boolean sendBeforeLoad(String url, String method) {
try {
JSONObject obj = new JSONObject();
obj.put("type", BEFORELOAD);
obj.put("url", url);
if(method != null) {
obj.put("method", method);
}
sendUpdate(obj, true);
return true;
} catch (JSONException ex) {
LOG.e(LOG_TAG, "URI passed in has caused a JSON error.");
}
return false;
}
/**
* New (added in API 21)
* For Android 5.0 and above.
*
* @param view
* @param request
*/
@Override
public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
return shouldInterceptRequest(request.getUrl().toString(), super.shouldInterceptRequest(view, request), request.getMethod());
}
public WebResourceResponse shouldInterceptRequest(String url, WebResourceResponse response, String method) {
return response;
}
/*
* onPageStarted fires the LOAD_START_EVENT
*
* @param view
* @param url
* @param favicon
*/
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
String newloc = "";
if (url.startsWith("http:") || url.startsWith("https:") || url.startsWith("file:")) {
newloc = url;
}
else
{
// Assume that everything is HTTP at this point, because if we don't specify,
// it really should be. Complain loudly about this!!!
LOG.e(LOG_TAG, "Possible Uncaught/Unknown URI");
newloc = "http://" + url;
}
// Update the UI if we haven't already
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.e(LOG_TAG, "URI passed in has caused a JSON error.");
}
}
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
LOG.d("","yellowin yellowin security~~~~ onPageFinished 1111");
//yellowin yellowin 보안처리 - start
if (detectDebugger() || detect_threadCpuTimeNanos()) { //디버그 개발용
String msg_val = "디버그모드가 감지되었습니다. 앱을 종료합니다.";
// Log.e("Security", "yellowin Security This device is rooted. Exiting app. 333");
new AlertDialog.Builder(cordova.getContext())
.setTitle("보안 경고")
.setMessage(msg_val)
.setPositiveButton("확인", null)
.setOnDismissListener(new DialogInterface.OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialog) {
// 다이얼로그가 닫힐 때 앱을 종료합니다.
ThemeableBrowser.closeGlobalInstance();
InAppBrowser.closeGlobalInstance();
// MainActivity.this.finish();
}
})
.show();
}
injectDeferredObject(
"if (!window.webkit) { window.webkit = {}; }" +
"if (!window.webkit.messageHandlers) { window.webkit.messageHandlers = {}; }" +
// cordova_iab 인터페이스 추가
"window.webkit.messageHandlers.cordova_iab = {" +
" postMessage: function(message) {" +
" if (typeof message === 'object') {" +
" message = JSON.stringify(message);" + // 객체를 JSON 문자열로 변환
" }" +
" cordova_iab.postMessage(message);" +
" }" +
"};" +
// firebase 인터페이스 추가
"window.webkit.messageHandlers.firebase = {" +
" postMessage: function(message) {" +
" if (typeof message === 'object') {" +
" message = JSON.stringify(message);" + // 객체를 JSON 문자열로 변환
" }" +
" firebase.postMessage(message);" +
" }" +
"};" +
"if (!webkit) { var webkit = window.webkit; }",
null
);
// // yellowin yellowin toolbar button 뒤로가기 가능여부
// if (inAppWebView.canGoBack()) {
// // tabView1.setAlpha(1f);
// tabView1_flag = 0;
// } else {
// // tabView1.setAlpha(0.3f);
// tabView1_flag = 1;
// }
// cur_url = "";
// CB-10395 InAppBrowser's WebView not storing cookies reliable to local device storage
CookieManager.getInstance().flush();
// <https://issues.apache.org/jira/browse/CB-11248>
view.clearFocus();
view.requestFocus();
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");
}
// yellowin yellowin swipeRefreshLayout
swipeRefreshLayout.setRefreshing(false);
}
public void onReceivedError(WebView 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");
}
}
@Override
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
super.onReceivedSslError(view, handler, error);
try {
JSONObject obj = new JSONObject();
obj.put("type", LOAD_ERROR_EVENT);
obj.put("url", error.getUrl());
obj.put("code", 0);
obj.put("sslerror", error.getPrimaryError());
String message;
switch (error.getPrimaryError()) {
case SslError.SSL_DATE_INVALID:
message = "The date of the certificate is invalid";
break;
case SslError.SSL_EXPIRED:
message = "The certificate has expired";
break;
case SslError.SSL_IDMISMATCH:
message = "Hostname mismatch";
break;
default:
case SslError.SSL_INVALID:
message = "A generic error occurred";
break;
case SslError.SSL_NOTYETVALID:
message = "The certificate is not yet valid";
break;
case SslError.SSL_UNTRUSTED:
message = "The certificate authority is not trusted";
break;
}
obj.put("message", message);
sendUpdate(obj, true, PluginResult.Status.ERROR);
} catch (JSONException ex) {
LOG.d(LOG_TAG, "Should never happen");
}
handler.cancel();
}
/**
* On received http auth request.
*/
@Override
public void onReceivedHttpAuthRequest(WebView view, HttpAuthHandler handler, String host, String realm) {
// Check if there is some plugin which can resolve this auth challenge
PluginManager pluginManager = null;
try {
Method gpm = webView.getClass().getMethod("getPluginManager");
pluginManager = (PluginManager)gpm.invoke(webView);
} catch (NoSuchMethodException e) {
LOG.d(LOG_TAG, e.getLocalizedMessage());
} catch (IllegalAccessException e) {
LOG.d(LOG_TAG, e.getLocalizedMessage());
} catch (InvocationTargetException e) {
LOG.d(LOG_TAG, e.getLocalizedMessage());
}
if (pluginManager == null) {
try {
Field pmf = webView.getClass().getField("pluginManager");
pluginManager = (PluginManager)pmf.get(webView);
} catch (NoSuchFieldException e) {
LOG.d(LOG_TAG, e.getLocalizedMessage());
} catch (IllegalAccessException e) {
LOG.d(LOG_TAG, e.getLocalizedMessage());
}
}
if (pluginManager != null && pluginManager.onReceivedHttpAuthRequest(webView, new CordovaHttpAuthHandler(handler), host, realm)) {
return;
}
// By default handle 401 like we'd normally do!
super.onReceivedHttpAuthRequest(view, handler, host, realm);
}
}
}
Powered by (주)옐로우윈