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 Paramat
parent 1b0fd195c6
commit f70f7875e2
23 changed files with 669 additions and 569 deletions

1
.gitignore vendored

@ -90,6 +90,7 @@ locale/
*.ninja *.ninja
.ninja* .ninja*
*.gch *.gch
*.iml
test_config.h test_config.h
cmake-build-debug/ cmake-build-debug/
cmake-build-release/ cmake-build-release/

@ -1,12 +1,17 @@
buildscript { buildscript {
repositories { repositories {
mavenCentral()
jcenter()
google()
maven { url 'https://maven.google.com' } maven { url 'https://maven.google.com' }
jcenter()
} }
dependencies { 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" apply plugin: "com.android.application"
android { android {
compileSdkVersion 26 compileSdkVersion 28
buildToolsVersion "26.0.3" buildToolsVersion "28.0.3"
defaultConfig { defaultConfig {
versionCode 20 versionCode 20
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 { ndk {
// Specifies the ABI configurations of your native // Specifies the ABI configurations of your native
// libraries Gradle should build and package with your APK. // libraries Gradle should build and package with your APK.
abiFilters 'x86', 'x86_64', 'armeabi', 'armeabi-v7a', // abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
'arm64-v8a' abiFilters 'armeabi-v7a', 'x86'
} }
} }
@ -63,58 +68,58 @@ android {
} }
} }
task cleanAssets(type:Delete) { task cleanAssets(type: Delete) {
delete 'src/main/assets' delete 'src/main/assets'
} }
task cleanIconv(type:Delete) { task cleanIconv(type: Delete) {
delete 'deps/libiconv' delete 'deps/libiconv'
} }
task cleanIrrlicht(type:Delete) { task cleanIrrlicht(type: Delete) {
delete 'deps/irrlicht' delete 'deps/irrlicht'
} }
task cleanLevelDB(type:Delete) { task cleanLevelDB(type: Delete) {
delete 'deps/leveldb' delete 'deps/leveldb'
} }
task cleanCURL(type:Delete) { task cleanCURL(type: Delete) {
delete 'deps/curl' delete 'deps/curl'
delete 'deps/curl-' + curl_version delete 'deps/curl-' + curl_version
} }
task cleanOpenSSL(type:Delete) { task cleanOpenSSL(type: Delete) {
delete 'deps/openssl' delete 'deps/openssl'
delete 'deps/openssl-' + openssl_version delete 'deps/openssl-' + openssl_version
delete 'deps/openssl-' + openssl_version + '.tar.gz' delete 'deps/openssl-' + openssl_version + '.tar.gz'
} }
task cleanOpenAL(type:Delete) { task cleanOpenAL(type: Delete) {
delete 'deps/openal-soft' delete 'deps/openal-soft'
} }
task cleanFreetype(type:Delete) { task cleanFreetype(type: Delete) {
delete 'deps/freetype2-android' delete 'deps/freetype2-android'
} }
task cleanOgg(type:Delete) { task cleanOgg(type: Delete) {
delete 'deps/libvorbis-libogg-android' 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
delete 'deps/sqlite-amalgamation-' + sqlite3_version + '.zip' delete 'deps/sqlite-amalgamation-' + sqlite3_version + '.zip'
} }
task cleanGMP(type:Delete) { task cleanGMP(type: Delete) {
delete 'deps/gmp' delete 'deps/gmp'
delete 'deps/gmp-' + gmp_version delete 'deps/gmp-' + gmp_version
} }
task cleanAll(type:Delete, dependsOn:[clean,cleanAssets,cleanIconv, task cleanAll(type: Delete, dependsOn: [clean, cleanAssets, cleanIconv,
cleanFreetype,cleanIrrlicht,cleanLevelDB,cleanSQLite3,cleanCURL, cleanFreetype, cleanIrrlicht, cleanLevelDB, cleanSQLite3, cleanCURL,
cleanOpenSSL,cleanOpenAL,cleanOgg,cleanGMP]) { cleanOpenSSL, cleanOpenAL, cleanOgg, cleanGMP]) {
delete 'deps' delete 'deps'
delete 'gen' delete 'gen'
delete 'libs' delete 'libs'
@ -123,3 +128,7 @@ task cleanAll(type:Delete, dependsOn:[clean,cleanAssets,cleanIconv,
delete 'Debug' delete 'Debug'
delete 'and_env' 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-4.6-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,410 +19,355 @@ 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();
/* 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;
TextView m_Filename;
copyAssetTask m_AssetCopy;
private class copyAssetTask extends AsyncTask<String, Integer, String>
{
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 private class copyAssetTask extends AsyncTask<String, Integer, String> {
protected String doInBackground(String... files)
{
m_foldernames = new Vector<String>();
m_filenames = new Vector<String>();
m_tocopy = new Vector<String>();
m_asset_size_unknown = new Vector<String>();
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);
}
boolean m_copy_started = false; boolean m_copy_started = false;
String m_Foldername = "media"; String m_Foldername = "media";
Vector<String> m_foldernames; Vector<String> m_foldernames;
Vector<String> m_filenames; Vector<String> m_filenames;
Vector<String> m_tocopy; Vector<String> m_tocopy;
Vector<String> m_asset_size_unknown; Vector<String> 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<String>();
m_filenames = new Vector<String>();
m_tocopy = new Vector<String>();
m_asset_size_unknown = new Vector<String>();
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);
}
} }
} }

@ -6,63 +6,59 @@ 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);
mTextInputWidget.setHint(hint); mTextInputWidget.setHint(hint);
mTextInputWidget.setText(current); mTextInputWidget.setText(current);
mTextInputWidget.setMinWidth(300); mTextInputWidget.setMinWidth(300);
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() {
public void onCancel(DialogInterface dialog) { public void onCancel(DialogInterface dialog) {
cancelDialog(); cancelDialog();
} }
}); });
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;
@ -70,19 +66,19 @@ public class MinetestTextEntry extends Activity {
return false; return false;
} }
}); });
mTextInputDialog = builder.create(); mTextInputDialog = builder.create();
mTextInputDialog.show(); mTextInputDialog.show();
} }
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();
} }
public void cancelDialog() { public void cancelDialog() {
setResult(Activity.RESULT_CANCELED); setResult(Activity.RESULT_CANCELED);
mTextInputDialog.dismiss(); mTextInputDialog.dismiss();

@ -2,23 +2,55 @@ 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);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
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() {
@ -27,7 +59,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();
@ -38,11 +70,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;
@ -67,32 +97,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("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>
</resources> <string name="not_granted">Required permission wasn\'t granted, Minetest can\'t run without it</string>
</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>