diff --git a/android-project/app/src/main/AndroidManifest.xml b/android-project/app/src/main/AndroidManifest.xml index 64a707a27..e72763632 100644 --- a/android-project/app/src/main/AndroidManifest.xml +++ b/android-project/app/src/main/AndroidManifest.xml @@ -3,6 +3,14 @@ xmlns:tools="http://schemas.android.com/tools" android:installLocation="auto"> + + + + + + + + diff --git a/android-project/app/src/main/java/org/diasurgical/devilutionx/ImportActivity.java b/android-project/app/src/main/java/org/diasurgical/devilutionx/ImportActivity.java index fcfe6140a..ae458e8f3 100644 --- a/android-project/app/src/main/java/org/diasurgical/devilutionx/ImportActivity.java +++ b/android-project/app/src/main/java/org/diasurgical/devilutionx/ImportActivity.java @@ -3,15 +3,23 @@ package org.diasurgical.devilutionx; import android.app.Activity; import android.app.AlertDialog; import android.content.ClipData; +import android.content.ComponentName; import android.content.ContentResolver; import android.content.Intent; +import android.content.pm.PackageManager; import android.net.Uri; import android.os.Build; import android.support.annotation.Nullable; import android.os.Bundle; import android.support.annotation.RequiresApi; import android.support.v4.provider.DocumentFile; +import android.text.SpannableString; +import android.text.Spanned; +import android.text.method.LinkMovementMethod; +import android.text.style.URLSpan; import android.util.Log; +import android.view.View; +import android.widget.TextView; import java.io.File; import java.io.FileOutputStream; @@ -19,11 +27,13 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; -import java.util.Objects; public class ImportActivity extends Activity { private static final int IMPORT_REQUEST_CODE = 0xD1AB70; + private static final String TV_STUB_PACKAGE = "com.android.tv.frameworkpackagestubs"; + private static final String RECOMMENDED_FILE_BROWSER = "AnExplorer"; + private static final String RECOMMENDED_FILE_BROWSER_PACKAGE = "dev.dworks.apps.anexplorer"; private boolean userConfirmed = false; @RequiresApi(api = Build.VERSION_CODES.KITKAT) @@ -31,25 +41,11 @@ public class ImportActivity extends Activity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - ExternalFilesManager fileManager = new ExternalFilesManager(this); - String externalFilesDir = fileManager.getExternalFilesDirectory(); - - AlertDialog.Builder builder = new AlertDialog.Builder(this); - builder.setMessage(getString(R.string.import_data_info, externalFilesDir)); - builder.setPositiveButton(R.string.ok_button, (dialog, which) -> { - this.userConfirmed = true; - Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT); - intent.addCategory(Intent.CATEGORY_OPENABLE); - intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true); - intent.setType("*/*"); - startActivityForResult(intent, IMPORT_REQUEST_CODE); - }); - builder.setOnDismissListener(dialog -> { - if (!this.userConfirmed && !isFinishing()) finish(); - }); - - AlertDialog dialog = builder.create(); - dialog.show(); + if (findFileBrowser()) { + runFileBrowser(); + } else { + recommendFileBrowser(); + } } @Override @@ -86,6 +82,81 @@ public class ImportActivity extends Activity { } } + private boolean findFileBrowser() { + Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT); + intent.addCategory(Intent.CATEGORY_OPENABLE); + intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true); + intent.setType("*/*"); + + PackageManager packageManager = getPackageManager(); + ComponentName defaultPackage = intent.resolveActivity(packageManager); + return defaultPackage != null && !TV_STUB_PACKAGE.equals(defaultPackage.getPackageName()); + } + + private void recommendFileBrowser() + { + String noFileBrowserText = getString(R.string.no_file_browser); + SpannableString message; + + boolean isTelevision = getPackageManager().hasSystemFeature(PackageManager.FEATURE_LEANBACK); + if (isTelevision) { + String recommendation = getString(R.string.recommended_file_browser, RECOMMENDED_FILE_BROWSER); + String messageText = noFileBrowserText + " " + recommendation; + message = new SpannableString(messageText); + + int index = messageText.indexOf(RECOMMENDED_FILE_BROWSER); + if (index >= 0) { + String url = "market://details?id=" + RECOMMENDED_FILE_BROWSER_PACKAGE; + URLSpan urlSpan = new URLSpan(url); + message.setSpan(urlSpan, index, index + RECOMMENDED_FILE_BROWSER.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + } + } else { + message = new SpannableString(noFileBrowserText); + } + + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setMessage(message); + builder.setPositiveButton("OK", null); + builder.setOnDismissListener(dialog -> { + if (findFileBrowser()) { + runFileBrowser(); + } else if (!isFinishing()) { + finish(); + } + }); + + AlertDialog dialog = builder.create(); + dialog.show(); + + View view = dialog.findViewById(android.R.id.message); + if (view instanceof TextView) { + TextView textView = (TextView)view; + textView.setMovementMethod(LinkMovementMethod.getInstance()); + } + } + + private void runFileBrowser() { + ExternalFilesManager fileManager = new ExternalFilesManager(this); + String externalFilesDir = fileManager.getExternalFilesDirectory(); + + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setMessage(getString(R.string.import_data_info, externalFilesDir)); + builder.setPositiveButton(R.string.ok_button, (dialog, which) -> { + userConfirmed = true; + Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT); + intent.addCategory(Intent.CATEGORY_OPENABLE); + intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true); + intent.setType("*/*"); + startActivityForResult(intent, IMPORT_REQUEST_CODE); + }); + builder.setOnDismissListener(dialog -> { + if (!userConfirmed && !isFinishing()) finish(); + }); + + AlertDialog dialog = builder.create(); + dialog.show(); + } + private ArrayList getItemUris(ClipData clipData) { ArrayList uriList = new ArrayList<>(); if (clipData == null) diff --git a/android-project/app/src/main/res/values/strings.xml b/android-project/app/src/main/res/values/strings.xml index 1f0054ea4..affb17a16 100644 --- a/android-project/app/src/main/res/values/strings.xml +++ b/android-project/app/src/main/res/values/strings.xml @@ -13,6 +13,8 @@ Diablo Demo Data Import Data This game requires a gamepad to play + Please install a file explorer to select the files you want to import. + For Android TV, we recommend %1$s. On the next screen, select files that will be imported into:\n\n%1$s The following files will be overwritten. Is this okay?\n\n%1$s OK