Convert MA to Kotlin, update gradle to 7.0.0

master
ubulem 2021-08-13 13:12:35 +06:00 committed by MoNTE48
parent 2793e9c655
commit 9188d2bbf7
10 changed files with 367 additions and 414 deletions

View File

@ -47,6 +47,10 @@ android {
targetCompatibility JavaVersion.VERSION_1_8
}
buildFeatures {
viewBinding true
}
// for multiple APKs
splits {
abi {
@ -62,8 +66,8 @@ dependencies {
implementation project(':native')
/* Third-party libraries */
implementation 'androidx.appcompat:appcompat:1.3.0'
implementation 'androidx.appcompat:appcompat-resources:1.3.0'
implementation 'androidx.appcompat:appcompat:1.3.1'
implementation 'androidx.appcompat:appcompat-resources:1.3.1'
implementation 'com.google.android.material:material:1.4.0'
implementation 'io.reactivex.rxjava3:rxjava:3.0.13'
implementation 'io.reactivex.rxjava3:rxandroid:3.0.0'

View File

@ -6,6 +6,7 @@
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"

View File

@ -1,329 +0,0 @@
/*
MultiCraft
Copyright (C) 2014-2021 MoNTE48, Maksim Gamarnik <MoNTE48@mail.ua>
Copyright (C) 2014-2021 ubulem, Bektur Mambetov <berkut87@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 3.0 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package com.multicraft.game;
import static android.content.DialogInterface.BUTTON_NEUTRAL;
import static android.provider.Settings.ACTION_WIFI_SETTINGS;
import static android.provider.Settings.ACTION_WIRELESS_SETTINGS;
import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
import static com.multicraft.game.UnzipService.ACTION_FAILURE;
import static com.multicraft.game.UnzipService.UNZIP_FAILURE;
import static com.multicraft.game.UnzipService.UNZIP_SUCCESS;
import static com.multicraft.game.helpers.Constants.FILES;
import static com.multicraft.game.helpers.Constants.NO_SPACE_LEFT;
import static com.multicraft.game.helpers.Constants.REQUEST_CONNECTION;
import static com.multicraft.game.helpers.Constants.versionName;
import static com.multicraft.game.helpers.PreferencesHelper.TAG_BUILD_NUMBER;
import static com.multicraft.game.helpers.PreferencesHelper.TAG_LAUNCH_TIMES;
import static com.multicraft.game.helpers.Utilities.addShortcut;
import static com.multicraft.game.helpers.Utilities.copyInputStreamToFile;
import static com.multicraft.game.helpers.Utilities.deleteFiles;
import static com.multicraft.game.helpers.Utilities.finishApp;
import static com.multicraft.game.helpers.Utilities.getIcon;
import static com.multicraft.game.helpers.Utilities.isConnected;
import static com.multicraft.game.helpers.Utilities.makeFullScreen;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.BlendModeColorFilterCompat;
import androidx.core.graphics.BlendModeCompat;
import com.multicraft.game.helpers.PreferencesHelper;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.core.Completable;
import io.reactivex.rxjava3.core.Observable;
import io.reactivex.rxjava3.disposables.Disposable;
import io.reactivex.rxjava3.schedulers.Schedulers;
public class MainActivity extends AppCompatActivity {
private ProgressBar mProgressBar, mProgressBarIndet;
private TextView mLoadingText;
private PreferencesHelper pf;
private final BroadcastReceiver myReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
int progress = 0;
if (intent != null)
progress = intent.getIntExtra(UnzipService.ACTION_PROGRESS, 0);
if (progress >= 0) {
showProgress(R.string.loading, R.string.loadingp, progress);
} else {
deleteFiles(Collections.singletonList(FILES), getCacheDir());
if (progress == UNZIP_FAILURE) {
String msg = intent.getStringExtra(ACTION_FAILURE);
showRestartDialog(msg);
} else if (progress == UNZIP_SUCCESS) {
pf.saveSettings(TAG_BUILD_NUMBER, versionName);
startNative();
}
}
}
};
private File externalStorage, filesDir, cacheDir;
private Disposable cleanSub, copySub, connectionSub;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().addFlags(FLAG_KEEP_SCREEN_ON);
try {
getSupportActionBar().hide();
} catch (Exception ignored) {
}
setContentView(R.layout.activity_main);
mLoadingText = findViewById(R.id.tv_progress);
mProgressBar = findViewById(R.id.PB);
mProgressBarIndet = findViewById(R.id.PB_Indet);
boolean isException = false;
try {
filesDir = getFilesDir();
cacheDir = getCacheDir();
externalStorage = getExternalFilesDir(null);
if (filesDir == null || cacheDir == null || externalStorage == null)
throw new IOException(getString(R.string.space_error));
} catch (IOException e) {
isException = true;
String msg = getString(R.string.restart, e.getLocalizedMessage());
if (e.getMessage().contains(NO_SPACE_LEFT)) {
msg = NO_SPACE_LEFT;
}
showRestartDialog(msg);
}
if (isException) {
return;
}
pf = PreferencesHelper.getInstance(this);
IntentFilter filter = new IntentFilter(UnzipService.ACTION_UPDATE);
registerReceiver(myReceiver, filter);
lateInit();
}
@Override
public void onBackPressed() {
// Prevent abrupt interruption when copy game files from assets
}
@Override
protected void onDestroy() {
super.onDestroy();
if (cleanSub != null) cleanSub.dispose();
if (copySub != null) copySub.dispose();
if (connectionSub != null) connectionSub.dispose();
if (myReceiver != null) unregisterReceiver(myReceiver);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CONNECTION) {
checkAppVersion();
}
}
@Override
protected void onResume() {
super.onResume();
makeFullScreen(getWindow());
}
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus) makeFullScreen(getWindow());
}
private void addLaunchTimes() {
int launchTimes = pf.getLaunchTimes() + 1;
pf.saveSettings(TAG_LAUNCH_TIMES, launchTimes);
}
// interface
private void showProgress(int textMessage, int progressMessage, int progress) {
if (mProgressBar == null) return;
if (mProgressBar.getVisibility() == View.GONE) {
updateViews(textMessage, View.GONE, View.VISIBLE);
mProgressBar.setProgress(0);
} else if (progress > 0) {
mLoadingText.setText(String.format(getResources().getString(progressMessage), progress));
mProgressBar.setProgress(progress);
// colorize the progress bar
Drawable progressDrawable = ((LayerDrawable)
mProgressBar.getProgressDrawable()).getDrawable(1);
int color = Color.rgb(255 - progress * 2, progress * 2, 25);
progressDrawable.setColorFilter(
BlendModeColorFilterCompat.createBlendModeColorFilterCompat(color, BlendModeCompat.SRC_IN));
}
}
private void lateInit() {
addLaunchTimes();
if (!pf.isCreateShortcut()) addShortcut(this);
connectionSub = checkConnection();
}
// check connection available
private Disposable checkConnection() {
return Observable.fromCallable(() -> isConnected(this))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(result -> {
if (result) checkAppVersion();
else showConnectionDialog();
},
throwable -> runOnUiThread(this::showConnectionDialog));
}
// connection dialog
private void showConnectionDialog() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setIcon(getIcon(this))
.setTitle(R.string.conn_title)
.setMessage(R.string.conn_message)
.setPositiveButton(R.string.conn_wifi, (dialogInterface, i) -> startHandledActivity(new Intent(ACTION_WIFI_SETTINGS)))
.setNegativeButton(R.string.conn_mobile, (dialogInterface, i) -> startHandledActivity(new Intent(ACTION_WIRELESS_SETTINGS)))
.setNeutralButton(R.string.ignore, (dialogInterface, i) -> checkAppVersion())
.setCancelable(false);
final AlertDialog dialog = builder.create();
makeFullScreen(dialog.getWindow());
if (!isFinishing()) {
dialog.show();
Button button = dialog.getButton(BUTTON_NEUTRAL);
if (button != null) button.setTextColor(Color.RED);
}
}
private void startHandledActivity(Intent intent) {
try {
startActivityForResult(intent, REQUEST_CONNECTION);
} catch (Exception e) {
checkAppVersion();
}
}
private void startNative() {
Intent intent = new Intent(this, GameActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
}
private void cleanUpOldFiles() {
updateViews(R.string.preparing, View.VISIBLE, View.GONE);
List<File> filesList = Arrays.asList(
new File(externalStorage, "cache"),
new File(externalStorage, "debug.txt"),
new File(filesDir, "builtin"),
new File(cacheDir, FILES)
);
Completable delObs = Completable.fromAction(() -> deleteFiles(filesList));
cleanSub = delObs.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(this::startCopy);
}
private void checkAppVersion() {
String prefVersion;
try {
prefVersion = pf.getBuildNumber();
} catch (ClassCastException e) {
prefVersion = "1";
}
if (prefVersion.equals(versionName))
startNative();
else
cleanUpOldFiles();
}
private void updateViews(int text, int progressIndetVisib, int progressVisib) {
mLoadingText.setText(text);
mLoadingText.setVisibility(View.VISIBLE);
mProgressBarIndet.setVisibility(progressIndetVisib);
mProgressBar.setVisibility(progressVisib);
}
private void startCopy() {
List<String> zips = new ArrayList<>(Collections.singletonList(FILES));
copySub = Observable.fromCallable(() -> copyAssets(zips))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(result -> {
if (result) startUnzipService(zips);
});
}
private boolean copyAssets(List<String> zips) {
for (String zipName : zips) {
try (InputStream in = getAssets().open("data/" + zipName)) {
copyInputStreamToFile(new File(cacheDir, zipName), in);
} catch (IOException e) {
if (e.getLocalizedMessage().contains(NO_SPACE_LEFT))
runOnUiThread(() -> showRestartDialog(NO_SPACE_LEFT));
else {
runOnUiThread(() -> showRestartDialog(e.getLocalizedMessage()));
}
return false;
}
}
return true;
}
private void startUnzipService(List<String> file) {
Intent intent = new Intent(this, UnzipService.class);
intent.putStringArrayListExtra(UnzipService.EXTRA_KEY_IN_FILE, (ArrayList<String>) file);
UnzipService.enqueueWork(this, intent);
}
private void showRestartDialog(final String source) {
boolean space = NO_SPACE_LEFT.equals(source);
String message = space ? getString(R.string.no_space) : source;
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(message)
.setPositiveButton(R.string.ok, (dialogInterface, i) -> finishApp(!space, this))
.setCancelable(false);
final AlertDialog dialog = builder.create();
makeFullScreen(dialog.getWindow());
if (!isFinishing())
dialog.show();
}
}

View File

@ -0,0 +1,286 @@
/*
MultiCraft
Copyright (C) 2014-2021 MoNTE48, Maksim Gamarnik <MoNTE48@mail.ua>
Copyright (C) 2014-2021 ubulem, Bektur Mambetov <berkut87@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 3.0 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package com.multicraft.game
import android.content.*
import android.graphics.Color
import android.graphics.drawable.LayerDrawable
import android.os.Bundle
import android.provider.Settings
import android.view.View
import android.view.WindowManager
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.core.graphics.BlendModeColorFilterCompat
import androidx.core.graphics.BlendModeCompat
import com.multicraft.game.UnzipService.Companion.enqueueWork
import com.multicraft.game.databinding.ActivityMainBinding
import com.multicraft.game.helpers.Constants.FILES
import com.multicraft.game.helpers.Constants.NO_SPACE_LEFT
import com.multicraft.game.helpers.Constants.REQUEST_CONNECTION
import com.multicraft.game.helpers.Constants.versionName
import com.multicraft.game.helpers.PreferenceHelper
import com.multicraft.game.helpers.PreferenceHelper.TAG_BUILD_VER
import com.multicraft.game.helpers.PreferenceHelper.TAG_LAUNCH_TIMES
import com.multicraft.game.helpers.PreferenceHelper.TAG_SHORTCUT_EXIST
import com.multicraft.game.helpers.PreferenceHelper.getBoolValue
import com.multicraft.game.helpers.PreferenceHelper.getIntValue
import com.multicraft.game.helpers.PreferenceHelper.getStringValue
import com.multicraft.game.helpers.PreferenceHelper.set
import com.multicraft.game.helpers.Utilities.addShortcut
import com.multicraft.game.helpers.Utilities.copyInputStreamToFile
import com.multicraft.game.helpers.Utilities.deleteFiles
import com.multicraft.game.helpers.Utilities.finishApp
import com.multicraft.game.helpers.Utilities.getIcon
import com.multicraft.game.helpers.Utilities.isConnected
import com.multicraft.game.helpers.Utilities.makeFullScreen
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.core.Completable
import io.reactivex.rxjava3.core.Observable
import io.reactivex.rxjava3.disposables.Disposable
import io.reactivex.rxjava3.schedulers.Schedulers
import java.io.File
import java.io.IOException
import java.util.*
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
private var externalStorage: File? = null
private lateinit var prefs: SharedPreferences
private val myReceiver: BroadcastReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent?) {
var progress = 0
if (intent != null) progress = intent.getIntExtra(UnzipService.ACTION_PROGRESS, 0)
if (progress >= 0) {
showProgress(R.string.loading, R.string.loadingp, progress)
} else {
deleteFiles(listOf(FILES), cacheDir)
if (progress == UnzipService.UNZIP_FAILURE) {
showRestartDialog(false)
} else if (progress == UnzipService.UNZIP_SUCCESS) {
prefs[TAG_BUILD_VER] = versionName
startNative()
}
}
}
}
private var connectionSub: Disposable? = null
private var cleanSub: Disposable? = null
private var copySub: Disposable? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
prefs = PreferenceHelper.init(this)
var storageUnavailable = false
try {
externalStorage = getExternalFilesDir(null)
if (filesDir == null || cacheDir == null || externalStorage == null) throw IOException("Bad disk space state")
} catch (e: IOException) {
storageUnavailable = true
showRestartDialog(e.message!!.contains(NO_SPACE_LEFT))
}
if (storageUnavailable) return
val filter = IntentFilter(UnzipService.ACTION_UPDATE)
registerReceiver(myReceiver, filter)
lateInit()
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
@Suppress("DEPRECATION")
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == REQUEST_CONNECTION)
checkAppVersion()
}
override fun onBackPressed() {
// Prevent abrupt interruption when copy game files from assets
}
override fun onDestroy() {
super.onDestroy()
if (connectionSub != null) connectionSub!!.dispose()
if (cleanSub != null) cleanSub!!.dispose()
if (copySub != null) copySub!!.dispose()
unregisterReceiver(myReceiver)
}
override fun onResume() {
super.onResume()
makeFullScreen(window)
}
override fun onWindowFocusChanged(hasFocus: Boolean) {
super.onWindowFocusChanged(hasFocus)
if (hasFocus) makeFullScreen(window)
}
private fun addLaunchTimes() {
val launchTimes = prefs.getIntValue(TAG_LAUNCH_TIMES) + 1
prefs[TAG_LAUNCH_TIMES] = launchTimes
}
// interface
private fun showProgress(textMessage: Int, progressMessage: Int, progress: Int) {
if (binding.progressBar.visibility == View.GONE) {
updateViews(textMessage, View.GONE, View.VISIBLE)
binding.progressBar.progress = 0
} else if (progress > 0) {
binding.tvProgress.text =
String.format(resources.getString(progressMessage), progress)
binding.progressBar.progress = progress
// colorize the progress bar
val progressDrawable =
(binding.progressBar.progressDrawable as LayerDrawable).getDrawable(1)
val color = Color.rgb(255 - progress * 2, progress * 2, 25)
progressDrawable.colorFilter =
BlendModeColorFilterCompat.createBlendModeColorFilterCompat(
color, BlendModeCompat.SRC_IN
)
}
}
private fun lateInit() {
addLaunchTimes()
if (!prefs.getBoolValue(TAG_SHORTCUT_EXIST)) addShortcut(this)
connectionSub = checkConnection()
}
private fun startNative() {
val intent = Intent(this, GameActivity::class.java)
intent.flags =
Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_CLEAR_TASK
startActivity(intent)
}
private fun cleanUpOldFiles() {
updateViews(R.string.preparing, View.VISIBLE, View.GONE)
val filesList = listOf(
File(externalStorage, "cache"),
File(externalStorage, "debug.txt"),
File(filesDir, "builtin"),
File(cacheDir, FILES),
)
cleanSub = Completable.fromAction { deleteFiles(filesList) }
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe { startCopy() }
}
private fun checkAppVersion() {
val prefVersion = prefs.getStringValue(TAG_BUILD_VER)
if (prefVersion == versionName)
startNative()
else
cleanUpOldFiles()
}
private fun updateViews(text: Int, progressIndetVisib: Int, progressVisib: Int) {
binding.tvProgress.setText(text)
binding.tvProgress.visibility = View.VISIBLE
binding.progressCircle.visibility = progressIndetVisib
binding.progressBar.visibility = progressVisib
}
// check connection available
private fun checkConnection() = Observable.fromCallable { isConnected(this) }
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe { result: Boolean ->
if (result) checkAppVersion() else showConnectionDialog()
}
private fun startCopy() {
val zips = mutableListOf(FILES)
copySub = Observable.fromCallable { copyAssets(zips) }
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe { result: Boolean -> if (result) startUnzipService(zips) }
}
private fun copyAssets(zips: List<String>): Boolean {
for (zipName in zips) {
try {
assets.open("data/$zipName")
.use { input -> File(cacheDir, zipName).copyInputStreamToFile(input) }
} catch (e: IOException) {
runOnUiThread { showRestartDialog(e.message!!.contains(NO_SPACE_LEFT)) }
return false
}
}
return true
}
private fun startUnzipService(file: MutableList<String>) {
val intent = Intent(this, UnzipService::class.java)
intent.putStringArrayListExtra(
UnzipService.EXTRA_KEY_IN_FILE,
file as ArrayList<String>
)
enqueueWork(this, intent)
}
private fun showRestartDialog(space: Boolean) {
val message = if (space) getString(R.string.no_space) else getString(R.string.restart)
val builder = AlertDialog.Builder(this)
builder.setMessage(message)
.setPositiveButton(R.string.ok) { _: DialogInterface?, _: Int ->
finishApp(!space, this)
}
.setCancelable(false)
val dialog = builder.create()
makeFullScreen(dialog.window!!)
if (!isFinishing) dialog.show()
}
// connection dialog
private fun showConnectionDialog() {
val builder = AlertDialog.Builder(this)
builder.setIcon(getIcon(this))
.setTitle(R.string.conn_title)
.setMessage(R.string.conn_message)
.setPositiveButton(R.string.conn_wifi) { _: DialogInterface?, _: Int ->
startHandledActivity(Intent(Settings.ACTION_WIFI_SETTINGS))
}
.setNegativeButton(R.string.conn_mobile) { _: DialogInterface?, _: Int ->
startHandledActivity(Intent(Settings.ACTION_WIRELESS_SETTINGS))
}
.setNeutralButton(R.string.ignore) { _: DialogInterface?, _: Int -> checkAppVersion() }
.setCancelable(false)
val dialog = builder.create()
makeFullScreen(dialog.window!!)
if (!isFinishing) {
dialog.show()
dialog.getButton(DialogInterface.BUTTON_NEUTRAL)?.setTextColor(Color.RED)
}
}
private fun startHandledActivity(intent: Intent) {
try {
@Suppress("DEPRECATION")
startActivityForResult(intent, REQUEST_CONNECTION)
} catch (e: Exception) {
checkAppVersion()
}
}
}

View File

@ -0,0 +1,63 @@
/*
MultiCraft
Copyright (C) 2014-2021 MoNTE48, Maksim Gamarnik <MoNTE48@mail.ua>
Copyright (C) 2014-2021 ubulem, Bektur Mambetov <berkut87@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 3.0 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package com.multicraft.game.helpers
import android.content.Context
import android.content.SharedPreferences
object PreferenceHelper {
const val TAG_SHORTCUT_EXIST = "createShortcut"
const val TAG_BUILD_VER = "buildVer"
const val TAG_LAUNCH_TIMES = "launchTimes"
fun init(context: Context): SharedPreferences =
context.getSharedPreferences("MultiCraftSettings", Context.MODE_PRIVATE)
private inline fun SharedPreferences.edit(operation: (SharedPreferences.Editor) -> Unit) {
val editor = this.edit()
operation(editor)
editor.apply()
}
operator fun SharedPreferences.set(key: String, value: Any?) = when (value) {
is String? -> edit { it.putString(key, value) }
is Int -> edit { it.putInt(key, value) }
is Boolean -> edit { it.putBoolean(key, value) }
is Float -> edit { it.putFloat(key, value) }
is Long -> edit { it.putLong(key, value) }
else -> throw UnsupportedOperationException("Not yet implemented")
}
fun SharedPreferences.getBoolValue(key: String): Boolean = when (key) {
TAG_SHORTCUT_EXIST -> getBoolean(key, false)
else -> throw UnsupportedOperationException("Not yet implemented")
}
fun SharedPreferences.getIntValue(key: String) = when (key) {
TAG_LAUNCH_TIMES -> getInt(key, 0)
else -> throw UnsupportedOperationException("Not yet implemented")
}
fun SharedPreferences.getStringValue(key: String) = when (key) {
TAG_BUILD_VER -> getString(key, "0") as String
else -> throw UnsupportedOperationException("Not yet implemented")
}
}

View File

@ -1,72 +0,0 @@
/*
MultiCraft
Copyright (C) 2014-2021 MoNTE48, Maksim Gamarnik <MoNTE48@mail.ua>
Copyright (C) 2014-2021 ubulem, Bektur Mambetov <berkut87@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 3.0 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package com.multicraft.game.helpers;
import android.content.Context;
import android.content.SharedPreferences;
public class PreferencesHelper {
public static final String TAG_SHORTCUT_EXIST = "createShortcut";
public static final String TAG_BUILD_NUMBER = "buildNumber";
public static final String TAG_LAUNCH_TIMES = "launchTimes";
private static final String SETTINGS = "MultiCraftSettings";
private static PreferencesHelper instance;
private static SharedPreferences sharedPreferences;
private PreferencesHelper(Context context) {
sharedPreferences = context.getSharedPreferences(SETTINGS, Context.MODE_PRIVATE);
}
public static PreferencesHelper getInstance(Context context) {
if (instance == null) {
synchronized (PreferencesHelper.class) {
if (instance == null)
instance = new PreferencesHelper(context.getApplicationContext());
}
}
return instance;
}
public boolean isCreateShortcut() {
return sharedPreferences.getBoolean(TAG_SHORTCUT_EXIST, false);
}
public String getBuildNumber() {
return sharedPreferences.getString(TAG_BUILD_NUMBER, "0");
}
public int getLaunchTimes() {
return sharedPreferences.getInt(TAG_LAUNCH_TIMES, 0);
}
public void saveSettings(String tag, boolean bool) {
sharedPreferences.edit().putBoolean(tag, bool).apply();
}
public void saveSettings(String tag, String value) {
sharedPreferences.edit().putString(tag, value).apply();
}
public void saveSettings(String tag, int value) {
sharedPreferences.edit().putInt(tag, value).apply();
}
}

View File

@ -47,8 +47,8 @@ import com.multicraft.game.R
import com.multicraft.game.helpers.ApiLevelHelper.isKitKat
import com.multicraft.game.helpers.ApiLevelHelper.isMarshmallow
import com.multicraft.game.helpers.ApiLevelHelper.isOreo
import com.multicraft.game.helpers.PreferencesHelper.TAG_SHORTCUT_EXIST
import com.multicraft.game.helpers.PreferencesHelper.getInstance
import com.multicraft.game.helpers.PreferenceHelper.TAG_SHORTCUT_EXIST
import com.multicraft.game.helpers.PreferenceHelper.set
import java.io.File
import java.io.InputStream
import kotlin.math.roundToInt
@ -124,7 +124,7 @@ object Utilities {
addIntent.action = "com.android.launcher.action.INSTALL_SHORTCUT"
activity.applicationContext.sendBroadcast(addIntent)
// save preference
getInstance(activity).saveSettings(TAG_SHORTCUT_EXIST, true)
PreferenceHelper.init(activity)[TAG_SHORTCUT_EXIST] = true
}
@JvmStatic

View File

@ -3,7 +3,7 @@
android:layout_height="match_parent">
<ProgressBar
android:id="@+id/PB"
android:id="@+id/progress_bar"
style="@style/Widget.MaterialComponents.LinearProgressIndicator"
android:layout_width="400dp"
android:layout_height="45dp"
@ -16,7 +16,7 @@
android:visibility="gone" />
<ProgressBar
android:id="@+id/PB_Indet"
android:id="@+id/progress_circle"
style="@style/Widget.AppCompat.ProgressBar"
android:layout_width="75dp"
android:layout_height="75dp"
@ -27,7 +27,7 @@
android:id="@+id/tv_progress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/PB_Indet"
android:layout_below="@id/progress_circle"
android:layout_centerInParent="true"
android:text="@string/loading"
android:textColor="@color/not_white"

View File

@ -1,11 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools">
<style name="AppTheme" parent="Theme.MaterialComponents.DayNight">
<style name="AppTheme" parent="Theme.MaterialComponents.DayNight.NoActionBar">
<item name="windowActionBar">false</item>
<item name="android:windowBackground">@drawable/bg</item>
<item name="android:windowFullscreen">true</item>
<item name="android:windowLayoutInDisplayCutoutMode" tools:targetApi="p">shortEdges
</item>
<item name="android:windowLayoutInDisplayCutoutMode" tools:targetApi="p">shortEdges</item>
<item name="fontFamily">@font/retron2000</item>
<item name="colorPrimary">@color/green</item>
</style>

View File

@ -7,8 +7,8 @@ buildscript {
maven { url 'https://plugins.gradle.org/m2/' }
}
dependencies {
classpath 'com.android.tools.build:gradle:4.2.2'
classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.20'
classpath 'com.android.tools.build:gradle:7.0.0'
classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.21'
classpath 'de.undercouch:gradle-download-task:4.1.1'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files