Convert MA to Kotlin, update gradle to 7.0.0
parent
2793e9c655
commit
9188d2bbf7
|
@ -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'
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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")
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue