Initial commit for support of launching a jME application as an Android Fragment
This commit is contained in:
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…
x
Reference in New Issue
Block a user