mirror of
https://github.com/vcmi/vcmi.git
synced 2024-11-21 17:17:06 +02:00
[android][launcher] copy existing oh3 files using Java
This commit is contained in:
parent
ed6ab19818
commit
d7bf6b7dbe
@ -157,4 +157,5 @@ def LoadSigningConfig(final signingConfigKey) {
|
||||
dependencies {
|
||||
implementation fileTree(dir: '../libs', include: ['*.jar', '*.aar'])
|
||||
implementation 'androidx.annotation:annotation:1.7.1'
|
||||
implementation 'androidx.documentfile:documentfile:1.0.1'
|
||||
}
|
||||
|
@ -1,10 +1,18 @@
|
||||
package eu.vcmi.vcmi;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.provider.DocumentsContract;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import eu.vcmi.vcmi.VcmiSDLActivity;
|
||||
import eu.vcmi.vcmi.util.FileUtil;
|
||||
|
||||
import org.libsdl.app.SDL;
|
||||
|
||||
@ -13,6 +21,8 @@ import org.libsdl.app.SDL;
|
||||
*/
|
||||
public class ActivityLauncher extends org.qtproject.qt5.android.bindings.QtActivity
|
||||
{
|
||||
private static final int PICK_EXTERNAL_VCMI_DATA_TO_COPY = 1;
|
||||
|
||||
public boolean justLaunched = true;
|
||||
|
||||
@Override
|
||||
@ -23,6 +33,28 @@ public class ActivityLauncher extends org.qtproject.qt5.android.bindings.QtActiv
|
||||
SDL.setContext(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent resultData)
|
||||
{
|
||||
if (requestCode == PICK_EXTERNAL_VCMI_DATA_TO_COPY && resultCode == Activity.RESULT_OK)
|
||||
{
|
||||
if (resultData != null && FileUtil.copyData(resultData.getData(), this))
|
||||
NativeMethods.heroesDataUpdate();
|
||||
return;
|
||||
}
|
||||
|
||||
super.onActivityResult(requestCode, resultCode, resultData);
|
||||
}
|
||||
|
||||
public void copyHeroesData()
|
||||
{
|
||||
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
|
||||
intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI,
|
||||
Uri.fromFile(new File(Environment.getExternalStorageDirectory(), "vcmi-data"))
|
||||
);
|
||||
startActivityForResult(intent, PICK_EXTERNAL_VCMI_DATA_TO_COPY);
|
||||
}
|
||||
|
||||
public void onLaunchGameBtnPressed()
|
||||
{
|
||||
startActivity(new Intent(ActivityLauncher.this, VcmiSDLActivity.class));
|
||||
|
@ -8,8 +8,6 @@ import android.os.Build;
|
||||
public class Const
|
||||
{
|
||||
public static final String JNI_METHOD_SUPPRESS = "unused"; // jni methods are marked as unused, because IDE doesn't understand jni calls
|
||||
// used to disable lint errors about try-with-resources being unsupported on api <19 (it is supported, because retrolambda backports it)
|
||||
public static final int SUPPRESS_TRY_WITH_RESOURCES_WARNING = Build.VERSION_CODES.KITKAT;
|
||||
|
||||
public static final String VCMI_DATA_ROOT_FOLDER_NAME = "vcmi-data";
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ public class NativeMethods
|
||||
}
|
||||
|
||||
public static native void initClassloader();
|
||||
|
||||
public static native void heroesDataUpdate();
|
||||
public static native boolean tryToSaveTheGame();
|
||||
|
||||
public static void setupMsg(final Messenger msg)
|
||||
|
107
android/vcmi-app/src/main/java/eu/vcmi/vcmi/util/FileUtil.java
Normal file
107
android/vcmi-app/src/main/java/eu/vcmi/vcmi/util/FileUtil.java
Normal file
@ -0,0 +1,107 @@
|
||||
package eu.vcmi.vcmi.util;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.net.Uri;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.documentfile.provider.DocumentFile;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.List;
|
||||
|
||||
import eu.vcmi.vcmi.Storage;
|
||||
|
||||
/**
|
||||
* @author F
|
||||
*/
|
||||
public class FileUtil
|
||||
{
|
||||
private static final int BUFFER_SIZE = 4096;
|
||||
|
||||
public static boolean copyData(Uri folderToCopy, Activity activity)
|
||||
{
|
||||
File targetDir = Storage.getVcmiDataDir(activity);
|
||||
DocumentFile sourceDir = DocumentFile.fromTreeUri(activity, folderToCopy);
|
||||
return copyDirectory(targetDir, sourceDir, List.of("Data", "Maps", "Mp3"), activity);
|
||||
}
|
||||
|
||||
private static boolean copyDirectory(File targetDir, DocumentFile sourceDir, @Nullable List<String> allowed, Activity activity)
|
||||
{
|
||||
if (!targetDir.exists())
|
||||
{
|
||||
targetDir.mkdir();
|
||||
}
|
||||
|
||||
for (DocumentFile child : sourceDir.listFiles())
|
||||
{
|
||||
if (allowed != null)
|
||||
{
|
||||
boolean fileAllowed = false;
|
||||
|
||||
for (String str : allowed)
|
||||
{
|
||||
if (str.equalsIgnoreCase(child.getName()))
|
||||
{
|
||||
fileAllowed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!fileAllowed)
|
||||
continue;
|
||||
}
|
||||
|
||||
File exported = new File(targetDir, child.getName());
|
||||
|
||||
if (child.isFile())
|
||||
{
|
||||
if (!exported.exists())
|
||||
{
|
||||
try
|
||||
{
|
||||
exported.createNewFile();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
Log.e(activity, "createNewFile failed: " + e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
try (
|
||||
final OutputStream targetStream = new FileOutputStream(exported, false);
|
||||
final InputStream sourceStream = activity.getContentResolver()
|
||||
.openInputStream(child.getUri()))
|
||||
{
|
||||
copyStream(sourceStream, targetStream);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
Log.e(activity, "copyStream failed: " + e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (child.isDirectory() && !copyDirectory(exported, child, null, activity))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static void copyStream(InputStream source, OutputStream target) throws IOException
|
||||
{
|
||||
final byte[] buffer = new byte[BUFFER_SIZE];
|
||||
int read;
|
||||
while ((read = source.read(buffer)) != -1)
|
||||
{
|
||||
target.write(buffer, 0, read);
|
||||
}
|
||||
}
|
||||
}
|
@ -26,6 +26,17 @@
|
||||
#include "cli/extract.hpp"
|
||||
#endif
|
||||
|
||||
#ifdef VCMI_ANDROID
|
||||
#include <QAndroidJniObject>
|
||||
#include <QtAndroid>
|
||||
|
||||
static FirstLaunchView * thiz;
|
||||
extern "C" JNIEXPORT void JNICALL Java_eu_vcmi_vcmi_NativeMethods_heroesDataUpdate(JNIEnv * env, jclass cls)
|
||||
{
|
||||
thiz->heroesDataUpdate();
|
||||
}
|
||||
#endif
|
||||
|
||||
FirstLaunchView::FirstLaunchView(QWidget * parent)
|
||||
: QWidget(parent)
|
||||
, ui(new Ui::FirstLaunchView)
|
||||
@ -97,7 +108,12 @@ void FirstLaunchView::on_pushButtonDataSearch_clicked()
|
||||
|
||||
void FirstLaunchView::on_pushButtonDataCopy_clicked()
|
||||
{
|
||||
#ifdef VCMI_ANDROID
|
||||
thiz = this;
|
||||
QtAndroid::androidActivity().callMethod<void>("copyHeroesData");
|
||||
#else
|
||||
copyHeroesData();
|
||||
#endif
|
||||
}
|
||||
|
||||
void FirstLaunchView::on_pushButtonGogInstall_clicked()
|
||||
@ -198,11 +214,22 @@ void FirstLaunchView::heroesDataMissing()
|
||||
ui->lineEditDataSystem->setPalette(newPalette);
|
||||
ui->lineEditDataUser->setPalette(newPalette);
|
||||
|
||||
ui->pushButtonDataSearch->setVisible(true);
|
||||
ui->pushButtonDataCopy->setVisible(true);
|
||||
|
||||
ui->labelDataSearch->setVisible(true);
|
||||
ui->labelDataCopy->setVisible(true);
|
||||
ui->pushButtonDataSearch->setVisible(true);
|
||||
|
||||
#ifdef VCMI_ANDROID
|
||||
// selecting directory with ACTION_OPEN_DOCUMENT_TREE is available only since API level 21
|
||||
if (QtAndroid::androidSdkVersion() < 21)
|
||||
{
|
||||
ui->labelDataCopy->hide();
|
||||
ui->pushButtonDataCopy->hide();
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
ui->labelDataCopy->show();
|
||||
ui->pushButtonDataCopy->show();
|
||||
}
|
||||
|
||||
ui->labelDataFound->setVisible(false);
|
||||
ui->pushButtonDataNext->setEnabled(false);
|
||||
|
@ -35,7 +35,6 @@ class FirstLaunchView : public QWidget
|
||||
void languageSelected(const QString & languageCode);
|
||||
|
||||
// Tab Heroes III Data
|
||||
bool heroesDataUpdate();
|
||||
bool heroesDataDetect();
|
||||
|
||||
void heroesDataMissing();
|
||||
@ -64,6 +63,9 @@ class FirstLaunchView : public QWidget
|
||||
public:
|
||||
explicit FirstLaunchView(QWidget * parent = nullptr);
|
||||
|
||||
// Tab Heroes III Data
|
||||
bool heroesDataUpdate();
|
||||
|
||||
public slots:
|
||||
|
||||
private slots:
|
||||
|
Loading…
Reference in New Issue
Block a user