@Override public void onWindowFocusChanged(boolean hasFocus) { LOG.Log(Module.GUI, "onWindowFocusChanged"); if (hasFocus) { LOG.Log(Module.GUI, "application has focus; calling foreground listener"); this.activityManager.loadUrlIntoWebView("javascript:try{Appverse._toForeground()}catch(e){}"); // check for notification details or other extra data this.checkLaunchedFromNotificationOrExternaly(); } else { if (!activityManager.isNotifyLoadingVisible()) { LOG.Log(Module.GUI, "application lost focus; calling background listener"); this.activityManager.loadUrlIntoWebView( "javascript:try{Appverse._toBackground()}catch(e){}"); } else { LOG.Log( Module.GUI, "application lost focus due to a showing dialog (StartNotifyLoading feature); application is NOT calling background listener to allow platform calls on the meantime."); } /* * if (server == null) { // security reasons; the splash screen is * shown when application enters in background (hiding sensitive * data) // it will be dismissed "onResume" method * if(!splashShownOnBackground) { splashShownOnBackground = * activityManager.showSplashScreen(appView); } } */ } }
@Override public void onRequestPermissionsResult( int requestCode, String[] permissions, int[] grantResults) { // this method is invoked with an CANCELED result code if the activity is a "singleInstance" // (launchMode) // that is the reason that we removed that launch mode for the AndroidManifest (see SVN logs) LOG.LogDebug( Module.GUI, "******** onActivityResult # requestCode " + requestCode + ", grantResults: " + grantResults); AndroidActivityManager aam = (AndroidActivityManager) AndroidServiceLocator.GetInstance() .GetService(AndroidServiceLocator.SERVICE_ANDROID_ACTIVITY_MANAGER); boolean handleResult = false; if (aam != null) { handleResult = aam.publishPermissionResult(requestCode, permissions, grantResults); } }
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { // this method is invoked with an CANCELED result code if the activity is a "singleInstance" // (launchMode) // that is the reason that we removed that launch mode for the AndroidManifest (see SVN logs) LOG.LogDebug( Module.GUI, "******** onActivityResult # requestCode " + requestCode + ", resultCode: " + resultCode); AndroidActivityManager aam = (AndroidActivityManager) AndroidServiceLocator.GetInstance() .GetService(AndroidServiceLocator.SERVICE_ANDROID_ACTIVITY_MANAGER); boolean handleResult = false; if (aam != null) { handleResult = aam.publishActivityResult(requestCode, resultCode, data); } if (!handleResult) { ResultReceiver resultReceiver = ((AndroidServiceLocator) AndroidServiceLocator.GetInstance()) .getResultReceiver(requestCode); if (resultReceiver != null) { LOG.LogDebug( Module.GUI, "******** Calling ResultReceiver send (probably from a module)..."); Bundle bundle = (data == null ? new Bundle() : data.getExtras()); bundle.putInt(IAppDelegate.ACTIVITY_RESULT_CODE_BUNDLE_KEY, resultCode); resultReceiver.send(requestCode, bundle); } else { LOG.LogDebug(Module.GUI, "******** Calling super.onActivityResult()"); super.onActivityResult(requestCode, resultCode, data); } } }
/** ACTIVITY OVERRIDEN METHODS * */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); LOG.Log(Module.GUI, "onCreate"); if (getIntent() != null && getIntent().getExtras() != null) { extras = getIntent().getExtras(); LOG.LogDebug(Module.GUI, "[K] notification Extra:" + extras.getString("item_id")); } // GUI initialization code getWindow().requestFeature(Window.FEATURE_NO_TITLE); getWindow() .setFlags( WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN, WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN); /*disableThumbnails = checkUnityProperty("Unity_DisableThumbnails"); blockRooted = checkUnityProperty("Appverse_BlockRooted"); blockROMModified = checkUnityProperty("Appverse_BlockROMModified");*/ // security reasons; don't allow screen shots while this window is displayed /* not valid for builds under level 14 */ // TODO DISABLETHUMBNAILS_1 // @@DISABLETHUMBNAILS_1@@ // Initialize Webview component and provide specific settings this.initialiazeWebViewSettings(); // create the application logger LogManager.setDelegate(new AndroidLoggerDelegate()); // initialize the service locator activityManager = initialiazeActivityManager(); // save the context for further access AndroidServiceLocator.setContext(this, activityManager); // killing previous background processes from the same package activityManager.killBackgroundProcesses(); AndroidServiceLocator serviceLocator = (AndroidServiceLocator) AndroidServiceLocator.GetInstance(); serviceLocator.RegisterService( this.getAssets(), AndroidServiceLocator.SERVICE_ANDROID_ASSET_MANAGER); serviceLocator.RegisterService( activityManager, AndroidServiceLocator.SERVICE_ANDROID_ACTIVITY_MANAGER); // registering Appverse modules (if any) this.registerModulesServices(); // initialize config data files for app delegates serviceLocator.initConfigDataForServices(); if (Build.VERSION.SDK_INT >= 17) { // Only used for JELLY_BEAN_MR1 or higher /** * INJECT SCRIPT MESSAGE HANDLER (new in Appverse 5) ** */ /** * From Android documentation: * * <p>This method can be used to allow JavaScript to control the host application. This is a * powerful feature, but also presents a security risk for apps targeting JELLY_BEAN or * earlier. Apps that target a version later than JELLY_BEAN are still vulnerable if the app * runs on a device running Android earlier than 4.2. The most secure way to use this method * is to target JELLY_BEAN_MR1 and to ensure the method is called only when running on Android * 4.2 or later. With these older versions, JavaScript could use reflection to access an * injected object's public fields. Use of this method in a WebView containing untrusted * content could allow an attacker to manipulate the host application in unintended ways, * executing Java code with the permissions of the host application. Use extreme care when * using this method in a WebView which could contain untrusted content. * * <p>JavaScript interacts with Java object on a private, background thread of this WebView. * Care is therefore required to maintain thread safety. The Java object's fields are not * accessible. For applications targeted to API level LOLLIPOP and above, methods of injected * Java objects are enumerable from JavaScript. */ this.addJavascriptIntefaceToWebView(serviceLocator, "appverseJSBridge"); } if (performSecurityChecks(serviceLocator)) { LOG.Log(Module.GUI, "Security checks passed... initializing Appverse..."); startServer(); /* THIS COULD NOT BE CHECKED ON API LEVEL < 11; NO suchmethodexception * boolean hwAccelerated = appView.isHardwareAccelerated(); * if(hwAccelerated) * LOG.Log(Module.GUI,"Application View is HARDWARE ACCELERATED"); else * LOG.Log(Module.GUI,"Application View is NOT hardware accelerated"); */ final IntentFilter actionFilter = new IntentFilter(); actionFilter.addAction(android.net.ConnectivityManager.CONNECTIVITY_ACTION); // actionFilter.addAction("android.intent.action.SERVICE_STATE"); registerReceiver(this.initialiazeNetworkReceiver(), actionFilter); ConnectivityManager conMan = (ConnectivityManager) this.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo networkInfo = conMan.getActiveNetworkInfo(); com.gft.unity.core.net.NetworkType type = NetworkType.Unknown; if (networkInfo != null) { boolean isWiFi = networkInfo.getType() == ConnectivityManager.TYPE_WIFI; boolean isMobile = networkInfo.getType() == ConnectivityManager.TYPE_MOBILE; boolean isConnected = networkInfo.isConnected(); if (isWiFi) { if (isConnected) { LOG.Log(Module.GUI, "Wi-Fi - CONNECTED (" + networkInfo.getType() + ")"); type = NetworkType.Wifi; } else { LOG.Log(Module.GUI, "Wi-Fi - DISCONNECTED (" + networkInfo.getType() + ")"); } } else if (isMobile) { if (isConnected) { LOG.Log(Module.GUI, "Mobile - CONNECTED (" + networkInfo.getType() + ")"); type = NetworkType.Carrier_3G; } else { LOG.Log(Module.GUI, "Mobile - DISCONNECTED (" + networkInfo.getType() + ")"); } } else { if (isConnected) { LOG.Log( Module.GUI, networkInfo.getTypeName() + " - CONNECTED (" + networkInfo.getType() + ")"); } else { LOG.Log( Module.GUI, networkInfo.getTypeName() + " - DISCONNECTED (" + networkInfo.getType() + ")"); } } } else { LOG.Log(Module.GUI, "DISCONNECTED"); } final int typeOrdinal = type.ordinal(); final Activity currentContext = this; new Thread( new Runnable() { public void run() { currentContext.runOnUiThread( new Runnable() { public void run() { InitializeAppverseContext(typeOrdinal); String networkStatusListener = "javascript:try{if(Appverse&&Appverse.Net){Appverse.Net.NetworkStatus = " + typeOrdinal + ";Appverse.Net.onConnectivityChange(Appverse.Net.NetworkStatus);}else{console.log('Appverse is not defined');}}catch(e){console.log('Error setting network status (please check onConnectivityChange method): '+e);}"; queueJSStatementsForWebviewClient(networkStatusListener); loadMainURLIntoWebview(); } }); } }) .start(); } holdSplashScreenOnStartup = checkUnityProperty("Unity_HoldSplashScreenOnStartup"); this.showSplashScreen(); LocalNotificationReceiver.initialize(this.activityManager, this); // notify app delegates about the onCreate event ((AndroidServiceLocator) AndroidServiceLocator.GetInstance()) .sendApplicationEvent(AndroidApplicationEvent.onCreate); }