parent
539dcf9c82
commit
6ec86fe919
@ -0,0 +1,647 @@ |
|||||||
|
/* |
||||||
|
* Copyright (c) 2009-2015 jMonkeyEngine |
||||||
|
* All rights reserved. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or without |
||||||
|
* modification, are permitted provided that the following conditions are |
||||||
|
* met: |
||||||
|
* |
||||||
|
* * Redistributions of source code must retain the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer. |
||||||
|
* |
||||||
|
* * Redistributions in binary form must reproduce the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer in the |
||||||
|
* documentation and/or other materials provided with the distribution. |
||||||
|
* |
||||||
|
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors |
||||||
|
* may be used to endorse or promote products derived from this software |
||||||
|
* without specific prior written permission. |
||||||
|
* |
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
||||||
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
*/ |
||||||
|
package com.jme3.app; |
||||||
|
|
||||||
|
import android.app.Activity; |
||||||
|
import android.app.AlertDialog; |
||||||
|
import android.app.Fragment; |
||||||
|
import android.content.DialogInterface; |
||||||
|
import android.graphics.drawable.Drawable; |
||||||
|
import android.graphics.drawable.NinePatchDrawable; |
||||||
|
import android.opengl.GLSurfaceView; |
||||||
|
import android.os.Bundle; |
||||||
|
import android.util.Log; |
||||||
|
import android.view.Gravity; |
||||||
|
import android.view.LayoutInflater; |
||||||
|
import android.view.View; |
||||||
|
import android.view.ViewGroup; |
||||||
|
import android.widget.FrameLayout; |
||||||
|
import android.widget.ImageView; |
||||||
|
import com.jme3.audio.AudioRenderer; |
||||||
|
import com.jme3.input.JoyInput; |
||||||
|
import com.jme3.input.TouchInput; |
||||||
|
import com.jme3.input.android.AndroidSensorJoyInput; |
||||||
|
import com.jme3.input.controls.TouchListener; |
||||||
|
import com.jme3.input.controls.TouchTrigger; |
||||||
|
import com.jme3.input.event.TouchEvent; |
||||||
|
import static com.jme3.input.event.TouchEvent.Type.KEY_UP; |
||||||
|
import com.jme3.system.AppSettings; |
||||||
|
import com.jme3.system.SystemListener; |
||||||
|
import com.jme3.system.android.JmeAndroidSystem; |
||||||
|
import com.jme3.system.android.OGLESContext; |
||||||
|
import com.jme3.util.AndroidLogHandler; |
||||||
|
import java.io.PrintWriter; |
||||||
|
import java.io.StringWriter; |
||||||
|
import java.util.logging.Handler; |
||||||
|
import java.util.logging.Level; |
||||||
|
import java.util.logging.LogManager; |
||||||
|
import java.util.logging.Logger; |
||||||
|
|
||||||
|
/** |
||||||
|
* |
||||||
|
* @author iwgeric |
||||||
|
*/ |
||||||
|
public class AndroidHarnessFragment extends Fragment implements TouchListener, DialogInterface.OnClickListener, SystemListener { |
||||||
|
private static final Logger logger = Logger.getLogger(AndroidHarnessFragment.class.getName()); |
||||||
|
|
||||||
|
/** |
||||||
|
* The application class to start |
||||||
|
*/ |
||||||
|
protected String appClass = "jme3test.android.Test"; |
||||||
|
|
||||||
|
/** |
||||||
|
* Sets the desired RGB size for the surfaceview. 16 = RGB565, 24 = RGB888. |
||||||
|
* (default = 24) |
||||||
|
*/ |
||||||
|
protected int eglBitsPerPixel = 24; |
||||||
|
|
||||||
|
/** |
||||||
|
* Sets the desired number of Alpha bits for the surfaceview. This affects |
||||||
|
* how the surfaceview is able to display Android views that are located |
||||||
|
* under the surfaceview jME uses to render the scenegraph. |
||||||
|
* 0 = Opaque surfaceview background (fastest) |
||||||
|
* 1->7 = Transparent surfaceview background |
||||||
|
* 8 or higher = Translucent surfaceview background |
||||||
|
* (default = 0) |
||||||
|
*/ |
||||||
|
protected int eglAlphaBits = 0; |
||||||
|
|
||||||
|
/** |
||||||
|
* The number of depth bits specifies the precision of the depth buffer. |
||||||
|
* (default = 16) |
||||||
|
*/ |
||||||
|
protected int eglDepthBits = 16; |
||||||
|
|
||||||
|
/** |
||||||
|
* Sets the number of samples to use for multisampling.</br> |
||||||
|
* Leave 0 (default) to disable multisampling.</br> |
||||||
|
* Set to 2 or 4 to enable multisampling. |
||||||
|
*/ |
||||||
|
protected int eglSamples = 0; |
||||||
|
|
||||||
|
/** |
||||||
|
* Set the number of stencil bits. |
||||||
|
* (default = 0) |
||||||
|
*/ |
||||||
|
protected int eglStencilBits = 0; |
||||||
|
|
||||||
|
/** |
||||||
|
* Set the desired frame rate. If frameRate > 0, the application |
||||||
|
* will be capped at the desired frame rate. |
||||||
|
* (default = -1, no frame rate cap) |
||||||
|
*/ |
||||||
|
protected int frameRate = -1; |
||||||
|
|
||||||
|
/** |
||||||
|
* Sets the type of Audio Renderer to be used. |
||||||
|
* <p> |
||||||
|
* Android MediaPlayer / SoundPool can be used on all |
||||||
|
* supported Android platform versions (2.2+)<br> |
||||||
|
* OpenAL Soft uses an OpenSL backend and is only supported on Android |
||||||
|
* versions 2.3+. |
||||||
|
* <p> |
||||||
|
* Only use ANDROID_ static strings found in AppSettings |
||||||
|
* |
||||||
|
*/ |
||||||
|
protected String audioRendererType = AppSettings.ANDROID_OPENAL_SOFT; |
||||||
|
|
||||||
|
/** |
||||||
|
* If true Android Sensors are used as simulated Joysticks. Users can use the |
||||||
|
* Android sensor feedback through the RawInputListener or by registering |
||||||
|
* JoyAxisTriggers. |
||||||
|
*/ |
||||||
|
protected boolean joystickEventsEnabled = false; |
||||||
|
|
||||||
|
/** |
||||||
|
* If true KeyEvents are generated from TouchEvents |
||||||
|
*/ |
||||||
|
protected boolean keyEventsEnabled = true; |
||||||
|
|
||||||
|
/** |
||||||
|
* If true MouseEvents are generated from TouchEvents |
||||||
|
*/ |
||||||
|
protected boolean mouseEventsEnabled = true; |
||||||
|
|
||||||
|
/** |
||||||
|
* Flip X axis |
||||||
|
*/ |
||||||
|
protected boolean mouseEventsInvertX = false; |
||||||
|
|
||||||
|
/** |
||||||
|
* Flip Y axis |
||||||
|
*/ |
||||||
|
protected boolean mouseEventsInvertY = false; |
||||||
|
|
||||||
|
/** |
||||||
|
* if true finish this activity when the jme app is stopped |
||||||
|
*/ |
||||||
|
protected boolean finishOnAppStop = true; |
||||||
|
|
||||||
|
/** |
||||||
|
* set to false if you don't want the harness to handle the exit hook |
||||||
|
*/ |
||||||
|
protected boolean handleExitHook = true; |
||||||
|
|
||||||
|
/** |
||||||
|
* Title of the exit dialog, default is "Do you want to exit?" |
||||||
|
*/ |
||||||
|
protected String exitDialogTitle = "Do you want to exit?"; |
||||||
|
|
||||||
|
/** |
||||||
|
* Message of the exit dialog, default is "Use your home key to bring this |
||||||
|
* app into the background or exit to terminate it." |
||||||
|
*/ |
||||||
|
protected String exitDialogMessage = "Use your home key to bring this app into the background or exit to terminate it."; |
||||||
|
|
||||||
|
/** |
||||||
|
* Set the screen window mode. If screenFullSize is true, then the |
||||||
|
* notification bar and title bar are removed and the screen covers the |
||||||
|
* entire display. If screenFullSize is false, then the notification bar |
||||||
|
* remains visible if screenShowTitle is true while screenFullScreen is |
||||||
|
* false, then the title bar is also displayed under the notification bar. |
||||||
|
*/ |
||||||
|
protected boolean screenFullScreen = true; |
||||||
|
/** |
||||||
|
* if screenShowTitle is true while screenFullScreen is false, then the |
||||||
|
* title bar is also displayed under the notification bar |
||||||
|
*/ |
||||||
|
protected boolean screenShowTitle = true; |
||||||
|
/** |
||||||
|
* Splash Screen picture Resource ID. If a Splash Screen is desired, set |
||||||
|
* splashPicID to the value of the Resource ID (i.e. R.drawable.picname). If |
||||||
|
* splashPicID = 0, then no splash screen will be displayed. |
||||||
|
*/ |
||||||
|
protected int splashPicID = 0; |
||||||
|
|
||||||
|
protected FrameLayout frameLayout = null; |
||||||
|
protected GLSurfaceView view = null; |
||||||
|
protected ImageView splashImageView = null; |
||||||
|
final private String ESCAPE_EVENT = "TouchEscape"; |
||||||
|
private boolean firstDrawFrame = true; |
||||||
|
private Application app = null; |
||||||
|
|
||||||
|
// Retrieves the jME application object
|
||||||
|
public Application getJmeApplication() { |
||||||
|
return app; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onAttach(Activity activity) { |
||||||
|
super.onAttach(activity); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* This Fragment uses setRetainInstance(true) so the onCreate method will only |
||||||
|
* be called once. During device configuration changes, the instance of |
||||||
|
* this Fragment will be reused in the new Activity. This method should not |
||||||
|
* contain any View related objects. They are created and destroyed by |
||||||
|
* other methods. View related objects should not be reused, but rather |
||||||
|
* created and destroyed along with the Activity. |
||||||
|
* |
||||||
|
* @param savedInstanceState |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public void onCreate(Bundle savedInstanceState) { |
||||||
|
initializeLogHandler(); |
||||||
|
logger.fine("onCreate"); |
||||||
|
super.onCreate(savedInstanceState); |
||||||
|
|
||||||
|
// Create Settings
|
||||||
|
logger.log(Level.FINE, "Creating settings"); |
||||||
|
AppSettings settings = new AppSettings(true); |
||||||
|
settings.setEmulateMouse(mouseEventsEnabled); |
||||||
|
settings.setEmulateMouseFlipAxis(mouseEventsInvertX, mouseEventsInvertY); |
||||||
|
settings.setUseJoysticks(joystickEventsEnabled); |
||||||
|
settings.setEmulateKeyboard(keyEventsEnabled); |
||||||
|
|
||||||
|
settings.setBitsPerPixel(eglBitsPerPixel); |
||||||
|
settings.setAlphaBits(eglAlphaBits); |
||||||
|
settings.setDepthBits(eglDepthBits); |
||||||
|
settings.setSamples(eglSamples); |
||||||
|
settings.setStencilBits(eglStencilBits); |
||||||
|
settings.setAudioRenderer(audioRendererType); |
||||||
|
|
||||||
|
settings.setFrameRate(frameRate); |
||||||
|
|
||||||
|
// Create application instance
|
||||||
|
try { |
||||||
|
if (app == null) { |
||||||
|
@SuppressWarnings("unchecked") |
||||||
|
Class<? extends Application> clazz = (Class<? extends Application>) Class.forName(appClass); |
||||||
|
app = clazz.newInstance(); |
||||||
|
} |
||||||
|
|
||||||
|
app.setSettings(settings); |
||||||
|
app.start(); |
||||||
|
} catch (Exception ex) { |
||||||
|
handleError("Class " + appClass + " init failed", ex); |
||||||
|
} |
||||||
|
|
||||||
|
OGLESContext ctx = (OGLESContext) app.getContext(); |
||||||
|
// AndroidHarness wraps the app as a SystemListener.
|
||||||
|
ctx.setSystemListener(this); |
||||||
|
|
||||||
|
setRetainInstance(true); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Called by the system to create the View hierchy associated with this |
||||||
|
* Fragment. For jME, this is a FrameLayout that contains the GLSurfaceView |
||||||
|
* and an overlaying SplashScreen Image (if used). The View that is returned |
||||||
|
* will be placed on the screen within the boundries of the View borders defined |
||||||
|
* by the Activity's layout parameters for this Fragment. For jME, we also |
||||||
|
* update the application reference to the new view. |
||||||
|
* |
||||||
|
* @param inflater |
||||||
|
* @param container |
||||||
|
* @param savedInstanceState |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { |
||||||
|
logger.fine("onCreateView"); |
||||||
|
// Create the GLSurfaceView for the application
|
||||||
|
view = ((OGLESContext) app.getContext()).createView(getActivity()); |
||||||
|
// store the glSurfaceView in JmeAndroidSystem for future use
|
||||||
|
JmeAndroidSystem.setView(view); |
||||||
|
createLayout(); |
||||||
|
return frameLayout; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onActivityCreated(Bundle savedInstanceState) { |
||||||
|
logger.fine("onActivityCreated"); |
||||||
|
super.onActivityCreated(savedInstanceState); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onStart() { |
||||||
|
logger.fine("onStart"); |
||||||
|
super.onStart(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* When the Fragment resumes (ie. after app resumes or device screen turned |
||||||
|
* back on), call the gainFocus() in the jME application. |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public void onResume() { |
||||||
|
logger.fine("onResume"); |
||||||
|
super.onResume(); |
||||||
|
|
||||||
|
gainFocus(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* When the Fragment pauses (ie. after home button pressed on the device |
||||||
|
* or device screen turned off) , call the loseFocus() in the jME application. |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public void onPause() { |
||||||
|
logger.fine("onPause"); |
||||||
|
loseFocus(); |
||||||
|
|
||||||
|
super.onPause(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onStop() { |
||||||
|
logger.fine("onStop"); |
||||||
|
super.onStop(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Called by the Android system each time the Activity is destroyed or recreated. |
||||||
|
* For jME, we clear references to the GLSurfaceView. |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public void onDestroyView() { |
||||||
|
logger.fine("onDestroyView"); |
||||||
|
view = null; |
||||||
|
JmeAndroidSystem.setView(null); |
||||||
|
|
||||||
|
super.onDestroyView(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Called by the system when the application is being destroyed. In this case, |
||||||
|
* the jME application is actually closed as well. This method is not called |
||||||
|
* during device configuration changes or when the application is put in the |
||||||
|
* background. |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public void onDestroy() { |
||||||
|
logger.fine("onDestroy"); |
||||||
|
if (app != null) { |
||||||
|
app.stop(false); |
||||||
|
} |
||||||
|
app = null; |
||||||
|
super.onDestroy(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onDetach() { |
||||||
|
logger.fine("onDetach"); |
||||||
|
super.onDetach(); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* Called when an error has occurred. By default, will show an error message |
||||||
|
* to the user and print the exception/error to the log. |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public void handleError(final String errorMsg, final Throwable t) { |
||||||
|
String stackTrace = ""; |
||||||
|
String title = "Error"; |
||||||
|
|
||||||
|
if (t != null) { |
||||||
|
// Convert exception to string
|
||||||
|
StringWriter sw = new StringWriter(100); |
||||||
|
t.printStackTrace(new PrintWriter(sw)); |
||||||
|
stackTrace = sw.toString(); |
||||||
|
title = t.toString(); |
||||||
|
} |
||||||
|
|
||||||
|
final String finalTitle = title; |
||||||
|
final String finalMsg = (errorMsg != null ? errorMsg : "Uncaught Exception") |
||||||
|
+ "\n" + stackTrace; |
||||||
|
|
||||||
|
logger.log(Level.SEVERE, finalMsg); |
||||||
|
|
||||||
|
getActivity().runOnUiThread(new Runnable() { |
||||||
|
@Override |
||||||
|
public void run() { |
||||||
|
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); |
||||||
|
builder.setTitle(finalTitle); |
||||||
|
builder.setPositiveButton("Kill", AndroidHarnessFragment.this); |
||||||
|
builder.setMessage(finalMsg); |
||||||
|
|
||||||
|
AlertDialog dialog = builder.create(); |
||||||
|
dialog.show(); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Called by the android alert dialog, terminate the activity and OpenGL |
||||||
|
* rendering |
||||||
|
* |
||||||
|
* @param dialog |
||||||
|
* @param whichButton |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public void onClick(DialogInterface dialog, int whichButton) { |
||||||
|
if (whichButton != -2) { |
||||||
|
if (app != null) { |
||||||
|
app.stop(true); |
||||||
|
} |
||||||
|
app = null; |
||||||
|
getActivity().finish(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Gets called by the InputManager on all touch/drag/scale events |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public void onTouch(String name, TouchEvent evt, float tpf) { |
||||||
|
if (name.equals(ESCAPE_EVENT)) { |
||||||
|
switch (evt.getType()) { |
||||||
|
case KEY_UP: |
||||||
|
getActivity().runOnUiThread(new Runnable() { |
||||||
|
@Override |
||||||
|
public void run() { |
||||||
|
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); |
||||||
|
builder.setTitle(exitDialogTitle); |
||||||
|
builder.setPositiveButton("Yes", AndroidHarnessFragment.this); |
||||||
|
builder.setNegativeButton("No", AndroidHarnessFragment.this); |
||||||
|
builder.setMessage(exitDialogMessage); |
||||||
|
|
||||||
|
AlertDialog dialog = builder.create(); |
||||||
|
dialog.show(); |
||||||
|
} |
||||||
|
}); |
||||||
|
break; |
||||||
|
default: |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public void createLayout() { |
||||||
|
logger.log(Level.FINE, "Splash Screen Picture Resource ID: {0}", splashPicID); |
||||||
|
FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams( |
||||||
|
ViewGroup.LayoutParams.MATCH_PARENT, |
||||||
|
ViewGroup.LayoutParams.MATCH_PARENT, |
||||||
|
Gravity.CENTER); |
||||||
|
|
||||||
|
if (frameLayout != null && frameLayout.getParent() != null) { |
||||||
|
((ViewGroup) frameLayout.getParent()).removeView(frameLayout); |
||||||
|
} |
||||||
|
frameLayout = new FrameLayout(getActivity()); |
||||||
|
|
||||||
|
if (view.getParent() != null) { |
||||||
|
((ViewGroup) view.getParent()).removeView(view); |
||||||
|
} |
||||||
|
frameLayout.addView(view); |
||||||
|
|
||||||
|
if (splashPicID != 0) { |
||||||
|
splashImageView = new ImageView(getActivity()); |
||||||
|
|
||||||
|
Drawable drawable = getResources().getDrawable(splashPicID); |
||||||
|
if (drawable instanceof NinePatchDrawable) { |
||||||
|
splashImageView.setBackgroundDrawable(drawable); |
||||||
|
} else { |
||||||
|
splashImageView.setImageResource(splashPicID); |
||||||
|
} |
||||||
|
|
||||||
|
if (splashImageView.getParent() != null) { |
||||||
|
((ViewGroup) splashImageView.getParent()).removeView(splashImageView); |
||||||
|
} |
||||||
|
frameLayout.addView(splashImageView, lp); |
||||||
|
|
||||||
|
logger.log(Level.FINE, "Splash Screen Created"); |
||||||
|
} else { |
||||||
|
logger.log(Level.FINE, "Splash Screen Skipped."); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public void removeSplashScreen() { |
||||||
|
logger.log(Level.FINE, "Splash Screen Picture Resource ID: {0}", splashPicID); |
||||||
|
if (splashPicID != 0) { |
||||||
|
if (frameLayout != null) { |
||||||
|
if (splashImageView != null) { |
||||||
|
getActivity().runOnUiThread(new Runnable() { |
||||||
|
@Override |
||||||
|
public void run() { |
||||||
|
splashImageView.setVisibility(View.INVISIBLE); |
||||||
|
frameLayout.removeView(splashImageView); |
||||||
|
} |
||||||
|
}); |
||||||
|
} else { |
||||||
|
logger.log(Level.FINE, "splashImageView is null"); |
||||||
|
} |
||||||
|
} else { |
||||||
|
logger.log(Level.FINE, "frameLayout is null"); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Removes the standard Android log handler due to an issue with not logging |
||||||
|
* entries lower than INFO level and adds a handler that produces |
||||||
|
* JME formatted log messages. |
||||||
|
*/ |
||||||
|
protected void initializeLogHandler() { |
||||||
|
Logger log = LogManager.getLogManager().getLogger(""); |
||||||
|
for (Handler handler : log.getHandlers()) { |
||||||
|
if (log.getLevel() != null && log.getLevel().intValue() <= Level.FINE.intValue()) { |
||||||
|
Log.v("AndroidHarness", "Removing Handler class: " + handler.getClass().getName()); |
||||||
|
} |
||||||
|
log.removeHandler(handler); |
||||||
|
} |
||||||
|
Handler handler = new AndroidLogHandler(); |
||||||
|
log.addHandler(handler); |
||||||
|
handler.setLevel(Level.ALL); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void initialize() { |
||||||
|
app.initialize(); |
||||||
|
if (handleExitHook) { |
||||||
|
// remove existing mapping from SimpleApplication that stops the app
|
||||||
|
// when the esc key is pressed (esc key = android back key) so that
|
||||||
|
// AndroidHarness can produce the exit app dialog box.
|
||||||
|
if (app.getInputManager().hasMapping(SimpleApplication.INPUT_MAPPING_EXIT)) { |
||||||
|
app.getInputManager().deleteMapping(SimpleApplication.INPUT_MAPPING_EXIT); |
||||||
|
} |
||||||
|
|
||||||
|
app.getInputManager().addMapping(ESCAPE_EVENT, new TouchTrigger(TouchInput.KEYCODE_BACK)); |
||||||
|
app.getInputManager().addListener(this, new String[]{ESCAPE_EVENT}); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void reshape(int width, int height) { |
||||||
|
app.reshape(width, height); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void update() { |
||||||
|
app.update(); |
||||||
|
// call to remove the splash screen, if present.
|
||||||
|
// call after app.update() to make sure no gap between
|
||||||
|
// splash screen going away and app display being shown.
|
||||||
|
if (firstDrawFrame) { |
||||||
|
removeSplashScreen(); |
||||||
|
firstDrawFrame = false; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void requestClose(boolean esc) { |
||||||
|
app.requestClose(esc); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void destroy() { |
||||||
|
if (app != null) { |
||||||
|
app.destroy(); |
||||||
|
} |
||||||
|
if (finishOnAppStop) { |
||||||
|
getActivity().finish(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void gainFocus() { |
||||||
|
logger.fine("gainFocus"); |
||||||
|
if (view != null) { |
||||||
|
view.onResume(); |
||||||
|
} |
||||||
|
|
||||||
|
if (app != null) { |
||||||
|
//resume the audio
|
||||||
|
AudioRenderer audioRenderer = app.getAudioRenderer(); |
||||||
|
if (audioRenderer != null) { |
||||||
|
audioRenderer.resumeAll(); |
||||||
|
} |
||||||
|
//resume the sensors (aka joysticks)
|
||||||
|
if (app.getContext() != null) { |
||||||
|
JoyInput joyInput = app.getContext().getJoyInput(); |
||||||
|
if (joyInput != null) { |
||||||
|
if (joyInput instanceof AndroidSensorJoyInput) { |
||||||
|
AndroidSensorJoyInput androidJoyInput = (AndroidSensorJoyInput) joyInput; |
||||||
|
androidJoyInput.resumeSensors(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if (app != null) { |
||||||
|
app.gainFocus(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void loseFocus() { |
||||||
|
logger.fine("loseFocus"); |
||||||
|
if (app != null) { |
||||||
|
app.loseFocus(); |
||||||
|
} |
||||||
|
|
||||||
|
if (view != null) { |
||||||
|
view.onPause(); |
||||||
|
} |
||||||
|
|
||||||
|
if (app != null) { |
||||||
|
//pause the audio
|
||||||
|
AudioRenderer audioRenderer = app.getAudioRenderer(); |
||||||
|
if (audioRenderer != null) { |
||||||
|
audioRenderer.pauseAll(); |
||||||
|
} |
||||||
|
//pause the sensors (aka joysticks)
|
||||||
|
if (app.getContext() != null) { |
||||||
|
JoyInput joyInput = app.getContext().getJoyInput(); |
||||||
|
if (joyInput != null) { |
||||||
|
if (joyInput instanceof AndroidSensorJoyInput) { |
||||||
|
AndroidSensorJoyInput androidJoyInput = (AndroidSensorJoyInput) joyInput; |
||||||
|
androidJoyInput.pauseSensors(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
} |
Loading…
Reference in new issue