Enable the ability to use Godot as a subview within an Android app
This commit is contained in:
parent
5079bea660
commit
920639511d
|
@ -30,11 +30,11 @@
|
||||||
|
|
||||||
package com.godot.game;
|
package com.godot.game;
|
||||||
|
|
||||||
import org.godotengine.godot.Godot;
|
import org.godotengine.godot.FullScreenGodotApp;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Template activity for Godot Android custom builds.
|
* Template activity for Godot Android custom builds.
|
||||||
* Feel free to extend and modify this class for your custom logic.
|
* Feel free to extend and modify this class for your custom logic.
|
||||||
*/
|
*/
|
||||||
public class GodotApp extends Godot {
|
public class GodotApp extends FullScreenGodotApp {
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:id="@+id/godot_fragment_container"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent" />
|
|
@ -0,0 +1,80 @@
|
||||||
|
/*************************************************************************/
|
||||||
|
/* FullScreenGodotApp.java */
|
||||||
|
/*************************************************************************/
|
||||||
|
/* This file is part of: */
|
||||||
|
/* GODOT ENGINE */
|
||||||
|
/* https://godotengine.org */
|
||||||
|
/*************************************************************************/
|
||||||
|
/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
|
||||||
|
/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
|
||||||
|
/* */
|
||||||
|
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||||
|
/* a copy of this software and associated documentation files (the */
|
||||||
|
/* "Software"), to deal in the Software without restriction, including */
|
||||||
|
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||||
|
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||||
|
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||||
|
/* the following conditions: */
|
||||||
|
/* */
|
||||||
|
/* The above copyright notice and this permission notice shall be */
|
||||||
|
/* included in all copies or substantial portions of the Software. */
|
||||||
|
/* */
|
||||||
|
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||||
|
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||||
|
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||||
|
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||||
|
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||||
|
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||||
|
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||||
|
/*************************************************************************/
|
||||||
|
|
||||||
|
package org.godotengine.godot;
|
||||||
|
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.KeyEvent;
|
||||||
|
|
||||||
|
import androidx.fragment.app.FragmentActivity;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base activity for Android apps intending to use Godot as the primary and only screen.
|
||||||
|
*
|
||||||
|
* It's also a reference implementation for how to setup and use the {@link Godot} fragment
|
||||||
|
* within an Android app.
|
||||||
|
*/
|
||||||
|
public abstract class FullScreenGodotApp extends FragmentActivity {
|
||||||
|
|
||||||
|
protected Godot godotFragment;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setContentView(R.layout.godot_app_layout);
|
||||||
|
godotFragment = new Godot();
|
||||||
|
getSupportFragmentManager().beginTransaction().replace(R.id.godot_fragment_container, godotFragment).setPrimaryNavigationFragment(godotFragment).commitNowAllowingStateLoss();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNewIntent(Intent intent) {
|
||||||
|
if (godotFragment != null) {
|
||||||
|
godotFragment.onNewIntent(intent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBackPressed() {
|
||||||
|
if (godotFragment != null) {
|
||||||
|
godotFragment.onBackPressed();
|
||||||
|
} else {
|
||||||
|
super.onBackPressed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onKeyMultiple(final int inKeyCode, int repeatCount, KeyEvent event) {
|
||||||
|
if (godotFragment != null && godotFragment.onKeyMultiple(inKeyCode, repeatCount, event)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return super.onKeyMultiple(inKeyCode, repeatCount, event);
|
||||||
|
}
|
||||||
|
}
|
|
@ -30,6 +30,9 @@
|
||||||
|
|
||||||
package org.godotengine.godot;
|
package org.godotengine.godot;
|
||||||
|
|
||||||
|
import static android.content.Context.MODE_PRIVATE;
|
||||||
|
import static android.content.Context.WINDOW_SERVICE;
|
||||||
|
|
||||||
import org.godotengine.godot.input.GodotEditText;
|
import org.godotengine.godot.input.GodotEditText;
|
||||||
import org.godotengine.godot.plugin.GodotPlugin;
|
import org.godotengine.godot.plugin.GodotPlugin;
|
||||||
import org.godotengine.godot.plugin.GodotPluginRegistry;
|
import org.godotengine.godot.plugin.GodotPluginRegistry;
|
||||||
|
@ -70,6 +73,7 @@ import android.os.Vibrator;
|
||||||
import android.provider.Settings.Secure;
|
import android.provider.Settings.Secure;
|
||||||
import android.view.Display;
|
import android.view.Display;
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
import android.view.Surface;
|
import android.view.Surface;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
@ -87,7 +91,7 @@ import androidx.annotation.CallSuper;
|
||||||
import androidx.annotation.Keep;
|
import androidx.annotation.Keep;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.fragment.app.FragmentActivity;
|
import androidx.fragment.app.Fragment;
|
||||||
|
|
||||||
import com.google.android.vending.expansion.downloader.DownloadProgressInfo;
|
import com.google.android.vending.expansion.downloader.DownloadProgressInfo;
|
||||||
import com.google.android.vending.expansion.downloader.DownloaderClientMarshaller;
|
import com.google.android.vending.expansion.downloader.DownloaderClientMarshaller;
|
||||||
|
@ -109,7 +113,7 @@ import java.util.Locale;
|
||||||
|
|
||||||
import javax.microedition.khronos.opengles.GL10;
|
import javax.microedition.khronos.opengles.GL10;
|
||||||
|
|
||||||
public abstract class Godot extends FragmentActivity implements SensorEventListener, IDownloaderClient {
|
public class Godot extends Fragment implements SensorEventListener, IDownloaderClient {
|
||||||
|
|
||||||
static final int MAX_SINGLETONS = 64;
|
static final int MAX_SINGLETONS = 64;
|
||||||
private IStub mDownloaderClientStub;
|
private IStub mDownloaderClientStub;
|
||||||
|
@ -142,7 +146,6 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe
|
||||||
|
|
||||||
static private Intent mCurrentIntent;
|
static private Intent mCurrentIntent;
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onNewIntent(Intent intent) {
|
public void onNewIntent(Intent intent) {
|
||||||
mCurrentIntent = intent;
|
mCurrentIntent = intent;
|
||||||
}
|
}
|
||||||
|
@ -245,6 +248,7 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe
|
||||||
private String[] command_line;
|
private String[] command_line;
|
||||||
private boolean use_apk_expansion;
|
private boolean use_apk_expansion;
|
||||||
|
|
||||||
|
private ViewGroup containerLayout;
|
||||||
public GodotView mView;
|
public GodotView mView;
|
||||||
private boolean godot_initialized = false;
|
private boolean godot_initialized = false;
|
||||||
|
|
||||||
|
@ -266,7 +270,7 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe
|
||||||
public ResultCallback result_callback;
|
public ResultCallback result_callback;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||||
if (result_callback != null) {
|
if (result_callback != null) {
|
||||||
result_callback.callback(requestCode, resultCode, data);
|
result_callback.callback(requestCode, resultCode, data);
|
||||||
result_callback = null;
|
result_callback = null;
|
||||||
|
@ -312,18 +316,18 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe
|
||||||
private void onVideoInit() {
|
private void onVideoInit() {
|
||||||
boolean use_gl3 = getGLESVersionCode() >= 0x00030000;
|
boolean use_gl3 = getGLESVersionCode() >= 0x00030000;
|
||||||
|
|
||||||
final FrameLayout layout = new FrameLayout(this);
|
final Activity activity = getActivity();
|
||||||
layout.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
|
containerLayout = new FrameLayout(activity);
|
||||||
setContentView(layout);
|
containerLayout.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
|
||||||
|
|
||||||
// GodotEditText layout
|
// GodotEditText layout
|
||||||
GodotEditText edittext = new GodotEditText(this);
|
GodotEditText edittext = new GodotEditText(activity);
|
||||||
edittext.setLayoutParams(new ViewGroup.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
|
edittext.setLayoutParams(new ViewGroup.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
|
||||||
// ...add to FrameLayout
|
// ...add to FrameLayout
|
||||||
layout.addView(edittext);
|
containerLayout.addView(edittext);
|
||||||
|
|
||||||
mView = new GodotView(this, xrMode, use_gl3, use_32_bits, use_debug_opengl);
|
mView = new GodotView(activity, this, xrMode, use_gl3, use_32_bits, use_debug_opengl);
|
||||||
layout.addView(mView, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
|
containerLayout.addView(mView, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
|
||||||
edittext.setView(mView);
|
edittext.setView(mView);
|
||||||
io.setEdit(edittext);
|
io.setEdit(edittext);
|
||||||
|
|
||||||
|
@ -331,7 +335,7 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe
|
||||||
@Override
|
@Override
|
||||||
public void onGlobalLayout() {
|
public void onGlobalLayout() {
|
||||||
Point fullSize = new Point();
|
Point fullSize = new Point();
|
||||||
getWindowManager().getDefaultDisplay().getSize(fullSize);
|
activity.getWindowManager().getDefaultDisplay().getSize(fullSize);
|
||||||
Rect gameSize = new Rect();
|
Rect gameSize = new Rect();
|
||||||
mView.getWindowVisibleDisplayFrame(gameSize);
|
mView.getWindowVisibleDisplayFrame(gameSize);
|
||||||
|
|
||||||
|
@ -359,9 +363,9 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe
|
||||||
public void run() {
|
public void run() {
|
||||||
// Include the non-null views returned in the Godot view hierarchy.
|
// Include the non-null views returned in the Godot view hierarchy.
|
||||||
for (int i = 0; i < singleton_count; i++) {
|
for (int i = 0; i < singleton_count; i++) {
|
||||||
View view = singletons[i].onMainCreateView(Godot.this);
|
View view = singletons[i].onMainCreateView(activity);
|
||||||
if (view != null) {
|
if (view != null) {
|
||||||
layout.addView(view);
|
containerLayout.addView(view);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -371,9 +375,9 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe
|
||||||
|
|
||||||
// Include the returned non-null views in the Godot view hierarchy.
|
// Include the returned non-null views in the Godot view hierarchy.
|
||||||
for (GodotPlugin plugin : pluginRegistry.getAllPlugins()) {
|
for (GodotPlugin plugin : pluginRegistry.getAllPlugins()) {
|
||||||
View pluginView = plugin.onMainCreate(this);
|
View pluginView = plugin.onMainCreate(activity);
|
||||||
if (pluginView != null) {
|
if (pluginView != null) {
|
||||||
layout.addView(pluginView);
|
containerLayout.addView(pluginView);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -383,9 +387,9 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
if (p_enabled) {
|
if (p_enabled) {
|
||||||
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
getActivity().getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
||||||
} else {
|
} else {
|
||||||
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -399,7 +403,7 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe
|
||||||
@Keep
|
@Keep
|
||||||
private void vibrate(int durationMs) {
|
private void vibrate(int durationMs) {
|
||||||
if (requestPermission("VIBRATE")) {
|
if (requestPermission("VIBRATE")) {
|
||||||
Vibrator v = (Vibrator)getSystemService(Context.VIBRATOR_SERVICE);
|
Vibrator v = (Vibrator)getContext().getSystemService(Context.VIBRATOR_SERVICE);
|
||||||
if (v != null) {
|
if (v != null) {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
v.vibrate(VibrationEffect.createOneShot(durationMs, VibrationEffect.DEFAULT_AMPLITUDE));
|
v.vibrate(VibrationEffect.createOneShot(durationMs, VibrationEffect.DEFAULT_AMPLITUDE));
|
||||||
|
@ -423,13 +427,16 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe
|
||||||
// Using instrumentation is a way of making the whole app process restart, because Android
|
// Using instrumentation is a way of making the whole app process restart, because Android
|
||||||
// will kill any process of the same package which was already running.
|
// will kill any process of the same package which was already running.
|
||||||
//
|
//
|
||||||
|
final Activity activity = getActivity();
|
||||||
|
if (activity != null) {
|
||||||
Bundle args = new Bundle();
|
Bundle args = new Bundle();
|
||||||
args.putParcelable("intent", mCurrentIntent);
|
args.putParcelable("intent", mCurrentIntent);
|
||||||
startInstrumentation(new ComponentName(this, GodotInstrumentation.class), null, args);
|
activity.startInstrumentation(new ComponentName(activity, GodotInstrumentation.class), null, args);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void alert(final String message, final String title) {
|
public void alert(final String message, final String title) {
|
||||||
final Activity activity = this;
|
final Activity activity = getActivity();
|
||||||
runOnUiThread(new Runnable() {
|
runOnUiThread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
@ -449,7 +456,7 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getGLESVersionCode() {
|
public int getGLESVersionCode() {
|
||||||
ActivityManager am = (ActivityManager)this.getSystemService(Context.ACTIVITY_SERVICE);
|
ActivityManager am = (ActivityManager)getContext().getSystemService(Context.ACTIVITY_SERVICE);
|
||||||
ConfigurationInfo deviceInfo = am.getDeviceConfigurationInfo();
|
ConfigurationInfo deviceInfo = am.getDeviceConfigurationInfo();
|
||||||
return deviceInfo.reqGlEsVersion;
|
return deviceInfo.reqGlEsVersion;
|
||||||
}
|
}
|
||||||
|
@ -458,7 +465,7 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe
|
||||||
protected String[] getCommandLine() {
|
protected String[] getCommandLine() {
|
||||||
InputStream is;
|
InputStream is;
|
||||||
try {
|
try {
|
||||||
is = getAssets().open("_cl_");
|
is = getActivity().getAssets().open("_cl_");
|
||||||
byte[] len = new byte[4];
|
byte[] len = new byte[4];
|
||||||
int r = is.read(len);
|
int r = is.read(len);
|
||||||
if (r < 4) {
|
if (r < 4) {
|
||||||
|
@ -538,11 +545,12 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe
|
||||||
command_line = new_cmdline;
|
command_line = new_cmdline;
|
||||||
}
|
}
|
||||||
|
|
||||||
io = new GodotIO(this);
|
final Activity activity = getActivity();
|
||||||
io.unique_id = Secure.getString(getContentResolver(), Secure.ANDROID_ID);
|
io = new GodotIO(activity);
|
||||||
|
io.unique_id = Secure.getString(activity.getContentResolver(), Secure.ANDROID_ID);
|
||||||
GodotLib.io = io;
|
GodotLib.io = io;
|
||||||
netUtils = new GodotNetUtils(this);
|
netUtils = new GodotNetUtils(activity);
|
||||||
mSensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE);
|
mSensorManager = (SensorManager)activity.getSystemService(Context.SENSOR_SERVICE);
|
||||||
mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
|
mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
|
||||||
mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_GAME);
|
mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_GAME);
|
||||||
mGravity = mSensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY);
|
mGravity = mSensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY);
|
||||||
|
@ -552,7 +560,7 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe
|
||||||
mGyroscope = mSensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE);
|
mGyroscope = mSensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE);
|
||||||
mSensorManager.registerListener(this, mGyroscope, SensorManager.SENSOR_DELAY_GAME);
|
mSensorManager.registerListener(this, mGyroscope, SensorManager.SENSOR_DELAY_GAME);
|
||||||
|
|
||||||
GodotLib.initialize(this, getAssets(), use_apk_expansion);
|
GodotLib.initialize(activity, this, activity.getAssets(), use_apk_expansion);
|
||||||
|
|
||||||
result_callback = null;
|
result_callback = null;
|
||||||
|
|
||||||
|
@ -566,16 +574,14 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle icicle) {
|
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle icicle) {
|
||||||
|
final Activity activity = getActivity();
|
||||||
super.onCreate(icicle);
|
Window window = activity.getWindow();
|
||||||
Window window = getWindow();
|
|
||||||
window.addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
|
window.addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
|
||||||
mClipboard = (ClipboardManager)getSystemService(Context.CLIPBOARD_SERVICE);
|
mClipboard = (ClipboardManager)activity.getSystemService(Context.CLIPBOARD_SERVICE);
|
||||||
pluginRegistry = GodotPluginRegistry.initializePluginRegistry(this);
|
pluginRegistry = GodotPluginRegistry.initializePluginRegistry(this);
|
||||||
|
|
||||||
//check for apk expansion API
|
//check for apk expansion API
|
||||||
if (true) {
|
|
||||||
boolean md5mismatch = false;
|
boolean md5mismatch = false;
|
||||||
command_line = getCommandLine();
|
command_line = getCommandLine();
|
||||||
String main_pack_md5 = null;
|
String main_pack_md5 = null;
|
||||||
|
@ -614,7 +620,8 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe
|
||||||
i++;
|
i++;
|
||||||
} else if (has_extra && command_line[i].equals("--apk_expansion_key")) {
|
} else if (has_extra && command_line[i].equals("--apk_expansion_key")) {
|
||||||
main_pack_key = command_line[i + 1];
|
main_pack_key = command_line[i + 1];
|
||||||
SharedPreferences prefs = getSharedPreferences("app_data_keys", MODE_PRIVATE);
|
SharedPreferences prefs = activity.getSharedPreferences("app_data_keys",
|
||||||
|
MODE_PRIVATE);
|
||||||
Editor editor = prefs.edit();
|
Editor editor = prefs.edit();
|
||||||
editor.putString("store_public_key", main_pack_key);
|
editor.putString("store_public_key", main_pack_key);
|
||||||
|
|
||||||
|
@ -639,8 +646,8 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe
|
||||||
|
|
||||||
// Build the full path to the app's expansion files
|
// Build the full path to the app's expansion files
|
||||||
try {
|
try {
|
||||||
expansion_pack_path = Helpers.getSaveFilePath(getApplicationContext());
|
expansion_pack_path = Helpers.getSaveFilePath(getContext());
|
||||||
expansion_pack_path += "/main." + getPackageManager().getPackageInfo(getPackageName(), 0).versionCode + "." + this.getPackageName() + ".obb";
|
expansion_pack_path += "/main." + activity.getPackageManager().getPackageInfo(activity.getPackageName(), 0).versionCode + "." + activity.getPackageName() + ".obb";
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
@ -663,17 +670,17 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe
|
||||||
|
|
||||||
if (!pack_valid) {
|
if (!pack_valid) {
|
||||||
|
|
||||||
Intent notifierIntent = new Intent(this, this.getClass());
|
Intent notifierIntent = new Intent(activity, activity.getClass());
|
||||||
notifierIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
|
notifierIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
|
||||||
Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
||||||
|
|
||||||
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
|
PendingIntent pendingIntent = PendingIntent.getActivity(activity, 0,
|
||||||
notifierIntent, PendingIntent.FLAG_UPDATE_CURRENT);
|
notifierIntent, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||||
|
|
||||||
int startResult;
|
int startResult;
|
||||||
try {
|
try {
|
||||||
startResult = DownloaderClientMarshaller.startDownloadServiceIfRequired(
|
startResult = DownloaderClientMarshaller.startDownloadServiceIfRequired(
|
||||||
getApplicationContext(),
|
getContext(),
|
||||||
pendingIntent,
|
pendingIntent,
|
||||||
GodotDownloaderService.class);
|
GodotDownloaderService.class);
|
||||||
|
|
||||||
|
@ -683,34 +690,35 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe
|
||||||
mDownloaderClientStub = DownloaderClientMarshaller.CreateStub(this,
|
mDownloaderClientStub = DownloaderClientMarshaller.CreateStub(this,
|
||||||
GodotDownloaderService.class);
|
GodotDownloaderService.class);
|
||||||
|
|
||||||
setContentView(R.layout.downloading_expansion);
|
View downloadingExpansionView =
|
||||||
mPB = (ProgressBar)findViewById(R.id.progressBar);
|
inflater.inflate(R.layout.downloading_expansion, container, false);
|
||||||
mStatusText = (TextView)findViewById(R.id.statusText);
|
mPB = (ProgressBar)downloadingExpansionView.findViewById(R.id.progressBar);
|
||||||
mProgressFraction = (TextView)findViewById(R.id.progressAsFraction);
|
mStatusText = (TextView)downloadingExpansionView.findViewById(R.id.statusText);
|
||||||
mProgressPercent = (TextView)findViewById(R.id.progressAsPercentage);
|
mProgressFraction = (TextView)downloadingExpansionView.findViewById(R.id.progressAsFraction);
|
||||||
mAverageSpeed = (TextView)findViewById(R.id.progressAverageSpeed);
|
mProgressPercent = (TextView)downloadingExpansionView.findViewById(R.id.progressAsPercentage);
|
||||||
mTimeRemaining = (TextView)findViewById(R.id.progressTimeRemaining);
|
mAverageSpeed = (TextView)downloadingExpansionView.findViewById(R.id.progressAverageSpeed);
|
||||||
mDashboard = findViewById(R.id.downloaderDashboard);
|
mTimeRemaining = (TextView)downloadingExpansionView.findViewById(R.id.progressTimeRemaining);
|
||||||
mCellMessage = findViewById(R.id.approveCellular);
|
mDashboard = downloadingExpansionView.findViewById(R.id.downloaderDashboard);
|
||||||
mPauseButton = (Button)findViewById(R.id.pauseButton);
|
mCellMessage = downloadingExpansionView.findViewById(R.id.approveCellular);
|
||||||
mWiFiSettingsButton = (Button)findViewById(R.id.wifiSettingsButton);
|
mPauseButton = (Button)downloadingExpansionView.findViewById(R.id.pauseButton);
|
||||||
|
mWiFiSettingsButton = (Button)downloadingExpansionView.findViewById(R.id.wifiSettingsButton);
|
||||||
|
|
||||||
return;
|
return downloadingExpansionView;
|
||||||
}
|
}
|
||||||
} catch (NameNotFoundException e) {
|
} catch (NameNotFoundException e) {
|
||||||
// TODO Auto-generated catch block
|
// TODO Auto-generated catch block
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
mCurrentIntent = getIntent();
|
mCurrentIntent = activity.getIntent();
|
||||||
|
|
||||||
initializeGodot();
|
initializeGodot();
|
||||||
|
return containerLayout;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onDestroy() {
|
public void onDestroy() {
|
||||||
|
|
||||||
for (int i = 0; i < singleton_count; i++) {
|
for (int i = 0; i < singleton_count; i++) {
|
||||||
singletons[i].onMainDestroy();
|
singletons[i].onMainDestroy();
|
||||||
|
@ -719,7 +727,7 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe
|
||||||
plugin.onMainDestroy();
|
plugin.onMainDestroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
GodotLib.ondestroy(this);
|
GodotLib.ondestroy();
|
||||||
|
|
||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
|
|
||||||
|
@ -729,13 +737,13 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onPause() {
|
public void onPause() {
|
||||||
super.onPause();
|
super.onPause();
|
||||||
activityResumed = false;
|
activityResumed = false;
|
||||||
|
|
||||||
if (!godot_initialized) {
|
if (!godot_initialized) {
|
||||||
if (null != mDownloaderClientStub) {
|
if (null != mDownloaderClientStub) {
|
||||||
mDownloaderClientStub.disconnect(this);
|
mDownloaderClientStub.disconnect(getActivity());
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -770,12 +778,12 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onResume() {
|
public void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
activityResumed = true;
|
activityResumed = true;
|
||||||
if (!godot_initialized) {
|
if (!godot_initialized) {
|
||||||
if (null != mDownloaderClientStub) {
|
if (null != mDownloaderClientStub) {
|
||||||
mDownloaderClientStub.connect(this);
|
mDownloaderClientStub.connect(getActivity());
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -788,7 +796,7 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe
|
||||||
mSensorManager.registerListener(this, mGyroscope, SensorManager.SENSOR_DELAY_GAME);
|
mSensorManager.registerListener(this, mGyroscope, SensorManager.SENSOR_DELAY_GAME);
|
||||||
|
|
||||||
if (use_immersive && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { // check if the application runs on an android 4.4+
|
if (use_immersive && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { // check if the application runs on an android 4.4+
|
||||||
Window window = getWindow();
|
Window window = getActivity().getWindow();
|
||||||
window.getDecorView().setSystemUiVisibility(
|
window.getDecorView().setSystemUiVisibility(
|
||||||
View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
|
View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
|
||||||
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
|
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
|
||||||
|
@ -808,7 +816,7 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UiChangeListener() {
|
public void UiChangeListener() {
|
||||||
final View decorView = getWindow().getDecorView();
|
final View decorView = getActivity().getWindow().getDecorView();
|
||||||
decorView.setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener() {
|
decorView.setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onSystemUiVisibilityChange(int visibility) {
|
public void onSystemUiVisibilityChange(int visibility) {
|
||||||
|
@ -829,7 +837,8 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSensorChanged(SensorEvent event) {
|
public void onSensorChanged(SensorEvent event) {
|
||||||
Display display = ((WindowManager)getSystemService(WINDOW_SERVICE)).getDefaultDisplay();
|
Display display =
|
||||||
|
((WindowManager)getActivity().getSystemService(WINDOW_SERVICE)).getDefaultDisplay();
|
||||||
int displayRotation = display.getRotation();
|
int displayRotation = display.getRotation();
|
||||||
|
|
||||||
float[] adjustedValues = new float[3];
|
float[] adjustedValues = new float[3];
|
||||||
|
@ -892,7 +901,6 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onBackPressed() {
|
public void onBackPressed() {
|
||||||
boolean shouldQuit = true;
|
boolean shouldQuit = true;
|
||||||
|
|
||||||
|
@ -928,6 +936,12 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final void runOnUiThread(@NonNull Runnable action) {
|
||||||
|
if (getActivity() != null) {
|
||||||
|
getActivity().runOnUiThread(action);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void forceQuit() {
|
private void forceQuit() {
|
||||||
System.exit(0);
|
System.exit(0);
|
||||||
}
|
}
|
||||||
|
@ -1034,17 +1048,16 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onKeyMultiple(final int inKeyCode, int repeatCount, KeyEvent event) {
|
public boolean onKeyMultiple(final int inKeyCode, int repeatCount, KeyEvent event) {
|
||||||
String s = event.getCharacters();
|
String s = event.getCharacters();
|
||||||
if (s == null || s.length() == 0)
|
if (s == null || s.length() == 0)
|
||||||
return super.onKeyMultiple(inKeyCode, repeatCount, event);
|
return false;
|
||||||
|
|
||||||
final char[] cc = s.toCharArray();
|
final char[] cc = s.toCharArray();
|
||||||
int cnt = 0;
|
int cnt = 0;
|
||||||
for (int i = cc.length; --i >= 0; cnt += cc[i] != 0 ? 1 : 0)
|
for (int i = cc.length; --i >= 0; cnt += cc[i] != 0 ? 1 : 0)
|
||||||
;
|
;
|
||||||
if (cnt == 0) return super.onKeyMultiple(inKeyCode, repeatCount, event);
|
if (cnt == 0) return false;
|
||||||
mView.queueEvent(new Runnable() {
|
mView.queueEvent(new Runnable() {
|
||||||
// This method will be called on the rendering thread:
|
// This method will be called on the rendering thread:
|
||||||
public void run() {
|
public void run() {
|
||||||
|
@ -1062,15 +1075,15 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean requestPermission(String p_name) {
|
public boolean requestPermission(String p_name) {
|
||||||
return PermissionsUtil.requestPermission(p_name, this);
|
return PermissionsUtil.requestPermission(p_name, getActivity());
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean requestPermissions() {
|
public boolean requestPermissions() {
|
||||||
return PermissionsUtil.requestManifestPermissions(this);
|
return PermissionsUtil.requestManifestPermissions(getActivity());
|
||||||
}
|
}
|
||||||
|
|
||||||
public String[] getGrantedPermissions() {
|
public String[] getGrantedPermissions() {
|
||||||
return PermissionsUtil.getGrantedPermissions(this);
|
return PermissionsUtil.getGrantedPermissions(getActivity());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -32,6 +32,7 @@ package org.godotengine.godot;
|
||||||
|
|
||||||
import org.godotengine.godot.input.*;
|
import org.godotengine.godot.input.*;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
import android.content.*;
|
import android.content.*;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.pm.ActivityInfo;
|
import android.content.pm.ActivityInfo;
|
||||||
|
@ -52,7 +53,7 @@ import java.util.Locale;
|
||||||
public class GodotIO {
|
public class GodotIO {
|
||||||
|
|
||||||
AssetManager am;
|
AssetManager am;
|
||||||
Godot activity;
|
final Activity activity;
|
||||||
GodotEditText edit;
|
GodotEditText edit;
|
||||||
|
|
||||||
MediaPlayer mediaPlayer;
|
MediaPlayer mediaPlayer;
|
||||||
|
@ -340,7 +341,7 @@ public class GodotIO {
|
||||||
dirs.remove(id);
|
dirs.remove(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
GodotIO(Godot p_activity) {
|
GodotIO(Activity p_activity) {
|
||||||
|
|
||||||
am = p_activity.getAssets();
|
am = p_activity.getAssets();
|
||||||
activity = p_activity;
|
activity = p_activity;
|
||||||
|
|
|
@ -50,13 +50,13 @@ public class GodotLib {
|
||||||
/**
|
/**
|
||||||
* Invoked on the main thread to initialize Godot native layer.
|
* Invoked on the main thread to initialize Godot native layer.
|
||||||
*/
|
*/
|
||||||
public static native void initialize(Godot p_instance, Object p_asset_manager, boolean use_apk_expansion);
|
public static native void initialize(Activity activity, Godot p_instance, Object p_asset_manager, boolean use_apk_expansion);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invoked on the main thread to clean up Godot native layer.
|
* Invoked on the main thread to clean up Godot native layer.
|
||||||
* @see Activity#onDestroy()
|
* @see androidx.fragment.app.Fragment#onDestroy()
|
||||||
*/
|
*/
|
||||||
public static native void ondestroy(Godot p_instance);
|
public static native void ondestroy();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invoked on the GL thread to complete setup for the Godot native layer logic.
|
* Invoked on the GL thread to complete setup for the Godot native layer logic.
|
||||||
|
@ -160,14 +160,14 @@ public class GodotLib {
|
||||||
public static native void joyconnectionchanged(int p_device, boolean p_connected, String p_name);
|
public static native void joyconnectionchanged(int p_device, boolean p_connected, String p_name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invoked when the Android activity resumes.
|
* Invoked when the Android app resumes.
|
||||||
* @see Activity#onResume()
|
* @see androidx.fragment.app.Fragment#onResume()
|
||||||
*/
|
*/
|
||||||
public static native void focusin();
|
public static native void focusin();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invoked when the Android activity pauses.
|
* Invoked when the Android app pauses.
|
||||||
* @see Activity#onPause()
|
* @see androidx.fragment.app.Fragment#onPause()
|
||||||
*/
|
*/
|
||||||
public static native void focusout();
|
public static native void focusout();
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,7 @@ import org.godotengine.godot.xr.regular.RegularContextFactory;
|
||||||
import org.godotengine.godot.xr.regular.RegularFallbackConfigChooser;
|
import org.godotengine.godot.xr.regular.RegularFallbackConfigChooser;
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
|
import android.content.Context;
|
||||||
import android.graphics.PixelFormat;
|
import android.graphics.PixelFormat;
|
||||||
import android.opengl.GLSurfaceView;
|
import android.opengl.GLSurfaceView;
|
||||||
import android.view.GestureDetector;
|
import android.view.GestureDetector;
|
||||||
|
@ -70,20 +71,21 @@ public class GodotView extends GLSurfaceView {
|
||||||
|
|
||||||
private static String TAG = GodotView.class.getSimpleName();
|
private static String TAG = GodotView.class.getSimpleName();
|
||||||
|
|
||||||
private final Godot activity;
|
private final Godot godot;
|
||||||
private final GodotInputHandler inputHandler;
|
private final GodotInputHandler inputHandler;
|
||||||
private final GestureDetector detector;
|
private final GestureDetector detector;
|
||||||
private final GodotRenderer godotRenderer;
|
private final GodotRenderer godotRenderer;
|
||||||
|
|
||||||
public GodotView(Godot activity, XRMode xrMode, boolean p_use_gl3, boolean p_use_32_bits, boolean p_use_debug_opengl) {
|
public GodotView(Context context, Godot godot, XRMode xrMode, boolean p_use_gl3,
|
||||||
super(activity);
|
boolean p_use_32_bits, boolean p_use_debug_opengl) {
|
||||||
|
super(context);
|
||||||
GLUtils.use_gl3 = p_use_gl3;
|
GLUtils.use_gl3 = p_use_gl3;
|
||||||
GLUtils.use_32 = p_use_32_bits;
|
GLUtils.use_32 = p_use_32_bits;
|
||||||
GLUtils.use_debug_opengl = p_use_debug_opengl;
|
GLUtils.use_debug_opengl = p_use_debug_opengl;
|
||||||
|
|
||||||
this.activity = activity;
|
this.godot = godot;
|
||||||
this.inputHandler = new GodotInputHandler(this);
|
this.inputHandler = new GodotInputHandler(this);
|
||||||
this.detector = new GestureDetector(activity, new GodotGestureHandler(this));
|
this.detector = new GestureDetector(context, new GodotGestureHandler(this));
|
||||||
this.godotRenderer = new GodotRenderer();
|
this.godotRenderer = new GodotRenderer();
|
||||||
init(xrMode, false, 16, 0);
|
init(xrMode, false, 16, 0);
|
||||||
}
|
}
|
||||||
|
@ -97,7 +99,7 @@ public class GodotView extends GLSurfaceView {
|
||||||
public boolean onTouchEvent(MotionEvent event) {
|
public boolean onTouchEvent(MotionEvent event) {
|
||||||
super.onTouchEvent(event);
|
super.onTouchEvent(event);
|
||||||
this.detector.onTouchEvent(event);
|
this.detector.onTouchEvent(event);
|
||||||
return activity.gotTouchEvent(event);
|
return godot.gotTouchEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -174,7 +176,7 @@ public class GodotView extends GLSurfaceView {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onBackPressed() {
|
public void onBackPressed() {
|
||||||
activity.onBackPressed();
|
godot.onBackPressed();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -98,7 +98,7 @@ public abstract class GodotPlugin {
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
protected Activity getActivity() {
|
protected Activity getActivity() {
|
||||||
return godot;
|
return godot.getActivity();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -32,6 +32,7 @@ package org.godotengine.godot.plugin;
|
||||||
|
|
||||||
import org.godotengine.godot.Godot;
|
import org.godotengine.godot.Godot;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
import android.content.pm.ApplicationInfo;
|
import android.content.pm.ApplicationInfo;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
@ -122,9 +123,11 @@ public final class GodotPluginRegistry {
|
||||||
|
|
||||||
private void loadPlugins(Godot godot) {
|
private void loadPlugins(Godot godot) {
|
||||||
try {
|
try {
|
||||||
ApplicationInfo appInfo = godot
|
final Activity activity = godot.getActivity();
|
||||||
|
ApplicationInfo appInfo = activity
|
||||||
.getPackageManager()
|
.getPackageManager()
|
||||||
.getApplicationInfo(godot.getPackageName(), PackageManager.GET_META_DATA);
|
.getApplicationInfo(activity.getPackageName(),
|
||||||
|
PackageManager.GET_META_DATA);
|
||||||
Bundle metaData = appInfo.metaData;
|
Bundle metaData = appInfo.metaData;
|
||||||
if (metaData == null || metaData.isEmpty()) {
|
if (metaData == null || metaData.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -30,8 +30,7 @@
|
||||||
|
|
||||||
package org.godotengine.godot.utils;
|
package org.godotengine.godot.utils;
|
||||||
|
|
||||||
import org.godotengine.godot.Godot;
|
import android.app.Activity;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.net.wifi.WifiManager;
|
import android.net.wifi.WifiManager;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
@ -46,7 +45,7 @@ public class GodotNetUtils {
|
||||||
/* A single, reference counted, multicast lock, or null if permission CHANGE_WIFI_MULTICAST_STATE is missing */
|
/* A single, reference counted, multicast lock, or null if permission CHANGE_WIFI_MULTICAST_STATE is missing */
|
||||||
private WifiManager.MulticastLock multicastLock;
|
private WifiManager.MulticastLock multicastLock;
|
||||||
|
|
||||||
public GodotNetUtils(Godot p_activity) {
|
public GodotNetUtils(Activity p_activity) {
|
||||||
if (PermissionsUtil.hasManifestPermission(p_activity, "android.permission.CHANGE_WIFI_MULTICAST_STATE")) {
|
if (PermissionsUtil.hasManifestPermission(p_activity, "android.permission.CHANGE_WIFI_MULTICAST_STATE")) {
|
||||||
WifiManager wifi = (WifiManager)p_activity.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
|
WifiManager wifi = (WifiManager)p_activity.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
|
||||||
multicastLock = wifi.createMulticastLock("GodotMulticastLock");
|
multicastLock = wifi.createMulticastLock("GodotMulticastLock");
|
||||||
|
|
|
@ -30,9 +30,8 @@
|
||||||
|
|
||||||
package org.godotengine.godot.utils;
|
package org.godotengine.godot.utils;
|
||||||
|
|
||||||
import org.godotengine.godot.Godot;
|
|
||||||
|
|
||||||
import android.Manifest;
|
import android.Manifest;
|
||||||
|
import android.app.Activity;
|
||||||
import android.content.pm.PackageInfo;
|
import android.content.pm.PackageInfo;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.content.pm.PermissionInfo;
|
import android.content.pm.PermissionInfo;
|
||||||
|
@ -66,7 +65,7 @@ public final class PermissionsUtil {
|
||||||
* @param activity the caller activity for this method.
|
* @param activity the caller activity for this method.
|
||||||
* @return true/false. "true" if permission was granted otherwise returns "false".
|
* @return true/false. "true" if permission was granted otherwise returns "false".
|
||||||
*/
|
*/
|
||||||
public static boolean requestPermission(String name, Godot activity) {
|
public static boolean requestPermission(String name, Activity activity) {
|
||||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
|
||||||
// Not necessary, asked on install already
|
// Not necessary, asked on install already
|
||||||
return true;
|
return true;
|
||||||
|
@ -94,7 +93,7 @@ public final class PermissionsUtil {
|
||||||
* @param activity the caller activity for this method.
|
* @param activity the caller activity for this method.
|
||||||
* @return true/false. "true" if all permissions were granted otherwise returns "false".
|
* @return true/false. "true" if all permissions were granted otherwise returns "false".
|
||||||
*/
|
*/
|
||||||
public static boolean requestManifestPermissions(Godot activity) {
|
public static boolean requestManifestPermissions(Activity activity) {
|
||||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -139,7 +138,7 @@ public final class PermissionsUtil {
|
||||||
* @param activity the caller activity for this method.
|
* @param activity the caller activity for this method.
|
||||||
* @return granted permissions list
|
* @return granted permissions list
|
||||||
*/
|
*/
|
||||||
public static String[] getGrantedPermissions(Godot activity) {
|
public static String[] getGrantedPermissions(Activity activity) {
|
||||||
String[] manifestPermissions;
|
String[] manifestPermissions;
|
||||||
try {
|
try {
|
||||||
manifestPermissions = getManifestPermissions(activity);
|
manifestPermissions = getManifestPermissions(activity);
|
||||||
|
@ -173,7 +172,7 @@ public final class PermissionsUtil {
|
||||||
* @param permission the permession to look for in the manifest file.
|
* @param permission the permession to look for in the manifest file.
|
||||||
* @return "true" if the permission is in the manifest file of the activity, "false" otherwise.
|
* @return "true" if the permission is in the manifest file of the activity, "false" otherwise.
|
||||||
*/
|
*/
|
||||||
public static boolean hasManifestPermission(Godot activity, String permission) {
|
public static boolean hasManifestPermission(Activity activity, String permission) {
|
||||||
try {
|
try {
|
||||||
for (String p : getManifestPermissions(activity)) {
|
for (String p : getManifestPermissions(activity)) {
|
||||||
if (permission.equals(p))
|
if (permission.equals(p))
|
||||||
|
@ -191,7 +190,7 @@ public final class PermissionsUtil {
|
||||||
* @return manifest permissions list
|
* @return manifest permissions list
|
||||||
* @throws PackageManager.NameNotFoundException the exception is thrown when a given package, application, or component name cannot be found.
|
* @throws PackageManager.NameNotFoundException the exception is thrown when a given package, application, or component name cannot be found.
|
||||||
*/
|
*/
|
||||||
private static String[] getManifestPermissions(Godot activity) throws PackageManager.NameNotFoundException {
|
private static String[] getManifestPermissions(Activity activity) throws PackageManager.NameNotFoundException {
|
||||||
PackageManager packageManager = activity.getPackageManager();
|
PackageManager packageManager = activity.getPackageManager();
|
||||||
PackageInfo packageInfo = packageManager.getPackageInfo(activity.getPackageName(), PackageManager.GET_PERMISSIONS);
|
PackageInfo packageInfo = packageManager.getPackageInfo(activity.getPackageName(), PackageManager.GET_PERMISSIONS);
|
||||||
if (packageInfo.requestedPermissions == null)
|
if (packageInfo.requestedPermissions == null)
|
||||||
|
@ -206,7 +205,7 @@ public final class PermissionsUtil {
|
||||||
* @return permission info object
|
* @return permission info object
|
||||||
* @throws PackageManager.NameNotFoundException the exception is thrown when a given package, application, or component name cannot be found.
|
* @throws PackageManager.NameNotFoundException the exception is thrown when a given package, application, or component name cannot be found.
|
||||||
*/
|
*/
|
||||||
private static PermissionInfo getPermissionInfo(Godot activity, String permission) throws PackageManager.NameNotFoundException {
|
private static PermissionInfo getPermissionInfo(Activity activity, String permission) throws PackageManager.NameNotFoundException {
|
||||||
PackageManager packageManager = activity.getPackageManager();
|
PackageManager packageManager = activity.getPackageManager();
|
||||||
return packageManager.getPermissionInfo(permission, 0);
|
return packageManager.getPermissionInfo(permission, 0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1244,7 +1244,7 @@ JavaClassWrapper::JavaClassWrapper(jobject p_activity) {
|
||||||
|
|
||||||
JNIEnv *env = ThreadAndroid::get_env();
|
JNIEnv *env = ThreadAndroid::get_env();
|
||||||
|
|
||||||
jclass activityClass = env->FindClass("org/godotengine/godot/Godot");
|
jclass activityClass = env->FindClass("android/app/Activity");
|
||||||
jmethodID getClassLoader = env->GetMethodID(activityClass, "getClassLoader", "()Ljava/lang/ClassLoader;");
|
jmethodID getClassLoader = env->GetMethodID(activityClass, "getClassLoader", "()Ljava/lang/ClassLoader;");
|
||||||
classLoader = env->CallObjectMethod(p_activity, getClassLoader);
|
classLoader = env->CallObjectMethod(p_activity, getClassLoader);
|
||||||
classLoader = (jclass)env->NewGlobalRef(classLoader);
|
classLoader = (jclass)env->NewGlobalRef(classLoader);
|
||||||
|
|
|
@ -120,7 +120,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_setVirtualKeyboardHei
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *env, jclass clazz, jobject activity, jobject p_asset_manager, jboolean p_use_apk_expansion) {
|
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *env, jclass clazz, jobject activity, jobject godot_instance, jobject p_asset_manager, jboolean p_use_apk_expansion) {
|
||||||
|
|
||||||
initialized = true;
|
initialized = true;
|
||||||
|
|
||||||
|
@ -128,7 +128,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *en
|
||||||
env->GetJavaVM(&jvm);
|
env->GetJavaVM(&jvm);
|
||||||
|
|
||||||
// create our wrapper classes
|
// create our wrapper classes
|
||||||
godot_java = new GodotJavaWrapper(env, activity); // our activity is our godot instance is our activity..
|
godot_java = new GodotJavaWrapper(env, activity, godot_instance);
|
||||||
godot_io_java = new GodotIOJavaWrapper(env, godot_java->get_member_object("io", "Lorg/godotengine/godot/GodotIO;", env));
|
godot_io_java = new GodotIOJavaWrapper(env, godot_java->get_member_object("io", "Lorg/godotengine/godot/GodotIO;", env));
|
||||||
|
|
||||||
ThreadAndroid::make_default(jvm);
|
ThreadAndroid::make_default(jvm);
|
||||||
|
@ -153,7 +153,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *en
|
||||||
godot_java->on_video_init(env);
|
godot_java->on_video_init(env);
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_ondestroy(JNIEnv *env, jclass clazz, jobject activity) {
|
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_ondestroy(JNIEnv *env, jclass clazz) {
|
||||||
// lets cleanup
|
// lets cleanup
|
||||||
if (godot_io_java) {
|
if (godot_io_java) {
|
||||||
delete godot_io_java;
|
delete godot_io_java;
|
||||||
|
|
|
@ -37,8 +37,8 @@
|
||||||
// These functions can be called from within JAVA and are the means by which our JAVA implementation calls back into our C++ code.
|
// These functions can be called from within JAVA and are the means by which our JAVA implementation calls back into our C++ code.
|
||||||
// See java/src/org/godotengine/godot/GodotLib.java for the JAVA side of this (yes that's why we have the long names)
|
// See java/src/org/godotengine/godot/GodotLib.java for the JAVA side of this (yes that's why we have the long names)
|
||||||
extern "C" {
|
extern "C" {
|
||||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *env, jclass clazz, jobject activity, jobject p_asset_manager, jboolean p_use_apk_expansion);
|
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *env, jclass clazz, jobject activity, jobject godot_instance, jobject p_asset_manager, jboolean p_use_apk_expansion);
|
||||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_ondestroy(JNIEnv *env, jclass clazz, jobject activity);
|
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_ondestroy(JNIEnv *env, jclass clazz);
|
||||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_setup(JNIEnv *env, jclass clazz, jobjectArray p_cmdline);
|
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_setup(JNIEnv *env, jclass clazz, jobjectArray p_cmdline);
|
||||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_resize(JNIEnv *env, jclass clazz, jint width, jint height);
|
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_resize(JNIEnv *env, jclass clazz, jint width, jint height);
|
||||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_newcontext(JNIEnv *env, jclass clazz, jboolean p_32_bits);
|
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_newcontext(JNIEnv *env, jclass clazz, jboolean p_32_bits);
|
||||||
|
|
|
@ -37,36 +37,47 @@
|
||||||
|
|
||||||
// TODO we could probably create a base class for this...
|
// TODO we could probably create a base class for this...
|
||||||
|
|
||||||
GodotJavaWrapper::GodotJavaWrapper(JNIEnv *p_env, jobject p_godot_instance) {
|
GodotJavaWrapper::GodotJavaWrapper(JNIEnv *p_env, jobject p_activity, jobject p_godot_instance) {
|
||||||
godot_instance = p_env->NewGlobalRef(p_godot_instance);
|
godot_instance = p_env->NewGlobalRef(p_godot_instance);
|
||||||
|
activity = p_env->NewGlobalRef(p_activity);
|
||||||
|
|
||||||
// get info about our Godot class so we can get pointers and stuff...
|
// get info about our Godot class so we can get pointers and stuff...
|
||||||
cls = p_env->FindClass("org/godotengine/godot/Godot");
|
godot_class = p_env->FindClass("org/godotengine/godot/Godot");
|
||||||
if (cls) {
|
if (godot_class) {
|
||||||
cls = (jclass)p_env->NewGlobalRef(cls);
|
godot_class = (jclass)p_env->NewGlobalRef(godot_class);
|
||||||
|
} else {
|
||||||
|
// this is a pretty serious fail.. bail... pointers will stay 0
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
activity_class = p_env->FindClass("android/app/Activity");
|
||||||
|
if (activity_class) {
|
||||||
|
activity_class = (jclass)p_env->NewGlobalRef(activity_class);
|
||||||
} else {
|
} else {
|
||||||
// this is a pretty serious fail.. bail... pointers will stay 0
|
// this is a pretty serious fail.. bail... pointers will stay 0
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// get some method pointers...
|
// get some Godot method pointers...
|
||||||
_on_video_init = p_env->GetMethodID(cls, "onVideoInit", "()V");
|
_on_video_init = p_env->GetMethodID(godot_class, "onVideoInit", "()V");
|
||||||
_restart = p_env->GetMethodID(cls, "restart", "()V");
|
_restart = p_env->GetMethodID(godot_class, "restart", "()V");
|
||||||
_finish = p_env->GetMethodID(cls, "forceQuit", "()V");
|
_finish = p_env->GetMethodID(godot_class, "forceQuit", "()V");
|
||||||
_set_keep_screen_on = p_env->GetMethodID(cls, "setKeepScreenOn", "(Z)V");
|
_set_keep_screen_on = p_env->GetMethodID(godot_class, "setKeepScreenOn", "(Z)V");
|
||||||
_alert = p_env->GetMethodID(cls, "alert", "(Ljava/lang/String;Ljava/lang/String;)V");
|
_alert = p_env->GetMethodID(godot_class, "alert", "(Ljava/lang/String;Ljava/lang/String;)V");
|
||||||
_get_GLES_version_code = p_env->GetMethodID(cls, "getGLESVersionCode", "()I");
|
_get_GLES_version_code = p_env->GetMethodID(godot_class, "getGLESVersionCode", "()I");
|
||||||
_get_clipboard = p_env->GetMethodID(cls, "getClipboard", "()Ljava/lang/String;");
|
_get_clipboard = p_env->GetMethodID(godot_class, "getClipboard", "()Ljava/lang/String;");
|
||||||
_set_clipboard = p_env->GetMethodID(cls, "setClipboard", "(Ljava/lang/String;)V");
|
_set_clipboard = p_env->GetMethodID(godot_class, "setClipboard", "(Ljava/lang/String;)V");
|
||||||
_request_permission = p_env->GetMethodID(cls, "requestPermission", "(Ljava/lang/String;)Z");
|
_request_permission = p_env->GetMethodID(godot_class, "requestPermission", "(Ljava/lang/String;)Z");
|
||||||
_request_permissions = p_env->GetMethodID(cls, "requestPermissions", "()Z");
|
_request_permissions = p_env->GetMethodID(godot_class, "requestPermissions", "()Z");
|
||||||
_get_granted_permissions = p_env->GetMethodID(cls, "getGrantedPermissions", "()[Ljava/lang/String;");
|
_get_granted_permissions = p_env->GetMethodID(godot_class, "getGrantedPermissions", "()[Ljava/lang/String;");
|
||||||
_init_input_devices = p_env->GetMethodID(cls, "initInputDevices", "()V");
|
_init_input_devices = p_env->GetMethodID(godot_class, "initInputDevices", "()V");
|
||||||
_get_surface = p_env->GetMethodID(cls, "getSurface", "()Landroid/view/Surface;");
|
_get_surface = p_env->GetMethodID(godot_class, "getSurface", "()Landroid/view/Surface;");
|
||||||
_is_activity_resumed = p_env->GetMethodID(cls, "isActivityResumed", "()Z");
|
_is_activity_resumed = p_env->GetMethodID(godot_class, "isActivityResumed", "()Z");
|
||||||
_vibrate = p_env->GetMethodID(cls, "vibrate", "(I)V");
|
_vibrate = p_env->GetMethodID(godot_class, "vibrate", "(I)V");
|
||||||
_get_input_fallback_mapping = p_env->GetMethodID(cls, "getInputFallbackMapping", "()Ljava/lang/String;");
|
_get_input_fallback_mapping = p_env->GetMethodID(godot_class, "getInputFallbackMapping", "()Ljava/lang/String;");
|
||||||
_on_godot_main_loop_started = p_env->GetMethodID(cls, "onGodotMainLoopStarted", "()V");
|
_on_godot_main_loop_started = p_env->GetMethodID(godot_class, "onGodotMainLoopStarted", "()V");
|
||||||
|
|
||||||
|
// get some Activity method pointers...
|
||||||
|
_get_class_loader = p_env->GetMethodID(activity_class, "getClassLoader", "()Ljava/lang/ClassLoader;");
|
||||||
}
|
}
|
||||||
|
|
||||||
GodotJavaWrapper::~GodotJavaWrapper() {
|
GodotJavaWrapper::~GodotJavaWrapper() {
|
||||||
|
@ -74,27 +85,25 @@ GodotJavaWrapper::~GodotJavaWrapper() {
|
||||||
}
|
}
|
||||||
|
|
||||||
jobject GodotJavaWrapper::get_activity() {
|
jobject GodotJavaWrapper::get_activity() {
|
||||||
// our godot instance is our activity
|
return activity;
|
||||||
return godot_instance;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
jobject GodotJavaWrapper::get_member_object(const char *p_name, const char *p_class, JNIEnv *p_env) {
|
jobject GodotJavaWrapper::get_member_object(const char *p_name, const char *p_class, JNIEnv *p_env) {
|
||||||
if (cls) {
|
if (godot_class) {
|
||||||
if (p_env == NULL)
|
if (p_env == NULL)
|
||||||
p_env = ThreadAndroid::get_env();
|
p_env = ThreadAndroid::get_env();
|
||||||
|
|
||||||
jfieldID fid = p_env->GetStaticFieldID(cls, p_name, p_class);
|
jfieldID fid = p_env->GetStaticFieldID(godot_class, p_name, p_class);
|
||||||
return p_env->GetStaticObjectField(cls, fid);
|
return p_env->GetStaticObjectField(godot_class, fid);
|
||||||
} else {
|
} else {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
jobject GodotJavaWrapper::get_class_loader() {
|
jobject GodotJavaWrapper::get_class_loader() {
|
||||||
if (cls) {
|
if (_get_class_loader) {
|
||||||
JNIEnv *env = ThreadAndroid::get_env();
|
JNIEnv *env = ThreadAndroid::get_env();
|
||||||
jmethodID getClassLoader = env->GetMethodID(cls, "getClassLoader", "()Ljava/lang/ClassLoader;");
|
return env->CallObjectMethod(godot_instance, _get_class_loader);
|
||||||
return env->CallObjectMethod(godot_instance, getClassLoader);
|
|
||||||
} else {
|
} else {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,9 @@
|
||||||
class GodotJavaWrapper {
|
class GodotJavaWrapper {
|
||||||
private:
|
private:
|
||||||
jobject godot_instance;
|
jobject godot_instance;
|
||||||
jclass cls;
|
jobject activity;
|
||||||
|
jclass godot_class;
|
||||||
|
jclass activity_class;
|
||||||
|
|
||||||
jmethodID _on_video_init = 0;
|
jmethodID _on_video_init = 0;
|
||||||
jmethodID _restart = 0;
|
jmethodID _restart = 0;
|
||||||
|
@ -62,9 +64,10 @@ private:
|
||||||
jmethodID _vibrate = 0;
|
jmethodID _vibrate = 0;
|
||||||
jmethodID _get_input_fallback_mapping = 0;
|
jmethodID _get_input_fallback_mapping = 0;
|
||||||
jmethodID _on_godot_main_loop_started = 0;
|
jmethodID _on_godot_main_loop_started = 0;
|
||||||
|
jmethodID _get_class_loader = 0;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GodotJavaWrapper(JNIEnv *p_env, jobject p_godot_instance);
|
GodotJavaWrapper(JNIEnv *p_env, jobject p_activity, jobject p_godot_instance);
|
||||||
~GodotJavaWrapper();
|
~GodotJavaWrapper();
|
||||||
|
|
||||||
jobject get_activity();
|
jobject get_activity();
|
||||||
|
|
Loading…
Reference in New Issue