Browse Source

[android] Game data installation screen

pull/2465/head
Anders Jenbo 5 years ago
parent
commit
51fbf6b839
  1. 1
      android-project/app/build.gradle
  2. 6
      android-project/app/src/main/AndroidManifest.xml
  3. 119
      android-project/app/src/main/java/org/diasurgical/devilutionx/DataActivity.java
  4. 51
      android-project/app/src/main/java/org/diasurgical/devilutionx/DevilutionXSDLActivity.java
  5. 78
      android-project/app/src/main/res/layout/activity_data.xml
  6. 7
      android-project/app/src/main/res/values/colors.xml
  7. 14
      android-project/app/src/main/res/values/strings.xml
  8. 9
      android-project/app/src/main/res/values/themes.xml

1
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'
}

6
android-project/app/src/main/AndroidManifest.xml

@ -35,6 +35,8 @@
<uses-permission android:name="android.permission.VIBRATE" />
<!-- Allow access to the network for multiplayer -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- Required for downloading shareware data on older devices -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="22" />
<application android:label="@string/app_name"
android:icon="@mipmap/ic_launcher"
@ -66,6 +68,10 @@
</intent-filter>
-->
</activity>
<activity android:name=".DataActivity"
android:theme="@style/Theme.MyApplication">
</activity>
</application>
</manifest>

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

51
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)) {

78
android-project/app/src/main/res/layout/activity_data.xml

@ -0,0 +1,78 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".DataActivity">
<TextView
android:id="@+id/headline"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:text="@string/title_activity_data"
android:textSize="20sp"
android:textStyle="bold"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/full_guide"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:text="@string/guide_full_installation"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/headline" />
<TextView
android:id="@+id/spawn_guide"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:text="@string/guide_shareware"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/check_data_button" />
<TextView
android:id="@+id/online_guide"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="16dp"
android:text="@string/faq_link"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<Button
android:id="@+id/download_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:onClick="sendDownloadRequest"
android:text="@string/download_spawn"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/spawn_guide" />
<Button
android:id="@+id/check_data_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:onClick="startGame"
android:text="@string/game_data_retry"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/full_guide" />
</android.support.constraint.ConstraintLayout>

7
android-project/app/src/main/res/values/colors.xml

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="red">#FFFC0000</color>
<color name="darkred">#FF7E0000</color>
<color name="black">#FF000000</color>
<color name="white">#FFFFFFFF</color>
</resources>

14
android-project/app/src/main/res/values/strings.xml

@ -1,3 +1,11 @@
<resources>
<string name="app_name">DevilutionX</string>
</resources>
<resources>
<string name="app_name">DevilutionX</string>
<string name="title_activity_data">Game Data</string>
<!-- Strings used for fragments for navigation -->
<string name="download_spawn">Download Shareware Data</string>
<string name="guide_full_installation">To play the full version you must place DIABDAT.MPQ from the original game in Android/data/org.diasurgical.devilutionx/files.<br/>\n<br/>\nIf you don\'t have the original game then you can buy Diablo from <a href="https://www.gog.com/game/diablo">GOG.com.</a></string>
<string name="guide_shareware">Alternatively you can download the spawn version, to play the shareware portion of the game.</string>
<string name="faq_link">See the <a href="https://github.com/diasurgical/devilutionX/blob/master/docs/installing.md#installing">Installation Instructions</a> for more details.</string>
<string name="game_data_retry">Check again</string>
</resources>

9
android-project/app/src/main/res/values/themes.xml

@ -0,0 +1,9 @@
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="Theme.MyApplication" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Primary brand color. -->
<item name="colorPrimary">@color/red</item>
<item name="colorPrimaryDark">@color/darkred</item>
<item name="colorAccent">@color/darkred</item>
</style>
</resources>
Loading…
Cancel
Save