2012-06-01 04:05:37 +00:00
|
|
|
package com.jme3.system.android;
|
|
|
|
|
|
|
|
import android.app.Activity;
|
2012-07-10 03:49:05 +00:00
|
|
|
import android.app.AlertDialog;
|
2012-12-05 00:59:52 +00:00
|
|
|
import android.content.Context;
|
2012-07-20 01:06:15 +00:00
|
|
|
import android.graphics.Bitmap;
|
2012-06-01 04:05:37 +00:00
|
|
|
import android.os.Environment;
|
|
|
|
import com.jme3.asset.AndroidAssetManager;
|
2012-09-09 23:39:45 +00:00
|
|
|
import com.jme3.asset.AndroidImageInfo;
|
2012-06-01 04:05:37 +00:00
|
|
|
import com.jme3.asset.AssetManager;
|
|
|
|
import com.jme3.audio.AudioRenderer;
|
2014-11-15 15:13:15 -05:00
|
|
|
import com.jme3.audio.android.AndroidAL;
|
|
|
|
import com.jme3.audio.android.AndroidALC;
|
|
|
|
import com.jme3.audio.android.AndroidEFX;
|
|
|
|
import com.jme3.audio.openal.AL;
|
|
|
|
import com.jme3.audio.openal.ALAudioRenderer;
|
|
|
|
import com.jme3.audio.openal.ALC;
|
|
|
|
import com.jme3.audio.openal.EFX;
|
2012-07-20 01:06:15 +00:00
|
|
|
import com.jme3.system.*;
|
2012-06-01 04:05:37 +00:00
|
|
|
import com.jme3.system.JmeContext.Type;
|
2012-09-09 23:39:45 +00:00
|
|
|
import com.jme3.texture.Image;
|
|
|
|
import com.jme3.texture.image.DefaultImageRaster;
|
|
|
|
import com.jme3.texture.image.ImageRaster;
|
2012-07-20 01:06:15 +00:00
|
|
|
import com.jme3.util.AndroidScreenshots;
|
2012-06-01 04:05:37 +00:00
|
|
|
import java.io.File;
|
2012-07-20 01:06:15 +00:00
|
|
|
import java.io.IOException;
|
|
|
|
import java.io.OutputStream;
|
2012-06-01 04:05:37 +00:00
|
|
|
import java.net.URL;
|
2012-07-20 01:06:15 +00:00
|
|
|
import java.nio.ByteBuffer;
|
2012-06-01 04:05:37 +00:00
|
|
|
import java.util.logging.Level;
|
|
|
|
|
|
|
|
public class JmeAndroidSystem extends JmeSystemDelegate {
|
|
|
|
|
|
|
|
private static Activity activity;
|
2014-11-20 20:27:43 -05:00
|
|
|
private static String audioRendererType = AppSettings.ANDROID_OPENAL_SOFT;
|
2012-06-01 04:05:37 +00:00
|
|
|
|
2012-09-09 23:39:45 +00:00
|
|
|
static {
|
|
|
|
try {
|
|
|
|
System.loadLibrary("bulletjme");
|
|
|
|
} catch (UnsatisfiedLinkError e) {
|
|
|
|
}
|
|
|
|
}
|
2012-09-16 22:00:27 +00:00
|
|
|
|
2012-07-20 01:06:15 +00:00
|
|
|
@Override
|
|
|
|
public void writeImageFile(OutputStream outStream, String format, ByteBuffer imageData, int width, int height) throws IOException {
|
|
|
|
Bitmap bitmapImage = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
|
|
|
|
AndroidScreenshots.convertScreenShot(imageData, bitmapImage);
|
|
|
|
Bitmap.CompressFormat compressFormat;
|
|
|
|
if (format.equals("png")) {
|
|
|
|
compressFormat = Bitmap.CompressFormat.PNG;
|
|
|
|
} else if (format.equals("jpg")) {
|
|
|
|
compressFormat = Bitmap.CompressFormat.JPEG;
|
|
|
|
} else {
|
|
|
|
throw new UnsupportedOperationException("Only 'png' and 'jpg' formats are supported on Android");
|
|
|
|
}
|
|
|
|
bitmapImage.compress(compressFormat, 95, outStream);
|
|
|
|
bitmapImage.recycle();
|
|
|
|
}
|
2012-09-16 22:00:27 +00:00
|
|
|
|
2012-09-09 23:39:45 +00:00
|
|
|
@Override
|
|
|
|
public ImageRaster createImageRaster(Image image, int slice) {
|
|
|
|
if (image.getEfficentData() != null) {
|
|
|
|
return (AndroidImageInfo) image.getEfficentData();
|
|
|
|
} else {
|
|
|
|
return new DefaultImageRaster(image, slice);
|
2012-06-01 04:05:37 +00:00
|
|
|
}
|
|
|
|
}
|
2012-09-16 22:00:27 +00:00
|
|
|
|
2012-06-01 04:05:37 +00:00
|
|
|
@Override
|
|
|
|
public AssetManager newAssetManager(URL configFile) {
|
2013-01-31 22:26:10 +00:00
|
|
|
logger.log(Level.FINE, "Creating asset manager with config {0}", configFile);
|
2012-06-01 04:05:37 +00:00
|
|
|
return new AndroidAssetManager(configFile);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public AssetManager newAssetManager() {
|
2013-01-31 22:26:10 +00:00
|
|
|
logger.log(Level.FINE, "Creating asset manager with default config");
|
2012-06-01 04:05:37 +00:00
|
|
|
return new AndroidAssetManager(null);
|
|
|
|
}
|
|
|
|
|
2012-07-10 03:49:05 +00:00
|
|
|
@Override
|
|
|
|
public void showErrorDialog(String message) {
|
|
|
|
final String finalMsg = message;
|
2012-08-29 15:58:18 +00:00
|
|
|
final String finalTitle = "Error in application";
|
2012-07-10 03:49:05 +00:00
|
|
|
final Activity context = JmeAndroidSystem.getActivity();
|
2012-09-16 22:00:27 +00:00
|
|
|
|
2012-07-10 03:49:05 +00:00
|
|
|
context.runOnUiThread(new Runnable() {
|
|
|
|
@Override
|
|
|
|
public void run() {
|
|
|
|
AlertDialog dialog = new AlertDialog.Builder(context)
|
|
|
|
.setTitle(finalTitle).setMessage(finalMsg).create();
|
|
|
|
dialog.show();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
2012-09-16 22:00:27 +00:00
|
|
|
|
2012-06-01 04:05:37 +00:00
|
|
|
@Override
|
|
|
|
public boolean showSettingsDialog(AppSettings sourceSettings, boolean loadFromRegistry) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public JmeContext newContext(AppSettings settings, Type contextType) {
|
2013-05-15 21:44:21 +00:00
|
|
|
if (settings.getAudioRenderer().equals(AppSettings.ANDROID_MEDIAPLAYER)) {
|
|
|
|
audioRendererType = AppSettings.ANDROID_MEDIAPLAYER;
|
|
|
|
} else if (settings.getAudioRenderer().equals(AppSettings.ANDROID_OPENAL_SOFT)) {
|
|
|
|
audioRendererType = AppSettings.ANDROID_OPENAL_SOFT;
|
|
|
|
} else {
|
2014-11-20 20:36:36 -05:00
|
|
|
logger.log(Level.INFO, "AudioRenderer not set. Defaulting to OpenAL Soft");
|
|
|
|
audioRendererType = AppSettings.ANDROID_OPENAL_SOFT;
|
2013-05-15 21:44:21 +00:00
|
|
|
}
|
2012-06-01 04:05:37 +00:00
|
|
|
initialize(settings);
|
2012-09-16 22:00:27 +00:00
|
|
|
JmeContext ctx = new OGLESContext();
|
|
|
|
ctx.setSettings(settings);
|
|
|
|
return ctx;
|
2012-06-01 04:05:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public AudioRenderer newAudioRenderer(AppSettings settings) {
|
2014-11-15 15:13:15 -05:00
|
|
|
ALC alc = new AndroidALC();
|
|
|
|
AL al = new AndroidAL();
|
|
|
|
EFX efx = new AndroidEFX();
|
|
|
|
return new ALAudioRenderer(al, alc, efx);
|
|
|
|
/*
|
2013-05-15 21:44:21 +00:00
|
|
|
if (settings.getAudioRenderer().equals(AppSettings.ANDROID_MEDIAPLAYER)) {
|
|
|
|
logger.log(Level.INFO, "newAudioRenderer settings set to Android MediaPlayer / SoundPool");
|
|
|
|
audioRendererType = AppSettings.ANDROID_MEDIAPLAYER;
|
|
|
|
return new AndroidMediaPlayerAudioRenderer(activity);
|
|
|
|
} else if (settings.getAudioRenderer().equals(AppSettings.ANDROID_OPENAL_SOFT)) {
|
|
|
|
logger.log(Level.INFO, "newAudioRenderer settings set to Android OpenAL Soft");
|
|
|
|
audioRendererType = AppSettings.ANDROID_OPENAL_SOFT;
|
2014-11-15 15:13:15 -05:00
|
|
|
return new AndroidMediaPlayerAudioRenderer(activity);
|
2013-05-15 21:44:21 +00:00
|
|
|
} else {
|
|
|
|
logger.log(Level.INFO, "AudioRenderer not set. Defaulting to Android MediaPlayer / SoundPool");
|
|
|
|
audioRendererType = AppSettings.ANDROID_MEDIAPLAYER;
|
|
|
|
return new AndroidMediaPlayerAudioRenderer(activity);
|
|
|
|
}
|
2014-11-15 15:13:15 -05:00
|
|
|
*/
|
2012-06-01 04:05:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void initialize(AppSettings settings) {
|
|
|
|
if (initialized) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
initialized = true;
|
2013-02-02 23:09:08 +00:00
|
|
|
logger.log(Level.INFO, "Running on {0}", getFullName());
|
2012-06-01 04:05:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public Platform getPlatform() {
|
|
|
|
String arch = System.getProperty("os.arch").toLowerCase();
|
|
|
|
if (arch.contains("arm")) {
|
|
|
|
if (arch.contains("v5")) {
|
|
|
|
return Platform.Android_ARM5;
|
|
|
|
} else if (arch.contains("v6")) {
|
|
|
|
return Platform.Android_ARM6;
|
|
|
|
} else if (arch.contains("v7")) {
|
|
|
|
return Platform.Android_ARM7;
|
|
|
|
} else {
|
|
|
|
return Platform.Android_ARM5; // unknown ARM
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
throw new UnsupportedOperationException("Unsupported Android Platform");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2012-12-05 00:59:52 +00:00
|
|
|
public synchronized File getStorageFolder(JmeSystem.StorageFolderType type) {
|
|
|
|
File storageFolder = null;
|
|
|
|
|
|
|
|
switch (type) {
|
|
|
|
case Internal:
|
|
|
|
// http://developer.android.com/guide/topics/data/data-storage.html
|
|
|
|
// http://developer.android.com/guide/topics/data/data-storage.html#filesInternal
|
|
|
|
// http://developer.android.com/reference/android/content/Context.html#getFilesDir()
|
|
|
|
// http://developer.android.com/reference/android/content/Context.html#getDir(java.lang.String, int)
|
|
|
|
|
|
|
|
// getDir automatically creates the directory if necessary.
|
|
|
|
// Directory structure should be: /data/data/<packagename>/app_
|
|
|
|
// When created this way, the directory is automatically removed by the Android
|
|
|
|
// system when the app is uninstalled.
|
|
|
|
// The directory is NOT accessible by a PC connected to the device
|
|
|
|
// The files can only be accessed by this application
|
|
|
|
storageFolder = storageFolders.get(type);
|
|
|
|
if (storageFolder == null) {
|
|
|
|
storageFolder = activity.getApplicationContext().getDir("", Context.MODE_PRIVATE);
|
|
|
|
storageFolders.put(type, storageFolder);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case External:
|
|
|
|
//http://developer.android.com/reference/android/content/Context.html#getExternalFilesDir
|
|
|
|
//http://developer.android.com/guide/topics/data/data-storage.html
|
|
|
|
|
|
|
|
// getExternalFilesDir automatically creates the directory if necessary.
|
|
|
|
// Directory structure should be: /mnt/sdcard/Android/data/<packagename>/files
|
|
|
|
// When created this way, the directory is automatically removed by the Android
|
|
|
|
// system when the app is uninstalled.
|
|
|
|
// The directory is also accessible by a PC connected to the device
|
|
|
|
// so the files can be copied to the PC (ie. screenshots)
|
|
|
|
storageFolder = storageFolders.get(type);
|
|
|
|
if (storageFolder == null) {
|
|
|
|
String state = Environment.getExternalStorageState();
|
2013-01-31 22:26:10 +00:00
|
|
|
logger.log(Level.FINE, "ExternalStorageState: {0}", state);
|
2012-12-05 00:59:52 +00:00
|
|
|
if (state.equals(Environment.MEDIA_MOUNTED)) {
|
|
|
|
storageFolder = activity.getApplicationContext().getExternalFilesDir(null);
|
|
|
|
storageFolders.put(type, storageFolder);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (storageFolder != null) {
|
2013-01-31 22:26:10 +00:00
|
|
|
logger.log(Level.FINE, "Base Storage Folder Path: {0}", storageFolder.getAbsolutePath());
|
2012-06-01 04:05:37 +00:00
|
|
|
} else {
|
2013-01-31 22:26:10 +00:00
|
|
|
logger.log(Level.FINE, "Base Storage Folder not found!");
|
2012-06-01 04:05:37 +00:00
|
|
|
}
|
2012-12-05 00:59:52 +00:00
|
|
|
return storageFolder;
|
2012-06-01 04:05:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public static void setActivity(Activity activity) {
|
|
|
|
JmeAndroidSystem.activity = activity;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static Activity getActivity() {
|
|
|
|
return activity;
|
|
|
|
}
|
2013-05-15 21:44:21 +00:00
|
|
|
|
|
|
|
public static String getAudioRendererType() {
|
|
|
|
return audioRendererType;
|
|
|
|
}
|
2012-06-01 04:05:37 +00:00
|
|
|
}
|