Fix so Android app is fully closed when exiting

This commit is contained in:
drdev
2014-08-24 18:06:26 +00:00
parent 32cac7b12c
commit efa6b60b47
10 changed files with 100 additions and 59 deletions

1
.gitattributes vendored
View File

@@ -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

View File

@@ -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>

View File

@@ -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>

View 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);
}
}

View File

@@ -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);
}
} }
} }

View File

@@ -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
}
} }
} }

View File

@@ -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

View 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;
} }

View File

@@ -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);
} }
}); });
} }

View File

@@ -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();
} }