Update Android java code (#7820)

Targets SDK 26 as required by the playstore.
Fixes screen auto-rotation closing game.
Hides on-screen navigation bar if present.

Update gradlew.
Fix display aspect on 18+/:9 displays (like a Samsung Galaxy S9).
Remove small app icons, not required.
Fix xml in unpacking activity.
Support Android permission: On Android 6.0+ you need to manually give write
permission (as required by google).
Background during unpacking (just a demo for now).
Material Design: no more Android 2 interface.
Immersive mode (Android 4.4+ - hide NavBar for fullscreen mode).
This commit is contained in:
Maksim 2018-12-03 00:39:35 +01:00 committed by Loic Blot
parent ce4497224f
commit 9d64805ec1
No known key found for this signature in database
GPG Key ID: EFAA458E8C153987
23 changed files with 723 additions and 553 deletions

3
.gitignore vendored

@ -77,6 +77,7 @@ src/cmake_config_githash.h
src/lua/build/ src/lua/build/
locale/ locale/
.directory .directory
.gradle/
*.cbp *.cbp
*.layout *.layout
*.o *.o
@ -84,6 +85,8 @@ locale/
*.ninja *.ninja
.ninja* .ninja*
*.gch *.gch
*.iml
test_config.h
cmake-build-debug/ cmake-build-debug/
cmake-build-release/ cmake-build-release/

@ -1,25 +1,39 @@
buildscript { buildscript {
repositories { repositories {
mavenCentral() maven { url 'https://maven.google.com' }
jcenter()
} }
dependencies { dependencies {
classpath "com.android.tools.build:gradle:2.3.0" classpath 'com.android.tools.build:gradle:3.1.3'
}
}
allprojects {
repositories {
maven { url 'https://maven.google.com' }
jcenter()
} }
} }
apply plugin: "com.android.application" apply plugin: "com.android.application"
android { android {
compileSdkVersion 26 compileSdkVersion 28
buildToolsVersion "26.0.3" buildToolsVersion "28.0.3"
defaultConfig { defaultConfig {
versionCode 21 versionCode 21
versionName "${System.env.VERSION_STR}.${versionCode}" versionName "${System.env.VERSION_STR}.${versionCode}"
minSdkVersion 14 minSdkVersion 14
targetSdkVersion 14 targetSdkVersion 28
applicationId "net.minetest.minetest" 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 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64',
'arm64-v8a'
}
} }
lintOptions { lintOptions {
@ -46,3 +60,68 @@ android {
} }
} }
} }
task cleanAssets(type: Delete) {
delete 'src/main/assets'
}
task cleanIconv(type: Delete) {
delete 'deps/libiconv'
}
task cleanIrrlicht(type: Delete) {
delete 'deps/irrlicht'
}
task cleanLevelDB(type: Delete) {
delete 'deps/leveldb'
}
task cleanCURL(type: Delete) {
delete 'deps/curl'
delete 'deps/curl-' + curl_version
}
task cleanOpenSSL(type: Delete) {
delete 'deps/openssl'
delete 'deps/openssl-' + openssl_version
delete 'deps/openssl-' + openssl_version + '.tar.gz'
}
task cleanOpenAL(type: Delete) {
delete 'deps/openal-soft'
}
task cleanFreetype(type: Delete) {
delete 'deps/freetype2-android'
}
task cleanOgg(type: Delete) {
delete 'deps/libvorbis-libogg-android'
}
task cleanSQLite3(type: Delete) {
delete 'deps/sqlite-amalgamation-' + sqlite3_version
delete 'deps/sqlite-amalgamation-' + sqlite3_version + '.zip'
}
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]) {
delete 'deps'
delete 'gen'
delete 'libs'
delete 'obj'
delete 'bin'
delete 'Debug'
delete 'and_env'
}
dependencies {
implementation 'com.android.support:support-v4:28.0.0'
}

Binary file not shown.

@ -1,6 +1,6 @@
#Sat Aug 27 20:10:09 CEST 2016 #Mon Oct 15 00:47:03 CEST 2018
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip

110
build/android/gradlew vendored

@ -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 # Attempt to set APP_HOME
# Resolve links: $0 may be a link # Resolve links: $0 may be a link
PRG="$0" PRG="$0"
@ -61,9 +20,49 @@ while [ -h "$PRG" ] ; do
fi fi
done done
SAVED="`pwd`" SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >&- cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`" 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 CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
@ -90,7 +89,7 @@ location of your Java installation."
fi fi
# Increase the maximum file descriptors if we can. # 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` MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
@ -114,6 +113,7 @@ fi
if $cygwin ; then if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"` APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath # We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
@ -154,11 +154,19 @@ if $cygwin ; then
esac esac
fi fi
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules # Escape application args
function splitJvmOpts() { save () {
JVM_OPTS=("$@") for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
} }
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS APP_ARGS=$(save "$@")
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
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" "$@"

@ -8,14 +8,14 @@
@rem Set local scope for the variables with windows NT shell @rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal 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 set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=. if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0 set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME% 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 @rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome if defined JAVA_HOME goto findJavaFromJavaHome
@ -46,10 +46,9 @@ echo location of your Java installation.
goto fail goto fail
:init :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 not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args
:win9xME_args :win9xME_args
@rem Slurp the command line arguments. @rem Slurp the command line arguments.
@ -60,11 +59,6 @@ set _SKIP=2
if "x%~1" == "x" goto execute if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%* set CMD_LINE_ARGS=%*
goto execute
:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$
:execute :execute
@rem Setup the command line @rem Setup the command line

@ -1,4 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"> <manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.SET_DEBUG_APP" />
<uses-permission android:name="android.permission.SET_DEBUG_APP" />
</manifest> </manifest>

@ -1,34 +1,59 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="net.minetest.minetest" package="net.minetest.minetest"
android:installLocation="auto"> android:installLocation="auto">
<uses-feature android:glEsVersion="0x00010000" android:required="true"/>
<uses-feature
android:glEsVersion="0x00010000"
android:required="true" />
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application android:icon="@drawable/irr_icon"
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="${project}"
android:resizeableActivity="false">
<meta-data
android:name="android.max_aspect"
android:value="2.1" />
<activity
android:name=".MainActivity"
android:configChanges="orientation|keyboardHidden|navigation|screenSize"
android:label="${project}" android:label="${project}"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen" android:launchMode="singleTask"
android:allowBackup="true"> android:screenOrientation="sensorLandscape"
<activity android:name=".MtNativeActivity" android:theme="@style/AppTheme">
android:label="${project}"
android:launchMode="singleTask"
android:configChanges="orientation|keyboard|keyboardHidden|navigation"
android:screenOrientation="sensorLandscape"
android:clearTaskOnLaunch="true">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter> </intent-filter>
<meta-data android:name="android.app.lib_name" android:value="minetest" />
</activity> </activity>
<activity android:name=".MinetestTextEntry" <activity
android:theme="@style/Theme.Transparent" android:name=".MtNativeActivity"
android:excludeFromRecents="true"> android:configChanges="orientation|keyboard|keyboardHidden|navigation|screenSize|smallestScreenSize"
</activity> android:hardwareAccelerated="true"
<activity android:name=".MinetestAssetCopy" android:launchMode="singleTask"
android:theme="@style/Theme.Transparent" android:screenOrientation="sensorLandscape"
android:excludeFromRecents="true"> android:theme="@style/AppTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
</intent-filter>
<meta-data
android:name="android.app.lib_name"
android:value="minetest" />
</activity> </activity>
<activity
android:name=".MinetestTextEntry"
android:configChanges="keyboardHidden|orientation|screenSize"
android:theme="@style/Theme.Dialog"
android:windowSoftInputMode="stateAlwaysHidden"/>
<activity
android:name=".MinetestAssetCopy"
android:screenOrientation="sensorLandscape"
android:theme="@style/AppTheme"/>
</application> </application>
</manifest> </manifest>

@ -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<String> missingPermissions = new ArrayList<String>();
// 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);
}
}

@ -1,5 +1,17 @@
package net.minetest.minetest; 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.BufferedReader;
import java.io.File; import java.io.File;
import java.io.FileOutputStream; import java.io.FileOutputStream;
@ -7,36 +19,20 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.io.OutputStream; import java.io.OutputStream;
import java.util.Vector;
import java.util.Iterator; import java.util.Iterator;
import java.lang.Object; import java.util.Vector;
import android.app.Activity; public class MinetestAssetCopy extends Activity {
import android.content.res.AssetFileDescriptor; 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 @Override
public void onCreate(Bundle savedInstanceState) public void onCreate(Bundle savedInstanceState) {
{
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.assetcopy); setContentView(R.layout.assetcopy);
m_ProgressBar = findViewById(R.id.progressBar1);
m_ProgressBar = (ProgressBar) findViewById(R.id.progressBar1); m_Filename = findViewById(R.id.textView1);
m_Filename = (TextView) findViewById(R.id.textView1);
Display display = getWindowManager().getDefaultDisplay(); Display display = getWindowManager().getDefaultDisplay();
m_ProgressBar.getLayoutParams().width = (int) (display.getWidth() * 0.8); m_ProgressBar.getLayoutParams().width = (int) (display.getWidth() * 0.8);
m_ProgressBar.invalidate(); m_ProgressBar.invalidate();
@ -44,75 +40,88 @@ public class MinetestAssetCopy extends Activity
/* check if there's already a copy in progress and reuse in case it is*/ /* check if there's already a copy in progress and reuse in case it is*/
MinetestAssetCopy prevActivity = MinetestAssetCopy prevActivity =
(MinetestAssetCopy) getLastNonConfigurationInstance(); (MinetestAssetCopy) getLastNonConfigurationInstance();
if(prevActivity!= null) { if (prevActivity != null) {
m_AssetCopy = prevActivity.m_AssetCopy; m_AssetCopy = prevActivity.m_AssetCopy;
} } else {
else {
m_AssetCopy = new copyAssetTask(); m_AssetCopy = new copyAssetTask();
m_AssetCopy.execute(); 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 */ /* preserve asset copy background task to prevent restart of copying */
/* this way of doing it is not recommended for latest android version */ /* this way of doing it is not recommended for latest android version */
/* but the recommended way isn't available on android 2.x */ /* but the recommended way isn't available on android 2.x */
public Object onRetainNonConfigurationInstance() public Object onRetainNonConfigurationInstance() {
{
return this; return this;
} }
ProgressBar m_ProgressBar; private class copyAssetTask extends AsyncTask<String, Integer, String> {
TextView m_Filename; boolean m_copy_started = false;
String m_Foldername = "media";
Vector<String> m_foldernames;
Vector<String> m_filenames;
Vector<String> m_tocopy;
Vector<String> m_asset_size_unknown;
copyAssetTask m_AssetCopy; private long getFullSize(String filename) {
private class copyAssetTask extends AsyncTask<String, Integer, String>
{
private long getFullSize(String filename)
{
long size = 0; long size = 0;
try { try {
InputStream src = getAssets().open(filename); InputStream src = getAssets().open(filename);
byte[] buf = new byte[4096]; byte[] buf = new byte[4096];
int len = 0; int len = 0;
while ((len = src.read(buf)) > 0) while ((len = src.read(buf)) > 0) {
{
size += len; size += len;
} }
} } catch (IOException e) {
catch (IOException e)
{
e.printStackTrace(); e.printStackTrace();
} }
return size; return size;
} }
@Override @Override
protected String doInBackground(String... files) protected String doInBackground(String... files) {
{ m_foldernames = new Vector<String>();
m_foldernames = new Vector<String>(); m_filenames = new Vector<String>();
m_filenames = new Vector<String>(); m_tocopy = new Vector<String>();
m_tocopy = new Vector<String>();
m_asset_size_unknown = new Vector<String>(); m_asset_size_unknown = new Vector<String>();
String baseDir = String baseDir =
Environment.getExternalStorageDirectory().getAbsolutePath() Environment.getExternalStorageDirectory().getAbsolutePath()
+ "/"; + "/";
// prepare temp folder // prepare temp folder
File TempFolder = new File(baseDir + "Minetest/tmp/"); File TempFolder = new File(baseDir + "Minetest/tmp/");
if (!TempFolder.exists()) if (!TempFolder.exists()) {
{
TempFolder.mkdir(); TempFolder.mkdir();
} } else {
else {
File[] todel = TempFolder.listFiles(); File[] todel = TempFolder.listFiles();
for(int i=0; i < todel.length; i++) for (int i = 0; i < todel.length; i++) {
{ Log.v("MinetestAssetCopy", "deleting: " + todel[i].getAbsolutePath());
Log.v("MinetestAssetCopy","deleting: " + todel[i].getAbsolutePath());
todel[i].delete(); todel[i].delete();
} }
} }
@ -122,7 +131,7 @@ public class MinetestAssetCopy extends Activity
OutputStream dst = new FileOutputStream(baseDir + "Minetest/.nomedia"); OutputStream dst = new FileOutputStream(baseDir + "Minetest/.nomedia");
dst.close(); dst.close();
} catch (IOException e) { } catch (IOException e) {
Log.e("MinetestAssetCopy","Failed to create .nomedia file"); Log.e("MinetestAssetCopy", "Failed to create .nomedia file");
e.printStackTrace(); e.printStackTrace();
} }
@ -138,75 +147,64 @@ public class MinetestAssetCopy extends Activity
m_copy_started = true; m_copy_started = true;
m_ProgressBar.setMax(m_tocopy.size()); m_ProgressBar.setMax(m_tocopy.size());
for (int i = 0; i < m_tocopy.size(); i++) for (int i = 0; i < m_tocopy.size(); i++) {
{ try {
try
{
String filename = m_tocopy.get(i); String filename = m_tocopy.get(i);
publishProgress(i); publishProgress(i);
boolean asset_size_unknown = false; boolean asset_size_unknown = false;
long filesize = -1; long filesize = -1;
if (m_asset_size_unknown.contains(filename)) if (m_asset_size_unknown.contains(filename)) {
{
File testme = new File(baseDir + "/" + filename); File testme = new File(baseDir + "/" + filename);
if(testme.exists()) if (testme.exists()) {
{
filesize = testme.length(); filesize = testme.length();
} }
asset_size_unknown = true; asset_size_unknown = true;
} }
InputStream src; InputStream src;
try try {
{
src = getAssets().open(filename); src = getAssets().open(filename);
} catch (IOException e) { } catch (IOException e) {
Log.e("MinetestAssetCopy","Copying file: " + filename + " FAILED (not in assets)"); Log.e("MinetestAssetCopy", "Copying file: " + filename + " FAILED (not in assets)");
e.printStackTrace(); e.printStackTrace();
continue; continue;
} }
// Transfer bytes from in to out // Transfer bytes from in to out
byte[] buf = new byte[1*1024]; byte[] buf = new byte[1024];
int len = src.read(buf, 0, 1024); int len = src.read(buf, 0, 1024);
/* following handling is crazy but we need to deal with */ /* following handling is crazy but we need to deal with */
/* compressed assets.Flash chips limited livetime due to */ /* compressed assets.Flash chips limited livetime due to */
/* write operations, we can't allow large files to destroy */ /* write operations, we can't allow large files to destroy */
/* users flash. */ /* users flash. */
if (asset_size_unknown) if (asset_size_unknown) {
{ if ((len > 0) && (len < buf.length) && (len == filesize)) {
if ( (len > 0) && (len < buf.length) && (len == filesize))
{
src.close(); src.close();
continue; continue;
} }
if (len == buf.length) if (len == buf.length) {
{
src.close(); src.close();
long size = getFullSize(filename); long size = getFullSize(filename);
if ( size == filesize) if (size == filesize) {
{
continue; continue;
} }
src = getAssets().open(filename); src = getAssets().open(filename);
len = src.read(buf, 0, 1024); len = src.read(buf, 0, 1024);
} }
} }
if (len > 0) if (len > 0) {
{
int total_filesize = 0; int total_filesize = 0;
OutputStream dst; OutputStream dst;
try try {
{
dst = new FileOutputStream(baseDir + "/" + filename); dst = new FileOutputStream(baseDir + "/" + filename);
} catch (IOException e) { } catch (IOException e) {
Log.e("MinetestAssetCopy","Copying file: " + baseDir + Log.e("MinetestAssetCopy", "Copying file: " + baseDir +
"/" + filename + " FAILED (couldn't open output file)"); "/" + filename + " FAILED (couldn't open output file)");
e.printStackTrace(); e.printStackTrace();
src.close(); src.close();
continue; continue;
@ -214,27 +212,22 @@ public class MinetestAssetCopy extends Activity
dst.write(buf, 0, len); dst.write(buf, 0, len);
total_filesize += len; total_filesize += len;
while ((len = src.read(buf)) > 0) while ((len = src.read(buf)) > 0) {
{
dst.write(buf, 0, len); dst.write(buf, 0, len);
total_filesize += len; total_filesize += len;
} }
dst.close(); dst.close();
Log.v("MinetestAssetCopy","Copied file: " + Log.v("MinetestAssetCopy", "Copied file: " +
m_tocopy.get(i) + " (" + total_filesize + m_tocopy.get(i) + " (" + total_filesize +
" bytes)"); " bytes)");
} } else if (len < 0) {
else if (len < 0) Log.e("MinetestAssetCopy", "Copying file: " +
{
Log.e("MinetestAssetCopy","Copying file: " +
m_tocopy.get(i) + " failed, size < 0"); m_tocopy.get(i) + " failed, size < 0");
} }
src.close(); src.close();
} } catch (IOException e) {
catch (IOException e) Log.e("MinetestAssetCopy", "Copying file: " +
{
Log.e("MinetestAssetCopy","Copying file: " +
m_tocopy.get(i) + " failed"); m_tocopy.get(i) + " failed");
e.printStackTrace(); e.printStackTrace();
} }
@ -242,22 +235,17 @@ public class MinetestAssetCopy extends Activity
return ""; return "";
} }
/** /**
* update progress bar * update progress bar
*/ */
protected void onProgressUpdate(Integer... progress) protected void onProgressUpdate(Integer... progress) {
{
if (m_copy_started) if (m_copy_started) {
{
boolean shortened = false; boolean shortened = false;
String todisplay = m_tocopy.get(progress[0]); String todisplay = m_tocopy.get(progress[0]);
m_ProgressBar.setProgress(progress[0]); m_ProgressBar.setProgress(progress[0]);
m_Filename.setText(todisplay); m_Filename.setText(todisplay);
} } else {
else
{
boolean shortened = false; boolean shortened = false;
String todisplay = m_Foldername; String todisplay = m_Foldername;
String full_text = "scanning " + todisplay + " ..."; String full_text = "scanning " + todisplay + " ...";
@ -266,38 +254,31 @@ public class MinetestAssetCopy extends Activity
} }
/** /**
* check al files and folders in filelist * check all files and folders in filelist
*/ */
protected void ProcessFileList() protected void ProcessFileList() {
{
String FlashBaseDir = String FlashBaseDir =
Environment.getExternalStorageDirectory().getAbsolutePath(); Environment.getExternalStorageDirectory().getAbsolutePath();
Iterator itr = m_filenames.iterator(); Iterator itr = m_filenames.iterator();
while (itr.hasNext()) while (itr.hasNext()) {
{
String current_path = (String) itr.next(); String current_path = (String) itr.next();
String FlashPath = FlashBaseDir + "/" + current_path; String FlashPath = FlashBaseDir + "/" + current_path;
if (isAssetFolder(current_path)) if (isAssetFolder(current_path)) {
{
/* store information and update gui */ /* store information and update gui */
m_Foldername = current_path; m_Foldername = current_path;
publishProgress(0); publishProgress(0);
/* open file in order to check if it's a folder */ /* open file in order to check if it's a folder */
File current_folder = new File(FlashPath); File current_folder = new File(FlashPath);
if (!current_folder.exists()) if (!current_folder.exists()) {
{ if (!current_folder.mkdirs()) {
if (!current_folder.mkdirs()) Log.e("MinetestAssetCopy", "\t failed create folder: " +
{
Log.e("MinetestAssetCopy","\t failed create folder: " +
FlashPath); FlashPath);
} } else {
else Log.v("MinetestAssetCopy", "\t created folder: " +
{
Log.v("MinetestAssetCopy","\t created folder: " +
FlashPath); FlashPath);
} }
} }
@ -313,33 +294,27 @@ public class MinetestAssetCopy extends Activity
long asset_filesize = -1; long asset_filesize = -1;
long stored_filesize = -1; long stored_filesize = -1;
if (testme.exists()) if (testme.exists()) {
{ try {
try
{
AssetFileDescriptor fd = getAssets().openFd(current_path); AssetFileDescriptor fd = getAssets().openFd(current_path);
asset_filesize = fd.getLength(); asset_filesize = fd.getLength();
fd.close(); fd.close();
} } catch (IOException e) {
catch (IOException e)
{
refresh = true; refresh = true;
m_asset_size_unknown.add(current_path); m_asset_size_unknown.add(current_path);
Log.e("MinetestAssetCopy","Failed to open asset file \"" + Log.e("MinetestAssetCopy", "Failed to open asset file \"" +
FlashPath + "\" for size check"); FlashPath + "\" for size check");
} }
stored_filesize = testme.length(); stored_filesize = testme.length();
if (asset_filesize == stored_filesize) if (asset_filesize == stored_filesize) {
{
refresh = false; refresh = false;
} }
} }
if (refresh) if (refresh) {
{
m_tocopy.add(current_path); m_tocopy.add(current_path);
} }
} }
@ -348,23 +323,19 @@ public class MinetestAssetCopy extends Activity
/** /**
* read list of folders prepared on package build * read list of folders prepared on package build
*/ */
protected void BuildFolderList() protected void BuildFolderList() {
{ try {
try
{
InputStream is = getAssets().open("index.txt"); InputStream is = getAssets().open("index.txt");
BufferedReader reader = new BufferedReader(new InputStreamReader(is)); BufferedReader reader = new BufferedReader(new InputStreamReader(is));
String line = reader.readLine(); String line = reader.readLine();
while (line != null) while (line != null) {
{
m_foldernames.add(line); m_foldernames.add(line);
line = reader.readLine(); line = reader.readLine();
} }
is.close(); is.close();
} catch (IOException e1) } catch (IOException e1) {
{ Log.e("MinetestAssetCopy", "Error on processing index.txt");
Log.e("MinetestAssetCopy","Error on processing index.txt");
e1.printStackTrace(); e1.printStackTrace();
} }
} }
@ -372,45 +343,31 @@ public class MinetestAssetCopy extends Activity
/** /**
* read list of asset files prepared on package build * read list of asset files prepared on package build
*/ */
protected void BuildFileList() protected void BuildFileList() {
{
long entrycount = 0; long entrycount = 0;
try try {
{
InputStream is = getAssets().open("filelist.txt"); InputStream is = getAssets().open("filelist.txt");
BufferedReader reader = new BufferedReader(new InputStreamReader(is)); BufferedReader reader = new BufferedReader(new InputStreamReader(is));
String line = reader.readLine(); String line = reader.readLine();
while (line != null) while (line != null) {
{
m_filenames.add(line); m_filenames.add(line);
line = reader.readLine(); line = reader.readLine();
entrycount ++; entrycount++;
} }
is.close(); is.close();
} } catch (IOException e1) {
catch (IOException e1) Log.e("MinetestAssetCopy", "Error on processing filelist.txt");
{
Log.e("MinetestAssetCopy","Error on processing filelist.txt");
e1.printStackTrace(); e1.printStackTrace();
} }
} }
protected void onPostExecute (String result) protected void onPostExecute(String result) {
{
finish(); finish();
} }
protected boolean isAssetFolder(String path) protected boolean isAssetFolder(String path) {
{
return m_foldernames.contains(path); return m_foldernames.contains(path);
} }
boolean m_copy_started = false;
String m_Foldername = "media";
Vector<String> m_foldernames;
Vector<String> m_filenames;
Vector<String> m_tocopy;
Vector<String> m_asset_size_unknown;
} }
} }

@ -6,29 +6,26 @@ import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.text.InputType; import android.text.InputType;
import android.util.Log;
import android.view.KeyEvent; import android.view.KeyEvent;
import android.view.View; import android.view.View;
import android.view.View.OnKeyListener; import android.view.View.OnKeyListener;
import android.widget.EditText; import android.widget.EditText;
public class MinetestTextEntry extends Activity { public class MinetestTextEntry extends Activity {
private final int MultiLineTextInput = 1;
private final int SingleLineTextInput = 2;
private final int SingleLinePasswordInput = 3;
public AlertDialog mTextInputDialog; public AlertDialog mTextInputDialog;
public EditText mTextInputWidget; public EditText mTextInputWidget;
private final int MultiLineTextInput = 1;
private final int SingleLineTextInput = 2;
private final int SingleLinePasswordInput = 3;
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
Bundle b = getIntent().getExtras(); Bundle b = getIntent().getExtras();
String acceptButton = b.getString("EnterButton"); String acceptButton = b.getString("EnterButton");
String hint = b.getString("hint"); String hint = b.getString("hint");
String current = b.getString("current"); String current = b.getString("current");
int editType = b.getInt("editType"); int editType = b.getInt("editType");
AlertDialog.Builder builder = new AlertDialog.Builder(this); AlertDialog.Builder builder = new AlertDialog.Builder(this);
mTextInputWidget = new EditText(this); mTextInputWidget = new EditText(this);
@ -38,19 +35,18 @@ public class MinetestTextEntry extends Activity {
if (editType == SingleLinePasswordInput) { if (editType == SingleLinePasswordInput) {
mTextInputWidget.setInputType(InputType.TYPE_CLASS_TEXT | mTextInputWidget.setInputType(InputType.TYPE_CLASS_TEXT |
InputType.TYPE_TEXT_VARIATION_PASSWORD); InputType.TYPE_TEXT_VARIATION_PASSWORD);
} } else {
else {
mTextInputWidget.setInputType(InputType.TYPE_CLASS_TEXT); mTextInputWidget.setInputType(InputType.TYPE_CLASS_TEXT);
} }
builder.setView(mTextInputWidget); builder.setView(mTextInputWidget);
if (editType == MultiLineTextInput) { if (editType == MultiLineTextInput) {
builder.setPositiveButton(acceptButton, new DialogInterface.OnClickListener() { builder.setPositiveButton(acceptButton, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) public void onClick(DialogInterface dialog, int whichButton) {
{ pushResult(mTextInputWidget.getText().toString()); } pushResult(mTextInputWidget.getText().toString());
}); }
});
} }
builder.setOnCancelListener(new DialogInterface.OnCancelListener() { builder.setOnCancelListener(new DialogInterface.OnCancelListener() {
@ -62,7 +58,7 @@ public class MinetestTextEntry extends Activity {
mTextInputWidget.setOnKeyListener(new OnKeyListener() { mTextInputWidget.setOnKeyListener(new OnKeyListener() {
@Override @Override
public boolean onKey(View view, int KeyCode, KeyEvent event) { public boolean onKey(View view, int KeyCode, KeyEvent event) {
if ( KeyCode == KeyEvent.KEYCODE_ENTER){ if (KeyCode == KeyEvent.KEYCODE_ENTER) {
pushResult(mTextInputWidget.getText().toString()); pushResult(mTextInputWidget.getText().toString());
return true; return true;
@ -78,7 +74,7 @@ public class MinetestTextEntry extends Activity {
public void pushResult(String text) { public void pushResult(String text) {
Intent resultData = new Intent(); Intent resultData = new Intent();
resultData.putExtra("text", text); resultData.putExtra("text", text);
setResult(Activity.RESULT_OK,resultData); setResult(Activity.RESULT_OK, resultData);
mTextInputDialog.dismiss(); mTextInputDialog.dismiss();
finish(); finish();
} }

@ -2,22 +2,54 @@ package net.minetest.minetest;
import android.app.NativeActivity; import android.app.NativeActivity;
import android.content.Intent; import android.content.Intent;
import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log; import android.view.View;
import android.view.WindowManager; import android.view.WindowManager;
public class MtNativeActivity extends NativeActivity { 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 @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
m_MessagReturnCode = -1; m_MessagReturnCode = -1;
m_MessageReturnValue = ""; m_MessageReturnValue = "";
} }
@Override @Override
public void onDestroy() { protected void onResume() {
super.onDestroy(); 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() { public void copyAssets() {
@ -26,7 +58,7 @@ public class MtNativeActivity extends NativeActivity {
} }
public void showDialog(String acceptButton, String hint, String current, public void showDialog(String acceptButton, String hint, String current,
int editType) { int editType) {
Intent intent = new Intent(this, MinetestTextEntry.class); Intent intent = new Intent(this, MinetestTextEntry.class);
Bundle params = new Bundle(); Bundle params = new Bundle();
@ -37,11 +69,9 @@ public class MtNativeActivity extends NativeActivity {
intent.putExtras(params); intent.putExtras(params);
startActivityForResult(intent, 101); startActivityForResult(intent, 101);
m_MessageReturnValue = ""; m_MessageReturnValue = "";
m_MessagReturnCode = -1; m_MessagReturnCode = -1;
} }
public static native void putMessageBoxResult(String text);
/* ugly code to workaround putMessageBoxResult not beeing found */ /* ugly code to workaround putMessageBoxResult not beeing found */
public int getDialogState() { public int getDialogState() {
return m_MessagReturnCode; return m_MessagReturnCode;
@ -66,34 +96,15 @@ public class MtNativeActivity extends NativeActivity {
@Override @Override
protected void onActivityResult(int requestCode, int resultCode, protected void onActivityResult(int requestCode, int resultCode,
Intent data) { Intent data) {
if (requestCode == 101) { if (requestCode == 101) {
if (resultCode == RESULT_OK) { if (resultCode == RESULT_OK) {
String text = data.getStringExtra("text"); String text = data.getStringExtra("text");
m_MessagReturnCode = 0; m_MessagReturnCode = 0;
m_MessageReturnValue = text; m_MessageReturnValue = text;
} } else {
else {
m_MessagReturnCode = 1; m_MessagReturnCode = 1;
} }
} }
} }
static {
System.loadLibrary("openal");
System.loadLibrary("ogg");
System.loadLibrary("vorbis");
System.loadLibrary("ssl");
System.loadLibrary("crypto");
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;
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 B

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/background"
android:tileMode="repeat" />

@ -1,24 +1,24 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:id="@+id/activity_main"
android:layout_height="fill_parent" android:layout_width="match_parent"
android:orientation="vertical" > android:layout_height="match_parent">
<ProgressBar <ProgressBar
android:id="@+id/progressBar1" android:id="@+id/progressBar1"
style="?android:attr/progressBarStyleHorizontal" style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="30dp"
android:layout_gravity="center_vertical" /> android:layout_centerInParent="true"
android:layout_marginLeft="90dp"
android:layout_marginRight="90dp" />
<TextView <TextView
android:id="@+id/textView1" android:id="@+id/textView1"
android:layout_width="match_parent" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:ellipsize="middle" android:layout_below="@+id/progressBar1"
android:singleLine="true" android:layout_centerInParent="true"
android:layout_gravity="center_horizontal" android:text="@string/preparing_media" />
android:text="@string/preparing_media"
android:textAppearance="?android:attr/textAppearanceSmall" />
</LinearLayout> </RelativeLayout>

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="AppTheme" parent="@android:style/android:Theme.Material.Light.NoActionBar.Fullscreen">
<item name="android:windowNoTitle">true</item>
<item name="android:windowAnimationStyle">@null</item>
<item name="android:background">@drawable/bg</item>
</style>
<style name="Theme.Dialog" parent="@android:style/Theme.Material.Light.Dialog.NoActionBar"/>
</resources>

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<string name="preparing_media">Preparing media...</string> <string name="preparing_media">Preparing media&#8230;</string>
<string name="not_granted">Required permission wasn\'t granted, Minetest can\'t run without it</string>
</resources> </resources>

@ -1,11 +1,12 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<style name="Theme.Transparent" parent="android:Theme">
<item name="android:windowIsTranslucent">true</item> <style name="AppTheme" parent="@android:style/android:Theme.Holo.Light.NoActionBar.Fullscreen">
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowContentOverlay">@null</item>
<item name="android:windowNoTitle">true</item> <item name="android:windowNoTitle">true</item>
<item name="android:windowIsFloating">true</item> <item name="android:windowAnimationStyle">@null</item>
<item name="android:backgroundDimEnabled">false</item> <item name="android:background">@drawable/bg</item>
</style> </style>
<style name="Theme.Dialog" parent="@android:style/android:Theme.Holo.Light.Dialog.NoActionBar"/>
</resources> </resources>