From 62ae7adab2bebde04864c12543caefbffab24963 Mon Sep 17 00:00:00 2001 From: Maksim Date: Wed, 15 Apr 2020 16:27:40 +0200 Subject: Android: add Android Studio support, completely redone java part (#9066) --- build/android/app/src/main/AndroidManifest.xml | 60 ++++++++ .../java/net/minetest/minetest/CopyZipTask.java | 82 +++++++++++ .../java/net/minetest/minetest/GameActivity.java | 120 ++++++++++++++++ .../net/minetest/minetest/InputDialogActivity.java | 98 +++++++++++++ .../java/net/minetest/minetest/MainActivity.java | 139 +++++++++++++++++++ .../java/net/minetest/minetest/UnzipService.java | 153 +++++++++++++++++++++ .../app/src/main/res/drawable/background.png | Bin 0 -> 83 bytes build/android/app/src/main/res/drawable/bg.xml | 4 + .../app/src/main/res/layout/activity_main.xml | 30 ++++ .../app/src/main/res/mipmap/ic_launcher.png | Bin 0 -> 5780 bytes build/android/app/src/main/res/values/strings.xml | 10 ++ build/android/app/src/main/res/values/styles.xml | 22 +++ 12 files changed, 718 insertions(+) create mode 100644 build/android/app/src/main/AndroidManifest.xml create mode 100644 build/android/app/src/main/java/net/minetest/minetest/CopyZipTask.java create mode 100644 build/android/app/src/main/java/net/minetest/minetest/GameActivity.java create mode 100644 build/android/app/src/main/java/net/minetest/minetest/InputDialogActivity.java create mode 100644 build/android/app/src/main/java/net/minetest/minetest/MainActivity.java create mode 100644 build/android/app/src/main/java/net/minetest/minetest/UnzipService.java create mode 100644 build/android/app/src/main/res/drawable/background.png create mode 100644 build/android/app/src/main/res/drawable/bg.xml create mode 100644 build/android/app/src/main/res/layout/activity_main.xml create mode 100644 build/android/app/src/main/res/mipmap/ic_launcher.png create mode 100644 build/android/app/src/main/res/values/strings.xml create mode 100644 build/android/app/src/main/res/values/styles.xml (limited to 'build/android/app/src') diff --git a/build/android/app/src/main/AndroidManifest.xml b/build/android/app/src/main/AndroidManifest.xml new file mode 100644 index 000000000..3a5342751 --- /dev/null +++ b/build/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/android/app/src/main/java/net/minetest/minetest/CopyZipTask.java b/build/android/app/src/main/java/net/minetest/minetest/CopyZipTask.java new file mode 100644 index 000000000..770995502 --- /dev/null +++ b/build/android/app/src/main/java/net/minetest/minetest/CopyZipTask.java @@ -0,0 +1,82 @@ +/* +Minetest +Copyright (C) 2014-2020 MoNTE48, Maksim Gamarnik +Copyright (C) 2014-2020 ubulem, Bektur Mambetov + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +package net.minetest.minetest; + +import android.content.Context; +import android.content.Intent; +import android.os.AsyncTask; +import android.util.Log; + +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.lang.ref.WeakReference; + +public class CopyZipTask extends AsyncTask { + + private final WeakReference contextRef; + + CopyZipTask(Context context) { + contextRef = new WeakReference<>(context); + } + + protected String doInBackground(String... params) { + copyAssets(params); + return params[0]; + } + + @Override + protected void onPostExecute(String result) { + startUnzipService(result); + } + + private void copyAsset(String zipName) throws IOException { + String filename = zipName.substring(zipName.lastIndexOf("/") + 1); + try (InputStream in = contextRef.get().getAssets().open(filename); + OutputStream out = new FileOutputStream(zipName)) { + copyFile(in, out); + } + } + + private void copyAssets(String[] zips) { + try { + for (String zipName : zips) + copyAsset(zipName); + } catch (IOException e) { + Log.e("CopyZipTask", e.getLocalizedMessage()); + cancel(true); + } + } + + private void copyFile(InputStream in, OutputStream out) throws IOException { + byte[] buffer = new byte[1024]; + int read; + while ((read = in.read(buffer)) != -1) + out.write(buffer, 0, read); + } + + private void startUnzipService(String file) { + Intent intent = new Intent(contextRef.get(), UnzipService.class); + intent.putExtra(UnzipService.EXTRA_KEY_IN_FILE, file); + contextRef.get().startService(intent); + } +} diff --git a/build/android/app/src/main/java/net/minetest/minetest/GameActivity.java b/build/android/app/src/main/java/net/minetest/minetest/GameActivity.java new file mode 100644 index 000000000..02b61b598 --- /dev/null +++ b/build/android/app/src/main/java/net/minetest/minetest/GameActivity.java @@ -0,0 +1,120 @@ +/* +Minetest +Copyright (C) 2014-2020 MoNTE48, Maksim Gamarnik +Copyright (C) 2014-2020 ubulem, Bektur Mambetov + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +package net.minetest.minetest; + +import android.app.NativeActivity; +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.view.View; +import android.view.WindowManager; + +public class GameActivity extends NativeActivity { + static { + System.loadLibrary("c++_shared"); + System.loadLibrary("Minetest"); + } + + private int messageReturnCode; + private String messageReturnValue; + + public static native void putMessageBoxResult(String text); + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + messageReturnCode = -1; + messageReturnValue = ""; + } + + private void makeFullScreen() { + if (Build.VERSION.SDK_INT >= 19) + this.getWindow().getDecorView().setSystemUiVisibility( + View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | + View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | + View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY); + } + + @Override + public void onWindowFocusChanged(boolean hasFocus) { + super.onWindowFocusChanged(hasFocus); + if (hasFocus) + makeFullScreen(); + } + + @Override + protected void onResume() { + super.onResume(); + makeFullScreen(); + } + + @Override + public void onBackPressed() { + // Ignore the back press so Minetest can handle it + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + if (requestCode == 101) { + if (resultCode == RESULT_OK) { + String text = data.getStringExtra("text"); + messageReturnCode = 0; + messageReturnValue = text; + } else + messageReturnCode = 1; + } + } + + public void showDialog(String acceptButton, String hint, String current, int editType) { + Intent intent = new Intent(this, InputDialogActivity.class); + Bundle params = new Bundle(); + params.putString("acceptButton", acceptButton); + params.putString("hint", hint); + params.putString("current", current); + params.putInt("editType", editType); + intent.putExtras(params); + startActivityForResult(intent, 101); + messageReturnValue = ""; + messageReturnCode = -1; + } + + public int getDialogState() { + return messageReturnCode; + } + + public String getDialogValue() { + messageReturnCode = -1; + return messageReturnValue; + } + + public float getDensity() { + return getResources().getDisplayMetrics().density; + } + + public int getDisplayHeight() { + return getResources().getDisplayMetrics().heightPixels; + } + + public int getDisplayWidth() { + return getResources().getDisplayMetrics().widthPixels; + } +} diff --git a/build/android/app/src/main/java/net/minetest/minetest/InputDialogActivity.java b/build/android/app/src/main/java/net/minetest/minetest/InputDialogActivity.java new file mode 100644 index 000000000..7c6aa111d --- /dev/null +++ b/build/android/app/src/main/java/net/minetest/minetest/InputDialogActivity.java @@ -0,0 +1,98 @@ +/* +Minetest +Copyright (C) 2014-2020 MoNTE48, Maksim Gamarnik +Copyright (C) 2014-2020 ubulem, Bektur Mambetov + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +package net.minetest.minetest; + +import android.app.Activity; +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.text.InputType; +import android.view.KeyEvent; +import android.view.View; +import android.view.inputmethod.InputMethodManager; +import android.widget.EditText; + +import androidx.appcompat.app.AlertDialog; +import androidx.appcompat.app.AppCompatActivity; + +import java.util.Objects; + +public class InputDialogActivity extends AppCompatActivity { + private AlertDialog alertDialog; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + Bundle b = getIntent().getExtras(); + int editType = Objects.requireNonNull(b).getInt("editType"); + String hint = b.getString("hint"); + String current = b.getString("current"); + final AlertDialog.Builder builder = new AlertDialog.Builder(this); + EditText editText = new EditText(this); + builder.setView(editText); + editText.requestFocus(); + editText.setHint(hint); + editText.setText(current); + final InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE); + Objects.requireNonNull(imm).toggleSoftInput(InputMethodManager.SHOW_FORCED, + InputMethodManager.HIDE_IMPLICIT_ONLY); + if (editType == 3) + editText.setInputType(InputType.TYPE_CLASS_TEXT | + InputType.TYPE_TEXT_VARIATION_PASSWORD); + else + editText.setInputType(InputType.TYPE_CLASS_TEXT); + editText.setOnKeyListener((view, KeyCode, event) -> { + if (KeyCode == KeyEvent.KEYCODE_ENTER) { + imm.hideSoftInputFromWindow(editText.getWindowToken(), 0); + pushResult(editText.getText().toString()); + return true; + } + return false; + }); + alertDialog = builder.create(); + if (!this.isFinishing()) + alertDialog.show(); + alertDialog.setOnCancelListener(dialog -> { + pushResult(editText.getText().toString()); + setResult(Activity.RESULT_CANCELED); + alertDialog.dismiss(); + makeFullScreen(); + finish(); + }); + } + + private void pushResult(String text) { + Intent resultData = new Intent(); + resultData.putExtra("text", text); + setResult(AppCompatActivity.RESULT_OK, resultData); + alertDialog.dismiss(); + makeFullScreen(); + finish(); + } + + private void makeFullScreen() { + if (Build.VERSION.SDK_INT >= 19) + this.getWindow().getDecorView().setSystemUiVisibility( + View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | + View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | + View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY); + } +} diff --git a/build/android/app/src/main/java/net/minetest/minetest/MainActivity.java b/build/android/app/src/main/java/net/minetest/minetest/MainActivity.java new file mode 100644 index 000000000..f37ae6d4b --- /dev/null +++ b/build/android/app/src/main/java/net/minetest/minetest/MainActivity.java @@ -0,0 +1,139 @@ +/* +Minetest +Copyright (C) 2014-2020 MoNTE48, Maksim Gamarnik +Copyright (C) 2014-2020 ubulem, Bektur Mambetov + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +package net.minetest.minetest; + +import android.Manifest; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.SharedPreferences; +import android.content.pm.PackageManager; +import android.os.Build; +import android.os.Bundle; +import android.view.View; +import android.widget.ProgressBar; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.appcompat.app.AppCompatActivity; +import androidx.core.app.ActivityCompat; +import androidx.core.content.ContextCompat; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class MainActivity extends AppCompatActivity { + private final static int versionCode = BuildConfig.VERSION_CODE; + private final static int PERMISSIONS = 1; + private static final String[] REQUIRED_SDK_PERMISSIONS = + new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}; + private static final String SETTINGS = "MinetestSettings"; + private static final String TAG_VERSION_CODE = "versionCode"; + private ProgressBar mProgressBar; + private TextView mTextView; + private SharedPreferences sharedPreferences; + private final BroadcastReceiver myReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + int progress = 0; + if (intent != null) + progress = intent.getIntExtra(UnzipService.ACTION_PROGRESS, 0); + if (progress >= 0) { + if (mProgressBar != null) { + mProgressBar.setVisibility(View.VISIBLE); + mProgressBar.setProgress(progress); + } + mTextView.setVisibility(View.VISIBLE); + } else + startNative(); + } + }; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + IntentFilter filter = new IntentFilter(UnzipService.ACTION_UPDATE); + registerReceiver(myReceiver, filter); + mProgressBar = findViewById(R.id.progressBar); + mTextView = findViewById(R.id.textView); + sharedPreferences = getSharedPreferences(SETTINGS, Context.MODE_PRIVATE); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) + checkPermission(); + else + checkAppVersion(); + } + + private void checkPermission() { + final List missingPermissions = new ArrayList<>(); + for (final String permission : REQUIRED_SDK_PERMISSIONS) { + final int result = ContextCompat.checkSelfPermission(this, permission); + if (result != PackageManager.PERMISSION_GRANTED) + missingPermissions.add(permission); + } + if (!missingPermissions.isEmpty()) { + final String[] permissions = missingPermissions + .toArray(new String[0]); + ActivityCompat.requestPermissions(this, permissions, PERMISSIONS); + } else { + final int[] grantResults = new int[REQUIRED_SDK_PERMISSIONS.length]; + Arrays.fill(grantResults, PackageManager.PERMISSION_GRANTED); + onRequestPermissionsResult(PERMISSIONS, REQUIRED_SDK_PERMISSIONS, grantResults); + } + } + + @Override + public void onRequestPermissionsResult(int requestCode, + @NonNull String[] permissions, @NonNull int[] grantResults) { + if (requestCode == PERMISSIONS) { + for (int grantResult : grantResults) { + if (grantResult != PackageManager.PERMISSION_GRANTED) { + Toast.makeText(this, R.string.not_granted, Toast.LENGTH_LONG).show(); + finish(); + } + } + checkAppVersion(); + } + } + + private void checkAppVersion() { + if (sharedPreferences.getInt(TAG_VERSION_CODE, 0) == versionCode) + startNative(); + else + new CopyZipTask(this).execute(getCacheDir() + "/Minetest.zip"); + } + + private void startNative() { + sharedPreferences.edit().putInt(TAG_VERSION_CODE, versionCode).apply(); + Intent intent = new Intent(this, GameActivity.class); + intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK); + startActivity(intent); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + unregisterReceiver(myReceiver); + } +} diff --git a/build/android/app/src/main/java/net/minetest/minetest/UnzipService.java b/build/android/app/src/main/java/net/minetest/minetest/UnzipService.java new file mode 100644 index 000000000..ac9116994 --- /dev/null +++ b/build/android/app/src/main/java/net/minetest/minetest/UnzipService.java @@ -0,0 +1,153 @@ +/* +Minetest +Copyright (C) 2014-2020 MoNTE48, Maksim Gamarnik +Copyright (C) 2014-2020 ubulem, Bektur Mambetov + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +package net.minetest.minetest; + +import android.app.IntentService; +import android.app.Notification; +import android.app.NotificationChannel; +import android.app.NotificationManager; +import android.content.Context; +import android.content.Intent; +import android.os.Build; +import android.os.Environment; +import android.util.Log; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; +import java.util.zip.ZipInputStream; + +public class UnzipService extends IntentService { + public static final String ACTION_UPDATE = "net.minetest.minetest.UPDATE"; + public static final String ACTION_PROGRESS = "net.minetest.minetest.PROGRESS"; + public static final String EXTRA_KEY_IN_FILE = "file"; + private static final String TAG = "UnzipService"; + private final int id = 1; + private NotificationManager mNotifyManager; + + public UnzipService() { + super("net.minetest.minetest.UnzipService"); + } + + private void isDir(String dir, String location) { + File f = new File(location + dir); + if (!f.isDirectory()) + f.mkdirs(); + } + + @Override + protected void onHandleIntent(Intent intent) { + createNotification(); + unzip(intent); + } + + private void createNotification() { + String name = "net.minetest.minetest"; + String channelId = "Minetest channel"; + String description = "notifications from Minetest"; + Notification.Builder builder; + if (mNotifyManager == null) + mNotifyManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + int importance = NotificationManager.IMPORTANCE_LOW; + NotificationChannel mChannel = null; + if (mNotifyManager != null) + mChannel = mNotifyManager.getNotificationChannel(channelId); + if (mChannel == null) { + mChannel = new NotificationChannel(channelId, name, importance); + mChannel.setDescription(description); + // Configure the notification channel, NO SOUND + mChannel.setSound(null, null); + mChannel.enableLights(false); + mChannel.enableVibration(false); + mNotifyManager.createNotificationChannel(mChannel); + } + builder = new Notification.Builder(this, channelId); + } else { + builder = new Notification.Builder(this); + } + builder.setContentTitle(getString(R.string.notification_title)) + .setSmallIcon(R.mipmap.ic_launcher) + .setContentText(getString(R.string.notification_description)); + mNotifyManager.notify(id, builder.build()); + } + + private void unzip(Intent intent) { + String zip = intent.getStringExtra(EXTRA_KEY_IN_FILE); + String location = Environment.getExternalStorageDirectory() + "/Minetest/"; + int per = 0; + int size = getSummarySize(zip); + File zipFile = new File(zip); + int readLen; + byte[] readBuffer = new byte[8192]; + try (FileInputStream fileInputStream = new FileInputStream(zipFile); + ZipInputStream zipInputStream = new ZipInputStream(fileInputStream)) { + ZipEntry ze; + while ((ze = zipInputStream.getNextEntry()) != null) { + if (ze.isDirectory()) { + ++per; + isDir(ze.getName(), location); + } else { + publishProgress(100 * ++per / size); + try (OutputStream outputStream = new FileOutputStream(location + ze.getName())) { + while ((readLen = zipInputStream.read(readBuffer)) != -1) { + outputStream.write(readBuffer, 0, readLen); + } + } + } + zipFile.delete(); + } + } catch (FileNotFoundException e) { + Log.e(TAG, e.getLocalizedMessage()); + } catch (IOException e) { + Log.e(TAG, e.getLocalizedMessage()); + } + } + + private void publishProgress(int progress) { + Intent intentUpdate = new Intent(ACTION_UPDATE); + intentUpdate.putExtra(ACTION_PROGRESS, progress); + sendBroadcast(intentUpdate); + } + + private int getSummarySize(String zip) { + int size = 0; + try { + ZipFile zipSize = new ZipFile(zip); + size += zipSize.size(); + } catch (IOException e) { + Log.e(TAG, e.getLocalizedMessage()); + } + return size; + } + + @Override + public void onDestroy() { + super.onDestroy(); + mNotifyManager.cancel(id); + publishProgress(-1); + } +} diff --git a/build/android/app/src/main/res/drawable/background.png b/build/android/app/src/main/res/drawable/background.png new file mode 100644 index 000000000..43bd6089e Binary files /dev/null and b/build/android/app/src/main/res/drawable/background.png differ diff --git a/build/android/app/src/main/res/drawable/bg.xml b/build/android/app/src/main/res/drawable/bg.xml new file mode 100644 index 000000000..903335ed9 --- /dev/null +++ b/build/android/app/src/main/res/drawable/bg.xml @@ -0,0 +1,4 @@ + + diff --git a/build/android/app/src/main/res/layout/activity_main.xml b/build/android/app/src/main/res/layout/activity_main.xml new file mode 100644 index 000000000..e6f461f14 --- /dev/null +++ b/build/android/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,30 @@ + + + + + + + diff --git a/build/android/app/src/main/res/mipmap/ic_launcher.png b/build/android/app/src/main/res/mipmap/ic_launcher.png new file mode 100644 index 000000000..88a83782c Binary files /dev/null and b/build/android/app/src/main/res/mipmap/ic_launcher.png differ diff --git a/build/android/app/src/main/res/values/strings.xml b/build/android/app/src/main/res/values/strings.xml new file mode 100644 index 000000000..a6fba70d5 --- /dev/null +++ b/build/android/app/src/main/res/values/strings.xml @@ -0,0 +1,10 @@ + + + + Minetest + Loading… + Required permission wasn\'t granted, Minetest can\'t run without it + Loading Minetest + Less than 1 minute… + + diff --git a/build/android/app/src/main/res/values/styles.xml b/build/android/app/src/main/res/values/styles.xml new file mode 100644 index 000000000..618507e63 --- /dev/null +++ b/build/android/app/src/main/res/values/styles.xml @@ -0,0 +1,22 @@ + + + + + + + + + + -- cgit v1.2.3 From 373bad16c089cd23448e8ce20b474e8fcf5b0c8b Mon Sep 17 00:00:00 2001 From: Maksim Date: Mon, 4 May 2020 08:47:00 +0200 Subject: Android: some java-part improvements (#9760) Replace Log to Toast. Start Native only after successful unpacking. Light refactoring in CopyZipTask. Update NDK version. Co-authored-by: ubulem --- build/android/app/build.gradle | 5 ++--- build/android/app/src/main/AndroidManifest.xml | 7 +++++++ .../src/main/java/net/minetest/minetest/CopyZipTask.java | 15 ++++----------- .../src/main/java/net/minetest/minetest/MainActivity.java | 13 ++++++++++--- .../src/main/java/net/minetest/minetest/UnzipService.java | 15 ++++++++------- build/android/native/build.gradle | 2 +- 6 files changed, 32 insertions(+), 25 deletions(-) (limited to 'build/android/app/src') diff --git a/build/android/app/build.gradle b/build/android/app/build.gradle index 9d14cdab8..00b8806bf 100644 --- a/build/android/app/build.gradle +++ b/build/android/app/build.gradle @@ -2,12 +2,11 @@ apply plugin: 'com.android.application' android { compileSdkVersion 29 buildToolsVersion '29.0.3' - ndkVersion '21.0.6113669' + ndkVersion '21.1.6352462' defaultConfig { applicationId 'net.minetest.minetest' minSdkVersion 16 - //noinspection OldTargetApi - targetSdkVersion 28 // Workaround for using `/sdcard` instead of the `data` patch for assets + targetSdkVersion 29 versionName "${versionMajor}.${versionMinor}.${versionPatch}" versionCode project.versionCode } diff --git a/build/android/app/src/main/AndroidManifest.xml b/build/android/app/src/main/AndroidManifest.xml index 3a5342751..aa5af110e 100644 --- a/build/android/app/src/main/AndroidManifest.xml +++ b/build/android/app/src/main/AndroidManifest.xml @@ -7,11 +7,18 @@ + + { } protected String doInBackground(String... params) { - copyAssets(params); + copyAsset(params[0]); return params[0]; } @@ -49,20 +49,13 @@ public class CopyZipTask extends AsyncTask { startUnzipService(result); } - private void copyAsset(String zipName) throws IOException { + private void copyAsset(String zipName) { String filename = zipName.substring(zipName.lastIndexOf("/") + 1); try (InputStream in = contextRef.get().getAssets().open(filename); OutputStream out = new FileOutputStream(zipName)) { copyFile(in, out); - } - } - - private void copyAssets(String[] zips) { - try { - for (String zipName : zips) - copyAsset(zipName); } catch (IOException e) { - Log.e("CopyZipTask", e.getLocalizedMessage()); + Toast.makeText(contextRef.get(), e.getLocalizedMessage(), Toast.LENGTH_LONG).show(); cancel(true); } } diff --git a/build/android/app/src/main/java/net/minetest/minetest/MainActivity.java b/build/android/app/src/main/java/net/minetest/minetest/MainActivity.java index f37ae6d4b..1e60beb55 100644 --- a/build/android/app/src/main/java/net/minetest/minetest/MainActivity.java +++ b/build/android/app/src/main/java/net/minetest/minetest/MainActivity.java @@ -43,6 +43,11 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import static net.minetest.minetest.UnzipService.ACTION_PROGRESS; +import static net.minetest.minetest.UnzipService.ACTION_UPDATE; +import static net.minetest.minetest.UnzipService.FAILURE; +import static net.minetest.minetest.UnzipService.SUCCESS; + public class MainActivity extends AppCompatActivity { private final static int versionCode = BuildConfig.VERSION_CODE; private final static int PERMISSIONS = 1; @@ -58,14 +63,16 @@ public class MainActivity extends AppCompatActivity { public void onReceive(Context context, Intent intent) { int progress = 0; if (intent != null) - progress = intent.getIntExtra(UnzipService.ACTION_PROGRESS, 0); + progress = intent.getIntExtra(ACTION_PROGRESS, 0); if (progress >= 0) { if (mProgressBar != null) { mProgressBar.setVisibility(View.VISIBLE); mProgressBar.setProgress(progress); } mTextView.setVisibility(View.VISIBLE); - } else + } else if (progress == FAILURE) { + finish(); + } else if (progress == SUCCESS) startNative(); } }; @@ -74,7 +81,7 @@ public class MainActivity extends AppCompatActivity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); - IntentFilter filter = new IntentFilter(UnzipService.ACTION_UPDATE); + IntentFilter filter = new IntentFilter(ACTION_UPDATE); registerReceiver(myReceiver, filter); mProgressBar = findViewById(R.id.progressBar); mTextView = findViewById(R.id.textView); diff --git a/build/android/app/src/main/java/net/minetest/minetest/UnzipService.java b/build/android/app/src/main/java/net/minetest/minetest/UnzipService.java index ac9116994..6356dff19 100644 --- a/build/android/app/src/main/java/net/minetest/minetest/UnzipService.java +++ b/build/android/app/src/main/java/net/minetest/minetest/UnzipService.java @@ -28,11 +28,10 @@ import android.content.Context; import android.content.Intent; import android.os.Build; import android.os.Environment; -import android.util.Log; +import android.widget.Toast; import java.io.File; import java.io.FileInputStream; -import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; @@ -44,9 +43,12 @@ public class UnzipService extends IntentService { public static final String ACTION_UPDATE = "net.minetest.minetest.UPDATE"; public static final String ACTION_PROGRESS = "net.minetest.minetest.PROGRESS"; public static final String EXTRA_KEY_IN_FILE = "file"; + public static final int SUCCESS = -1; + public static final int FAILURE = -2; private static final String TAG = "UnzipService"; private final int id = 1; private NotificationManager mNotifyManager; + private boolean isSuccess = true; public UnzipService() { super("net.minetest.minetest.UnzipService"); @@ -120,10 +122,9 @@ public class UnzipService extends IntentService { } zipFile.delete(); } - } catch (FileNotFoundException e) { - Log.e(TAG, e.getLocalizedMessage()); } catch (IOException e) { - Log.e(TAG, e.getLocalizedMessage()); + isSuccess = false; + Toast.makeText(this, e.getLocalizedMessage(), Toast.LENGTH_LONG).show(); } } @@ -139,7 +140,7 @@ public class UnzipService extends IntentService { ZipFile zipSize = new ZipFile(zip); size += zipSize.size(); } catch (IOException e) { - Log.e(TAG, e.getLocalizedMessage()); + Toast.makeText(this, e.getLocalizedMessage(), Toast.LENGTH_LONG).show(); } return size; } @@ -148,6 +149,6 @@ public class UnzipService extends IntentService { public void onDestroy() { super.onDestroy(); mNotifyManager.cancel(id); - publishProgress(-1); + publishProgress(isSuccess ? SUCCESS : FAILURE); } } diff --git a/build/android/native/build.gradle b/build/android/native/build.gradle index f06e4e3f0..cbd50db6a 100644 --- a/build/android/native/build.gradle +++ b/build/android/native/build.gradle @@ -4,7 +4,7 @@ import org.ajoberstar.grgit.Grgit android { compileSdkVersion 29 buildToolsVersion '29.0.3' - ndkVersion '21.0.6113669' + ndkVersion '21.1.6352462' defaultConfig { minSdkVersion 16 targetSdkVersion 29 -- cgit v1.2.3 From a9c3a423231e26ea3edee51d5f0bf949ca8e529b Mon Sep 17 00:00:00 2001 From: rubenwardy Date: Sun, 17 May 2020 19:09:10 +0100 Subject: Add core.open_url() to main menu API (#8592) --- .../java/net/minetest/minetest/GameActivity.java | 6 ++ builtin/mainmenu/dlg_contentstore.lua | 113 ++++----------------- builtin/mainmenu/tab_credits.lua | 11 +- doc/menu_lua_api.txt | 5 + src/porting.cpp | 30 +++++- src/porting.h | 3 + src/porting_android.cpp | 12 +++ src/porting_android.h | 2 + src/script/lua_api/l_mainmenu.cpp | 9 ++ src/script/lua_api/l_mainmenu.h | 3 + 10 files changed, 98 insertions(+), 96 deletions(-) (limited to 'build/android/app/src') diff --git a/build/android/app/src/main/java/net/minetest/minetest/GameActivity.java b/build/android/app/src/main/java/net/minetest/minetest/GameActivity.java index 02b61b598..635512569 100644 --- a/build/android/app/src/main/java/net/minetest/minetest/GameActivity.java +++ b/build/android/app/src/main/java/net/minetest/minetest/GameActivity.java @@ -22,6 +22,7 @@ package net.minetest.minetest; import android.app.NativeActivity; import android.content.Intent; +import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.view.View; @@ -117,4 +118,9 @@ public class GameActivity extends NativeActivity { public int getDisplayWidth() { return getResources().getDisplayMetrics().widthPixels; } + + public void openURL(String url) { + Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); + startActivity(browserIntent); + } } diff --git a/builtin/mainmenu/dlg_contentstore.lua b/builtin/mainmenu/dlg_contentstore.lua index 3bc5f60bb..ce5c061c6 100644 --- a/builtin/mainmenu/dlg_contentstore.lua +++ b/builtin/mainmenu/dlg_contentstore.lua @@ -16,7 +16,6 @@ --51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. local store = { packages = {}, packages_full = {} } -local package_dialog = {} -- Screenshot local screenshot_dir = core.get_cache_path() .. DIR_DELIM .. "cdb" @@ -44,8 +43,6 @@ local filter_types_type = { } - - local function download_package(param) if core.download_file(param.package.url, param.filename) then return { @@ -195,74 +192,6 @@ local function get_screenshot(package) return defaulttexturedir .. "loading_screenshot.png" end - - -function package_dialog.get_formspec() - local package = package_dialog.package - - store.update_paths() - - local formspec = { - "size[9,4;true]", - "image[0,1;4.5,3;", core.formspec_escape(get_screenshot(package)), ']', - "label[3.8,1;", - minetest.colorize(mt_color_green, core.formspec_escape(package.title)), "\n", - minetest.colorize('#BFBFBF', "by " .. core.formspec_escape(package.author)), "]", - "textarea[4,2;5.3,2;;;", core.formspec_escape(package.short_description), "]", - "button[0,0;2,1;back;", fgettext("Back"), "]", - } - - if not package.path then - formspec[#formspec + 1] = "button[7,0;2,1;install;" - formspec[#formspec + 1] = fgettext("Install") - formspec[#formspec + 1] = "]" - elseif package.installed_release < package.release then - -- The install_ action also handles updating - formspec[#formspec + 1] = "button[7,0;2,1;install;" - formspec[#formspec + 1] = fgettext("Update") - formspec[#formspec + 1] = "]" - formspec[#formspec + 1] = "button[5,0;2,1;uninstall;" - formspec[#formspec + 1] = fgettext("Uninstall") - formspec[#formspec + 1] = "]" - else - formspec[#formspec + 1] = "button[7,0;2,1;uninstall;" - formspec[#formspec + 1] = fgettext("Uninstall") - formspec[#formspec + 1] = "]" - end - - return table.concat(formspec, "") -end - -function package_dialog.handle_submit(this, fields) - if fields.back then - this:delete() - return true - end - - if fields.install then - start_install(this, package_dialog.package) - return true - end - - if fields.uninstall then - local dlg_delmod = create_delete_content_dlg(package_dialog.package) - dlg_delmod:set_parent(this) - this:hide() - dlg_delmod:show() - return true - end - - return false -end - -function package_dialog.create(package) - package_dialog.package = package - return dialog_create("package_view", - package_dialog.get_formspec, - package_dialog.handle_submit, - nil) -end - function store.load() local tmpdir = os.tempfolder() local target = tmpdir .. DIR_DELIM .. "packages.json" @@ -462,44 +391,45 @@ function store.get_formspec(dlgdata) minetest.colorize("#BFBFBF", " by " .. package.author)) formspec[#formspec + 1] = "]" - -- description - if package.path and package.installed_release < package.release then - formspec[#formspec + 1] = "textarea[1.25,0.3;7.5,1;;;" - else - formspec[#formspec + 1] = "textarea[1.25,0.3;9,1;;;" - end - formspec[#formspec + 1] = core.formspec_escape(package.short_description) - formspec[#formspec + 1] = "]" - -- buttons + local description_width = 7.5 if not package.path then - formspec[#formspec + 1] = "button[9.9,0;1.5,1;install_" + formspec[#formspec + 1] = "button[8.4,0;1.5,1;install_" formspec[#formspec + 1] = tostring(i) formspec[#formspec + 1] = ";" formspec[#formspec + 1] = fgettext("Install") formspec[#formspec + 1] = "]" else if package.installed_release < package.release then + description_width = 6 + -- The install_ action also handles updating - formspec[#formspec + 1] = "button[8.4,0;1.5,1;install_" + formspec[#formspec + 1] = "button[6.9,0;1.5,1;install_" formspec[#formspec + 1] = tostring(i) formspec[#formspec + 1] = ";" formspec[#formspec + 1] = fgettext("Update") formspec[#formspec + 1] = "]" end - formspec[#formspec + 1] = "button[9.9,0;1.5,1;uninstall_" + formspec[#formspec + 1] = "button[8.4,0;1.5,1;uninstall_" formspec[#formspec + 1] = tostring(i) formspec[#formspec + 1] = ";" formspec[#formspec + 1] = fgettext("Uninstall") formspec[#formspec + 1] = "]" end - --formspec[#formspec + 1] = "button[9.9,0;1.5,1;view_" - --formspec[#formspec + 1] = tostring(i) - --formspec[#formspec + 1] = ";" - --formspec[#formspec + 1] = fgettext("View") - --formspec[#formspec + 1] = "]" + formspec[#formspec + 1] = "button[9.9,0;1.5,1;view_" + formspec[#formspec + 1] = tostring(i) + formspec[#formspec + 1] = ";" + formspec[#formspec + 1] = fgettext("View") + formspec[#formspec + 1] = "]" + + -- description + formspec[#formspec + 1] = "textarea[1.25,0.3;" + formspec[#formspec + 1] = tostring(description_width) + formspec[#formspec + 1] = ",1;;;" + formspec[#formspec + 1] = core.formspec_escape(package.short_description) + formspec[#formspec + 1] = "]" formspec[#formspec + 1] = "container_end[]" end @@ -576,10 +506,9 @@ function store.handle_submit(this, fields) end if fields["view_" .. i] then - local dlg = package_dialog.create(package) - dlg:set_parent(this) - this:hide() - dlg:show() + local url = ("%s/packages/%s?protocol_version=%d"):format( + core.settings:get("contentdb_url"), package.id, core.get_max_supp_proto()) + core.open_url(url) return true end end diff --git a/builtin/mainmenu/tab_credits.lua b/builtin/mainmenu/tab_credits.lua index 962d2a3b4..c2b7e503a 100644 --- a/builtin/mainmenu/tab_credits.lua +++ b/builtin/mainmenu/tab_credits.lua @@ -101,8 +101,8 @@ return { local logofile = defaulttexturedir .. "logo.png" local version = core.get_version() return "image[0.5,1;" .. core.formspec_escape(logofile) .. "]" .. - "label[0.5,3.2;" .. version.project .. " " .. version.string .. "]" .. - "label[0.5,3.5;http://minetest.net]" .. + "label[0.5,2.8;" .. version.project .. " " .. version.string .. "]" .. + "button[0.5,3;2,2;homepage;minetest.net]" .. "tablecolumns[color;text]" .. "tableoptions[background=#00000000;highlight=#00000000;border=false]" .. "table[3.5,-0.25;8.5,6.05;list_credits;" .. @@ -115,5 +115,10 @@ return { "#FFFF00," .. fgettext("Previous Contributors") .. ",," .. buildCreditList(previous_contributors) .. "," .. ";1]" - end + end, + cbf_button_handler = function(this, fields, name, tabdata) + if fields.homepage then + core.open_url("https://www.minetest.net") + end + end, } diff --git a/doc/menu_lua_api.txt b/doc/menu_lua_api.txt index 8f5460acb..485c50110 100644 --- a/doc/menu_lua_api.txt +++ b/doc/menu_lua_api.txt @@ -234,6 +234,11 @@ core.get_min_supp_proto() core.get_max_supp_proto() ^ returns the maximum supported network protocol version +Other: +core.open_url(url) +^ opens the URL in a web browser, returns false on failure. +^ Must begin with http:// or https:// + Async: core.handle_async(async_job,parameters,finished) ^ execute a function asynchronously diff --git a/src/porting.cpp b/src/porting.cpp index c0381ad06..ef1640467 100644 --- a/src/porting.cpp +++ b/src/porting.cpp @@ -33,22 +33,28 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #include #include + #include #endif #if !defined(_WIN32) #include #include + #if !defined(__ANDROID__) + #include + #endif #endif #if defined(__hpux) #define _PSTAT64 #include #endif +#if defined(__ANDROID__) + #include "porting_android.h" +#endif #include "config.h" #include "debug.h" #include "filesys.h" #include "log.h" #include "util/string.h" -#include "settings.h" #include #include #include @@ -697,6 +703,28 @@ int mt_snprintf(char *buf, const size_t buf_size, const char *fmt, ...) return c; } +bool openURL(const std::string &url) +{ + if ((url.substr(0, 7) != "http://" && url.substr(0, 8) != "https://") || + url.find_first_of("\r\n") != std::string::npos) { + errorstream << "Invalid url: " << url << std::endl; + return false; + } + +#if defined(_WIN32) + return (intptr_t)ShellExecuteA(NULL, NULL, url.c_str(), NULL, NULL, SW_SHOWNORMAL) > 32; +#elif defined(__ANDROID__) + openURLAndroid(url); + return true; +#elif defined(__APPLE__) + const char *argv[] = {"open", url.c_str(), NULL}; + return posix_spawnp(NULL, "open", NULL, NULL, (char**)argv, environ) == 0; +#else + const char *argv[] = {"xdg-open", url.c_str(), NULL}; + return posix_spawnp(NULL, "xdg-open", NULL, NULL, (char**)argv, environ) == 0; +#endif +} + // Load performance counter frequency only once at startup #ifdef _WIN32 diff --git a/src/porting.h b/src/porting.h index 4d30a5970..f50f0a950 100644 --- a/src/porting.h +++ b/src/porting.h @@ -329,6 +329,9 @@ bool secure_rand_fill_buf(void *buf, size_t len); void attachOrCreateConsole(); int mt_snprintf(char *buf, const size_t buf_size, const char *fmt, ...); + +bool openURL(const std::string &url); + } // namespace porting #ifdef __ANDROID__ diff --git a/src/porting_android.cpp b/src/porting_android.cpp index 2c91df235..41b521ec2 100644 --- a/src/porting_android.cpp +++ b/src/porting_android.cpp @@ -213,6 +213,18 @@ void showInputDialog(const std::string &acceptButton, const std::string &hint, jacceptButton, jhint, jcurrent, jeditType); } +void openURLAndroid(const std::string &url) +{ + jmethodID url_open = jnienv->GetMethodID(nativeActivity, "openURL", + "(Ljava/lang/String;)V"); + + FATAL_ERROR_IF(url_open == nullptr, + "porting::openURLAndroid unable to find java openURL method"); + + jstring jurl = jnienv->NewStringUTF(url.c_str()); + jnienv->CallVoidMethod(app_global->activity->clazz, url_open, jurl); +} + int getInputDialogState() { jmethodID dialogstate = jnienv->GetMethodID(nativeActivity, diff --git a/src/porting_android.h b/src/porting_android.h index 42f90b60b..6eb054041 100644 --- a/src/porting_android.h +++ b/src/porting_android.h @@ -58,6 +58,8 @@ void initializePathsAndroid(); void showInputDialog(const std::string &acceptButton, const std::string &hint, const std::string ¤t, int editType); +void openURLAndroid(const std::string &url); + /** * WORKAROUND for not working callbacks from java -> c++ * get current state of input dialog diff --git a/src/script/lua_api/l_mainmenu.cpp b/src/script/lua_api/l_mainmenu.cpp index a76e9f079..f32c477c2 100644 --- a/src/script/lua_api/l_mainmenu.cpp +++ b/src/script/lua_api/l_mainmenu.cpp @@ -1063,6 +1063,14 @@ int ModApiMainMenu::l_get_max_supp_proto(lua_State *L) return 1; } +/******************************************************************************/ +int ModApiMainMenu::l_open_url(lua_State *L) +{ + std::string url = luaL_checkstring(L, 1); + lua_pushboolean(L, porting::openURL(url)); + return 1; +} + /******************************************************************************/ int ModApiMainMenu::l_do_async_callback(lua_State *L) { @@ -1125,6 +1133,7 @@ void ModApiMainMenu::Initialize(lua_State *L, int top) API_FCT(get_screen_info); API_FCT(get_min_supp_proto); API_FCT(get_max_supp_proto); + API_FCT(open_url); API_FCT(do_async_callback); } diff --git a/src/script/lua_api/l_mainmenu.h b/src/script/lua_api/l_mainmenu.h index b2ca49320..5a16b3bfe 100644 --- a/src/script/lua_api/l_mainmenu.h +++ b/src/script/lua_api/l_mainmenu.h @@ -145,6 +145,9 @@ private: static int l_get_max_supp_proto(lua_State *L); + // other + static int l_open_url(lua_State *L); + // async static int l_do_async_callback(lua_State *L); -- cgit v1.2.3 From 87b25e583dcb2bc1079a7b5906b97a787ac04be8 Mon Sep 17 00:00:00 2001 From: Bektur Date: Fri, 5 Jun 2020 07:22:19 +0600 Subject: Show Toast in UI thread and fix unpacking on Android 10 (#9900) --- .../java/net/minetest/minetest/CopyZipTask.java | 23 ++++++++++++++-------- .../java/net/minetest/minetest/MainActivity.java | 7 +++++++ .../java/net/minetest/minetest/UnzipService.java | 11 +++++++---- 3 files changed, 29 insertions(+), 12 deletions(-) (limited to 'build/android/app/src') diff --git a/build/android/app/src/main/java/net/minetest/minetest/CopyZipTask.java b/build/android/app/src/main/java/net/minetest/minetest/CopyZipTask.java index d6e9d9ee1..6d4b6ab0f 100644 --- a/build/android/app/src/main/java/net/minetest/minetest/CopyZipTask.java +++ b/build/android/app/src/main/java/net/minetest/minetest/CopyZipTask.java @@ -20,11 +20,12 @@ with this program; if not, write to the Free Software Foundation, Inc., package net.minetest.minetest; -import android.content.Context; import android.content.Intent; import android.os.AsyncTask; import android.widget.Toast; +import androidx.appcompat.app.AppCompatActivity; + import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; @@ -33,10 +34,10 @@ import java.lang.ref.WeakReference; public class CopyZipTask extends AsyncTask { - private final WeakReference contextRef; + private final WeakReference activityRef; - CopyZipTask(Context context) { - contextRef = new WeakReference<>(context); + CopyZipTask(AppCompatActivity activity) { + activityRef = new WeakReference<>(activity); } protected String doInBackground(String... params) { @@ -51,11 +52,14 @@ public class CopyZipTask extends AsyncTask { private void copyAsset(String zipName) { String filename = zipName.substring(zipName.lastIndexOf("/") + 1); - try (InputStream in = contextRef.get().getAssets().open(filename); + try (InputStream in = activityRef.get().getAssets().open(filename); OutputStream out = new FileOutputStream(zipName)) { copyFile(in, out); } catch (IOException e) { - Toast.makeText(contextRef.get(), e.getLocalizedMessage(), Toast.LENGTH_LONG).show(); + AppCompatActivity activity = activityRef.get(); + if (activity != null) { + activity.runOnUiThread(() -> Toast.makeText(activityRef.get(), e.getLocalizedMessage(), Toast.LENGTH_LONG).show()); + } cancel(true); } } @@ -68,8 +72,11 @@ public class CopyZipTask extends AsyncTask { } private void startUnzipService(String file) { - Intent intent = new Intent(contextRef.get(), UnzipService.class); + Intent intent = new Intent(activityRef.get(), UnzipService.class); intent.putExtra(UnzipService.EXTRA_KEY_IN_FILE, file); - contextRef.get().startService(intent); + AppCompatActivity activity = activityRef.get(); + if (activity != null) { + activity.startService(intent); + } } } diff --git a/build/android/app/src/main/java/net/minetest/minetest/MainActivity.java b/build/android/app/src/main/java/net/minetest/minetest/MainActivity.java index 1e60beb55..2aa50d9ad 100644 --- a/build/android/app/src/main/java/net/minetest/minetest/MainActivity.java +++ b/build/android/app/src/main/java/net/minetest/minetest/MainActivity.java @@ -43,6 +43,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import static net.minetest.minetest.UnzipService.ACTION_FAILURE; import static net.minetest.minetest.UnzipService.ACTION_PROGRESS; import static net.minetest.minetest.UnzipService.ACTION_UPDATE; import static net.minetest.minetest.UnzipService.FAILURE; @@ -71,6 +72,7 @@ public class MainActivity extends AppCompatActivity { } mTextView.setVisibility(View.VISIBLE); } else if (progress == FAILURE) { + Toast.makeText(MainActivity.this, intent.getStringExtra(ACTION_FAILURE), Toast.LENGTH_LONG).show(); finish(); } else if (progress == SUCCESS) startNative(); @@ -138,6 +140,11 @@ public class MainActivity extends AppCompatActivity { startActivity(intent); } + @Override + public void onBackPressed() { + // Prevent abrupt interruption when copy game files from assets + } + @Override protected void onDestroy() { super.onDestroy(); diff --git a/build/android/app/src/main/java/net/minetest/minetest/UnzipService.java b/build/android/app/src/main/java/net/minetest/minetest/UnzipService.java index 6356dff19..b69f7f36e 100644 --- a/build/android/app/src/main/java/net/minetest/minetest/UnzipService.java +++ b/build/android/app/src/main/java/net/minetest/minetest/UnzipService.java @@ -42,20 +42,21 @@ import java.util.zip.ZipInputStream; public class UnzipService extends IntentService { public static final String ACTION_UPDATE = "net.minetest.minetest.UPDATE"; public static final String ACTION_PROGRESS = "net.minetest.minetest.PROGRESS"; + public static final String ACTION_FAILURE = "net.minetest.minetest.FAILURE"; public static final String EXTRA_KEY_IN_FILE = "file"; public static final int SUCCESS = -1; public static final int FAILURE = -2; - private static final String TAG = "UnzipService"; private final int id = 1; private NotificationManager mNotifyManager; private boolean isSuccess = true; + private String failureMessage; public UnzipService() { super("net.minetest.minetest.UnzipService"); } private void isDir(String dir, String location) { - File f = new File(location + dir); + File f = new File(location, dir); if (!f.isDirectory()) f.mkdirs(); } @@ -99,7 +100,8 @@ public class UnzipService extends IntentService { private void unzip(Intent intent) { String zip = intent.getStringExtra(EXTRA_KEY_IN_FILE); - String location = Environment.getExternalStorageDirectory() + "/Minetest/"; + isDir("Minetest", Environment.getExternalStorageDirectory().toString()); + String location = Environment.getExternalStorageDirectory() + File.separator + "Minetest" + File.separator; int per = 0; int size = getSummarySize(zip); File zipFile = new File(zip); @@ -124,13 +126,14 @@ public class UnzipService extends IntentService { } } catch (IOException e) { isSuccess = false; - Toast.makeText(this, e.getLocalizedMessage(), Toast.LENGTH_LONG).show(); + failureMessage = e.getLocalizedMessage(); } } private void publishProgress(int progress) { Intent intentUpdate = new Intent(ACTION_UPDATE); intentUpdate.putExtra(ACTION_PROGRESS, progress); + if (!isSuccess) intentUpdate.putExtra(ACTION_FAILURE, failureMessage); sendBroadcast(intentUpdate); } -- cgit v1.2.3 From 646af2ef5f52cc3a04ea806d13dd2a048395da88 Mon Sep 17 00:00:00 2001 From: Maksim Date: Tue, 23 Jun 2020 20:00:34 +0200 Subject: Android: fix maxAspectRatio (should be float) (#10080) --- build/android/app/src/main/AndroidManifest.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'build/android/app/src') diff --git a/build/android/app/src/main/AndroidManifest.xml b/build/android/app/src/main/AndroidManifest.xml index aa5af110e..0a7c8d95a 100644 --- a/build/android/app/src/main/AndroidManifest.xml +++ b/build/android/app/src/main/AndroidManifest.xml @@ -23,12 +23,12 @@ + android:value="3.0" /> @@ -42,7 +42,7 @@ android:configChanges="orientation|keyboard|keyboardHidden|navigation|screenSize|smallestScreenSize" android:hardwareAccelerated="true" android:launchMode="singleTask" - android:maxAspectRatio="3" + android:maxAspectRatio="3.0" android:screenOrientation="sensorLandscape" android:theme="@style/AppTheme"> @@ -55,7 +55,7 @@