mirror of https://github.com/encounter/SDL.git
Merged changes from Alexey Petruchik to support Android obb files
http://developer.android.com/google/play/expansion-files.html
This commit is contained in:
commit
e8d84fbfaa
|
@ -1,10 +1,13 @@
|
||||||
package org.libsdl.app;
|
package org.libsdl.app;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
import android.app.*;
|
import android.app.*;
|
||||||
import android.content.*;
|
import android.content.*;
|
||||||
|
@ -20,7 +23,6 @@ import android.graphics.*;
|
||||||
import android.media.*;
|
import android.media.*;
|
||||||
import android.hardware.*;
|
import android.hardware.*;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
SDL Activity
|
SDL Activity
|
||||||
*/
|
*/
|
||||||
|
@ -296,6 +298,7 @@ public class SDLActivity extends Activity {
|
||||||
int is_accelerometer, int nbuttons,
|
int is_accelerometer, int nbuttons,
|
||||||
int naxes, int nhats, int nballs);
|
int naxes, int nhats, int nballs);
|
||||||
public static native int nativeRemoveJoystick(int device_id);
|
public static native int nativeRemoveJoystick(int device_id);
|
||||||
|
public static native String nativeGetHint(String name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method is called by SDL using JNI.
|
* This method is called by SDL using JNI.
|
||||||
|
@ -532,6 +535,51 @@ public class SDLActivity extends Activity {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// APK extension files support
|
||||||
|
|
||||||
|
/** com.android.vending.expansion.zipfile.ZipResourceFile object or null. */
|
||||||
|
private Object expansionFile;
|
||||||
|
|
||||||
|
/** com.android.vending.expansion.zipfile.ZipResourceFile's getInputStream() or null. */
|
||||||
|
private Method expansionFileMethod;
|
||||||
|
|
||||||
|
public InputStream openAPKExtensionInputStream(String fileName) throws IOException {
|
||||||
|
// Get a ZipResourceFile representing a merger of both the main and patch files
|
||||||
|
if (expansionFile == null) {
|
||||||
|
Integer mainVersion = Integer.parseInt(nativeGetHint("SDL_ANDROID_APK_EXPANSION_MAIN_FILE_VERSION"));
|
||||||
|
Integer patchVersion = Integer.parseInt(nativeGetHint("SDL_ANDROID_APK_EXPANSION_PATCH_FILE_VERSION"));
|
||||||
|
|
||||||
|
try {
|
||||||
|
// To avoid direct dependency on Google APK extension library that is
|
||||||
|
// not a part of Android SDK we access it using reflection
|
||||||
|
expansionFile = Class.forName("com.android.vending.expansion.zipfile.APKExpansionSupport")
|
||||||
|
.getMethod("getAPKExpansionZipFile", Context.class, int.class, int.class)
|
||||||
|
.invoke(null, this, mainVersion, patchVersion);
|
||||||
|
|
||||||
|
expansionFileMethod = expansionFile.getClass()
|
||||||
|
.getMethod("getInputStream", String.class);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
expansionFile = null;
|
||||||
|
expansionFileMethod = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get an input stream for a known file inside the expansion file ZIPs
|
||||||
|
InputStream fileStream;
|
||||||
|
try {
|
||||||
|
fileStream = (InputStream)expansionFileMethod.invoke(expansionFile, fileName);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
fileStream = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fileStream == null) {
|
||||||
|
throw new IOException();
|
||||||
|
}
|
||||||
|
|
||||||
|
return fileStream;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -457,6 +457,16 @@ extern "C" {
|
||||||
*/
|
*/
|
||||||
#define SDL_HINT_VIDEO_MAC_FULLSCREEN_SPACES "SDL_VIDEO_MAC_FULLSCREEN_SPACES"
|
#define SDL_HINT_VIDEO_MAC_FULLSCREEN_SPACES "SDL_VIDEO_MAC_FULLSCREEN_SPACES"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Android APK expansion main file version. Should be a string number like "1", "2" etc.
|
||||||
|
*/
|
||||||
|
#define SDL_HINT_ANDROID_APK_EXPANSION_MAIN_FILE_VERSION "SDL_ANDROID_APK_EXPANSION_MAIN_FILE_VERSION"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Android APK expansion patch file version. Should be a string number like "1", "2" etc.
|
||||||
|
*/
|
||||||
|
#define SDL_HINT_ANDROID_APK_EXPANSION_PATCH_FILE_VERSION "SDL_ANDROID_APK_EXPANSION_PATCH_FILE_VERSION"
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief An enumeration of hint priorities
|
* \brief An enumeration of hint priorities
|
||||||
|
|
|
@ -385,7 +385,15 @@ JNIEXPORT void JNICALL Java_org_libsdl_app_SDLInputConnection_nativeSetComposing
|
||||||
(*env)->ReleaseStringUTFChars(env, text, utftext);
|
(*env)->ReleaseStringUTFChars(env, text, utftext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
jstring Java_org_libsdl_app_SDLActivity_nativeGetHint(JNIEnv* env, jclass cls, jstring name) {
|
||||||
|
const char *utfname = (*env)->GetStringUTFChars(env, name, NULL);
|
||||||
|
const char *hint = SDL_GetHint(utfname);
|
||||||
|
|
||||||
|
jstring result = (*env)->NewStringUTF(env, hint);
|
||||||
|
(*env)->ReleaseStringUTFChars(env, name, utfname);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
Functions called by SDL into Java
|
Functions called by SDL into Java
|
||||||
|
@ -757,9 +765,16 @@ fallback:
|
||||||
mid = (*mEnv)->GetMethodID(mEnv, (*mEnv)->GetObjectClass(mEnv, assetManager),
|
mid = (*mEnv)->GetMethodID(mEnv, (*mEnv)->GetObjectClass(mEnv, assetManager),
|
||||||
"open", "(Ljava/lang/String;I)Ljava/io/InputStream;");
|
"open", "(Ljava/lang/String;I)Ljava/io/InputStream;");
|
||||||
inputStream = (*mEnv)->CallObjectMethod(mEnv, assetManager, mid, fileNameJString, 1 /* ACCESS_RANDOM */);
|
inputStream = (*mEnv)->CallObjectMethod(mEnv, assetManager, mid, fileNameJString, 1 /* ACCESS_RANDOM */);
|
||||||
|
if (Android_JNI_ExceptionOccurred(false)) {
|
||||||
|
// Try fallback to APK Extension files
|
||||||
|
mid = (*mEnv)->GetMethodID(mEnv, (*mEnv)->GetObjectClass(mEnv, context),
|
||||||
|
"openAPKExtensionInputStream", "(Ljava/lang/String;)Ljava/io/InputStream;");
|
||||||
|
inputStream = (*mEnv)->CallObjectMethod(mEnv, context, mid, fileNameJString);
|
||||||
|
|
||||||
if (Android_JNI_ExceptionOccurred(false)) {
|
if (Android_JNI_ExceptionOccurred(false)) {
|
||||||
goto failure;
|
goto failure;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ctx->hidden.androidio.inputStreamRef = (*mEnv)->NewGlobalRef(mEnv, inputStream);
|
ctx->hidden.androidio.inputStreamRef = (*mEnv)->NewGlobalRef(mEnv, inputStream);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue