diff --git a/.gitignore b/.gitignore
index d5cb9b6ea..6591b84bc 100644
--- a/.gitignore
+++ b/.gitignore
@@ -90,6 +90,7 @@ locale/
*.ninja
.ninja*
*.gch
+*.iml
test_config.h
cmake-build-debug/
cmake-build-release/
diff --git a/build/android/build.gradle b/build/android/build.gradle
index f539ea7b8..09273ff03 100644
--- a/build/android/build.gradle
+++ b/build/android/build.gradle
@@ -1,12 +1,17 @@
buildscript {
repositories {
- mavenCentral()
- jcenter()
- google()
maven { url 'https://maven.google.com' }
+ jcenter()
}
dependencies {
- classpath "com.android.tools.build:gradle:3.1.3"
+ classpath 'com.android.tools.build:gradle:3.1.3'
+ }
+}
+
+allprojects {
+ repositories {
+ maven { url 'https://maven.google.com' }
+ jcenter()
}
}
@@ -20,21 +25,21 @@ def sqlite3_version = "3240000"
apply plugin: "com.android.application"
android {
- compileSdkVersion 26
- buildToolsVersion "26.0.3"
+ compileSdkVersion 28
+ buildToolsVersion "28.0.3"
defaultConfig {
versionCode 20
versionName "${System.env.VERSION_STR}.${versionCode}"
minSdkVersion 14
- targetSdkVersion 14
+ targetSdkVersion 28
applicationId "net.minetest.minetest"
- manifestPlaceholders = [ package: "net.minetest.minetest", project: project.name ]
+ manifestPlaceholders = [package: "net.minetest.minetest", project: project.name]
ndk {
// Specifies the ABI configurations of your native
// libraries Gradle should build and package with your APK.
- abiFilters 'x86', 'x86_64', 'armeabi', 'armeabi-v7a',
- 'arm64-v8a'
+ // abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
+ abiFilters 'armeabi-v7a', 'x86'
}
}
@@ -63,58 +68,58 @@ android {
}
}
-task cleanAssets(type:Delete) {
+task cleanAssets(type: Delete) {
delete 'src/main/assets'
}
-task cleanIconv(type:Delete) {
+task cleanIconv(type: Delete) {
delete 'deps/libiconv'
}
-task cleanIrrlicht(type:Delete) {
+task cleanIrrlicht(type: Delete) {
delete 'deps/irrlicht'
}
-task cleanLevelDB(type:Delete) {
+task cleanLevelDB(type: Delete) {
delete 'deps/leveldb'
}
-task cleanCURL(type:Delete) {
+task cleanCURL(type: Delete) {
delete 'deps/curl'
delete 'deps/curl-' + curl_version
}
-task cleanOpenSSL(type:Delete) {
+task cleanOpenSSL(type: Delete) {
delete 'deps/openssl'
delete 'deps/openssl-' + openssl_version
delete 'deps/openssl-' + openssl_version + '.tar.gz'
}
-task cleanOpenAL(type:Delete) {
+task cleanOpenAL(type: Delete) {
delete 'deps/openal-soft'
}
-task cleanFreetype(type:Delete) {
+task cleanFreetype(type: Delete) {
delete 'deps/freetype2-android'
}
-task cleanOgg(type:Delete) {
+task cleanOgg(type: Delete) {
delete 'deps/libvorbis-libogg-android'
}
-task cleanSQLite3(type:Delete) {
+task cleanSQLite3(type: Delete) {
delete 'deps/sqlite-amalgamation-' + sqlite3_version
delete 'deps/sqlite-amalgamation-' + sqlite3_version + '.zip'
}
-task cleanGMP(type:Delete) {
+task cleanGMP(type: Delete) {
delete 'deps/gmp'
delete 'deps/gmp-' + gmp_version
}
-task cleanAll(type:Delete, dependsOn:[clean,cleanAssets,cleanIconv,
- cleanFreetype,cleanIrrlicht,cleanLevelDB,cleanSQLite3,cleanCURL,
- cleanOpenSSL,cleanOpenAL,cleanOgg,cleanGMP]) {
+task cleanAll(type: Delete, dependsOn: [clean, cleanAssets, cleanIconv,
+ cleanFreetype, cleanIrrlicht, cleanLevelDB, cleanSQLite3, cleanCURL,
+ cleanOpenSSL, cleanOpenAL, cleanOgg, cleanGMP]) {
delete 'deps'
delete 'gen'
delete 'libs'
@@ -123,3 +128,7 @@ task cleanAll(type:Delete, dependsOn:[clean,cleanAssets,cleanIconv,
delete 'Debug'
delete 'and_env'
}
+
+dependencies {
+ implementation 'com.android.support:support-v4:28.0.0'
+}
diff --git a/build/android/gradle/wrapper/gradle-wrapper.jar b/build/android/gradle/wrapper/gradle-wrapper.jar
index 8c0fb64a8..6b6ea3ab4 100644
Binary files a/build/android/gradle/wrapper/gradle-wrapper.jar and b/build/android/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/build/android/gradle/wrapper/gradle-wrapper.properties b/build/android/gradle/wrapper/gradle-wrapper.properties
index 9d1a1850d..d7d50b600 100644
--- a/build/android/gradle/wrapper/gradle-wrapper.properties
+++ b/build/android/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
-#Sat Aug 27 20:10:09 CEST 2016
+#Mon Oct 15 00:47:03 CEST 2018
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip
diff --git a/build/android/gradlew b/build/android/gradlew
index 91a7e269e..cccdd3d51 100755
--- a/build/android/gradlew
+++ b/build/android/gradlew
@@ -1,4 +1,4 @@
-#!/usr/bin/env bash
+#!/usr/bin/env sh
##############################################################################
##
@@ -6,47 +6,6 @@
##
##############################################################################
-# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-DEFAULT_JVM_OPTS=""
-
-APP_NAME="Gradle"
-APP_BASE_NAME=`basename "$0"`
-
-# Use the maximum available, or set MAX_FD != -1 to use that value.
-MAX_FD="maximum"
-
-warn ( ) {
- echo "$*"
-}
-
-die ( ) {
- echo
- echo "$*"
- echo
- exit 1
-}
-
-# OS specific support (must be 'true' or 'false').
-cygwin=false
-msys=false
-darwin=false
-case "`uname`" in
- CYGWIN* )
- cygwin=true
- ;;
- Darwin* )
- darwin=true
- ;;
- MINGW* )
- msys=true
- ;;
-esac
-
-# For Cygwin, ensure paths are in UNIX format before anything is touched.
-if $cygwin ; then
- [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
-fi
-
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
@@ -61,9 +20,49 @@ while [ -h "$PRG" ] ; do
fi
done
SAVED="`pwd`"
-cd "`dirname \"$PRG\"`/" >&-
+cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
-cd "$SAVED" >&-
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
@@ -90,7 +89,7 @@ location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
-if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
@@ -114,6 +113,7 @@ fi
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+ JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
@@ -154,11 +154,19 @@ if $cygwin ; then
esac
fi
-# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
-function splitJvmOpts() {
- JVM_OPTS=("$@")
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
}
-eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
-JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+APP_ARGS=$(save "$@")
-exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
+if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
+ cd "$(dirname "$0")"
+fi
+
+exec "$JAVACMD" "$@"
diff --git a/build/android/gradlew.bat b/build/android/gradlew.bat
index 8a0b282aa..f9553162f 100644
--- a/build/android/gradlew.bat
+++ b/build/android/gradlew.bat
@@ -8,14 +8,14 @@
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
-@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-set DEFAULT_JVM_OPTS=
-
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
@@ -46,10 +46,9 @@ echo location of your Java installation.
goto fail
:init
-@rem Get command-line arguments, handling Windowz variants
+@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
-if "%@eval[2+2]" == "4" goto 4NT_args
:win9xME_args
@rem Slurp the command line arguments.
@@ -60,11 +59,6 @@ set _SKIP=2
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
-goto execute
-
-:4NT_args
-@rem Get arguments from the 4NT Shell from JP Software
-set CMD_LINE_ARGS=%$
:execute
@rem Setup the command line
diff --git a/build/android/src/debug/AndroidManifest.xml b/build/android/src/debug/AndroidManifest.xml
index a3815b9f8..ee04d1d03 100644
--- a/build/android/src/debug/AndroidManifest.xml
+++ b/build/android/src/debug/AndroidManifest.xml
@@ -1,4 +1,5 @@
-
+
+
diff --git a/build/android/src/main/AndroidManifest.xml b/build/android/src/main/AndroidManifest.xml
index df218fb33..7f61cda38 100644
--- a/build/android/src/main/AndroidManifest.xml
+++ b/build/android/src/main/AndroidManifest.xml
@@ -1,34 +1,59 @@
-
+ package="net.minetest.minetest"
+ android:installLocation="auto">
+
+
+
-
-
+
+
+
+
-
+ android:launchMode="singleTask"
+ android:screenOrientation="sensorLandscape"
+ android:theme="@style/AppTheme">
-
-
-
-
+
+
+
+
+
+
+
diff --git a/build/android/src/main/java/net.minetest.minetest/MainActivity.java b/build/android/src/main/java/net.minetest.minetest/MainActivity.java
new file mode 100644
index 000000000..1baa71668
--- /dev/null
+++ b/build/android/src/main/java/net.minetest.minetest/MainActivity.java
@@ -0,0 +1,79 @@
+package net.minetest.minetest;
+
+import android.Manifest;
+import android.app.Activity;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.os.Build;
+import android.os.Bundle;
+import android.support.annotation.NonNull;
+import android.support.v4.app.ActivityCompat;
+import android.support.v4.content.ContextCompat;;
+import android.widget.Toast;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class MainActivity extends Activity {
+
+ private final static int PERMISSIONS = 1;
+ private static final String[] REQUIRED_SDK_PERMISSIONS = new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE};
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+ checkPermission();
+ } else {
+ next();
+ }
+ }
+
+ protected void checkPermission() {
+ final List missingPermissions = new ArrayList();
+ // check required permission
+ 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()) {
+ // request permission
+ final String[] permissions = missingPermissions
+ .toArray(new String[missingPermissions.size()]);
+ 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) {
+ switch (requestCode) {
+ case PERMISSIONS:
+ for (int index = 0; index < permissions.length; index++) {
+ if (grantResults[index] != PackageManager.PERMISSION_GRANTED) {
+ // permission not granted - toast and exit
+ Toast.makeText(this, R.string.not_granted, Toast.LENGTH_LONG).show();
+ finish();
+ return;
+ }
+ }
+ // permission were granted - run
+ next();
+ break;
+ }
+ }
+
+ public void next() {
+ Intent intent = new Intent(this, MtNativeActivity.class);
+ intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK);
+ startActivity(intent);
+ }
+}
diff --git a/build/android/src/main/java/net.minetest.minetest/MinetestAssetCopy.java b/build/android/src/main/java/net.minetest.minetest/MinetestAssetCopy.java
index eb92acb63..b570fe61a 100644
--- a/build/android/src/main/java/net.minetest.minetest/MinetestAssetCopy.java
+++ b/build/android/src/main/java/net.minetest.minetest/MinetestAssetCopy.java
@@ -1,5 +1,17 @@
package net.minetest.minetest;
+import android.app.Activity;
+import android.content.res.AssetFileDescriptor;
+import android.os.AsyncTask;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.Environment;
+import android.util.Log;
+import android.view.Display;
+import android.view.View;
+import android.widget.ProgressBar;
+import android.widget.TextView;
+
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
@@ -7,410 +19,355 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
-import java.util.Vector;
import java.util.Iterator;
-import java.lang.Object;
+import java.util.Vector;
-import android.app.Activity;
-import android.content.res.AssetFileDescriptor;
+public class MinetestAssetCopy extends Activity {
+ ProgressBar m_ProgressBar;
+ TextView m_Filename;
+ copyAssetTask m_AssetCopy;
-import android.os.AsyncTask;
-import android.os.Bundle;
-import android.os.Environment;
-import android.util.Log;
-import android.view.Display;
-import android.widget.ProgressBar;
-import android.widget.TextView;
-import android.graphics.Rect;
-import android.graphics.Paint;
-import android.text.TextPaint;
-
-public class MinetestAssetCopy extends Activity
-{
@Override
- public void onCreate(Bundle savedInstanceState)
- {
+ public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
-
setContentView(R.layout.assetcopy);
-
- m_ProgressBar = (ProgressBar) findViewById(R.id.progressBar1);
- m_Filename = (TextView) findViewById(R.id.textView1);
-
+ m_ProgressBar = findViewById(R.id.progressBar1);
+ m_Filename = findViewById(R.id.textView1);
Display display = getWindowManager().getDefaultDisplay();
m_ProgressBar.getLayoutParams().width = (int) (display.getWidth() * 0.8);
m_ProgressBar.invalidate();
-
+
/* check if there's already a copy in progress and reuse in case it is*/
- MinetestAssetCopy prevActivity =
+ MinetestAssetCopy prevActivity =
(MinetestAssetCopy) getLastNonConfigurationInstance();
- if(prevActivity!= null) {
+ if (prevActivity != null) {
m_AssetCopy = prevActivity.m_AssetCopy;
- }
- else {
+ } else {
m_AssetCopy = new copyAssetTask();
m_AssetCopy.execute();
}
}
-
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ makeFullScreen();
+ }
+
+ public void makeFullScreen() {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
+ 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();
+ }
+ }
+
/* preserve asset copy background task to prevent restart of copying */
/* this way of doing it is not recommended for latest android version */
/* but the recommended way isn't available on android 2.x */
- public Object onRetainNonConfigurationInstance()
- {
+ public Object onRetainNonConfigurationInstance() {
return this;
}
-
- ProgressBar m_ProgressBar;
- TextView m_Filename;
-
- copyAssetTask m_AssetCopy;
-
- private class copyAssetTask extends AsyncTask
- {
- private long getFullSize(String filename)
- {
- long size = 0;
- try {
- InputStream src = getAssets().open(filename);
- byte[] buf = new byte[4096];
-
- int len = 0;
- while ((len = src.read(buf)) > 0)
- {
- size += len;
- }
- }
- catch (IOException e)
- {
- e.printStackTrace();
- }
- return size;
- }
- @Override
- protected String doInBackground(String... files)
- {
- m_foldernames = new Vector();
- m_filenames = new Vector();
- m_tocopy = new Vector();
- m_asset_size_unknown = new Vector();
- String baseDir =
- Environment.getExternalStorageDirectory().getAbsolutePath()
- + "/";
-
-
- // prepare temp folder
- File TempFolder = new File(baseDir + "Minetest/tmp/");
-
- if (!TempFolder.exists())
- {
- TempFolder.mkdir();
- }
- else {
- File[] todel = TempFolder.listFiles();
-
- for(int i=0; i < todel.length; i++)
- {
- Log.v("MinetestAssetCopy","deleting: " + todel[i].getAbsolutePath());
- todel[i].delete();
- }
- }
-
- // add a .nomedia file
- try {
- OutputStream dst = new FileOutputStream(baseDir + "Minetest/.nomedia");
- dst.close();
- } catch (IOException e) {
- Log.e("MinetestAssetCopy","Failed to create .nomedia file");
- e.printStackTrace();
- }
-
-
- // build lists from prepared data
- BuildFolderList();
- BuildFileList();
-
- // scan filelist
- ProcessFileList();
-
- // doing work
- m_copy_started = true;
- m_ProgressBar.setMax(m_tocopy.size());
-
- for (int i = 0; i < m_tocopy.size(); i++)
- {
- try
- {
- String filename = m_tocopy.get(i);
- publishProgress(i);
-
- boolean asset_size_unknown = false;
- long filesize = -1;
-
- if (m_asset_size_unknown.contains(filename))
- {
- File testme = new File(baseDir + "/" + filename);
-
- if(testme.exists())
- {
- filesize = testme.length();
- }
- asset_size_unknown = true;
- }
-
- InputStream src;
- try
- {
- src = getAssets().open(filename);
- } catch (IOException e) {
- Log.e("MinetestAssetCopy","Copying file: " + filename + " FAILED (not in assets)");
- e.printStackTrace();
- continue;
- }
-
- // Transfer bytes from in to out
- byte[] buf = new byte[1*1024];
- int len = src.read(buf, 0, 1024);
-
- /* following handling is crazy but we need to deal with */
- /* compressed assets.Flash chips limited livetime due to */
- /* write operations, we can't allow large files to destroy */
- /* users flash. */
- if (asset_size_unknown)
- {
- if ( (len > 0) && (len < buf.length) && (len == filesize))
- {
- src.close();
- continue;
- }
-
- if (len == buf.length)
- {
- src.close();
- long size = getFullSize(filename);
- if ( size == filesize)
- {
- continue;
- }
- src = getAssets().open(filename);
- len = src.read(buf, 0, 1024);
- }
- }
- if (len > 0)
- {
- int total_filesize = 0;
- OutputStream dst;
- try
- {
- dst = new FileOutputStream(baseDir + "/" + filename);
- } catch (IOException e) {
- Log.e("MinetestAssetCopy","Copying file: " + baseDir +
- "/" + filename + " FAILED (couldn't open output file)");
- e.printStackTrace();
- src.close();
- continue;
- }
- dst.write(buf, 0, len);
- total_filesize += len;
-
- while ((len = src.read(buf)) > 0)
- {
- dst.write(buf, 0, len);
- total_filesize += len;
- }
-
- dst.close();
- Log.v("MinetestAssetCopy","Copied file: " +
- m_tocopy.get(i) + " (" + total_filesize +
- " bytes)");
- }
- else if (len < 0)
- {
- Log.e("MinetestAssetCopy","Copying file: " +
- m_tocopy.get(i) + " failed, size < 0");
- }
- src.close();
- }
- catch (IOException e)
- {
- Log.e("MinetestAssetCopy","Copying file: " +
- m_tocopy.get(i) + " failed");
- e.printStackTrace();
- }
- }
- return "";
- }
-
-
- /**
- * update progress bar
- */
- protected void onProgressUpdate(Integer... progress)
- {
-
- if (m_copy_started)
- {
- boolean shortened = false;
- String todisplay = m_tocopy.get(progress[0]);
- m_ProgressBar.setProgress(progress[0]);
- m_Filename.setText(todisplay);
- }
- else
- {
- boolean shortened = false;
- String todisplay = m_Foldername;
- String full_text = "scanning " + todisplay + " ...";
- m_Filename.setText(full_text);
- }
- }
-
- /**
- * check al files and folders in filelist
- */
- protected void ProcessFileList()
- {
- String FlashBaseDir =
- Environment.getExternalStorageDirectory().getAbsolutePath();
-
- Iterator itr = m_filenames.iterator();
-
- while (itr.hasNext())
- {
- String current_path = (String) itr.next();
- String FlashPath = FlashBaseDir + "/" + current_path;
-
- if (isAssetFolder(current_path))
- {
- /* store information and update gui */
- m_Foldername = current_path;
- publishProgress(0);
-
- /* open file in order to check if it's a folder */
- File current_folder = new File(FlashPath);
- if (!current_folder.exists())
- {
- if (!current_folder.mkdirs())
- {
- Log.e("MinetestAssetCopy","\t failed create folder: " +
- FlashPath);
- }
- else
- {
- Log.v("MinetestAssetCopy","\t created folder: " +
- FlashPath);
- }
- }
-
- continue;
- }
-
- /* if it's not a folder it's most likely a file */
- boolean refresh = true;
-
- File testme = new File(FlashPath);
-
- long asset_filesize = -1;
- long stored_filesize = -1;
-
- if (testme.exists())
- {
- try
- {
- AssetFileDescriptor fd = getAssets().openFd(current_path);
- asset_filesize = fd.getLength();
- fd.close();
- }
- catch (IOException e)
- {
- refresh = true;
- m_asset_size_unknown.add(current_path);
- Log.e("MinetestAssetCopy","Failed to open asset file \"" +
- FlashPath + "\" for size check");
- }
-
- stored_filesize = testme.length();
-
- if (asset_filesize == stored_filesize)
- {
- refresh = false;
- }
-
- }
-
- if (refresh)
- {
- m_tocopy.add(current_path);
- }
- }
- }
-
- /**
- * read list of folders prepared on package build
- */
- protected void BuildFolderList()
- {
- try
- {
- InputStream is = getAssets().open("index.txt");
- BufferedReader reader = new BufferedReader(new InputStreamReader(is));
-
- String line = reader.readLine();
- while (line != null)
- {
- m_foldernames.add(line);
- line = reader.readLine();
- }
- is.close();
- } catch (IOException e1)
- {
- Log.e("MinetestAssetCopy","Error on processing index.txt");
- e1.printStackTrace();
- }
- }
-
- /**
- * read list of asset files prepared on package build
- */
- protected void BuildFileList()
- {
- long entrycount = 0;
- try
- {
- InputStream is = getAssets().open("filelist.txt");
- BufferedReader reader = new BufferedReader(new InputStreamReader(is));
-
- String line = reader.readLine();
- while (line != null)
- {
- m_filenames.add(line);
- line = reader.readLine();
- entrycount ++;
- }
- is.close();
- }
- catch (IOException e1)
- {
- Log.e("MinetestAssetCopy","Error on processing filelist.txt");
- e1.printStackTrace();
- }
- }
-
- protected void onPostExecute (String result)
- {
- finish();
- }
-
- protected boolean isAssetFolder(String path)
- {
- return m_foldernames.contains(path);
- }
-
+ private class copyAssetTask extends AsyncTask {
boolean m_copy_started = false;
String m_Foldername = "media";
Vector m_foldernames;
Vector m_filenames;
Vector m_tocopy;
Vector m_asset_size_unknown;
+
+ private long getFullSize(String filename) {
+ long size = 0;
+ try {
+ InputStream src = getAssets().open(filename);
+ byte[] buf = new byte[4096];
+
+ int len = 0;
+ while ((len = src.read(buf)) > 0) {
+ size += len;
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return size;
+ }
+
+ @Override
+ protected String doInBackground(String... files) {
+ m_foldernames = new Vector();
+ m_filenames = new Vector();
+ m_tocopy = new Vector();
+ m_asset_size_unknown = new Vector();
+ String baseDir =
+ Environment.getExternalStorageDirectory().getAbsolutePath()
+ + "/";
+
+
+ // prepare temp folder
+ File TempFolder = new File(baseDir + "Minetest/tmp/");
+
+ if (!TempFolder.exists()) {
+ TempFolder.mkdir();
+ } else {
+ File[] todel = TempFolder.listFiles();
+
+ for (int i = 0; i < todel.length; i++) {
+ Log.v("MinetestAssetCopy", "deleting: " + todel[i].getAbsolutePath());
+ todel[i].delete();
+ }
+ }
+
+ // add a .nomedia file
+ try {
+ OutputStream dst = new FileOutputStream(baseDir + "Minetest/.nomedia");
+ dst.close();
+ } catch (IOException e) {
+ Log.e("MinetestAssetCopy", "Failed to create .nomedia file");
+ e.printStackTrace();
+ }
+
+
+ // build lists from prepared data
+ BuildFolderList();
+ BuildFileList();
+
+ // scan filelist
+ ProcessFileList();
+
+ // doing work
+ m_copy_started = true;
+ m_ProgressBar.setMax(m_tocopy.size());
+
+ for (int i = 0; i < m_tocopy.size(); i++) {
+ try {
+ String filename = m_tocopy.get(i);
+ publishProgress(i);
+
+ boolean asset_size_unknown = false;
+ long filesize = -1;
+
+ if (m_asset_size_unknown.contains(filename)) {
+ File testme = new File(baseDir + "/" + filename);
+
+ if (testme.exists()) {
+ filesize = testme.length();
+ }
+ asset_size_unknown = true;
+ }
+
+ InputStream src;
+ try {
+ src = getAssets().open(filename);
+ } catch (IOException e) {
+ Log.e("MinetestAssetCopy", "Copying file: " + filename + " FAILED (not in assets)");
+ e.printStackTrace();
+ continue;
+ }
+
+ // Transfer bytes from in to out
+ byte[] buf = new byte[1024];
+ int len = src.read(buf, 0, 1024);
+
+ /* following handling is crazy but we need to deal with */
+ /* compressed assets.Flash chips limited livetime due to */
+ /* write operations, we can't allow large files to destroy */
+ /* users flash. */
+ if (asset_size_unknown) {
+ if ((len > 0) && (len < buf.length) && (len == filesize)) {
+ src.close();
+ continue;
+ }
+
+ if (len == buf.length) {
+ src.close();
+ long size = getFullSize(filename);
+ if (size == filesize) {
+ continue;
+ }
+ src = getAssets().open(filename);
+ len = src.read(buf, 0, 1024);
+ }
+ }
+ if (len > 0) {
+ int total_filesize = 0;
+ OutputStream dst;
+ try {
+ dst = new FileOutputStream(baseDir + "/" + filename);
+ } catch (IOException e) {
+ Log.e("MinetestAssetCopy", "Copying file: " + baseDir +
+ "/" + filename + " FAILED (couldn't open output file)");
+ e.printStackTrace();
+ src.close();
+ continue;
+ }
+ dst.write(buf, 0, len);
+ total_filesize += len;
+
+ while ((len = src.read(buf)) > 0) {
+ dst.write(buf, 0, len);
+ total_filesize += len;
+ }
+
+ dst.close();
+ Log.v("MinetestAssetCopy", "Copied file: " +
+ m_tocopy.get(i) + " (" + total_filesize +
+ " bytes)");
+ } else if (len < 0) {
+ Log.e("MinetestAssetCopy", "Copying file: " +
+ m_tocopy.get(i) + " failed, size < 0");
+ }
+ src.close();
+ } catch (IOException e) {
+ Log.e("MinetestAssetCopy", "Copying file: " +
+ m_tocopy.get(i) + " failed");
+ e.printStackTrace();
+ }
+ }
+ return "";
+ }
+
+ /**
+ * update progress bar
+ */
+ protected void onProgressUpdate(Integer... progress) {
+
+ if (m_copy_started) {
+ boolean shortened = false;
+ String todisplay = m_tocopy.get(progress[0]);
+ m_ProgressBar.setProgress(progress[0]);
+ m_Filename.setText(todisplay);
+ } else {
+ boolean shortened = false;
+ String todisplay = m_Foldername;
+ String full_text = "scanning " + todisplay + " ...";
+ m_Filename.setText(full_text);
+ }
+ }
+
+ /**
+ * check all files and folders in filelist
+ */
+ protected void ProcessFileList() {
+ String FlashBaseDir =
+ Environment.getExternalStorageDirectory().getAbsolutePath();
+
+ Iterator itr = m_filenames.iterator();
+
+ while (itr.hasNext()) {
+ String current_path = (String) itr.next();
+ String FlashPath = FlashBaseDir + "/" + current_path;
+
+ if (isAssetFolder(current_path)) {
+ /* store information and update gui */
+ m_Foldername = current_path;
+ publishProgress(0);
+
+ /* open file in order to check if it's a folder */
+ File current_folder = new File(FlashPath);
+ if (!current_folder.exists()) {
+ if (!current_folder.mkdirs()) {
+ Log.e("MinetestAssetCopy", "\t failed create folder: " +
+ FlashPath);
+ } else {
+ Log.v("MinetestAssetCopy", "\t created folder: " +
+ FlashPath);
+ }
+ }
+
+ continue;
+ }
+
+ /* if it's not a folder it's most likely a file */
+ boolean refresh = true;
+
+ File testme = new File(FlashPath);
+
+ long asset_filesize = -1;
+ long stored_filesize = -1;
+
+ if (testme.exists()) {
+ try {
+ AssetFileDescriptor fd = getAssets().openFd(current_path);
+ asset_filesize = fd.getLength();
+ fd.close();
+ } catch (IOException e) {
+ refresh = true;
+ m_asset_size_unknown.add(current_path);
+ Log.e("MinetestAssetCopy", "Failed to open asset file \"" +
+ FlashPath + "\" for size check");
+ }
+
+ stored_filesize = testme.length();
+
+ if (asset_filesize == stored_filesize) {
+ refresh = false;
+ }
+
+ }
+
+ if (refresh) {
+ m_tocopy.add(current_path);
+ }
+ }
+ }
+
+ /**
+ * read list of folders prepared on package build
+ */
+ protected void BuildFolderList() {
+ try {
+ InputStream is = getAssets().open("index.txt");
+ BufferedReader reader = new BufferedReader(new InputStreamReader(is));
+
+ String line = reader.readLine();
+ while (line != null) {
+ m_foldernames.add(line);
+ line = reader.readLine();
+ }
+ is.close();
+ } catch (IOException e1) {
+ Log.e("MinetestAssetCopy", "Error on processing index.txt");
+ e1.printStackTrace();
+ }
+ }
+
+ /**
+ * read list of asset files prepared on package build
+ */
+ protected void BuildFileList() {
+ long entrycount = 0;
+ try {
+ InputStream is = getAssets().open("filelist.txt");
+ BufferedReader reader = new BufferedReader(new InputStreamReader(is));
+
+ String line = reader.readLine();
+ while (line != null) {
+ m_filenames.add(line);
+ line = reader.readLine();
+ entrycount++;
+ }
+ is.close();
+ } catch (IOException e1) {
+ Log.e("MinetestAssetCopy", "Error on processing filelist.txt");
+ e1.printStackTrace();
+ }
+ }
+
+ protected void onPostExecute(String result) {
+ finish();
+ }
+
+ protected boolean isAssetFolder(String path) {
+ return m_foldernames.contains(path);
+ }
}
}
diff --git a/build/android/src/main/java/net.minetest.minetest/MinetestTextEntry.java b/build/android/src/main/java/net.minetest.minetest/MinetestTextEntry.java
index 68dc73274..4cd899025 100644
--- a/build/android/src/main/java/net.minetest.minetest/MinetestTextEntry.java
+++ b/build/android/src/main/java/net.minetest.minetest/MinetestTextEntry.java
@@ -6,63 +6,59 @@ import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.text.InputType;
-import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnKeyListener;
import android.widget.EditText;
public class MinetestTextEntry extends Activity {
+ private final int MultiLineTextInput = 1;
+ private final int SingleLineTextInput = 2;
+ private final int SingleLinePasswordInput = 3;
public AlertDialog mTextInputDialog;
public EditText mTextInputWidget;
-
- private final int MultiLineTextInput = 1;
- private final int SingleLineTextInput = 2;
- private final int SingleLinePasswordInput = 3;
-
+
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
-
Bundle b = getIntent().getExtras();
String acceptButton = b.getString("EnterButton");
- String hint = b.getString("hint");
- String current = b.getString("current");
- int editType = b.getInt("editType");
-
+ String hint = b.getString("hint");
+ String current = b.getString("current");
+ int editType = b.getInt("editType");
+
AlertDialog.Builder builder = new AlertDialog.Builder(this);
mTextInputWidget = new EditText(this);
mTextInputWidget.setHint(hint);
mTextInputWidget.setText(current);
mTextInputWidget.setMinWidth(300);
if (editType == SingleLinePasswordInput) {
- mTextInputWidget.setInputType(InputType.TYPE_CLASS_TEXT |
+ mTextInputWidget.setInputType(InputType.TYPE_CLASS_TEXT |
InputType.TYPE_TEXT_VARIATION_PASSWORD);
- }
- else {
+ } else {
mTextInputWidget.setInputType(InputType.TYPE_CLASS_TEXT);
}
-
-
+
builder.setView(mTextInputWidget);
-
+
if (editType == MultiLineTextInput) {
builder.setPositiveButton(acceptButton, new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int whichButton)
- { pushResult(mTextInputWidget.getText().toString()); }
- });
+ public void onClick(DialogInterface dialog, int whichButton) {
+ pushResult(mTextInputWidget.getText().toString());
+ }
+ });
}
-
+
builder.setOnCancelListener(new DialogInterface.OnCancelListener() {
public void onCancel(DialogInterface dialog) {
cancelDialog();
}
});
-
+
mTextInputWidget.setOnKeyListener(new OnKeyListener() {
@Override
public boolean onKey(View view, int KeyCode, KeyEvent event) {
- if ( KeyCode == KeyEvent.KEYCODE_ENTER){
+ if (KeyCode == KeyEvent.KEYCODE_ENTER) {
pushResult(mTextInputWidget.getText().toString());
return true;
@@ -70,19 +66,19 @@ public class MinetestTextEntry extends Activity {
return false;
}
});
-
+
mTextInputDialog = builder.create();
mTextInputDialog.show();
}
-
+
public void pushResult(String text) {
Intent resultData = new Intent();
resultData.putExtra("text", text);
- setResult(Activity.RESULT_OK,resultData);
+ setResult(Activity.RESULT_OK, resultData);
mTextInputDialog.dismiss();
finish();
}
-
+
public void cancelDialog() {
setResult(Activity.RESULT_CANCELED);
mTextInputDialog.dismiss();
diff --git a/build/android/src/main/java/net.minetest.minetest/MtNativeActivity.java b/build/android/src/main/java/net.minetest.minetest/MtNativeActivity.java
index dd611158f..f76634c20 100644
--- a/build/android/src/main/java/net.minetest.minetest/MtNativeActivity.java
+++ b/build/android/src/main/java/net.minetest.minetest/MtNativeActivity.java
@@ -2,23 +2,55 @@ package net.minetest.minetest;
import android.app.NativeActivity;
import android.content.Intent;
+import android.os.Build;
import android.os.Bundle;
-import android.util.Log;
+import android.view.View;
import android.view.WindowManager;
public class MtNativeActivity extends NativeActivity {
+
+ static {
+ System.loadLibrary("openal");
+ System.loadLibrary("ogg");
+ System.loadLibrary("vorbis");
+ System.loadLibrary("gmp");
+ System.loadLibrary("iconv");
+ System.loadLibrary("minetest");
+ }
+
+ private int m_MessagReturnCode;
+ private String m_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);
m_MessagReturnCode = -1;
m_MessageReturnValue = "";
-
}
@Override
- public void onDestroy() {
- super.onDestroy();
+ protected void onResume() {
+ super.onResume();
+ makeFullScreen();
+ }
+
+ public void makeFullScreen() {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
+ 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();
+ }
}
public void copyAssets() {
@@ -27,7 +59,7 @@ public class MtNativeActivity extends NativeActivity {
}
public void showDialog(String acceptButton, String hint, String current,
- int editType) {
+ int editType) {
Intent intent = new Intent(this, MinetestTextEntry.class);
Bundle params = new Bundle();
@@ -38,11 +70,9 @@ public class MtNativeActivity extends NativeActivity {
intent.putExtras(params);
startActivityForResult(intent, 101);
m_MessageReturnValue = "";
- m_MessagReturnCode = -1;
+ m_MessagReturnCode = -1;
}
- public static native void putMessageBoxResult(String text);
-
/* ugly code to workaround putMessageBoxResult not beeing found */
public int getDialogState() {
return m_MessagReturnCode;
@@ -67,32 +97,15 @@ public class MtNativeActivity extends NativeActivity {
@Override
protected void onActivityResult(int requestCode, int resultCode,
- Intent data) {
+ Intent data) {
if (requestCode == 101) {
if (resultCode == RESULT_OK) {
String text = data.getStringExtra("text");
m_MessagReturnCode = 0;
m_MessageReturnValue = text;
- }
- else {
+ } else {
m_MessagReturnCode = 1;
}
}
}
-
- static {
- System.loadLibrary("openal");
- System.loadLibrary("ogg");
- System.loadLibrary("vorbis");
- System.loadLibrary("gmp");
- System.loadLibrary("iconv");
-
- // We don't have to load libminetest.so ourselves,
- // but if we do, we get nicer logcat errors when
- // loading fails.
- System.loadLibrary("minetest");
- }
-
- private int m_MessagReturnCode;
- private String m_MessageReturnValue;
}
diff --git a/build/android/src/main/res/drawable-hdpi/irr_icon.png b/build/android/src/main/res/drawable-hdpi/irr_icon.png
deleted file mode 100644
index 0b6861a0d..000000000
Binary files a/build/android/src/main/res/drawable-hdpi/irr_icon.png and /dev/null differ
diff --git a/build/android/src/main/res/drawable-ldpi/irr_icon.png b/build/android/src/main/res/drawable-ldpi/irr_icon.png
deleted file mode 100644
index b8c5d0177..000000000
Binary files a/build/android/src/main/res/drawable-ldpi/irr_icon.png and /dev/null differ
diff --git a/build/android/src/main/res/drawable-mdpi/irr_icon.png b/build/android/src/main/res/drawable-mdpi/irr_icon.png
deleted file mode 100644
index 951a7f8c1..000000000
Binary files a/build/android/src/main/res/drawable-mdpi/irr_icon.png and /dev/null differ
diff --git a/build/android/src/main/res/drawable-xhdpi/irr_icon.png b/build/android/src/main/res/drawable-xhdpi/irr_icon.png
deleted file mode 100644
index 2ec528ef7..000000000
Binary files a/build/android/src/main/res/drawable-xhdpi/irr_icon.png and /dev/null differ
diff --git a/build/android/src/main/res/drawable/background.png b/build/android/src/main/res/drawable/background.png
new file mode 100644
index 000000000..43bd6089e
Binary files /dev/null and b/build/android/src/main/res/drawable/background.png differ
diff --git a/build/android/src/main/res/drawable/bg.xml b/build/android/src/main/res/drawable/bg.xml
new file mode 100644
index 000000000..c76ec372d
--- /dev/null
+++ b/build/android/src/main/res/drawable/bg.xml
@@ -0,0 +1,4 @@
+
+
\ No newline at end of file
diff --git a/build/android/src/main/res/layout/assetcopy.xml b/build/android/src/main/res/layout/assetcopy.xml
index 1fcfffd65..b3da2f027 100644
--- a/build/android/src/main/res/layout/assetcopy.xml
+++ b/build/android/src/main/res/layout/assetcopy.xml
@@ -1,24 +1,24 @@
-
+
-
+
-
+
-
+
diff --git a/build/android/src/main/res/mipmap/ic_launcher.png b/build/android/src/main/res/mipmap/ic_launcher.png
new file mode 100644
index 000000000..88a83782c
Binary files /dev/null and b/build/android/src/main/res/mipmap/ic_launcher.png differ
diff --git a/build/android/src/main/res/values-v21/styles.xml b/build/android/src/main/res/values-v21/styles.xml
new file mode 100644
index 000000000..efd09d274
--- /dev/null
+++ b/build/android/src/main/res/values-v21/styles.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/build/android/src/main/res/values/strings.xml b/build/android/src/main/res/values/strings.xml
index b407a77c6..a5eaef5d1 100644
--- a/build/android/src/main/res/values/strings.xml
+++ b/build/android/src/main/res/values/strings.xml
@@ -1,5 +1,5 @@
- Preparing media...
-
-
+ Preparing media…
+ Required permission wasn\'t granted, Minetest can\'t run without it
+
\ No newline at end of file
diff --git a/build/android/src/main/res/values/styles.xml b/build/android/src/main/res/values/styles.xml
index 25b8df5a3..8b52472a5 100644
--- a/build/android/src/main/res/values/styles.xml
+++ b/build/android/src/main/res/values/styles.xml
@@ -1,11 +1,12 @@
-
+
+
+
\ No newline at end of file