diff --git a/android-project/app/build.gradle b/android-project/app/build.gradle
index 96a6c1484..5f3230077 100644
--- a/android-project/app/build.gradle
+++ b/android-project/app/build.gradle
@@ -61,4 +61,5 @@ android {
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
+ implementation 'com.android.support.constraint:constraint-layout:2.0.4'
}
diff --git a/android-project/app/src/main/AndroidManifest.xml b/android-project/app/src/main/AndroidManifest.xml
index 80f5f96b8..d50f041d4 100644
--- a/android-project/app/src/main/AndroidManifest.xml
+++ b/android-project/app/src/main/AndroidManifest.xml
@@ -35,6 +35,8 @@
+
+
-->
+
+
+
diff --git a/android-project/app/src/main/java/org/diasurgical/devilutionx/DataActivity.java b/android-project/app/src/main/java/org/diasurgical/devilutionx/DataActivity.java
new file mode 100644
index 000000000..66c5be705
--- /dev/null
+++ b/android-project/app/src/main/java/org/diasurgical/devilutionx/DataActivity.java
@@ -0,0 +1,119 @@
+package org.diasurgical.devilutionx;
+
+import android.app.DownloadManager;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.database.Cursor;
+import android.net.Uri;
+import android.support.v7.app.AppCompatActivity;
+import android.os.Bundle;
+import android.text.method.LinkMovementMethod;
+import android.view.View;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import java.io.File;
+
+public class DataActivity extends AppCompatActivity {
+ private String externalDir;
+ private DownloadReceiver mReceiver;
+ private boolean isDownloading = false;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ externalDir = getExternalFilesDir(null).getAbsolutePath();
+
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_data);
+
+ ((TextView) findViewById(R.id.full_guide)).setMovementMethod(LinkMovementMethod.getInstance());
+ ((TextView) findViewById(R.id.online_guide)).setMovementMethod(LinkMovementMethod.getInstance());
+ }
+
+ protected void onResume() {
+ super.onResume();
+ startGame();
+ }
+
+ public void startGame(View view) {
+ startGame();
+ }
+
+ private void startGame() {
+ if (missingGameData()) {
+ Toast toast = Toast.makeText(getApplicationContext(), "Game data missing", Toast.LENGTH_SHORT);
+ toast.show();
+ return;
+ }
+
+ Intent intent = new Intent(this, DevilutionXSDLActivity.class);
+ startActivity(intent);
+ this.finish();
+ }
+
+ /**
+ * Check if the game data is present
+ */
+ private boolean missingGameData() {
+ File fileLower = new File(externalDir + "/diabdat.mpq");
+ File fileUpper = new File(externalDir + "/DIABDAT.MPQ");
+ File spawnFile = new File(externalDir + "/spawn.mpq");
+
+ return !fileUpper.exists() && !fileLower.exists() && (!spawnFile.exists() || isDownloading);
+ }
+
+ /**
+ * Start downloading the shareware
+ */
+ public void sendDownloadRequest(View view) {
+ String url = "https://github.com/d07RiV/diabloweb/raw/3a5a51e84d5dab3cfd4fef661c46977b091aaa9c/spawn.mpq";
+ String fileName = "spawn.mpq";
+
+ DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url))
+ .setTitle(fileName)
+ .setDescription("Diablo Shareware Data")
+ .setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE);
+
+ request.setDestinationInExternalFilesDir(this, null, fileName);
+
+ DownloadManager downloadManager = (DownloadManager)this.getSystemService(Context.DOWNLOAD_SERVICE);
+ downloadManager.enqueue(request);
+
+ if (mReceiver == null)
+ mReceiver = new DownloadReceiver();
+ registerReceiver(mReceiver, new IntentFilter("android.intent.action.DOWNLOAD_COMPLETE"));
+
+ isDownloading = true;
+ view.setEnabled(false);
+
+ Toast toast = Toast.makeText(getApplicationContext(), "Download started", Toast.LENGTH_SHORT);
+ toast.show();
+ }
+
+ /**
+ * Start game when download finishes
+ */
+ private class DownloadReceiver extends BroadcastReceiver {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ isDownloading = false;
+
+ long receivedID = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1L);
+ DownloadManager mgr = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
+
+ DownloadManager.Query query = new DownloadManager.Query();
+ query.setFilterById(receivedID);
+ Cursor cur = mgr.query(query);
+ int index = cur.getColumnIndex(DownloadManager.COLUMN_STATUS);
+ if (cur.moveToFirst()) {
+ if (cur.getInt(index) == DownloadManager.STATUS_SUCCESSFUL) {
+ startGame();
+ }
+ }
+ cur.close();
+ findViewById(R.id.download_button).setEnabled(true);
+ }
+ }
+}
diff --git a/android-project/app/src/main/java/org/diasurgical/devilutionx/DevilutionXSDLActivity.java b/android-project/app/src/main/java/org/diasurgical/devilutionx/DevilutionXSDLActivity.java
index a5ce0c51f..7627785c4 100644
--- a/android-project/app/src/main/java/org/diasurgical/devilutionx/DevilutionXSDLActivity.java
+++ b/android-project/app/src/main/java/org/diasurgical/devilutionx/DevilutionXSDLActivity.java
@@ -1,13 +1,12 @@
package org.diasurgical.devilutionx;
import android.Manifest;
-import android.app.AlertDialog;
-import android.content.SharedPreferences;
+import android.annotation.SuppressLint;
+import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
-import android.preference.PreferenceManager;
import android.util.Log;
import org.libsdl.app.SDLActivity;
@@ -20,8 +19,6 @@ import java.io.InputStream;
import java.io.OutputStream;
public class DevilutionXSDLActivity extends SDLActivity {
- private SharedPreferences mPrefs;
- final private String shouldShowInstallationGuidePref = "shouldShowInstallationGuide";
private String externalDir;
protected void onCreate(Bundle savedInstanceState) {
@@ -29,44 +26,28 @@ public class DevilutionXSDLActivity extends SDLActivity {
migrateAppData();
- if (shouldShowInstallationGuide()) {
- showInstallationGuide();
- }
-
super.onCreate(savedInstanceState);
}
/**
- * Check if this is the first time the app is run and the full game data is not already present
+ * On app launch make sure the game data is present
*/
- private boolean shouldShowInstallationGuide() {
- mPrefs = PreferenceManager.getDefaultSharedPreferences(this);
- return mPrefs.getBoolean(shouldShowInstallationGuidePref, !hasFullGameData());
+ protected void onStart() {
+ super.onStart();
+
+ if (missingGameData()) {
+ Intent intent = new Intent(this, DataActivity.class);
+ startActivity(intent);
+ this.finish();
+ }
}
- private boolean hasFullGameData() {
+ private boolean missingGameData() {
File fileLower = new File(externalDir + "/diabdat.mpq");
File fileUpper = new File(externalDir + "/DIABDAT.MPQ");
+ File spawnFile = new File(externalDir + "/spawn.mpq");
- return fileUpper.exists() || fileLower.exists();
- }
-
- private void installationGuideShown() {
- SharedPreferences.Editor editor = mPrefs.edit();
- editor.putBoolean(shouldShowInstallationGuidePref, false);
- editor.apply();
- }
-
- private void showInstallationGuide() {
- String message = "To play the full version you must place DIABDAT.MPQ from the original game in Android"
- + externalDir.split("/Android")[1]
- + ".\n\nIf you don't have the original game then you can buy Diablo from GOG.com.";
- new AlertDialog.Builder(this)
- .setTitle("Shareware version")
- .setPositiveButton("OK", null)
- .setMessage(message)
- .show();
- installationGuideShown();
+ return !fileUpper.exists() && !fileLower.exists() && !spawnFile.exists();
}
private boolean copyFile(File src, File dst) {
@@ -106,6 +87,7 @@ public class DevilutionXSDLActivity extends SDLActivity {
File newPath = new File(externalDir + "/" + file.getName());
if (newPath.exists()) {
if (file.canWrite()) {
+ //noinspection ResultOfMethodCallIgnored
file.delete();
}
return;
@@ -115,6 +97,7 @@ public class DevilutionXSDLActivity extends SDLActivity {
}
if (!file.renameTo(newPath)) {
if (copyFile(file, newPath) && file.canWrite()) {
+ //noinspection ResultOfMethodCallIgnored
file.delete();
}
}
@@ -123,6 +106,8 @@ public class DevilutionXSDLActivity extends SDLActivity {
/**
* This can be removed Nov 2021 and Google will no longer permit access to the old folder from that point on
*/
+ @SuppressWarnings("deprecation")
+ @SuppressLint("SdCardPath")
private void migrateAppData() {
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1) {
if (PackageManager.PERMISSION_GRANTED != checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE)) {
diff --git a/android-project/app/src/main/res/layout/activity_data.xml b/android-project/app/src/main/res/layout/activity_data.xml
new file mode 100644
index 000000000..6d87a0578
--- /dev/null
+++ b/android-project/app/src/main/res/layout/activity_data.xml
@@ -0,0 +1,78 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android-project/app/src/main/res/values/colors.xml b/android-project/app/src/main/res/values/colors.xml
new file mode 100644
index 000000000..d37192c36
--- /dev/null
+++ b/android-project/app/src/main/res/values/colors.xml
@@ -0,0 +1,7 @@
+
+
+ #FFFC0000
+ #FF7E0000
+ #FF000000
+ #FFFFFFFF
+
diff --git a/android-project/app/src/main/res/values/strings.xml b/android-project/app/src/main/res/values/strings.xml
index e1422313b..3ff740a73 100644
--- a/android-project/app/src/main/res/values/strings.xml
+++ b/android-project/app/src/main/res/values/strings.xml
@@ -1,3 +1,11 @@
-
- DevilutionX
-
+
+ DevilutionX
+ Game Data
+
+ Download Shareware Data
+
+ To play the full version you must place DIABDAT.MPQ from the original game in Android/data/org.diasurgical.devilutionx/files.
\n
\nIf you don\'t have the original game then you can buy Diablo from GOG.com.
+ Alternatively you can download the spawn version, to play the shareware portion of the game.
+ See the Installation Instructions for more details.
+ Check again
+
diff --git a/android-project/app/src/main/res/values/themes.xml b/android-project/app/src/main/res/values/themes.xml
new file mode 100644
index 000000000..16f0837d2
--- /dev/null
+++ b/android-project/app/src/main/res/values/themes.xml
@@ -0,0 +1,9 @@
+
+
+
+