mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-16 02:38:02 +00:00
Fix so Android app is fully closed when exiting
This commit is contained in:
1
.gitattributes
vendored
1
.gitattributes
vendored
@@ -690,6 +690,7 @@ forge-gui-android/res/drawable-xhdpi/ic_launcher.png -text
|
|||||||
forge-gui-android/res/drawable-xxhdpi/ic_launcher.png -text
|
forge-gui-android/res/drawable-xxhdpi/ic_launcher.png -text
|
||||||
forge-gui-android/res/layout/main.xml -text
|
forge-gui-android/res/layout/main.xml -text
|
||||||
forge-gui-android/res/values/strings.xml -text
|
forge-gui-android/res/values/strings.xml -text
|
||||||
|
forge-gui-android/src/forge/app/Exiter.java -text
|
||||||
forge-gui-android/src/forge/app/Main.java -text
|
forge-gui-android/src/forge/app/Main.java -text
|
||||||
forge-gui-desktop/.classpath -text
|
forge-gui-desktop/.classpath -text
|
||||||
forge-gui-desktop/.project -text
|
forge-gui-desktop/.project -text
|
||||||
|
|||||||
@@ -10,7 +10,8 @@
|
|||||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||||
<uses-permission android:name="android.permission.VIBRATE"/>
|
<uses-permission android:name="android.permission.VIBRATE"/>
|
||||||
<uses-permission android:name="android.permission.INTERNET"/>
|
<uses-permission android:name="android.permission.INTERNET"/>
|
||||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
|
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
|
||||||
|
<uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES"/>
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
@@ -19,11 +20,12 @@
|
|||||||
android:largeHeap="true">
|
android:largeHeap="true">
|
||||||
<activity
|
<activity
|
||||||
android:name=".Main"
|
android:name=".Main"
|
||||||
android:label="@string/app_name" >
|
android:label="@string/app_name">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN" />
|
<action android:name="android.intent.action.MAIN" />
|
||||||
<category android:name="android.intent.category.LAUNCHER" />
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
|
<activity android:name=".Exiter" android:theme="@android:style/Theme.NoDisplay"/>
|
||||||
</application>
|
</application>
|
||||||
</manifest>
|
</manifest>
|
||||||
|
|||||||
@@ -356,13 +356,6 @@
|
|||||||
<include name="assets.zip" />
|
<include name="assets.zip" />
|
||||||
</fileset>
|
</fileset>
|
||||||
</ftp>
|
</ftp>
|
||||||
<ftp password="${cardforge.pass}" server="ftp.cardforge.org"
|
|
||||||
userid="${cardforge.user}" passive="true"
|
|
||||||
remotedir="releases/forge/forge-gui-android/">
|
|
||||||
<fileset dir="${project.build.directory}/classes">
|
|
||||||
<include name="version.txt" />
|
|
||||||
</fileset>
|
|
||||||
</ftp>
|
|
||||||
</target>
|
</target>
|
||||||
</configuration>
|
</configuration>
|
||||||
<goals>
|
<goals>
|
||||||
|
|||||||
14
forge-gui-android/src/forge/app/Exiter.java
Normal file
14
forge-gui-android/src/forge/app/Exiter.java
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
package forge.app;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
public class Exiter extends Activity {
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
finish();
|
||||||
|
|
||||||
|
//ensure process fully killed
|
||||||
|
System.exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
package forge.app;
|
package forge.app;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
|
||||||
import android.content.ClipData;
|
import android.content.ClipData;
|
||||||
import android.content.ClipboardManager;
|
import android.content.ClipboardManager;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
@@ -20,7 +19,6 @@ import com.badlogic.gdx.backends.android.AndroidApplication;
|
|||||||
|
|
||||||
import forge.Forge;
|
import forge.Forge;
|
||||||
import forge.interfaces.IDeviceAdapter;
|
import forge.interfaces.IDeviceAdapter;
|
||||||
import forge.util.Callback;
|
|
||||||
import forge.util.FileUtil;
|
import forge.util.FileUtil;
|
||||||
|
|
||||||
public class Main extends AndroidApplication {
|
public class Main extends AndroidApplication {
|
||||||
@@ -34,47 +32,34 @@ public class Main extends AndroidApplication {
|
|||||||
this.setRequestedOrientation(7);
|
this.setRequestedOrientation(7);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AndroidAdapter adapter = new AndroidAdapter();
|
||||||
|
|
||||||
//establish assets directory
|
//establish assets directory
|
||||||
if (!Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
|
if (!Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
|
||||||
Gdx.app.error("Forge", "Can't access external storage");
|
Gdx.app.error("Forge", "Can't access external storage");
|
||||||
Gdx.app.exit();
|
adapter.exit();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
String assetsDir = Environment.getExternalStorageDirectory() + "/Forge/";
|
String assetsDir = Environment.getExternalStorageDirectory() + "/Forge/";
|
||||||
if (!FileUtil.ensureDirectoryExists(assetsDir)) {
|
if (!FileUtil.ensureDirectoryExists(assetsDir)) {
|
||||||
Gdx.app.error("Forge", "Can't access external storage");
|
Gdx.app.error("Forge", "Can't access external storage");
|
||||||
Gdx.app.exit();
|
adapter.exit();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
initialize(Forge.getApp(new AndroidClipboard(), new AndroidAdapter(),
|
initialize(Forge.getApp(new AndroidClipboard(), adapter, assetsDir));
|
||||||
assetsDir, new Callback<String>() {
|
|
||||||
@Override
|
|
||||||
public void run(String runOnExit) {
|
|
||||||
if (runOnExit != null) {
|
|
||||||
runFile(runOnExit);
|
|
||||||
}
|
|
||||||
|
|
||||||
//ensure process doesn't stick around after exiting
|
|
||||||
finish();
|
|
||||||
System.exit(0);
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void runFile(String filename) {
|
/*@Override
|
||||||
try {
|
protected void onDestroy() {
|
||||||
Intent intent = new Intent(Intent.ACTION_VIEW);
|
super.onDestroy();
|
||||||
Uri uri = Uri.fromFile(new File(filename));
|
|
||||||
String type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(
|
//ensure app doesn't stick around
|
||||||
MimeTypeMap.getFileExtensionFromUrl(uri.toString()));
|
//ActivityManager am = (ActivityManager)getSystemService(Activity.ACTIVITY_SERVICE);
|
||||||
intent.setDataAndType(uri, type);
|
//am.killBackgroundProcesses(getApplicationContext().getPackageName());
|
||||||
startActivity(intent);
|
|
||||||
}
|
|
||||||
catch (Exception e) {
|
}*/
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//special clipboard that words on Android
|
//special clipboard that words on Android
|
||||||
private class AndroidClipboard implements com.badlogic.gdx.utils.Clipboard {
|
private class AndroidClipboard implements com.badlogic.gdx.utils.Clipboard {
|
||||||
@@ -118,5 +103,34 @@ public class Main extends AndroidApplication {
|
|||||||
public String getDownloadsDir() {
|
public String getDownloadsDir() {
|
||||||
return Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/";
|
return Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean openFile(String filename) {
|
||||||
|
try {
|
||||||
|
Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||||
|
Uri uri = Uri.fromFile(new File(filename));
|
||||||
|
String type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(
|
||||||
|
MimeTypeMap.getFileExtensionFromUrl(uri.toString()));
|
||||||
|
intent.setDataAndType(uri, type);
|
||||||
|
startActivity(intent);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void exit() {
|
||||||
|
// Replace the current task with one that is excluded from the recent
|
||||||
|
// apps and that will finish itself immediately. It's critical that this
|
||||||
|
// activity get launched in the task that you want to hide.
|
||||||
|
final Intent relaunch = new Intent(Main.this, Exiter.class)
|
||||||
|
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK // CLEAR_TASK requires this
|
||||||
|
| Intent.FLAG_ACTIVITY_CLEAR_TASK // finish everything else in the task
|
||||||
|
| Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); // hide (remove, in this case) task from recents
|
||||||
|
startActivity(relaunch);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,10 @@
|
|||||||
package forge.app;
|
package forge.app;
|
||||||
|
|
||||||
|
import java.awt.Desktop;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.Gdx;
|
||||||
import com.badlogic.gdx.backends.lwjgl.LwjglApplication;
|
import com.badlogic.gdx.backends.lwjgl.LwjglApplication;
|
||||||
import com.badlogic.gdx.backends.lwjgl.LwjglClipboard;
|
import com.badlogic.gdx.backends.lwjgl.LwjglClipboard;
|
||||||
|
|
||||||
@@ -17,7 +22,7 @@ public class Main {
|
|||||||
}
|
}
|
||||||
|
|
||||||
new LwjglApplication(Forge.getApp(new LwjglClipboard(), new DesktopAdapter(),
|
new LwjglApplication(Forge.getApp(new LwjglClipboard(), new DesktopAdapter(),
|
||||||
assetsDir, null), "Forge", Utils.DEV_SCREEN_WIDTH, Utils.DEV_SCREEN_HEIGHT);
|
assetsDir), "Forge", Utils.DEV_SCREEN_WIDTH, Utils.DEV_SCREEN_HEIGHT);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class DesktopAdapter implements IDeviceAdapter {
|
private static class DesktopAdapter implements IDeviceAdapter {
|
||||||
@@ -36,5 +41,22 @@ public class Main {
|
|||||||
public String getDownloadsDir() {
|
public String getDownloadsDir() {
|
||||||
return System.getProperty("user.home") + "/Downloads/";
|
return System.getProperty("user.home") + "/Downloads/";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean openFile(String filename) {
|
||||||
|
try {
|
||||||
|
Desktop.getDesktop().open(new File(filename));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void exit() {
|
||||||
|
Gdx.app.exit(); //can just use Gdx.app.exit for desktop
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,23 +42,20 @@ public class Forge implements ApplicationListener {
|
|||||||
private static final ApplicationListener app = new Forge();
|
private static final ApplicationListener app = new Forge();
|
||||||
private static Clipboard clipboard;
|
private static Clipboard clipboard;
|
||||||
private static IDeviceAdapter deviceAdapter;
|
private static IDeviceAdapter deviceAdapter;
|
||||||
private static Callback<String> onExit;
|
|
||||||
private static int screenWidth;
|
private static int screenWidth;
|
||||||
private static int screenHeight;
|
private static int screenHeight;
|
||||||
private static Graphics graphics;
|
private static Graphics graphics;
|
||||||
private static FScreen currentScreen;
|
private static FScreen currentScreen;
|
||||||
private static SplashScreen splashScreen;
|
private static SplashScreen splashScreen;
|
||||||
private static KeyInputAdapter keyInputAdapter;
|
private static KeyInputAdapter keyInputAdapter;
|
||||||
private static String runAfterExit;
|
|
||||||
private static boolean exited;
|
private static boolean exited;
|
||||||
private static final SoundSystem soundSystem = new SoundSystem();
|
private static final SoundSystem soundSystem = new SoundSystem();
|
||||||
private static final Stack<FScreen> screens = new Stack<FScreen>();
|
private static final Stack<FScreen> screens = new Stack<FScreen>();
|
||||||
|
|
||||||
public static ApplicationListener getApp(Clipboard clipboard0, IDeviceAdapter deviceAdapter0, String assetDir0, Callback<String> onExit0) {
|
public static ApplicationListener getApp(Clipboard clipboard0, IDeviceAdapter deviceAdapter0, String assetDir0) {
|
||||||
if (GuiBase.getInterface() == null) {
|
if (GuiBase.getInterface() == null) {
|
||||||
clipboard = clipboard0;
|
clipboard = clipboard0;
|
||||||
deviceAdapter = deviceAdapter0;
|
deviceAdapter = deviceAdapter0;
|
||||||
onExit = onExit0;
|
|
||||||
GuiBase.setInterface(new GuiMobile(assetDir0));
|
GuiBase.setInterface(new GuiMobile(assetDir0));
|
||||||
}
|
}
|
||||||
return app;
|
return app;
|
||||||
@@ -145,7 +142,7 @@ public class Forge implements ApplicationListener {
|
|||||||
|
|
||||||
public static void back() {
|
public static void back() {
|
||||||
if (screens.size() < 2) {
|
if (screens.size() < 2) {
|
||||||
exit(false, null); //prompt to exit if attempting to go back from home screen
|
exit(false); //prompt to exit if attempting to go back from home screen
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
currentScreen.onClose(new Callback<Boolean>() {
|
currentScreen.onClose(new Callback<Boolean>() {
|
||||||
@@ -159,7 +156,7 @@ public class Forge implements ApplicationListener {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void exit(boolean silent, final String runAfterExit0) {
|
public static void exit(boolean silent) {
|
||||||
if (exited) { return; } //don't allow exiting multiple times
|
if (exited) { return; } //don't allow exiting multiple times
|
||||||
|
|
||||||
Callback<Boolean> callback = new Callback<Boolean>() {
|
Callback<Boolean> callback = new Callback<Boolean>() {
|
||||||
@@ -167,8 +164,7 @@ public class Forge implements ApplicationListener {
|
|||||||
public void run(Boolean result) {
|
public void run(Boolean result) {
|
||||||
if (result) {
|
if (result) {
|
||||||
exited = true;
|
exited = true;
|
||||||
runAfterExit = runAfterExit0;
|
deviceAdapter.exit();
|
||||||
Gdx.app.exit();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -291,10 +287,6 @@ public class Forge implements ApplicationListener {
|
|||||||
screens.clear();
|
screens.clear();
|
||||||
graphics.dispose();
|
graphics.dispose();
|
||||||
soundSystem.dispose();
|
soundSystem.dispose();
|
||||||
|
|
||||||
if (onExit != null) {
|
|
||||||
onExit.run(runAfterExit);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//log message to Forge.log file
|
//log message to Forge.log file
|
||||||
|
|||||||
@@ -56,7 +56,8 @@ public class AssetsDownloader {
|
|||||||
"http://cardforge.org/android/releases/forge/forge-gui-android/" + version + "/",
|
"http://cardforge.org/android/releases/forge/forge-gui-android/" + version + "/",
|
||||||
Forge.getDeviceAdapter().getDownloadsDir(), splashScreen.getProgressBar());
|
Forge.getDeviceAdapter().getDownloadsDir(), splashScreen.getProgressBar());
|
||||||
if (apkFile != null) {
|
if (apkFile != null) {
|
||||||
Forge.exit(true, apkFile);
|
Forge.getDeviceAdapter().openFile(apkFile);
|
||||||
|
Forge.exit(true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
SOptionPane.showMessageDialog("Could not download update. " +
|
SOptionPane.showMessageDialog("Could not download update. " +
|
||||||
@@ -77,7 +78,7 @@ public class AssetsDownloader {
|
|||||||
}
|
}
|
||||||
catch (IOException e) {
|
catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
Forge.exit(true, null); //can't continue if this fails
|
Forge.exit(true); //can't continue if this fails
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -99,7 +100,7 @@ public class AssetsDownloader {
|
|||||||
}
|
}
|
||||||
SOptionPane.showMessageDialog(message, "No Internet Connection");
|
SOptionPane.showMessageDialog(message, "No Internet Connection");
|
||||||
if (!canIgnoreDownload) {
|
if (!canIgnoreDownload) {
|
||||||
Forge.exit(true, null); //exit if can't ignore download
|
Forge.exit(true); //exit if can't ignore download
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -127,11 +128,11 @@ public class AssetsDownloader {
|
|||||||
null, options)) {
|
null, options)) {
|
||||||
case 1:
|
case 1:
|
||||||
if (!canIgnoreDownload) {
|
if (!canIgnoreDownload) {
|
||||||
Forge.exit(true, null); //exit if can't ignore download
|
Forge.exit(true); //exit if can't ignore download
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
case 2:
|
case 2:
|
||||||
Forge.exit(true, null);
|
Forge.exit(true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ public class BugReportDialog extends FScreen { //use screen rather than dialog s
|
|||||||
btnExit.setCommand(new FEventHandler() {
|
btnExit.setCommand(new FEventHandler() {
|
||||||
@Override
|
@Override
|
||||||
public void handleEvent(FEvent e) {
|
public void handleEvent(FEvent e) {
|
||||||
Forge.exit(true, null);
|
Forge.exit(true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,4 +4,6 @@ public interface IDeviceAdapter {
|
|||||||
boolean isConnectedToInternet();
|
boolean isConnectedToInternet();
|
||||||
boolean isConnectedToWifi();
|
boolean isConnectedToWifi();
|
||||||
String getDownloadsDir();
|
String getDownloadsDir();
|
||||||
|
boolean openFile(String filename);
|
||||||
|
void exit();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user