1 package com.jme3.app;
\r
3 import java.util.logging.Logger;
\r
5 import android.app.Activity;
\r
6 import android.app.AlertDialog;
\r
7 import android.content.DialogInterface;
\r
8 import android.opengl.GLSurfaceView;
\r
9 import android.os.Bundle;
\r
10 import android.view.SurfaceView;
\r
11 import android.view.View;
\r
12 import android.view.Window;
\r
13 import android.view.WindowManager;
\r
14 import android.widget.TextView;
\r
16 import com.jme3.app.Application;
\r
17 import com.jme3.input.TouchInput;
\r
18 import com.jme3.input.android.AndroidInput;
\r
19 import com.jme3.input.controls.TouchListener;
\r
20 import com.jme3.input.controls.TouchTrigger;
\r
21 import com.jme3.input.event.TouchEvent;
\r
22 import com.jme3.system.AppSettings;
\r
23 import com.jme3.system.JmeSystem;
\r
24 import com.jme3.system.android.OGLESContext;
\r
25 import com.jme3.system.android.AndroidConfigChooser.ConfigType;
\r
29 * <code>AndroidHarness</code> wraps a jme application object and runs it on Android
\r
33 public class AndroidHarness extends Activity implements TouchListener, DialogInterface.OnClickListener
\r
35 protected final static Logger logger = Logger.getLogger(AndroidHarness.class.getName());
\r
38 * The application class to start
\r
40 protected String appClass = "jme3test.android.Test";
\r
43 * The jme3 application object
\r
45 protected Application app = null;
\r
48 * ConfigType.FASTEST is RGB565, GLSurfaceView default
\r
49 * ConfigType.BEST is RGBA8888 or better if supported by the hardware
\r
51 protected ConfigType eglConfigType = ConfigType.FASTEST;
\r
54 * If true all valid and not valid egl configs are logged
\r
56 protected boolean eglConfigVerboseLogging = false;
\r
59 * Title of the exit dialog, default is "Do you want to exit?"
\r
61 protected String exitDialogTitle = "Do you want to exit?";
\r
63 * Message of the exit dialog, default is "Use your home key to bring this app into the background or exit to terminate it."
\r
65 protected String exitDialogMessage = "Use your home key to bring this app into the background or exit to terminate it.";
\r
68 protected OGLESContext ctx;
\r
69 protected GLSurfaceView view;
\r
71 final private String ESCAPE_EVENT = "TouchEscape";
\r
74 public void onCreate(Bundle savedInstanceState)
\r
76 super.onCreate(savedInstanceState);
\r
78 JmeSystem.setResources(getResources());
\r
79 JmeSystem.setActivity(this);
\r
81 requestWindowFeature(Window.FEATURE_NO_TITLE);
\r
82 getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
\r
83 WindowManager.LayoutParams.FLAG_FULLSCREEN);
\r
85 AppSettings settings = new AppSettings(true);
\r
86 AndroidInput input = new AndroidInput(this);
\r
88 // Create application instance
\r
94 @SuppressWarnings("unchecked")
\r
95 Class<? extends Application> clazz = (Class<? extends Application>) Class.forName(appClass);
\r
96 app = clazz.newInstance();
\r
98 app.setSettings(settings);
\r
100 ctx = (OGLESContext) app.getContext();
\r
101 view = ctx.createView(input, eglConfigType, eglConfigVerboseLogging);
\r
102 setContentView(view);
\r
104 catch (Exception ex)
\r
106 handleError("Class " + appClass + " init failed", ex);
\r
107 setContentView(new TextView(this));
\r
113 protected void onRestart(){
\r
114 super.onRestart();
\r
117 logger.info("onRestart");
\r
122 protected void onStart(){
\r
124 logger.info("onStart");
\r
128 protected void onResume() {
\r
132 logger.info("onResume");
\r
136 protected void onPause() {
\r
140 logger.info("onPause");
\r
144 protected void onStop(){
\r
146 logger.info("onStop");
\r
150 protected void onDestroy(){
\r
153 super.onDestroy();
\r
154 logger.info("onDestroy");
\r
157 public Application getJmeApplication()
\r
163 * Called when an error has occured. This is typically
\r
164 * invoked when an uncought exception is thrown in the render thread.
\r
165 * @param errorMsg The error message, if any, or null.
\r
166 * @param t Throwable object, or null.
\r
168 public void handleError(final String errorMsg, final Throwable t)
\r
172 if (t != null && t.getStackTrace() != null)
\r
174 for (StackTraceElement ste: t.getStackTrace())
\r
176 s += ste.getClassName() + "." + ste.getMethodName() + "(" + + ste.getLineNumber() + ") ";
\r
180 final String sTrace = s;
\r
182 logger.severe(t != null ? t.toString() : "OpenGL Exception");
\r
183 logger.severe((errorMsg != null ? errorMsg + ": " : "") + sTrace);
\r
185 this.runOnUiThread(new Runnable() {
\r
189 AlertDialog dialog = new AlertDialog.Builder(AndroidHarness.this)
\r
190 // .setIcon(R.drawable.alert_dialog_icon)
\r
191 .setTitle(t != null ? (t.getMessage() != null ? (t.getMessage() + ": " + t.getClass().getName()) : t.getClass().getName()) : "OpenGL Exception")
\r
192 .setPositiveButton("Kill", AndroidHarness.this)
\r
193 .setMessage((errorMsg != null ? errorMsg + ": " : "") + sTrace)
\r
202 * Called by the android alert dialog, terminate the activity and OpenGL rendering
\r
204 * @param whichButton
\r
206 public void onClick(DialogInterface dialog, int whichButton)
\r
208 if (whichButton != -2)
\r
217 * Gets called by the InputManager on all touch/drag/scale events
\r
220 public void onTouch(String name, TouchEvent evt, float tpf)
\r
222 if (name.equals(ESCAPE_EVENT))
\r
224 switch(evt.getType())
\r
227 this.runOnUiThread(new Runnable()
\r
232 AlertDialog dialog = new AlertDialog.Builder(AndroidHarness.this)
\r
233 // .setIcon(R.drawable.alert_dialog_icon)
\r
234 .setTitle(exitDialogTitle)
\r
235 .setPositiveButton("Yes", AndroidHarness.this)
\r
236 .setNegativeButton("No", AndroidHarness.this)
\r
237 .setMessage(exitDialogMessage)
\r