mirror of
https://github.com/doukutsu-rs/doukutsu-rs
synced 2025-03-24 19:09:22 +00:00
Implement "Open game/user data directory" menus on Android[ci skip]
This commit is contained in:
parent
12a305becb
commit
06ae269b7b
|
@ -10,16 +10,20 @@ import android.os.CancellationSignal;
|
|||
import android.os.ParcelFileDescriptor;
|
||||
import android.provider.DocumentsContract;
|
||||
import android.provider.DocumentsContract.Document;
|
||||
import android.provider.DocumentsContract.Path;
|
||||
import android.provider.DocumentsContract.Root;
|
||||
import android.provider.DocumentsProvider;
|
||||
import android.util.Log;
|
||||
import android.webkit.MimeTypeMap;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.RequiresApi;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.util.LinkedList;
|
||||
|
||||
import static android.os.Build.VERSION.SDK_INT;
|
||||
|
||||
|
@ -175,6 +179,29 @@ public class DoukutsuDocumentsProvider extends DocumentsProvider {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@RequiresApi(Build.VERSION_CODES.O)
|
||||
public Path findDocumentPath(@Nullable String parentDocumentId, String childDocumentId) throws FileNotFoundException {
|
||||
if (parentDocumentId == null) {
|
||||
parentDocumentId = getContext().getFilesDir().getAbsolutePath();
|
||||
}
|
||||
|
||||
File childFile = new File(childDocumentId);
|
||||
if (!childFile.exists()) {
|
||||
throw new FileNotFoundException(childFile.getAbsolutePath()+" doesn't exist");
|
||||
} else if (!isChildDocument(parentDocumentId, childDocumentId)) {
|
||||
throw new FileNotFoundException(childDocumentId+" is not child of "+parentDocumentId);
|
||||
}
|
||||
|
||||
LinkedList<String> path = new LinkedList<>();
|
||||
while (childFile != null && isChildDocument(parentDocumentId, childFile.getAbsolutePath())) {
|
||||
path.addFirst(childFile.getAbsolutePath());
|
||||
childFile = childFile.getParentFile();
|
||||
}
|
||||
|
||||
return new Path(parentDocumentId, path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDocumentType(String documentId) throws FileNotFoundException {
|
||||
File file = new File(documentId);
|
||||
|
|
|
@ -1,14 +1,17 @@
|
|||
package io.github.doukutsu_rs;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.app.NativeActivity;
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Configuration;
|
||||
import android.hardware.SensorManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.provider.DocumentsContract;
|
||||
import android.view.OrientationEventListener;
|
||||
import android.view.WindowInsets;
|
||||
import android.widget.Toast;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
|
@ -87,7 +90,27 @@ public class GameActivity extends NativeActivity {
|
|||
this.displayInsets[2] = Math.max(this.displayInsets[0], cutout.getSafeInsetRight());
|
||||
this.displayInsets[3] = Math.max(this.displayInsets[0], cutout.getSafeInsetBottom());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void openDir(String path) {
|
||||
Uri uri = DocumentsContract.buildDocumentUri(BuildConfig.DOCUMENTS_AUTHORITY, path);
|
||||
|
||||
File file = new File(path);
|
||||
if (!file.isDirectory()) {
|
||||
Toast.makeText(getApplicationContext(), R.string.dir_not_found, Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||
intent.addCategory(Intent.CATEGORY_DEFAULT);
|
||||
intent.setDataAndType(uri, DocumentsContract.Document.MIME_TYPE_DIR);
|
||||
intent.setFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
|
||||
|
||||
try {
|
||||
startActivity(intent);
|
||||
} catch(ActivityNotFoundException e) {
|
||||
Toast.makeText(getApplicationContext(), R.string.no_app_found_to_open_dir, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<string name="download_desc">No data files found, would you like to download them?</string>
|
||||
|
||||
<string name="download_status_error_http">Bad HTTP response code: %d</string>
|
||||
<!-- Downloading {entry_name}... {percentage progress}% ({downloaded}/{from} KiB, {speed} KiB/s) -->
|
||||
<!-- Downloading {entry_name}… {progress}% ({downloaded_size}/{total_size} KiB, {speed} KiB/s) -->
|
||||
<string name="download_status_downloading">Downloading %1$s… %2$d%% (%3$d/%4$d KiB, %5$d KiB/s)</string>
|
||||
<string name="download_status_downloading_null">Downloading %1$s… --%% (%2$d KiB, %3$d KiB/s)</string>
|
||||
<string name="download_status_unpacking">Unpacking: %s</string>
|
||||
|
@ -14,4 +14,7 @@
|
|||
|
||||
<!-- Look {entry_name} on 9th line -->
|
||||
<string name="download_entries_base">base game files</string>
|
||||
|
||||
<string name="dir_not_found">Dir not found</string>
|
||||
<string name="no_app_found_to_open_dir">No app found to open dir</string>
|
||||
</resources>
|
||||
|
|
|
@ -147,7 +147,6 @@ fn get_insets() -> GameResult<(f32, f32, f32, f32)> {
|
|||
let vm = JavaVM::from_raw(vm_ptr)?;
|
||||
let vm_env = vm.attach_current_thread()?;
|
||||
|
||||
//let class = vm_env.find_class("io/github/doukutsu_rs/MainActivity")?;
|
||||
let class = vm_env.new_global_ref(JObject::from_raw(ndk_glue::native_activity().activity()))?;
|
||||
let field = vm_env.get_field(class.as_obj(), "displayInsets", "[I")?.to_jni().l as jni::sys::jintArray;
|
||||
|
||||
|
@ -155,11 +154,11 @@ fn get_insets() -> GameResult<(f32, f32, f32, f32)> {
|
|||
vm_env.get_int_array_region(field, 0, &mut elements)?;
|
||||
|
||||
vm_env.delete_local_ref(JObject::from_raw(field));
|
||||
|
||||
|
||||
//Game always runs with horizontal orientation so top and bottom cutouts not needed and only wastes piece of the screen
|
||||
elements[1] = 0;
|
||||
elements[3] = 0;
|
||||
|
||||
|
||||
Ok((elements[0] as f32, elements[1] as f32, elements[2] as f32, elements[3] as f32))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -196,7 +196,21 @@ impl FilesystemContainer {
|
|||
return Ok(()); // can't open directories on switch
|
||||
|
||||
#[cfg(target_os = "android")]
|
||||
return Ok(()); // TODO: figure out how to do this on android
|
||||
unsafe {
|
||||
use jni::objects::{JObject, JValue};
|
||||
use jni::JavaVM;
|
||||
|
||||
let vm_ptr = ndk_glue::native_activity().vm();
|
||||
let vm = JavaVM::from_raw(vm_ptr)?;
|
||||
let vm_env = vm.attach_current_thread()?;
|
||||
|
||||
let class = vm_env.new_global_ref(JObject::from_raw(ndk_glue::native_activity().activity()))?;
|
||||
let method = vm_env.call_method(class.as_obj(), "openDir", "(Ljava/lang/String;)V", &[
|
||||
JValue::from(vm_env.new_string(path.to_str().unwrap()).unwrap())
|
||||
])?;
|
||||
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
#[cfg(not(any(target_os = "android", target_os = "horizon")))]
|
||||
open::that(path).map_err(|e| {
|
||||
|
|
|
@ -392,7 +392,7 @@ impl SettingsMenu {
|
|||
);
|
||||
self.links.push_entry(LinksMenuEntry::Link(GETPLUS_LINK), MenuEntry::Active("Get Cave Story+".to_owned()));
|
||||
|
||||
#[cfg(not(any(target_os = "android", target_os = "horizon")))]
|
||||
#[cfg(not(any(target_os = "horizon")))]
|
||||
self.main.push_entry(
|
||||
MainMenuEntry::Advanced,
|
||||
MenuEntry::Active(state.loc.t("menus.options_menu.advanced").to_owned()),
|
||||
|
|
Loading…
Reference in a new issue