2014-12-03 07:25:55 +00:00
|
|
|
package com.virtualapplications.play;
|
|
|
|
|
2016-02-08 17:14:08 +00:00
|
|
|
import android.Manifest;
|
2015-04-05 23:29:49 -04:00
|
|
|
import android.app.*;
|
2015-09-22 23:24:43 +01:00
|
|
|
import android.app.AlertDialog;
|
2015-07-23 19:41:54 -04:00
|
|
|
import android.app.ProgressDialog;
|
2015-04-05 23:29:49 -04:00
|
|
|
import android.content.*;
|
2015-05-11 00:53:35 -04:00
|
|
|
import android.content.pm.*;
|
2015-07-17 00:25:09 -04:00
|
|
|
import android.content.res.Configuration;
|
2015-08-02 12:51:01 +01:00
|
|
|
import android.graphics.Color;
|
2015-08-03 00:09:20 +01:00
|
|
|
import android.graphics.drawable.GradientDrawable;
|
2021-08-13 17:21:17 -04:00
|
|
|
import android.net.Uri;
|
2015-03-19 23:54:47 -04:00
|
|
|
import android.os.*;
|
2021-07-06 12:57:48 -04:00
|
|
|
|
|
|
|
import androidx.annotation.NonNull;
|
2021-08-13 17:21:17 -04:00
|
|
|
import androidx.documentfile.provider.DocumentFile;
|
2021-05-31 18:30:41 -04:00
|
|
|
import androidx.preference.PreferenceManager;
|
2020-08-25 14:39:41 -04:00
|
|
|
import androidx.core.app.ActivityCompat;
|
|
|
|
import androidx.core.content.ContextCompat;
|
|
|
|
import androidx.appcompat.app.*;
|
|
|
|
import androidx.appcompat.app.ActionBar;
|
|
|
|
import androidx.appcompat.widget.Toolbar;
|
|
|
|
|
2021-10-15 16:08:35 -04:00
|
|
|
import android.util.Log;
|
2014-12-03 07:25:55 +00:00
|
|
|
import android.view.*;
|
2015-07-15 01:39:11 -04:00
|
|
|
import android.view.View;
|
2014-12-03 07:25:55 +00:00
|
|
|
import android.widget.*;
|
2015-08-05 03:20:16 -04:00
|
|
|
import android.widget.GridView;
|
2017-07-05 10:17:37 -04:00
|
|
|
|
2021-08-25 10:28:20 -04:00
|
|
|
import java.net.URLDecoder;
|
|
|
|
import java.nio.charset.StandardCharsets;
|
2015-05-11 00:53:35 -04:00
|
|
|
import java.text.*;
|
2015-03-19 23:54:47 -04:00
|
|
|
import java.util.*;
|
2014-12-03 07:25:55 +00:00
|
|
|
|
2015-08-19 19:54:21 +01:00
|
|
|
import com.virtualapplications.play.database.GameIndexer;
|
2015-07-31 00:06:51 -04:00
|
|
|
import com.virtualapplications.play.database.GameInfo;
|
2015-07-29 19:46:41 -04:00
|
|
|
|
2019-01-06 03:09:05 +00:00
|
|
|
import static com.virtualapplications.play.BootablesInterop.PurgeInexistingFiles;
|
|
|
|
import static com.virtualapplications.play.BootablesInterop.UnregisterBootable;
|
2019-01-06 00:34:32 +00:00
|
|
|
import static com.virtualapplications.play.BootablesInterop.getBootables;
|
|
|
|
import static com.virtualapplications.play.BootablesInterop.setLastBootedTime;
|
2019-02-11 18:38:16 -05:00
|
|
|
import static com.virtualapplications.play.BootablesInterop.SORT_RECENT;
|
|
|
|
import static com.virtualapplications.play.BootablesInterop.SORT_HOMEBREW;
|
|
|
|
import static com.virtualapplications.play.BootablesInterop.SORT_NONE;
|
2021-05-31 16:36:10 -04:00
|
|
|
import static com.virtualapplications.play.Constants.PREF_UI_CLEAR_UNAVAILABLE;
|
2021-10-13 12:45:56 -04:00
|
|
|
import static com.virtualapplications.play.Constants.PREF_UI_MIGRATE_DATA_FILES;
|
2021-05-31 16:36:10 -04:00
|
|
|
import static com.virtualapplications.play.Constants.PREF_UI_RESCAN;
|
2016-01-25 18:23:42 +00:00
|
|
|
import static com.virtualapplications.play.ThemeManager.getThemeColor;
|
|
|
|
|
2017-07-05 10:17:37 -04:00
|
|
|
public class MainActivity extends AppCompatActivity implements NavigationDrawerFragment.NavigationDrawerCallbacks, SharedPreferences.OnSharedPreferenceChangeListener
|
|
|
|
{
|
2021-10-13 09:36:58 -04:00
|
|
|
private static final String PREF_ANDROID11_USER_NOTIFIED = "android11_user_notified";
|
|
|
|
|
2015-07-19 01:04:51 -04:00
|
|
|
private int currentOrientation;
|
2017-06-11 06:21:44 +01:00
|
|
|
private GameInfo gameInfo;
|
2015-08-02 12:51:01 +01:00
|
|
|
protected NavigationDrawerFragment mNavigationDrawerFragment;
|
2019-01-06 00:34:32 +00:00
|
|
|
private List<Bootable> currentGames = new ArrayList<>();
|
2019-02-11 18:38:16 -05:00
|
|
|
private int sortMethod = SORT_NONE;
|
2015-09-22 23:24:43 +01:00
|
|
|
private String navSubtitle;
|
2021-05-31 19:23:24 -04:00
|
|
|
private Toolbar toolbar;
|
2015-08-07 22:52:19 +01:00
|
|
|
|
2021-08-11 14:04:50 -04:00
|
|
|
static final int g_settingsRequestCode = 0xDEAD;
|
2021-08-13 17:21:17 -04:00
|
|
|
static final int g_folderPickerRequestCode = 0xBEEF;
|
2021-10-13 09:36:58 -04:00
|
|
|
static final int g_dataFilesFolderPickerRequestCode = 0xBEF0;
|
2021-08-11 14:04:50 -04:00
|
|
|
|
2016-02-08 17:14:08 +00:00
|
|
|
@Override
|
|
|
|
protected void onCreate(Bundle savedInstanceState)
|
2015-03-11 01:03:38 -04:00
|
|
|
{
|
2015-04-05 23:29:49 -04:00
|
|
|
super.onCreate(savedInstanceState);
|
2015-04-11 23:07:40 -04:00
|
|
|
//Log.w(Constants.TAG, "MainActivity - onCreate");
|
2015-08-08 16:48:35 -04:00
|
|
|
|
2015-07-19 01:04:51 -04:00
|
|
|
currentOrientation = getResources().getConfiguration().orientation;
|
2015-08-08 16:48:35 -04:00
|
|
|
|
2021-05-31 19:23:24 -04:00
|
|
|
ThemeManager.applyTheme(this, toolbar);
|
2017-07-05 10:17:37 -04:00
|
|
|
if(isAndroidTV(this))
|
|
|
|
{
|
2015-08-08 16:48:35 -04:00
|
|
|
setContentView(R.layout.tele);
|
2017-07-05 10:17:37 -04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2015-08-08 16:48:35 -04:00
|
|
|
setContentView(R.layout.main);
|
|
|
|
}
|
|
|
|
|
2016-02-08 17:14:08 +00:00
|
|
|
// if (isAndroidTV(this)) {
|
|
|
|
// // Load the menus for Android TV
|
|
|
|
// } else {
|
2021-05-31 19:23:24 -04:00
|
|
|
toolbar = findViewById(R.id.main_toolbar);
|
2016-02-08 17:14:08 +00:00
|
|
|
setSupportActionBar(toolbar);
|
|
|
|
toolbar.bringToFront();
|
|
|
|
setUIcolor();
|
|
|
|
|
|
|
|
mNavigationDrawerFragment = (NavigationDrawerFragment)
|
|
|
|
getFragmentManager().findFragmentById(R.id.navigation_drawer);
|
|
|
|
|
|
|
|
// Set up the drawer.
|
|
|
|
mNavigationDrawerFragment.setUp(
|
|
|
|
R.id.navigation_drawer,
|
2021-07-06 12:57:48 -04:00
|
|
|
findViewById(R.id.drawer_layout));
|
2016-02-08 17:14:08 +00:00
|
|
|
|
|
|
|
int attributeResourceId = getThemeColor(this, R.attr.colorPrimaryDark);
|
|
|
|
findViewById(R.id.navigation_drawer).setBackgroundColor(Color.parseColor(
|
|
|
|
("#" + Integer.toHexString(attributeResourceId)).replace("#ff", "#8e")
|
|
|
|
));
|
|
|
|
// }
|
|
|
|
|
2023-08-17 12:01:31 -04:00
|
|
|
//We can't request WRITE_EXTERNAL_STORAGE permission on SDK < 33 (we don't necessarily need it anyways)
|
|
|
|
if((Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) && (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED))
|
2017-07-05 10:17:37 -04:00
|
|
|
{
|
2016-02-08 17:14:08 +00:00
|
|
|
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, Constants.READ_WRITE_PERMISSION);
|
2017-07-05 10:17:37 -04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2016-02-08 17:14:08 +00:00
|
|
|
Startup();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-06-14 23:55:55 +01:00
|
|
|
@Override
|
|
|
|
public void onDestroy()
|
|
|
|
{
|
|
|
|
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
|
|
|
prefs.unregisterOnSharedPreferenceChangeListener(this);
|
|
|
|
super.onDestroy();
|
|
|
|
}
|
|
|
|
|
2017-07-05 10:17:37 -04:00
|
|
|
private void Startup()
|
|
|
|
{
|
2021-08-11 14:04:15 -04:00
|
|
|
NativeInterop.setFilesDirPath(getApplicationContext().getFilesDir().getAbsolutePath());
|
2021-08-04 09:35:56 -04:00
|
|
|
NativeInterop.setCacheDirPath(getApplicationContext().getCacheDir().getAbsolutePath());
|
2016-05-23 13:30:46 -04:00
|
|
|
NativeInterop.setAssetManager(getAssets());
|
2021-08-13 17:21:17 -04:00
|
|
|
NativeInterop.setContentResolver(getApplicationContext().getContentResolver());
|
2015-08-08 16:48:35 -04:00
|
|
|
|
2015-08-08 10:10:12 -04:00
|
|
|
EmulatorActivity.RegisterPreferences();
|
2015-08-08 16:48:35 -04:00
|
|
|
|
2015-08-08 10:10:12 -04:00
|
|
|
if(!NativeInterop.isVirtualMachineCreated())
|
|
|
|
{
|
|
|
|
NativeInterop.createVirtualMachine();
|
|
|
|
}
|
2015-08-08 16:48:35 -04:00
|
|
|
|
Organize classes, Database support, Remove dupes
Conflicts:
Source/ui_android/java/com/virtualapplications/play/MainActivity.java
Source/ui_android/java/com/virtualapplications/play/SetupDB.java
Source/ui_android/java/com/virtualapplications/play/TheGameDB.java
Source/ui_android/java/com/virtualapplications/play/getGameDetails.java
Load internal database, Fill from internet APIs
If a cover image and description are not in the database, attempt to
retrieve them from the API by ID. If an ID is not present, generate
temporary values based on search. These values are saved according to
the API ID, but not associated with the file name in storage. This
allows these entries to be applied to a game retrieved by ID at a later
time.
Combine long click calls into generic function
Fix long click function to return a value
Now that this is only the listener, it is no longer self-contained
Add a settings option to clear the cover cache
Log serial in relation to filename for reference
This may prove useful to obtain missing serial numbers.
Verify the existence of an image before loading
An image entry has been added to avoid the StackOverflow generated by
simply looping through the possible suffix values. The database has
been configured to pick up these image entries during the course of
regular checks.
Most images are -1, but a few have been found with alternate endings,
depending on revisions.
External database versioning for assets file
Using database version would cause the database to be rebuilt
internally, which would not copy the assets file.
The last modified time only applies to the written file and could not
be compared to the assets file, which would result in unnecessary
writes for every app update.
This method allow the value to be hard-coded in the app to reflect only
when the assets database is updated and avoid the restrictions of
runtime options.
Conflicts:
Source/ui_android/java/com/virtualapplications/play/getGameDetails.java
Conflicts:
Source/ui_android/java/com/virtualapplications/play/TheGamesDB.java
build_android/assets/games.db
Conflicts:
Source/ui_android/java/com/virtualapplications/play/TheGamesDB.java
build_android/assets/games.db
Reconnect getSerial call after rebase
2015-07-24 00:55:42 -04:00
|
|
|
gameInfo = new GameInfo(MainActivity.this);
|
2015-08-02 12:51:01 +01:00
|
|
|
|
2015-09-22 23:24:43 +01:00
|
|
|
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
|
2024-10-25 21:21:52 +01:00
|
|
|
sortMethod = sp.getInt("sortMethod.v2", SORT_NONE);
|
2015-09-22 23:24:43 +01:00
|
|
|
onNavigationDrawerItemSelected(sortMethod);
|
2017-06-14 23:55:55 +01:00
|
|
|
sp.registerOnSharedPreferenceChangeListener(this);
|
2023-10-10 11:59:59 -04:00
|
|
|
|
|
|
|
Intent intent = getIntent();
|
|
|
|
if(intent.getAction() != null && intent.getAction().equals(Intent.ACTION_VIEW))
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
Uri uri = intent.getData();
|
|
|
|
VirtualMachineManager.launchGame(this, uri.toString(), this::finish);
|
|
|
|
}
|
|
|
|
catch(Exception e)
|
|
|
|
{
|
|
|
|
displaySimpleMessage("Error", e.getMessage());
|
|
|
|
finish();
|
|
|
|
}
|
|
|
|
}
|
2015-08-02 12:51:01 +01:00
|
|
|
}
|
|
|
|
|
2016-02-08 17:14:08 +00:00
|
|
|
@Override
|
2021-07-06 12:57:48 -04:00
|
|
|
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults)
|
2017-07-05 10:17:37 -04:00
|
|
|
{
|
2021-07-06 12:57:48 -04:00
|
|
|
if(requestCode == Constants.READ_WRITE_PERMISSION)
|
|
|
|
{// If request is cancelled, the result arrays are empty.
|
2017-07-05 10:17:37 -04:00
|
|
|
if(grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED)
|
|
|
|
{
|
|
|
|
Startup();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2021-06-10 19:27:05 -04:00
|
|
|
new AlertDialog.Builder(this)
|
|
|
|
.setTitle(R.string.permission_dialog_title)
|
|
|
|
.setMessage(R.string.permission_dialog_summary)
|
|
|
|
.setPositiveButton(android.R.string.ok, (dialog, id) ->
|
|
|
|
finish()
|
|
|
|
)
|
|
|
|
.create()
|
|
|
|
.show();
|
2016-02-08 17:14:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-05 10:17:37 -04:00
|
|
|
private void setUIcolor()
|
|
|
|
{
|
|
|
|
View content = findViewById(R.id.content_frame);
|
|
|
|
if(content != null)
|
|
|
|
{
|
2015-08-09 02:49:24 +01:00
|
|
|
int[] colors = new int[2];// you can increase array size to add more colors to gradient.
|
2016-01-25 18:23:42 +00:00
|
|
|
int topgradientcolor = getThemeColor(this, R.attr.colorPrimary);
|
2015-08-09 02:49:24 +01:00
|
|
|
|
|
|
|
float[] hsv = new float[3];
|
|
|
|
Color.colorToHSV(topgradientcolor, hsv);
|
|
|
|
hsv[2] *= 0.8f;// make it darker
|
|
|
|
colors[0] = Color.HSVToColor(hsv);
|
|
|
|
/*
|
|
|
|
using this will blend the top of the gradient with actionbar (aka using the same color)
|
|
|
|
colors[0] = topgradientcolor
|
|
|
|
*/
|
|
|
|
colors[1] = Color.rgb(20, 20, 20);
|
|
|
|
GradientDrawable gradientbg = new GradientDrawable(GradientDrawable.Orientation.TOP_BOTTOM, colors);
|
|
|
|
content.setBackground(gradientbg);
|
|
|
|
}
|
2016-01-25 18:23:42 +00:00
|
|
|
int attributeResourceId = getThemeColor(this, R.attr.colorPrimaryDark);
|
2015-08-09 02:49:24 +01:00
|
|
|
findViewById(R.id.navigation_drawer).setBackgroundColor(Color.parseColor(
|
|
|
|
("#" + Integer.toHexString(attributeResourceId)).replace("#ff", "#8e")
|
|
|
|
));
|
|
|
|
}
|
|
|
|
|
2017-06-11 06:14:54 +01:00
|
|
|
private void displaySimpleMessage(String title, String message)
|
2015-04-24 01:51:40 -04:00
|
|
|
{
|
2021-06-10 19:27:05 -04:00
|
|
|
new AlertDialog.Builder(this)
|
|
|
|
.setTitle(title)
|
|
|
|
.setMessage(message)
|
|
|
|
.setPositiveButton(android.R.string.ok, null)
|
|
|
|
.create()
|
|
|
|
.show();
|
2015-08-23 23:53:29 +01:00
|
|
|
}
|
|
|
|
|
2019-01-06 00:34:32 +00:00
|
|
|
private void displayGameNotFound(final Bootable game)
|
2015-08-23 23:53:29 +01:00
|
|
|
{
|
2021-06-10 19:27:05 -04:00
|
|
|
new AlertDialog.Builder(this)
|
|
|
|
.setTitle(R.string.not_found)
|
|
|
|
.setMessage(R.string.game_unavailable)
|
|
|
|
.setPositiveButton(android.R.string.ok, (dialog, id) -> {
|
|
|
|
UnregisterBootable(game.path);
|
|
|
|
prepareFileListView(false);
|
|
|
|
})
|
|
|
|
.setNegativeButton(android.R.string.cancel, null)
|
|
|
|
.create()
|
|
|
|
.show();
|
2015-04-24 01:51:40 -04:00
|
|
|
}
|
2017-07-05 10:17:37 -04:00
|
|
|
|
2015-07-08 23:15:06 -04:00
|
|
|
private void displaySettingsActivity()
|
|
|
|
{
|
|
|
|
Intent intent = new Intent(getApplicationContext(), SettingsActivity.class);
|
2021-08-11 14:04:50 -04:00
|
|
|
startActivityForResult(intent, g_settingsRequestCode);
|
2015-07-08 23:15:06 -04:00
|
|
|
}
|
2015-08-09 02:49:24 +01:00
|
|
|
|
2021-08-13 17:21:17 -04:00
|
|
|
private void displayFolderPicker()
|
|
|
|
{
|
2023-10-11 10:51:30 -04:00
|
|
|
try
|
|
|
|
{
|
|
|
|
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
|
|
|
|
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
|
|
|
intent.addFlags(Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
|
|
|
|
intent.addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
|
|
|
|
intent.putExtra(Intent.EXTRA_LOCAL_ONLY, true);
|
|
|
|
startActivityForResult(intent, g_folderPickerRequestCode);
|
|
|
|
}
|
|
|
|
catch(Exception ex)
|
|
|
|
{
|
|
|
|
displaySimpleMessage("Error", String.format("Error occurred while trying to use ACTION_OPEN_DOCUMENT_TREE intent:\n%s", ex.toString()));
|
|
|
|
}
|
2021-08-13 17:21:17 -04:00
|
|
|
}
|
|
|
|
|
2017-07-05 10:17:37 -04:00
|
|
|
protected void onActivityResult(int requestCode, int resultCode, Intent data)
|
|
|
|
{
|
2021-07-06 12:57:48 -04:00
|
|
|
super.onActivityResult(requestCode, resultCode, data);
|
2021-08-11 14:04:50 -04:00
|
|
|
if(requestCode == g_settingsRequestCode)
|
2017-07-05 10:17:37 -04:00
|
|
|
{
|
2021-05-31 19:23:24 -04:00
|
|
|
ThemeManager.applyTheme(this, toolbar);
|
2015-08-18 00:05:31 +01:00
|
|
|
setUIcolor();
|
2015-08-09 02:49:24 +01:00
|
|
|
}
|
2015-08-20 22:26:01 +01:00
|
|
|
|
2017-07-05 10:17:37 -04:00
|
|
|
if(requestCode == 1 && resultCode == RESULT_OK)
|
|
|
|
{
|
|
|
|
if(data != null)
|
|
|
|
{
|
2017-06-12 06:23:47 +01:00
|
|
|
gameInfo.removeBitmapFromMemCache(data.getStringExtra("indexid"));
|
2015-08-20 22:26:01 +01:00
|
|
|
}
|
|
|
|
prepareFileListView(false);
|
|
|
|
}
|
2021-08-13 17:21:17 -04:00
|
|
|
|
|
|
|
if(requestCode == g_folderPickerRequestCode && resultCode == RESULT_OK)
|
|
|
|
{
|
|
|
|
Uri folderUri = data.getData();
|
|
|
|
getContentResolver().takePersistableUriPermission(folderUri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
2021-11-08 12:26:06 -05:00
|
|
|
prepareFileListView(false);
|
2021-08-13 17:21:17 -04:00
|
|
|
}
|
2021-10-13 09:36:58 -04:00
|
|
|
|
|
|
|
if(requestCode == g_dataFilesFolderPickerRequestCode && resultCode == RESULT_OK)
|
|
|
|
{
|
|
|
|
Uri folderUri = data.getData();
|
|
|
|
executeDataFilesMigration(folderUri);
|
|
|
|
}
|
2015-08-09 02:49:24 +01:00
|
|
|
}
|
|
|
|
|
2015-05-11 00:53:35 -04:00
|
|
|
private void displayAboutDialog()
|
|
|
|
{
|
2017-05-01 16:57:40 +01:00
|
|
|
Date buildDate = BuildConfig.buildTime;
|
2017-05-20 18:45:25 -04:00
|
|
|
String buildDateString = new SimpleDateFormat("yyyy/MM/dd K:mm a", Locale.getDefault()).format(buildDate);
|
2021-07-06 12:57:48 -04:00
|
|
|
String timestamp = buildDateString.substring(11).startsWith("0:")
|
2017-05-20 18:45:25 -04:00
|
|
|
? buildDateString.replace("0:", "12:") : buildDateString;
|
2023-07-11 01:33:13 +08:00
|
|
|
String aboutMessage = String.format(getString(R.string.about_play_emu) + "\n\n" + getString(R.string.about_play_version) + " %s\n" + getString(R.string.about_play_date) + " %s\n\n" + getString(R.string.about_play_founder) + "\nJean-Philip Desjardins", BuildConfig.VERSION_NAME, timestamp);
|
|
|
|
displaySimpleMessage(getString(R.string.about_play), aboutMessage);
|
2015-05-11 00:53:35 -04:00
|
|
|
}
|
2015-08-03 00:09:20 +01:00
|
|
|
|
2015-07-17 00:25:09 -04:00
|
|
|
@Override
|
2021-07-06 12:57:48 -04:00
|
|
|
public void onConfigurationChanged(@NonNull Configuration newConfig)
|
2017-07-05 10:17:37 -04:00
|
|
|
{
|
2015-07-17 00:25:09 -04:00
|
|
|
super.onConfigurationChanged(newConfig);
|
2015-08-02 12:51:01 +01:00
|
|
|
mNavigationDrawerFragment.onConfigurationChanged(newConfig);
|
2017-07-05 10:17:37 -04:00
|
|
|
if(newConfig.orientation != currentOrientation)
|
|
|
|
{
|
2015-08-03 00:36:26 -04:00
|
|
|
currentOrientation = newConfig.orientation;
|
2015-08-18 00:05:31 +01:00
|
|
|
setUIcolor();
|
2021-07-06 12:57:48 -04:00
|
|
|
prepareFileListView(currentGames != null && !currentGames.isEmpty());
|
2015-08-03 00:36:26 -04:00
|
|
|
}
|
2015-07-17 00:25:09 -04:00
|
|
|
}
|
2015-09-16 19:47:34 +01:00
|
|
|
|
2015-08-19 21:35:14 +01:00
|
|
|
@Override
|
2017-07-05 10:17:37 -04:00
|
|
|
public void onNavigationDrawerItemSelected(int position)
|
|
|
|
{
|
|
|
|
switch(position)
|
|
|
|
{
|
|
|
|
case SORT_RECENT:
|
|
|
|
sortMethod = SORT_RECENT;
|
|
|
|
navSubtitle = getString(R.string.file_list_recent);
|
|
|
|
break;
|
|
|
|
case SORT_HOMEBREW:
|
|
|
|
sortMethod = SORT_HOMEBREW;
|
|
|
|
navSubtitle = getString(R.string.file_list_homebrew);
|
|
|
|
break;
|
|
|
|
case SORT_NONE:
|
|
|
|
default:
|
|
|
|
sortMethod = SORT_NONE;
|
|
|
|
navSubtitle = getString(R.string.file_list_default);
|
|
|
|
break;
|
2015-08-04 13:01:16 -04:00
|
|
|
}
|
2015-09-22 23:24:43 +01:00
|
|
|
|
|
|
|
ActionBar actionbar = getSupportActionBar();
|
2017-07-05 10:17:37 -04:00
|
|
|
if(actionbar != null)
|
|
|
|
{
|
2023-07-11 01:33:13 +08:00
|
|
|
actionbar.setSubtitle(getString(R.string.menu_title_shut) + " - " + navSubtitle);
|
2015-09-22 23:24:43 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
prepareFileListView(false);
|
|
|
|
|
|
|
|
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
|
2024-10-25 21:21:52 +01:00
|
|
|
sp.edit().putInt("sortMethod.v2", sortMethod).apply();
|
2015-08-02 12:51:01 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2017-07-05 10:17:37 -04:00
|
|
|
public void onNavigationDrawerBottomItemSelected(int position)
|
|
|
|
{
|
|
|
|
switch(position)
|
|
|
|
{
|
|
|
|
case 0:
|
|
|
|
displaySettingsActivity();
|
|
|
|
break;
|
|
|
|
case 1:
|
2021-08-13 17:21:17 -04:00
|
|
|
displayFolderPicker();
|
|
|
|
break;
|
|
|
|
case 2:
|
2017-07-05 10:17:37 -04:00
|
|
|
displayAboutDialog();
|
|
|
|
break;
|
2015-08-02 12:51:01 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-05 10:17:37 -04:00
|
|
|
public void restoreActionBar()
|
|
|
|
{
|
2021-07-06 12:57:48 -04:00
|
|
|
ActionBar actionBar = getSupportActionBar();
|
2015-08-02 12:51:01 +01:00
|
|
|
actionBar.setDisplayShowTitleEnabled(true);
|
|
|
|
actionBar.setTitle(R.string.app_name);
|
2023-07-11 01:33:13 +08:00
|
|
|
actionBar.setSubtitle(getString(R.string.menu_title_shut) + " - " + navSubtitle);
|
2015-08-02 12:51:01 +01:00
|
|
|
}
|
|
|
|
|
2017-07-05 10:17:37 -04:00
|
|
|
public boolean onCreateOptionsMenu(Menu menu)
|
|
|
|
{
|
|
|
|
if(!mNavigationDrawerFragment.isDrawerOpen())
|
|
|
|
{
|
2015-08-02 12:51:01 +01:00
|
|
|
// Only show items in the action bar relevant to this screen
|
|
|
|
// if the drawer is not showing. Otherwise, let the drawer
|
|
|
|
// decide what to show in the action bar.
|
|
|
|
//getMenuInflater().inflate(R.menu.main, menu);
|
|
|
|
restoreActionBar();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return super.onCreateOptionsMenu(menu);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2017-07-05 10:17:37 -04:00
|
|
|
public void onBackPressed()
|
|
|
|
{
|
2021-07-06 12:57:48 -04:00
|
|
|
if(NavigationDrawerFragment.mDrawerLayout != null && mNavigationDrawerFragment.isDrawerOpen())
|
2017-07-05 10:17:37 -04:00
|
|
|
{
|
2021-07-06 12:57:48 -04:00
|
|
|
NavigationDrawerFragment.mDrawerLayout.closeDrawer(NavigationDrawerFragment.mFragmentContainerView);
|
2015-08-02 12:51:01 +01:00
|
|
|
return;
|
|
|
|
}
|
2015-08-03 07:44:30 +01:00
|
|
|
super.onBackPressed();
|
|
|
|
finish();
|
2015-08-02 12:51:01 +01:00
|
|
|
}
|
|
|
|
|
2017-06-14 23:55:55 +01:00
|
|
|
@Override
|
2017-07-05 10:17:37 -04:00
|
|
|
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key)
|
|
|
|
{
|
2021-05-31 16:36:10 -04:00
|
|
|
if(key.equals(PREF_UI_RESCAN))
|
2017-06-14 23:55:55 +01:00
|
|
|
{
|
2021-05-31 16:36:10 -04:00
|
|
|
if(sharedPreferences.getBoolean(PREF_UI_RESCAN, false))
|
2017-06-14 23:55:55 +01:00
|
|
|
{
|
2021-05-31 16:36:10 -04:00
|
|
|
sharedPreferences.edit().putBoolean(PREF_UI_RESCAN, false).apply();
|
2017-06-14 23:55:55 +01:00
|
|
|
prepareFileListView(false, true);
|
|
|
|
}
|
|
|
|
}
|
2021-05-31 16:36:10 -04:00
|
|
|
else if(key.equals(PREF_UI_CLEAR_UNAVAILABLE))
|
2017-06-14 23:55:55 +01:00
|
|
|
{
|
2021-05-31 16:36:10 -04:00
|
|
|
if(sharedPreferences.getBoolean(PREF_UI_CLEAR_UNAVAILABLE, false))
|
2017-07-05 10:17:37 -04:00
|
|
|
{
|
2021-05-31 16:36:10 -04:00
|
|
|
sharedPreferences.edit().putBoolean(PREF_UI_CLEAR_UNAVAILABLE, false).apply();
|
2019-01-06 03:09:05 +00:00
|
|
|
PurgeInexistingFiles();
|
2017-06-14 23:55:55 +01:00
|
|
|
prepareFileListView(false);
|
|
|
|
}
|
|
|
|
}
|
2021-10-13 12:45:56 -04:00
|
|
|
else if(key.equals(PREF_UI_MIGRATE_DATA_FILES))
|
|
|
|
{
|
|
|
|
if(sharedPreferences.getBoolean(PREF_UI_MIGRATE_DATA_FILES, false))
|
|
|
|
{
|
|
|
|
sharedPreferences.edit().putBoolean(PREF_UI_MIGRATE_DATA_FILES, false).apply();
|
|
|
|
selectDataFilesFolderToMigrate();
|
|
|
|
}
|
|
|
|
}
|
2017-06-14 23:55:55 +01:00
|
|
|
}
|
|
|
|
|
2021-10-15 16:08:35 -04:00
|
|
|
private void scanContentFolder(DocumentFile folderDoc)
|
|
|
|
{
|
2021-08-13 17:21:17 -04:00
|
|
|
for(DocumentFile fileDoc : folderDoc.listFiles())
|
|
|
|
{
|
2021-08-25 10:28:20 -04:00
|
|
|
try
|
|
|
|
{
|
2021-10-15 16:08:35 -04:00
|
|
|
if(fileDoc.isDirectory())
|
|
|
|
{
|
|
|
|
scanContentFolder(fileDoc);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
String docUriString = fileDoc.getUri().toString();
|
2021-11-08 12:22:54 -05:00
|
|
|
if(!BootablesInterop.tryRegisterBootable(docUriString))
|
2021-10-20 09:06:01 -04:00
|
|
|
{
|
|
|
|
Log.w(Constants.TAG, String.format("scanContentFolder: Failed to register '%s'.", docUriString));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2021-10-23 11:32:46 -04:00
|
|
|
Log.w(Constants.TAG, String.format("scanContentFolder: Registered '%s'.", docUriString));
|
2021-10-20 09:06:01 -04:00
|
|
|
}
|
2021-10-15 16:08:35 -04:00
|
|
|
}
|
2021-08-25 10:28:20 -04:00
|
|
|
}
|
|
|
|
catch(Exception ex)
|
|
|
|
{
|
2021-10-15 16:08:35 -04:00
|
|
|
Log.w(Constants.TAG, String.format("scanContentFolder: Error while processing '%s': %s", fileDoc.getUri().toString(), ex.toString()));
|
2021-08-25 10:28:20 -04:00
|
|
|
}
|
2021-08-13 17:21:17 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-01-06 00:34:32 +00:00
|
|
|
private final class ImageFinder extends AsyncTask<String, Integer, List<Bootable>>
|
2017-07-05 10:17:37 -04:00
|
|
|
{
|
2015-08-19 21:35:14 +01:00
|
|
|
private final boolean fullscan;
|
2015-07-23 19:41:54 -04:00
|
|
|
private ProgressDialog progDialog;
|
2017-07-05 10:17:37 -04:00
|
|
|
|
|
|
|
public ImageFinder(boolean fullscan)
|
|
|
|
{
|
2015-08-19 21:35:14 +01:00
|
|
|
this.fullscan = fullscan;
|
2015-07-17 00:25:09 -04:00
|
|
|
}
|
2015-08-19 21:35:14 +01:00
|
|
|
|
2021-10-23 10:15:40 -04:00
|
|
|
@Override
|
2017-07-05 10:17:37 -04:00
|
|
|
protected void onPreExecute()
|
|
|
|
{
|
2015-07-23 19:41:54 -04:00
|
|
|
progDialog = ProgressDialog.show(MainActivity.this,
|
2017-07-05 10:17:37 -04:00
|
|
|
getString(R.string.search_games),
|
|
|
|
getString(R.string.search_games_msg), true);
|
2015-07-11 15:12:15 -04:00
|
|
|
}
|
2017-07-05 10:17:37 -04:00
|
|
|
|
2021-10-23 10:15:40 -04:00
|
|
|
void updateProgressText(String progressText)
|
|
|
|
{
|
|
|
|
runOnUiThread(new Runnable()
|
|
|
|
{
|
|
|
|
@Override
|
|
|
|
public void run()
|
|
|
|
{
|
|
|
|
progDialog.setMessage(progressText);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2015-07-11 15:12:15 -04:00
|
|
|
@Override
|
2019-01-06 00:34:32 +00:00
|
|
|
protected List<Bootable> doInBackground(String... paths)
|
2017-07-05 10:17:37 -04:00
|
|
|
{
|
2021-10-23 10:15:40 -04:00
|
|
|
//With scoped storage on Android 30, it's not possible to scan the device's filesystem
|
2021-10-22 09:07:07 -04:00
|
|
|
if(Build.VERSION.SDK_INT < Build.VERSION_CODES.R)
|
2017-07-05 10:17:37 -04:00
|
|
|
{
|
2021-10-26 08:48:07 -04:00
|
|
|
updateProgressText(getString(R.string.search_games_scanning));
|
2021-10-22 09:07:07 -04:00
|
|
|
if(fullscan)
|
|
|
|
{
|
|
|
|
GameIndexer.fullScan();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
GameIndexer.startupScan();
|
|
|
|
}
|
2015-08-19 21:35:14 +01:00
|
|
|
}
|
2019-01-06 00:34:32 +00:00
|
|
|
|
2021-11-08 12:26:06 -05:00
|
|
|
List<UriPermission> uriPermissions = getContentResolver().getPersistedUriPermissions();
|
|
|
|
if(!uriPermissions.isEmpty())
|
|
|
|
{
|
2021-11-08 18:14:15 -05:00
|
|
|
updateProgressText(getString(R.string.search_games_scan_folders));
|
2021-11-08 12:26:06 -05:00
|
|
|
|
|
|
|
for(UriPermission uriPermission : uriPermissions)
|
|
|
|
{
|
|
|
|
DocumentFile folderDoc = DocumentFile.fromTreeUri(MainActivity.this, uriPermission.getUri());
|
|
|
|
scanContentFolder(folderDoc);
|
|
|
|
}
|
|
|
|
|
2021-11-08 18:14:15 -05:00
|
|
|
updateProgressText(getString(R.string.search_games_fetching_titles));
|
2021-11-08 12:26:06 -05:00
|
|
|
BootablesInterop.fetchGameTitles();
|
|
|
|
}
|
|
|
|
|
2021-10-26 08:48:07 -04:00
|
|
|
updateProgressText(getString(R.string.search_games_fetching));
|
2021-10-23 10:15:40 -04:00
|
|
|
Bootable[] bootables = getBootables(sortMethod);
|
|
|
|
|
|
|
|
return new ArrayList<>(Arrays.asList(bootables));
|
2015-07-11 15:12:15 -04:00
|
|
|
}
|
2017-07-05 10:17:37 -04:00
|
|
|
|
2015-07-11 15:12:15 -04:00
|
|
|
@Override
|
2019-01-06 00:34:32 +00:00
|
|
|
protected void onPostExecute(List<Bootable> images)
|
2017-07-05 10:17:37 -04:00
|
|
|
{
|
2021-10-26 08:48:07 -04:00
|
|
|
updateProgressText(getString(R.string.search_games_populating));
|
2021-10-23 10:15:40 -04:00
|
|
|
|
|
|
|
currentGames = images;
|
|
|
|
// Create the list of acceptable images
|
|
|
|
populateImages(images);
|
|
|
|
|
2017-07-05 10:17:37 -04:00
|
|
|
if(progDialog != null && progDialog.isShowing())
|
|
|
|
{
|
2021-11-17 08:49:22 -05:00
|
|
|
try
|
|
|
|
{
|
|
|
|
progDialog.dismiss();
|
|
|
|
}
|
|
|
|
catch(final Exception e)
|
|
|
|
{
|
|
|
|
//We don't really care if we get an exception while dismissing
|
|
|
|
}
|
2015-07-23 19:41:54 -04:00
|
|
|
}
|
2015-08-04 15:00:16 -04:00
|
|
|
}
|
|
|
|
}
|
2017-07-05 10:17:37 -04:00
|
|
|
|
2019-01-06 00:34:32 +00:00
|
|
|
private void populateImages(List<Bootable> images)
|
2017-07-05 10:17:37 -04:00
|
|
|
{
|
2021-07-06 12:57:48 -04:00
|
|
|
GridView gameGrid = findViewById(R.id.game_grid);
|
2017-07-05 10:17:37 -04:00
|
|
|
if(gameGrid != null)
|
|
|
|
{
|
2015-08-04 15:00:16 -04:00
|
|
|
gameGrid.setAdapter(null);
|
2017-07-05 10:17:37 -04:00
|
|
|
if(isAndroidTV(this))
|
|
|
|
{
|
2021-07-06 12:57:48 -04:00
|
|
|
gameGrid.setOnItemClickListener((parent, v, position, id) -> v.performClick());
|
2015-09-11 22:41:15 +01:00
|
|
|
}
|
2017-07-05 10:17:37 -04:00
|
|
|
if(images == null || images.isEmpty())
|
|
|
|
{
|
2015-09-11 22:41:15 +01:00
|
|
|
// Display warning that no disks exist
|
|
|
|
ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, (sortMethod == SORT_RECENT) ? new String[]{getString(R.string.no_recent_adapter)} : new String[]{getString(R.string.no_game_found_adapter)});
|
|
|
|
gameGrid.setNumColumns(1);
|
|
|
|
gameGrid.setAdapter(adapter);
|
2017-07-05 10:17:37 -04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-06-06 00:49:13 +01:00
|
|
|
GamesAdapter adapter = new GamesAdapter(this, R.layout.game_list_item, images, gameInfo);
|
2015-09-11 22:41:15 +01:00
|
|
|
/*
|
|
|
|
-1 = autofit
|
|
|
|
*/
|
|
|
|
gameGrid.setNumColumns(-1);
|
2017-07-05 10:17:37 -04:00
|
|
|
gameGrid.setColumnWidth((int)getResources().getDimension(R.dimen.cover_width));
|
2015-09-11 22:41:15 +01:00
|
|
|
|
|
|
|
gameGrid.setAdapter(adapter);
|
|
|
|
gameGrid.invalidate();
|
|
|
|
}
|
2015-08-04 15:00:16 -04:00
|
|
|
}
|
2015-07-11 15:12:15 -04:00
|
|
|
}
|
2015-08-19 19:54:21 +01:00
|
|
|
|
2019-01-06 00:34:32 +00:00
|
|
|
public void launchGame(Bootable game)
|
2017-07-05 10:17:37 -04:00
|
|
|
{
|
2021-08-04 13:47:28 -04:00
|
|
|
if(BootablesInterop.DoesBootableExist(game.path))
|
2017-07-05 10:17:37 -04:00
|
|
|
{
|
2019-01-06 00:34:32 +00:00
|
|
|
setLastBootedTime(game.path, System.currentTimeMillis());
|
2017-07-05 10:17:37 -04:00
|
|
|
try
|
|
|
|
{
|
2023-10-10 11:59:59 -04:00
|
|
|
VirtualMachineManager.launchGame(this, game.path, null);
|
2017-07-05 10:17:37 -04:00
|
|
|
}
|
|
|
|
catch(Exception e)
|
|
|
|
{
|
2017-06-11 06:14:54 +01:00
|
|
|
displaySimpleMessage("Error", e.getMessage());
|
2015-11-06 13:22:16 +00:00
|
|
|
}
|
2017-07-05 10:17:37 -04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-06-11 06:14:54 +01:00
|
|
|
displayGameNotFound(game);
|
2015-08-23 23:53:29 +01:00
|
|
|
}
|
Organize classes, Database support, Remove dupes
Conflicts:
Source/ui_android/java/com/virtualapplications/play/MainActivity.java
Source/ui_android/java/com/virtualapplications/play/SetupDB.java
Source/ui_android/java/com/virtualapplications/play/TheGameDB.java
Source/ui_android/java/com/virtualapplications/play/getGameDetails.java
Load internal database, Fill from internet APIs
If a cover image and description are not in the database, attempt to
retrieve them from the API by ID. If an ID is not present, generate
temporary values based on search. These values are saved according to
the API ID, but not associated with the file name in storage. This
allows these entries to be applied to a game retrieved by ID at a later
time.
Combine long click calls into generic function
Fix long click function to return a value
Now that this is only the listener, it is no longer self-contained
Add a settings option to clear the cover cache
Log serial in relation to filename for reference
This may prove useful to obtain missing serial numbers.
Verify the existence of an image before loading
An image entry has been added to avoid the StackOverflow generated by
simply looping through the possible suffix values. The database has
been configured to pick up these image entries during the course of
regular checks.
Most images are -1, but a few have been found with alternate endings,
depending on revisions.
External database versioning for assets file
Using database version would cause the database to be rebuilt
internally, which would not copy the assets file.
The last modified time only applies to the written file and could not
be compared to the assets file, which would result in unnecessary
writes for every app update.
This method allow the value to be hard-coded in the app to reflect only
when the assets database is updated and avoid the restrictions of
runtime options.
Conflicts:
Source/ui_android/java/com/virtualapplications/play/getGameDetails.java
Conflicts:
Source/ui_android/java/com/virtualapplications/play/TheGamesDB.java
build_android/assets/games.db
Conflicts:
Source/ui_android/java/com/virtualapplications/play/TheGamesDB.java
build_android/assets/games.db
Reconnect getSerial call after rebase
2015-07-24 00:55:42 -04:00
|
|
|
}
|
2015-11-06 13:22:16 +00:00
|
|
|
|
2017-07-05 10:17:37 -04:00
|
|
|
private boolean isAndroidTV(Context context)
|
|
|
|
{
|
2021-07-06 12:57:48 -04:00
|
|
|
UiModeManager uiModeManager = (UiModeManager)
|
|
|
|
context.getSystemService(Context.UI_MODE_SERVICE);
|
|
|
|
return uiModeManager.getCurrentModeType() == Configuration.UI_MODE_TYPE_TELEVISION;
|
2015-07-17 16:15:35 -04:00
|
|
|
}
|
2015-07-16 10:09:26 -04:00
|
|
|
|
2017-06-14 23:55:55 +01:00
|
|
|
public void prepareFileListView(boolean retainList)
|
2015-08-19 21:35:14 +01:00
|
|
|
{
|
2017-07-11 23:27:46 +01:00
|
|
|
prepareFileListView(retainList, false);
|
2015-08-19 21:35:14 +01:00
|
|
|
}
|
2015-09-16 19:47:34 +01:00
|
|
|
|
2015-08-19 21:35:14 +01:00
|
|
|
private void prepareFileListView(boolean retainList, boolean fullscan)
|
2015-03-19 23:54:47 -04:00
|
|
|
{
|
2017-07-05 10:17:37 -04:00
|
|
|
if(gameInfo == null)
|
|
|
|
{
|
Organize classes, Database support, Remove dupes
Conflicts:
Source/ui_android/java/com/virtualapplications/play/MainActivity.java
Source/ui_android/java/com/virtualapplications/play/SetupDB.java
Source/ui_android/java/com/virtualapplications/play/TheGameDB.java
Source/ui_android/java/com/virtualapplications/play/getGameDetails.java
Load internal database, Fill from internet APIs
If a cover image and description are not in the database, attempt to
retrieve them from the API by ID. If an ID is not present, generate
temporary values based on search. These values are saved according to
the API ID, but not associated with the file name in storage. This
allows these entries to be applied to a game retrieved by ID at a later
time.
Combine long click calls into generic function
Fix long click function to return a value
Now that this is only the listener, it is no longer self-contained
Add a settings option to clear the cover cache
Log serial in relation to filename for reference
This may prove useful to obtain missing serial numbers.
Verify the existence of an image before loading
An image entry has been added to avoid the StackOverflow generated by
simply looping through the possible suffix values. The database has
been configured to pick up these image entries during the course of
regular checks.
Most images are -1, but a few have been found with alternate endings,
depending on revisions.
External database versioning for assets file
Using database version would cause the database to be rebuilt
internally, which would not copy the assets file.
The last modified time only applies to the written file and could not
be compared to the assets file, which would result in unnecessary
writes for every app update.
This method allow the value to be hard-coded in the app to reflect only
when the assets database is updated and avoid the restrictions of
runtime options.
Conflicts:
Source/ui_android/java/com/virtualapplications/play/getGameDetails.java
Conflicts:
Source/ui_android/java/com/virtualapplications/play/TheGamesDB.java
build_android/assets/games.db
Conflicts:
Source/ui_android/java/com/virtualapplications/play/TheGamesDB.java
build_android/assets/games.db
Reconnect getSerial call after rebase
2015-07-24 00:55:42 -04:00
|
|
|
gameInfo = new GameInfo(MainActivity.this);
|
|
|
|
}
|
2015-08-19 21:35:14 +01:00
|
|
|
|
2017-07-05 10:17:37 -04:00
|
|
|
if(retainList)
|
|
|
|
{
|
2015-08-04 15:00:16 -04:00
|
|
|
populateImages(currentGames);
|
2017-07-05 10:17:37 -04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2015-08-19 21:35:14 +01:00
|
|
|
new ImageFinder(fullscan).execute();
|
2015-08-04 13:01:16 -04:00
|
|
|
}
|
2015-04-11 23:07:40 -04:00
|
|
|
}
|
2021-10-13 09:36:58 -04:00
|
|
|
|
|
|
|
private void selectDataFilesFolderToMigrate()
|
|
|
|
{
|
2021-10-13 15:31:56 -04:00
|
|
|
new AlertDialog.Builder(this)
|
2021-10-13 16:30:14 -04:00
|
|
|
.setTitle(getString(R.string.migration_title))
|
|
|
|
.setMessage(getString(R.string.migration_selectfolder))
|
2021-10-13 15:31:56 -04:00
|
|
|
.setPositiveButton(android.R.string.ok, (dialog, id) -> {
|
|
|
|
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
|
2021-10-23 11:59:41 -04:00
|
|
|
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
|
|
|
intent.addFlags(Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
|
|
|
|
intent.addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
|
|
|
|
intent.putExtra(Intent.EXTRA_LOCAL_ONLY, true);
|
2021-10-13 15:31:56 -04:00
|
|
|
startActivityForResult(intent, g_dataFilesFolderPickerRequestCode);
|
|
|
|
})
|
|
|
|
.create()
|
|
|
|
.show();
|
2021-10-13 09:36:58 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
private void executeDataFilesMigration(Uri dataFilesFolderUri)
|
|
|
|
{
|
2021-10-19 09:59:49 -04:00
|
|
|
DataFilesMigrationProcessTask task = new DataFilesMigrationProcessTask(this, dataFilesFolderUri);
|
|
|
|
task.execute();
|
2021-10-13 09:36:58 -04:00
|
|
|
}
|
2014-12-03 07:25:55 +00:00
|
|
|
}
|