Android: Update java part to the latest changes (#149)

* Update android part to the latest changes
master
Bektur 2019-11-09 05:12:36 +06:00 committed by MoNTE48
parent 8bc5168b00
commit acc23ec945
56 changed files with 406 additions and 756 deletions

5
.gitignore vendored
View File

@ -94,15 +94,14 @@ cmake-build-release/
## Android build files
build/android/build
build/android/release
build/android/local.properties
build/android/.gradle
build/android/app/src/main/assets
build/android/app/build
build/android/app/release
build/android/app/src/main/assets
build/android/native/.*
build/android/native/build
build/android/native/deps
timestamp
.idea
.externalNativeBuild

View File

@ -1,13 +1,14 @@
apply plugin: 'com.android.application'
android {
compileSdkVersion 29
buildToolsVersion "29.0.2"
buildToolsVersion '29.0.2'
defaultConfig {
applicationId 'com.multicraft.game'
minSdkVersion 16
targetSdkVersion 29
versionCode 8
versionCode 21
/*multiDexEnabled true*/
}
Properties props = new Properties()
props.load(new FileInputStream(file('../local.properties')))
@ -35,36 +36,21 @@ android {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
// for multiple APKs
// for multiple APKs
splits {
abi {
enable true
reset()
include 'armeabi-v7a', 'arm64-v8a'//, 'x86'
include 'armeabi-v7a', 'arm64-v8a'
}
}
}
// Map for the version code that gives each ABI a value.
/*import com.android.build.OutputFile
def abiCodes = ['armeabi-v7a': 0, 'arm64-v8a': 1] //['armeabi-v7a': 0, 'arm64-v8a': 1, 'x86': 2*]
android.applicationVariants.all { variant ->
variant.outputs.each {
output ->
def abiName = output.getFilter(OutputFile.ABI)
output.versionCodeOverride = abiCodes.get(abiName, 0) + variant.versionCode
}
}*/
dependencies {
/*implementation 'androidx.multidex:multidex:2.0.1'*/
implementation 'androidx.preference:preference:1.1.0'
// MultiCraft Native
implementation project(':native')
// Analytics libraries
implementation 'com.google.firebase:firebase-core:17.2.0'
implementation 'com.crashlytics.sdk.android:crashlytics:2.10.1'
// Third-party libraries
implementation 'com.itlgl:iosdialog:1.0.0'
implementation 'gun0912.ted:tedpermission:2.2.2'
implementation group: 'commons-io', name: 'commons-io', version: '2.4'
//noinspection GradleDependency
implementation 'commons-io:commons-io:2.5'
}

View File

@ -5,12 +5,8 @@
android:installLocation="auto"
android:versionName="@string/ver">
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
tools:node="replace" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />
<uses-feature
@ -26,25 +22,24 @@
android:xlargeScreens="true" />
<application
android:name=".MyApplication"
android:allowBackup="true"
android:fullBackupContent="@xml/my_backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:networkSecurityConfig="@xml/network_security_config"
android:resizeableActivity="false"
tools:ignore="GoogleAppIndexingWarning">
android:roundIcon="@mipmap/ic_launcher_round"
tools:ignore="GoogleAppIndexingWarning,UnusedAttribute">
<meta-data
android:name="android.max_aspect"
android:value="2.4" />
<uses-library
android:name="org.apache.http.legacy"
android:required="false" />
<activity
android:name="com.multicraft.game.MainActivity"
android:configChanges="orientation|keyboardHidden|navigation|screenSize"
android:maxAspectRatio="2.4"
android:screenOrientation="sensorLandscape"
android:theme="@style/AppTheme">
<intent-filter>
@ -57,8 +52,10 @@
android:configChanges="orientation|keyboard|keyboardHidden|navigation|screenSize|smallestScreenSize"
android:hardwareAccelerated="true"
android:launchMode="singleTask"
android:maxAspectRatio="2.4"
android:screenOrientation="sensorLandscape"
android:theme="@style/AppTheme">
android:theme="@style/AppTheme"
tools:ignore="LockedOrientationActivity">
<meta-data
android:name="android.app.lib_name"
android:value="MultiCraft" />
@ -69,8 +66,8 @@
</activity>
<activity
android:name="com.multicraft.game.InputDialogActivity"
android:theme="@style/Theme.Transparent"
android:windowSoftInputMode="stateAlwaysHidden" />
android:maxAspectRatio="2.4"
android:theme="@style/InputTheme" />
<service
android:name="com.multicraft.game.UnzipService"
@ -78,4 +75,4 @@
android:exported="false" />
</application>
</manifest>
</manifest>

View File

@ -0,0 +1,19 @@
package com.bugsnag.android;
import android.app.Application;
import android.util.Log;
public class Bugsnag {
public static void notify(Throwable e) {
Log.getStackTraceString(e);
}
public static void leaveBreadcrumb(String s) {
Log.d("Bugsnag", s);
}
public static void init(Application application) {
Log.d("Bugsnag", "Bugsnag initialized");
}
}

View File

@ -1,13 +1,13 @@
package com.multicraft.game;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.graphics.drawable.Drawable;
import android.view.ContextThemeWrapper;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
public class AlertDialogHelper {
class AlertDialogHelper {
private final AppCompatActivity activity;
private DialogsCallback sCallback = null;
private Drawable icon = null;
private String title = null;
@ -15,9 +15,8 @@ public class AlertDialogHelper {
private String buttonPositive = null;
private String buttonNegative = null;
private String buttonNeutral = null;
private Activity activity;
AlertDialogHelper(Activity activity) {
AlertDialogHelper(AppCompatActivity activity) {
this.activity = activity;
}
@ -74,36 +73,19 @@ public class AlertDialogHelper {
}
void showAlert(final String source) {
ContextThemeWrapper ctw = new ContextThemeWrapper(activity, R.style.CustomLollipopDialogStyle);
AlertDialog.Builder builder = new AlertDialog.Builder(ctw);
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
if (getIcon() != null) builder.setIcon(getIcon());
if (getTitle() != null) builder.setTitle(getTitle());
if (getMessage() != null) builder.setMessage(getMessage());
if (getButtonPositive() != null)
builder.setPositiveButton(getButtonPositive(), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
sCallback.onPositive(source);
}
});
builder.setPositiveButton(getButtonPositive(), (dialogInterface, i) -> sCallback.onPositive(source));
if (getButtonNegative() != null)
builder.setNegativeButton(getButtonNegative(), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
sCallback.onNegative(source);
}
});
builder.setNegativeButton(getButtonNegative(), (dialogInterface, i) -> sCallback.onNegative(source));
if (getButtonNeutral() != null)
builder.setNeutralButton(getButtonNeutral(), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
sCallback.onNeutral(source);
}
});
builder.setNeutralButton(getButtonNeutral(), (dialogInterface, i) -> sCallback.onNeutral(source));
builder.setCancelable(false);
final AlertDialog dialog = builder.create();
if (!activity.isFinishing()) {
if (!activity.isFinishing())
dialog.show();
}
}
}

View File

@ -1,6 +1,6 @@
package com.multicraft.game;
public interface CallBackListener {
interface CallBackListener {
void updateViews(int text, int textVisibility, int progressVisibility);
void onEvent(String source, String param);

View File

@ -3,16 +3,13 @@ package com.multicraft.game;
import android.content.Context;
import android.os.AsyncTask;
import com.crashlytics.android.Crashlytics;
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.net.HttpURLConnection;
import java.net.URL;
public class CheckConnectionTask extends AsyncTask<Void, Void, Boolean> {
private WeakReference<Context> contextRef;
class CheckConnectionTask extends AsyncTask<Void, Void, Boolean> {
private final WeakReference<Context> contextRef;
private CallBackListener listener;
CheckConnectionTask(Context context) {
@ -34,24 +31,23 @@ public class CheckConnectionTask extends AsyncTask<Void, Void, Boolean> {
listener.onEvent("CheckConnectionTask", isStart.toString());
}
private boolean isGoogleAvailable(String url, int timeout) {
private boolean isInternetAvailable(String url) {
try {
HttpURLConnection urlc = (HttpURLConnection)
(new URL(url)
.openConnection());
urlc.setRequestProperty("User-Agent", "Android");
urlc.setRequestProperty("Connection", "close");
urlc.setConnectTimeout(timeout);
urlc.setConnectTimeout(1500);
urlc.connect();
return urlc.getResponseCode() == HttpURLConnection.HTTP_NO_CONTENT && urlc.getContentLength() == 0;
return urlc.getResponseCode() == HttpURLConnection.HTTP_NO_CONTENT || urlc.getResponseCode() == HttpURLConnection.HTTP_OK;
} catch (IOException e) {
Crashlytics.logException(e);
// nothing
}
return false;
}
private boolean isReachable() {
return isGoogleAvailable("http://clients3.google.com/generate_204", 1500) ||
isGoogleAvailable("http://g.cn/generate_204", 1000);
return isInternetAvailable("http://clients3.google.com/generate_204") ||
isInternetAvailable("http://servers.multicraft.world");
}
}

View File

@ -1,6 +1,5 @@
package com.multicraft.game;
import android.app.Activity;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
@ -8,17 +7,20 @@ import android.content.Intent;
import android.os.AsyncTask;
import android.view.View;
import com.crashlytics.android.Crashlytics;
import androidx.appcompat.app.AppCompatActivity;
import com.bugsnag.android.Bugsnag;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.ref.WeakReference;
import java.util.Objects;
public class CopyZipTask extends AsyncTask<String, Void, String[]> implements DialogsCallback {
private WeakReference<Context> contextRef;
private final WeakReference<Context> contextRef;
private CallBackListener listener;
private boolean isCancel = false;
@ -27,9 +29,8 @@ public class CopyZipTask extends AsyncTask<String, Void, String[]> implements Di
}
protected String[] doInBackground(String... params) {
while (!isCancel) {
while (!isCancel)
copyAssets(params);
}
return params;
}
@ -42,10 +43,8 @@ public class CopyZipTask extends AsyncTask<String, Void, String[]> implements Di
private void copyAsset(String zipName) throws IOException {
String filename = zipName.substring(zipName.lastIndexOf("/") + 1);
InputStream in;
OutputStream out;
in = contextRef.get().getAssets().open(filename);
out = new FileOutputStream(zipName);
InputStream in = contextRef.get().getAssets().open(filename);
OutputStream out = new FileOutputStream(zipName);
copyFile(in, out);
in.close();
out.flush();
@ -54,47 +53,38 @@ public class CopyZipTask extends AsyncTask<String, Void, String[]> implements Di
private void copyAssets(String[] zips) {
try {
for (String zipName : zips) {
for (String zipName : zips)
copyAsset(zipName);
}
isCancel = true;
} catch (IOException e) {
Crashlytics.logException(e);
Bugsnag.notify(e);
isCancel = true;
cancel(true);
if (e.getMessage().contains("ENOSPC")) {
if (Objects.requireNonNull(e.getMessage()).contains("ENOSPC"))
showRestartDialog("ENOSPC");
} else {
else
showRestartDialog("UKNWN");
}
}
}
private void copyFile(InputStream in, OutputStream out) throws IOException {
byte[] buffer = new byte[1024];
int read;
while ((read = in.read(buffer)) != -1) {
while ((read = in.read(buffer)) != -1)
out.write(buffer, 0, read);
}
}
private void showRestartDialog(final String source) {
String message;
if ("ENOSPC".equals(source)) {
if ("ENOSPC".equals(source))
message = contextRef.get().getString(R.string.no_space);
} else {
else
message = contextRef.get().getString(R.string.restart);
}
final AlertDialogHelper dialogHelper = new AlertDialogHelper((Activity) contextRef.get());
final AlertDialogHelper dialogHelper = new AlertDialogHelper((AppCompatActivity) contextRef.get());
dialogHelper.setListener(this);
dialogHelper.setMessage(message);
dialogHelper.setButtonPositive(contextRef.get().getString(android.R.string.ok));
((Activity) contextRef.get()).runOnUiThread(new Runnable() {
@Override
public void run() {
dialogHelper.showAlert(source);
}
});
((AppCompatActivity) contextRef.get()).runOnUiThread(() -> dialogHelper.showAlert(source));
}
private void startUnzipService(String[] file) {
@ -102,7 +92,6 @@ public class CopyZipTask extends AsyncTask<String, Void, String[]> implements Di
Intent intentMyIntentService = new Intent(contextRef.get(), UnzipService.class);
intentMyIntentService.putExtra(UnzipService.EXTRA_KEY_IN_FILE, file);
contextRef.get().startService(intentMyIntentService);
}
private void restartApp() {
@ -111,9 +100,8 @@ public class CopyZipTask extends AsyncTask<String, Void, String[]> implements Di
int mPendingIntentId = 1337;
PendingIntent mPendingIntent = PendingIntent.getActivity(context, mPendingIntentId, intent, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager mgr = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
if (mgr != null) {
if (mgr != null)
mgr.set(AlarmManager.RTC, System.currentTimeMillis(), mPendingIntent);
}
System.exit(0);
}
@ -128,11 +116,9 @@ public class CopyZipTask extends AsyncTask<String, Void, String[]> implements Di
@Override
public void onNegative(String source) {
}
@Override
public void onNeutral(String source) {
}
}

View File

@ -3,15 +3,14 @@ package com.multicraft.game;
import android.os.AsyncTask;
import android.view.View;
import com.crashlytics.android.Crashlytics;
import com.bugsnag.android.Bugsnag;
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.IOException;
public class DeleteTask extends AsyncTask<String, Void, Void> {
class DeleteTask extends AsyncTask<String, Void, Void> {
private CallBackListener listener;
private String location;
@ -25,9 +24,8 @@ public class DeleteTask extends AsyncTask<String, Void, Void> {
@Override
protected Void doInBackground(String... params) {
location = params[0];
for (String p : params) {
for (String p : params)
deleteFiles(p);
}
return null;
}
@ -45,7 +43,7 @@ public class DeleteTask extends AsyncTask<String, Void, Void> {
FileUtils.deleteDirectory(file);
else FileUtils.deleteQuietly(file);
} catch (IOException e) {
Crashlytics.logException(e);
Bugsnag.notify(e);
}
}
}

View File

@ -1,6 +1,6 @@
package com.multicraft.game;
public interface DialogsCallback {
interface DialogsCallback {
void onPositive(String source);
void onNegative(String source);

View File

@ -11,27 +11,37 @@ import android.os.Bundle;
import android.view.View;
import android.view.WindowManager;
import com.crashlytics.android.Crashlytics;
import com.bugsnag.android.Bugsnag;
import static com.multicraft.game.PreferencesHelper.TAG_BUILD_NUMBER;
import static com.multicraft.game.PreferencesHelper.getInstance;
/*import static com.multicraft.game.AdManager.initAd;
import static com.multicraft.game.AdManager.setAdsCallback;
import static com.multicraft.game.AdManager.startAd;
import static com.multicraft.game.AdManager.stopAd;*/
import static com.multicraft.game.PreferencesHelper.TAG_BUILD_NUMBER;
import static com.multicraft.game.PreferencesHelper.getInstance;
public class GameActivity extends NativeActivity {
static {
System.loadLibrary("c++_shared");
System.loadLibrary("MultiCraft");
try {
System.loadLibrary("c++_shared");
System.loadLibrary("MultiCraft");
} catch (UnsatisfiedLinkError e) {
Bugsnag.notify(e);
} catch (IllegalArgumentException e) {
Bugsnag.notify(e);
} catch (OutOfMemoryError e) {
Bugsnag.notify(e);
} catch (Error | Exception error) {
Bugsnag.notify(error);
}
}
private int messageReturnCode;
private String messageReturnValue;
private int height, width;
private boolean consent;
private boolean isMultiPlayer;
/*private boolean consent;
private boolean isMultiPlayer;*/
public static native void putMessageBoxResult(String text);
@ -41,11 +51,10 @@ public class GameActivity extends NativeActivity {
Bundle bundle = getIntent().getExtras();
height = bundle != null ? bundle.getInt("height", 0) : getResources().getDisplayMetrics().heightPixels;
width = bundle != null ? bundle.getInt("width", 0) : getResources().getDisplayMetrics().widthPixels;
consent = bundle == null || bundle.getBoolean("consent", true);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
messageReturnCode = -1;
messageReturnValue = "";
new AdInitTask().execute();
/*new AdInitTask().execute();*/
}
private void makeFullScreen() {
@ -124,14 +133,14 @@ public class GameActivity extends NativeActivity {
double memory = memInfo.totalMem * 1.0f / (1024 * 1024 * 1024);
return (Math.round(memory * 100) / 100.0f);
} else {
Crashlytics.log(1, "RAM", "Cannot get RAM");
Bugsnag.leaveBreadcrumb("RAM: Cannot get RAM");
return 1;
}
}
public void notifyServerConnect(boolean isMultiplayer) {
/*isMultiPlayer = isMultiplayer;
if (isMultiplayer) stopAd();*/
public void notifyServerConnect(boolean isMultiPlayer) {
/*isMultiPlayer = isMultiPlayer;
if (isMultiPlayer) stopAd();*/
}
public void notifyAbortLoading() {
@ -158,5 +167,4 @@ public class GameActivity extends NativeActivity {
/*setAdsCallback(GameActivity.this);*/
}
}
}

View File

@ -2,22 +2,22 @@ package com.multicraft.game;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.text.InputType;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnKeyListener;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
public class InputDialogActivity extends Activity {
import java.util.Objects;
public class InputDialogActivity extends AppCompatActivity {
private AlertDialog alertDialog;
@SuppressLint("InflateParams")
@ -25,62 +25,54 @@ public class InputDialogActivity extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle b = getIntent().getExtras();
int editType = b.getInt("editType");
int editType = Objects.requireNonNull(b).getInt("editType");
String hint = b.getString("hint");
String current = b.getString("current");
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
LayoutInflater inflater = this.getLayoutInflater();
View dialogView = inflater.inflate(R.layout.input_dialog, null);
builder.setView(dialogView);
final EditText editText = dialogView.findViewById(R.id.editText);
EditText editText = new EditText(this);
builder.setView(editText);
editText.requestFocus();
editText.setHint(hint);
editText.setText(current);
final InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY);
Objects.requireNonNull(imm).toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY);
if (editType == 3) {
editText.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
} else {
editText.setInputType(InputType.TYPE_CLASS_TEXT);
}
editText.setOnKeyListener(new OnKeyListener() {
@Override
public boolean onKey(View view, int KeyCode, KeyEvent event) {
if (KeyCode == KeyEvent.KEYCODE_ENTER) {
imm.hideSoftInputFromWindow(editText.getWindowToken(), 0);
pushResult(editText.getText().toString());
return true;
}
return false;
editText.setOnKeyListener((view, KeyCode, event) -> {
if (KeyCode == KeyEvent.KEYCODE_ENTER) {
imm.hideSoftInputFromWindow(editText.getWindowToken(), 0);
pushResult(editText.getText().toString());
return true;
}
return false;
});
alertDialog = builder.create();
alertDialog.show();
alertDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
pushResult(editText.getText().toString());
setResult(Activity.RESULT_CANCELED);
alertDialog.dismiss();
makeFullScreen();
finish();
}
if (!this.isFinishing())
alertDialog.show();
alertDialog.setOnCancelListener(dialog -> {
pushResult(editText.getText().toString());
setResult(Activity.RESULT_CANCELED);
alertDialog.dismiss();
makeFullScreen();
finish();
});
}
public void pushResult(String text) {
private void pushResult(String text) {
Intent resultData = new Intent();
resultData.putExtra("text", text);
setResult(Activity.RESULT_OK, resultData);
setResult(AppCompatActivity.RESULT_OK, resultData);
alertDialog.dismiss();
makeFullScreen();
finish();
}
public void makeFullScreen() {
if (Build.VERSION.SDK_INT >= 19) {
private void makeFullScreen() {
if (Build.VERSION.SDK_INT >= 19)
this.getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
);
}
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
}
}

View File

@ -1,13 +1,9 @@
package com.multicraft.game;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
@ -18,78 +14,62 @@ import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.provider.Settings;
import android.text.TextUtils;
import android.text.method.LinkMovementMethod;
import android.view.ContextThemeWrapper;
import android.view.Display;
import android.view.LayoutInflater;
import android.view.Gravity;
import android.view.View;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;
import com.crashlytics.android.Crashlytics;
import com.gun0912.tedpermission.PermissionListener;
import com.gun0912.tedpermission.TedPermission;
import org.apache.commons.io.FileUtils;
import com.bugsnag.android.Bugsnag;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static android.Manifest.permission.ACCESS_COARSE_LOCATION;
import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
import static com.multicraft.game.PreferencesHelper.TAG_BUILD_NUMBER;
import static com.multicraft.game.PreferencesHelper.TAG_CONSENT_ASKED;
import static com.multicraft.game.PreferencesHelper.TAG_COPY_WORLDS;
import static com.multicraft.game.PreferencesHelper.TAG_LAUNCH_TIMES;
import static com.multicraft.game.PreferencesHelper.TAG_SHORTCUT_CREATED;
public class MainActivity extends Activity implements WVersionManager.ActivityListener, CallBackListener, DialogsCallback {
public final static int REQUEST_CODE = 104;
public class MainActivity extends AppCompatActivity implements WVersionManager.ActivityListener, CallBackListener, DialogsCallback {
public final static Map<String, String> zipLocations = new HashMap<>();
public static final String UPDATE_LINK = "http://updates.multicraft.world/Android.json";
private final static int REQUEST_CODE = 104;
private final static String CREATE_SHORTCUT = "com.android.launcher.action.INSTALL_SHORTCUT";
private final static String EXTERNAL_STORAGE = Environment.getExternalStorageDirectory().toString();
private final static String FILES = EXTERNAL_STORAGE + "/Files.zip";
private final static String WORLDS = EXTERNAL_STORAGE + "/worlds.zip";
private final static String GAMES = EXTERNAL_STORAGE + "/games.zip";
private final static String CACHE = EXTERNAL_STORAGE + "/cache.zip";
private static final String UPDATE_LINK = "http://updates.multicraft.world/Android.json";
private static final String[] EU_COUNTRIES = new String[]{
"AT", "BE", "BG", "HR", "CY", "CZ",
"DK", "EE", "FI", "FR", "DE", "GR",
"HU", "IE", "IT", "LV", "LT", "LU",
"MT", "NL", "PL", "PT", "RO", "SK",
"SI", "ES", "SE", "GB", "IS", "LI", "NO"};
private static String worldPath = EXTERNAL_STORAGE + "/Android/data/mobi.MultiCraft/files/worlds";
private static String FILES, WORLDS, GAMES, CACHE;
private String unzipLocation;
private int height, width;
private boolean consent;
private ProgressBar mProgressBar;
private ProgressBar mProgressBarIndeterminate;
private TextView mLoading;
private ImageView iv;
private WVersionManager versionManager = null;
private PreferencesHelper pf;
private BroadcastReceiver myReceiver = new BroadcastReceiver() {
private final BroadcastReceiver myReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
int progress = 0;
if (intent != null) {
if (intent != null)
progress = intent.getIntExtra(UnzipService.ACTION_PROGRESS, 0);
}
if (progress >= 0) {
if (mProgressBar != null) {
mProgressBar.setVisibility(View.VISIBLE);
@ -97,14 +77,12 @@ public class MainActivity extends Activity implements WVersionManager.ActivityLi
}
} else {
createNomedia();
File folder = new File(worldPath);
if (folder.exists() && !pf.isWorldsCopied())
copyWorldsToNewFolder();
runGame();
}
}
};
//helpful utilities
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@ -118,7 +96,10 @@ public class MainActivity extends Activity implements WVersionManager.ActivityLi
return;
}
addLaunchTimes();
askStoragePermissions();
/*PermissionHelper permission = new PermissionHelper(this);
permission.setListener(this);
permission.askPermissions();*/
askGdpr();
}
@Override
@ -133,10 +114,13 @@ public class MainActivity extends Activity implements WVersionManager.ActivityLi
unregisterReceiver(myReceiver);
}
//helpful utilities
private void initZipLocations() {
unzipLocation = getExternalFilesDir(null) + "/";
String appData = getFilesDir() + "/";
FILES = getCacheDir() + "/Files.zip";
WORLDS = getCacheDir() + "/worlds.zip";
GAMES = getCacheDir() + "/games.zip";
CACHE = getCacheDir() + "/cache.zip";
zipLocations.put(FILES, appData);
zipLocations.put(GAMES, appData);
zipLocations.put(WORLDS, unzipLocation);
@ -144,22 +128,10 @@ public class MainActivity extends Activity implements WVersionManager.ActivityLi
}
private boolean isArm64() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
return TextUtils.join(", ", Build.SUPPORTED_ABIS).contains("64");
} else {
else
return false;
}
}
private void copyWorldsToNewFolder() {
File source = new File(worldPath);
File dest = new File(unzipLocation + "worlds");
try {
FileUtils.copyDirectory(source, dest);
pf.saveSettings(TAG_COPY_WORLDS, true);
} catch (IOException e) {
Crashlytics.logException(e);
}
}
private void addLaunchTimes() {
@ -188,7 +160,7 @@ public class MainActivity extends Activity implements WVersionManager.ActivityLi
try {
myFile.createNewFile();
} catch (IOException e) {
Crashlytics.logException(e);
Bugsnag.notify(e);
}
}
@ -196,9 +168,8 @@ public class MainActivity extends Activity implements WVersionManager.ActivityLi
private void addShortcut() {
ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
int size = 0;
if (activityManager != null) {
if (activityManager != null)
size = activityManager.getLauncherLargeIconSize();
}
try {
Drawable icon = getPackageManager().getApplicationIcon(getPackageName());
Bitmap shortcutIconBitmap = ((BitmapDrawable) icon).getBitmap();
@ -218,55 +189,38 @@ public class MainActivity extends Activity implements WVersionManager.ActivityLi
addIntent.setAction(CREATE_SHORTCUT);
getApplicationContext().sendBroadcast(addIntent);
} catch (PackageManager.NameNotFoundException e) {
Crashlytics.logException(e);
Bugsnag.notify(e);
}
}
private void addImageView(int pos) {
int marginTop = pos == 0 ? 48 : 288;
RelativeLayout rl = findViewById(R.id.activity_main);
iv = new ImageView(this);
iv.setBackgroundResource(R.mipmap.logo);
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
lp.addRule(RelativeLayout.CENTER_HORIZONTAL);
lp.setMargins(0, marginTop, 0, 0);
iv.requestLayout();
iv.setLayoutParams(lp);
rl.addView(iv);
}
private void hideViews() {
mProgressBar.setVisibility(View.GONE);
mProgressBarIndeterminate.setVisibility(View.GONE);
iv.setVisibility(View.GONE);
mLoading.setVisibility(View.GONE);
}
public void getDefaultResolution() {
private void getDefaultResolution() {
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1)
display.getRealSize(size);
} else {
else
display.getSize(size);
}
height = Math.min(size.x, size.y);
width = Math.max(size.x, size.y);
}
public void makeFullScreen() {
if (Build.VERSION.SDK_INT >= 19) {
private void makeFullScreen() {
if (Build.VERSION.SDK_INT >= 19)
this.getWindow().getDecorView()
.setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
}
}
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus) {
if (hasFocus)
makeFullScreen();
}
}
private void askGdpr() {
@ -292,148 +246,14 @@ public class MainActivity extends Activity implements WVersionManager.ActivityLi
checkAppVersion();
}
//permission block
private void askStoragePermissions() {
PermissionListener permissionlistener = new PermissionListener() {
@Override
public void onPermissionGranted() {
/*if (pf.getLaunchTimes() % 3 == 1) {
askLocationPermissions();
} else*/ askGdpr();
}
@Override
public void onPermissionDenied(List<String> deniedPermissions) {
if (TedPermission.canRequestPermission(MainActivity.this, WRITE_EXTERNAL_STORAGE))
askStorageRationalePermissions();
else askStorageWhenDoNotShow();
}
};
TedPermission.with(this)
.setPermissionListener(permissionlistener)
.setPermissions(WRITE_EXTERNAL_STORAGE)
.check();
}
//storage permissions block
private void askStorageRationalePermissions() {
PermissionListener permissionlistener = new PermissionListener() {
@Override
public void onPermissionGranted() {
/*if (pf.getLaunchTimes() % 3 == 1) {
askLocationPermissions();
} else*/ askGdpr();
}
@Override
public void onPermissionDenied(List<String> deniedPermissions) {
finish();
}
};
TedPermission.with(this)
.setPermissionListener(permissionlistener)
.setPermissions(WRITE_EXTERNAL_STORAGE)
.setRationaleMessage(R.string.explain)
.setDeniedMessage(R.string.denied)
.setDeniedCloseButtonText(R.string.close_game)
.setGotoSettingButtonText(R.string.settings)
.check();
}
private void askStorageWhenDoNotShow() {
PermissionListener permissionlistener = new PermissionListener() {
@Override
public void onPermissionGranted() {
/*if (pf.getLaunchTimes() % 3 == 1) {
askLocationPermissions();
} else*/ askGdpr();
}
@Override
public void onPermissionDenied(List<String> deniedPermissions) {
finish();
}
};
TedPermission.with(this)
.setPermissionListener(permissionlistener)
.setPermissions(WRITE_EXTERNAL_STORAGE)
.setDeniedMessage(R.string.denied)
.setDeniedCloseButtonText(R.string.close_game)
.setGotoSettingButtonText(R.string.settings)
.check();
}
//location permissions block
private void askLocationPermissions() {
PermissionListener permissionlistener = new PermissionListener() {
@Override
public void onPermissionGranted() {
askGdpr();
}
@Override
public void onPermissionDenied(List<String> deniedPermissions) {
if (TedPermission.canRequestPermission(MainActivity.this, ACCESS_COARSE_LOCATION))
askLocationRationalePermissions();
else askLocationWhenDoNotShow();
}
};
TedPermission.with(this)
.setPermissionListener(permissionlistener)
.setPermissions(ACCESS_COARSE_LOCATION)
.check();
}
private void askLocationRationalePermissions() {
PermissionListener permissionlistener = new PermissionListener() {
@Override
public void onPermissionGranted() {
askGdpr();
}
@Override
public void onPermissionDenied(List<String> deniedPermissions) {
askGdpr();
}
};
TedPermission.with(this)
.setPermissionListener(permissionlistener)
.setPermissions(ACCESS_COARSE_LOCATION)
.setRationaleMessage(R.string.location)
.check();
}
private void askLocationWhenDoNotShow() {
PermissionListener permissionlistener = new PermissionListener() {
@Override
public void onPermissionGranted() {
/*if (pf.getLaunchTimes() % 3 == 1) {
askLocationPermissions();
} else*/ askGdpr();
}
@Override
public void onPermissionDenied(List<String> deniedPermissions) {
askGdpr();
}
};
TedPermission.with(this)
.setPermissionListener(permissionlistener)
.setPermissions(ACCESS_COARSE_LOCATION)
.setDeniedMessage(R.string.location)
.setGotoSettingButtonText(R.string.settings)
.check();
}
//game logic
private void checkRateDialog() {
if (RateMe.shouldShowRateDialog()) {
hideViews();
RateMe.showRateDialog();
RateMe.setListener(this);
} else {
} else
getNativeResolutionAndStart();
}
}
@Override
@ -441,16 +261,13 @@ public class MainActivity extends Activity implements WVersionManager.ActivityLi
if (flag) {
versionManager.showDialog();
versionManager.setListener(this);
} else {
} else
checkRateDialog();
}
}
private void checkUrlVersion() {
versionManager = new WVersionManager(this);
versionManager.setVersionContentUrl(UPDATE_LINK);
versionManager.checkVersion();
}
private void getNativeResolutionAndStart() {
@ -465,15 +282,12 @@ public class MainActivity extends Activity implements WVersionManager.ActivityLi
cct.setListener(this);
cct.execute();
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
if (cct.getStatus() == AsyncTask.Status.RUNNING) {
cct.cancel(true);
onEvent("CheckConnectionTask", "false");
}
handler.postDelayed(() -> {
if (cct.getStatus() == AsyncTask.Status.RUNNING) {
cct.cancel(true);
onEvent("CheckConnectionTask", "false");
}
}, 2500);
}, 3000);
}
private void startNative() {
@ -487,25 +301,25 @@ public class MainActivity extends Activity implements WVersionManager.ActivityLi
private boolean isGdprSubject() {
String locale;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
locale = getResources().getConfiguration().getLocales().get(0).getCountry();
} else {
else
locale = getResources().getConfiguration().locale.getCountry();
}
return Arrays.asList(EU_COUNTRIES).contains(locale.toUpperCase());
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
getNativeResolutionAndStart();
}
private void prepareToRun(boolean isAll) {
DeleteTask dt = new DeleteTask();
dt.setListener(this);
if (isAll) {
if (isAll)
dt.execute(unzipLocation);
} else {
else {
if (isArm64())
dt.execute(unzipLocation + "cache", unzipLocation + "builtin", unzipLocation + "games", unzipLocation + "debug.txt");
else
@ -515,15 +329,13 @@ public class MainActivity extends Activity implements WVersionManager.ActivityLi
private void checkAppVersion() {
if (pf.getBuildNumber().equals(getString(R.string.ver))) {
addImageView(1);
mProgressBarIndeterminate.setVisibility(View.VISIBLE);
runGame();
} else if (pf.getBuildNumber().equals("0")) {
addImageView(0);
} else if (pf.getBuildNumber().equals("0"))
prepareToRun(true);
} else {
addImageView(0);
else
prepareToRun(false);
}
}
@Override
@ -551,44 +363,44 @@ public class MainActivity extends Activity implements WVersionManager.ActivityLi
cpt.execute(FILES, GAMES);
}
} else if ("CheckConnectionTask".equals(source)) {
if ("true".equals(param)) {
if ("true".equals(param))
checkUrlVersion();
} else {
else
showConnectionDialog();
}
/*} else if ("Permissions".equals(source)) {
if ("askGdpr".equals(param)) askGdpr();
else finish();*/
}
}
private void showGdprDialog() {
ContextThemeWrapper ctw = new ContextThemeWrapper(this, R.style.CustomLollipopDialogStyle);
AlertDialog.Builder builder = new AlertDialog.Builder(ctw);
LayoutInflater inflater = getLayoutInflater();
@SuppressLint("InflateParams") View dialogView = inflater.inflate(R.layout.gdpr_dialog, null);
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setIcon(R.mipmap.ic_launcher);
builder.setTitle(R.string.app_name);
EditText dialogView = new EditText(this);
builder.setView(dialogView)
.setPositiveButton(R.string.gdpr_agree, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
pf.saveSettings(TAG_CONSENT_ASKED, false);
dialog.dismiss();
consent = true;
init();
}
.setPositiveButton(R.string.gdpr_agree, (dialog, id) -> {
pf.saveSettings(TAG_CONSENT_ASKED, false);
dialog.dismiss();
consent = true;
init();
})
.setNegativeButton(R.string.gdpr_disagree, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
pf.saveSettings(TAG_CONSENT_ASKED, false);
dialog.dismiss();
consent = false;
init();
}
.setNegativeButton(R.string.gdpr_disagree, (dialog, id) -> {
pf.saveSettings(TAG_CONSENT_ASKED, false);
dialog.dismiss();
consent = false;
init();
});
TextView tv = dialogView.findViewById(R.id.gdprTextView);
TextView tv = new TextView(this);
builder.setView(tv);
tv.setText(R.string.gdpr_main_text);
tv.setPadding(20, 0, 20, 0);
tv.setGravity(Gravity.CENTER);
Dialog dialog = builder.create();
dialog.setCanceledOnTouchOutside(false);
dialog.setCancelable(false);
dialog.show();
if (!this.isFinishing())
dialog.show();
tv.setMovementMethod(LinkMovementMethod.getInstance());
}
@ -604,11 +416,11 @@ public class MainActivity extends Activity implements WVersionManager.ActivityLi
@Override
public void onPositive(String source) {
if ("RateMe".equals(source)) {
if ("RateMe".equals(source))
finish();
} else if ("ConnectionDialog".equals(source)) {
else if ("ConnectionDialog".equals(source))
startActivityForResult(new Intent(Settings.ACTION_WIFI_SETTINGS), REQUEST_CODE);
} else {
else {
versionManager.updateNow(versionManager.getUpdateUrl());
finish();
}
@ -619,9 +431,9 @@ public class MainActivity extends Activity implements WVersionManager.ActivityLi
if ("RateMe".equals(source)) {
Toast.makeText(MainActivity.this, R.string.sad, Toast.LENGTH_LONG).show();
getNativeResolutionAndStart();
} else if ("ConnectionDialog".equals(source)) {
} else if ("ConnectionDialog".equals(source))
startActivityForResult(new Intent(Settings.ACTION_WIRELESS_SETTINGS), REQUEST_CODE);
} else {
else {
versionManager.ignoreThisVersion();
checkRateDialog();
}
@ -629,14 +441,13 @@ public class MainActivity extends Activity implements WVersionManager.ActivityLi
@Override
public void onNeutral(String source) {
if ("RateMe".equals(source)) {
if ("RateMe".equals(source))
getNativeResolutionAndStart();
} else if ("ConnectionDialog".equals(source)) {
else if ("ConnectionDialog".equals(source))
getNativeResolutionAndStart();
} else {
versionManager.remindMeLater(versionManager.getReminderTimer());
else {
versionManager.remindMeLater();
checkRateDialog();
}
}
}

View File

@ -0,0 +1,15 @@
package com.multicraft.game;
import android.app.Application;
/*import androidx.multidex.MultiDexApplication;*/
import com.bugsnag.android.Bugsnag;
public class MyApplication extends Application {
/*public class MyApplication extends MultiDexApplication {*/
@Override
public void onCreate() {
super.onCreate();
Bugsnag.init(this);
}
}

View File

@ -26,9 +26,8 @@ class PreferencesHelper {
static PreferencesHelper getInstance(Context context) {
if (instance == null) {
synchronized (PreferencesHelper.class) {
if (instance == null) {
if (instance == null)
instance = new PreferencesHelper(context.getApplicationContext());
}
}
}
return instance;
@ -51,7 +50,7 @@ class PreferencesHelper {
}
boolean isWorldsCopied() {
return sharedPreferences.getBoolean(TAG_COPY_WORLDS, true);
return sharedPreferences.getBoolean(TAG_COPY_WORLDS, false);
}
String getBuildNumber() {
@ -63,7 +62,7 @@ class PreferencesHelper {
}
int getAdsDelay() {
return sharedPreferences.getInt(ADS_DELAY, 300);
return sharedPreferences.getInt(ADS_DELAY, 600);
}
int getAdsRepeat() {

View File

@ -1,9 +1,7 @@
package com.multicraft.game;
import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
@ -11,19 +9,18 @@ import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.util.Log;
import android.view.View;
import android.widget.RatingBar;
import androidx.appcompat.app.AppCompatActivity;
import java.lang.ref.WeakReference;
import java.util.Date;
import java.util.Objects;
class RateMe {
private static final int INSTALL_DAYS = 3;
private static final int INSTALL_DAYS = 5;
private static final int LAUNCH_TIMES = 3;
private static final boolean DEBUG = false;
private static final String TAG = RateMe.class.getSimpleName();
private static final String GOOGLE_PLAY = "https://play.google.com/store/apps/details?id=";
private static final String PREF_NAME = "RateMe";
private static final String KEY_INSTALL_DATE = "rta_install_date";
@ -34,20 +31,19 @@ class RateMe {
private static boolean mOptOut = false;
private static DialogsCallback sCallback = null;
private static WeakReference<Activity> mainActivityRef = null;
private static WeakReference<AppCompatActivity> mainActivityRef = null;
static void setListener(DialogsCallback callback) {
sCallback = callback;
}
static void onStart(Context context) {
mainActivityRef = new WeakReference<>((Activity) context);
mainActivityRef = new WeakReference<>((AppCompatActivity) context);
SharedPreferences pref = context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE);
Editor editor = pref.edit();
// If it is the first launch, save the date in shared preference.
if (pref.getLong(KEY_INSTALL_DATE, 0) == 0L) {
if (pref.getLong(KEY_INSTALL_DATE, 0) == 0L)
storeInstallDate(context, editor);
}
// Increment launch times
int launchTimes = pref.getInt(KEY_LAUNCH_TIMES, 0);
launchTimes++;
@ -58,76 +54,60 @@ class RateMe {
mInstallDate = new Date(pref.getLong(KEY_INSTALL_DATE, 0));
mLaunchTimes = pref.getInt(KEY_LAUNCH_TIMES, 0);
mOptOut = pref.getBoolean(KEY_OPT_OUT, false);
printStatus();
}
static boolean shouldShowRateDialog() {
if (mOptOut) {
if (mOptOut)
return false;
} else {
if (mLaunchTimes >= LAUNCH_TIMES) {
else {
if (mLaunchTimes >= LAUNCH_TIMES)
return true;
}
long threshold = INSTALL_DAYS * 24 * 60 * 60 * 1000L;
return new Date().getTime() - mInstallDate.getTime() >= threshold;
}
}
static void showRateDialog() {
final Activity activity = mainActivityRef.get();
final Dialog dialog = new Dialog(activity, R.style.DialogTheme);
final AppCompatActivity activity = mainActivityRef.get();
final Dialog dialog = new Dialog(activity, R.style.RateMe);
dialog.setCanceledOnTouchOutside(false);
if (Build.VERSION.SDK_INT >= 19) {
dialog.getWindow().getDecorView().setSystemUiVisibility(
if (Build.VERSION.SDK_INT >= 19)
Objects.requireNonNull(dialog.getWindow()).getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
}
dialog.setContentView(R.layout.rate_dialog);
dialog.setTitle(R.string.rta_dialog_title);
RatingBar ratingBar = dialog.findViewById(R.id.ratingBar);
ratingBar.setOnRatingBarChangeListener(new RatingBar.OnRatingBarChangeListener() {
@Override
public void onRatingChanged(RatingBar ratingBar, float rating, boolean fromUser) {
if (rating >= 4) {
if (sCallback != null) {
sCallback.onPositive("RateMe");
}
dialog.dismiss();
String appPackage = activity.getPackageName();
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(GOOGLE_PLAY + appPackage));
activity.startActivity(intent);
setOptOut(activity, true);
} else {
if (sCallback != null) {
sCallback.onNegative("RateMe");
}
dialog.dismiss();
clearSharedPreferences(activity);
}
}
});
dialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
if (sCallback != null) {
sCallback.onNeutral("RateMe");
}
ratingBar.setOnRatingBarChangeListener((ratingBar1, rating, fromUser) -> {
if (rating >= 4) {
if (sCallback != null)
sCallback.onPositive("RateMe");
dialog.dismiss();
String appPackage = activity.getPackageName();
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(GOOGLE_PLAY + appPackage));
activity.startActivity(intent);
setOptOut(activity);
} else {
if (sCallback != null)
sCallback.onNegative("RateMe");
dialog.dismiss();
clearSharedPreferences(activity);
}
});
if (!activity.isFinishing()) {
dialog.setOnCancelListener(dialog1 -> {
if (sCallback != null)
sCallback.onNeutral("RateMe");
clearSharedPreferences(activity);
});
if (!activity.isFinishing())
dialog.show();
} else {
if (sCallback != null) {
sCallback.onNegative("RateMe");
}
}
else if (sCallback != null)
sCallback.onNegative("RateMe");
}
private static void clearSharedPreferences(Activity context) {
private static void clearSharedPreferences(AppCompatActivity context) {
SharedPreferences pref = context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE);
Editor editor = pref.edit();
editor.remove(KEY_INSTALL_DATE);
@ -135,12 +115,12 @@ class RateMe {
editor.apply();
}
private static void setOptOut(final Activity context, boolean optOut) {
private static void setOptOut(final AppCompatActivity context) {
SharedPreferences pref = context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE);
Editor editor = pref.edit();
editor.putBoolean(KEY_OPT_OUT, optOut);
editor.putBoolean(KEY_OPT_OUT, true);
editor.apply();
mOptOut = optOut;
mOptOut = true;
}
private static void storeInstallDate(final Context context, SharedPreferences.Editor editor) {
@ -153,20 +133,5 @@ class RateMe {
e.printStackTrace();
}
editor.putLong(KEY_INSTALL_DATE, installDate.getTime());
log("First install: " + installDate.toString());
}
private static void printStatus() {
log("*** RateMe Status ***");
log("Install Date: " + mInstallDate);
log("Launch Times: " + mLaunchTimes);
log("Opt out: " + mOptOut);
}
private static void log(String message) {
if (DEBUG) {
Log.v(TAG, message);
}
}
}

View File

@ -8,24 +8,27 @@ import android.content.Context;
import android.content.Intent;
import android.os.Build;
import com.crashlytics.android.Crashlytics;
import com.bugsnag.android.Bugsnag;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Objects;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
import static com.multicraft.game.MainActivity.zipLocations;
public class UnzipService extends IntentService {
public static final String ACTION_UPDATE = "mobi.MultiCraft.UPDATE";
public static final String ACTION_UPDATE = "com.multicraft.game.UPDATE";
public static final String EXTRA_KEY_IN_FILE = "file";
public static final String EXTRA_KEY_IN_LOCATION = "location";
public static final String ACTION_PROGRESS = "progress";
private final int id = 1;
private NotificationManager mNotifyManager;
private int id = 1;
public UnzipService() {
super("com.multicraft.game.UnzipService");
@ -34,35 +37,33 @@ public class UnzipService extends IntentService {
private void isDir(String dir, String unzipLocation) {
File f = new File(unzipLocation + dir);
if (!f.isDirectory()) {
if (!f.isDirectory())
f.mkdirs();
}
}
@Override
protected void onHandleIntent(Intent intent) {
createNotification();
unzip(intent);
}
private String getSettings() {
return getString(R.string.gdpr_main_text);
}
private void createNotification() {
// There are hardcoding only for show it's just strings
String name = "mobi.MultiCraft";
String name = "com.multicraft.game";
String channelId = "MultiCraft channel"; // The user-visible name of the channel.
String description = "notifications from MultiCraft"; // The user-visible description of the channel.
Notification.Builder builder;
if (mNotifyManager == null) {
mNotifyManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
}
if (mNotifyManager == null)
mNotifyManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
int importance = NotificationManager.IMPORTANCE_LOW;
NotificationChannel mChannel = null;
if (mNotifyManager != null) {
if (mNotifyManager != null)
mChannel = mNotifyManager.getNotificationChannel(channelId);
}
if (mChannel == null) {
mChannel = new NotificationChannel(channelId, name, importance);
mChannel.setDescription(description);
@ -74,54 +75,45 @@ public class UnzipService extends IntentService {
}
builder = new Notification.Builder(this, channelId);
builder.setContentTitle(getString(R.string.notification_title)) // required
.setSmallIcon(R.mipmap.update) // required
.setSmallIcon(R.drawable.update) // required
.setContentText(getString(R.string.notification_description)); // required
} else {
builder = new Notification.Builder(this);
builder.setContentTitle(getString(R.string.notification_title))
.setContentText(getString(R.string.notification_description))
.setSmallIcon(R.mipmap.update);
.setSmallIcon(R.drawable.update);
}
mNotifyManager.notify(id, builder.build());
}
private void unzip(Intent intent) {
String[] file = intent.getStringArrayExtra(EXTRA_KEY_IN_FILE);
String location = intent.getStringExtra(EXTRA_KEY_IN_LOCATION);
String[] zips = intent.getStringArrayExtra(EXTRA_KEY_IN_FILE);
int per = 0;
int size = getSummarySize(file);
for (String f : file) {
try {
try {
FileInputStream fin = new FileInputStream(f);
ZipInputStream zin = new ZipInputStream(fin);
ZipEntry ze;
while ((ze = zin.getNextEntry()) != null) {
if (ze.isDirectory()) {
per++;
isDir(ze.getName(), location);
} else {
per++;
int progress = 100 * per / size;
// send update
publishProgress(progress);
FileOutputStream f_out = new FileOutputStream(location + ze.getName());
byte[] buffer = new byte[8192];
int len;
while ((len = zin.read(buffer)) != -1) {
f_out.write(buffer, 0, len);
int size = getSummarySize(Objects.requireNonNull(zips));
for (String zip : zips) {
File zipFile = new File(zip);
int readLen;
byte[] readBuffer = new byte[8192];
try (FileInputStream fileInputStream = new FileInputStream(zipFile);
ZipInputStream zipInputStream = new ZipInputStream(fileInputStream)) {
ZipEntry ze;
while ((ze = zipInputStream.getNextEntry()) != null) {
if (ze.isDirectory()) {
++per;
isDir(ze.getName(), zipLocations.get(zip));
} else {
publishProgress(100 * ++per / size);
try (OutputStream outputStream = new FileOutputStream(zipLocations.get(zip) + ze.getName())) {
while ((readLen = zipInputStream.read(readBuffer)) != -1) {
outputStream.write(readBuffer, 0, readLen);
}
f_out.close();
zin.closeEntry();
f_out.close();
}
}
zin.close();
} catch (FileNotFoundException e) {
Crashlytics.logException(e);
}
} catch (FileNotFoundException e) {
Bugsnag.notify(e);
} catch (IOException e) {
Crashlytics.logException(e);
Bugsnag.notify(e);
}
}
}
@ -139,7 +131,7 @@ public class UnzipService extends IntentService {
ZipFile zipSize = new ZipFile(z);
size += zipSize.size();
} catch (IOException e) {
Crashlytics.logException(e);
Bugsnag.notify(e);
}
}
return size;

View File

@ -1,19 +1,18 @@
package com.multicraft.game;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.AsyncTask;
import android.preference.PreferenceManager;
import android.text.Editable;
import android.text.Html;
import com.crashlytics.android.Crashlytics;
import androidx.appcompat.app.AppCompatActivity;
import androidx.preference.PreferenceManager;
import com.bugsnag.android.Bugsnag;
import org.json.JSONException;
import org.json.JSONObject;
@ -30,23 +29,21 @@ import java.net.URL;
import java.util.Calendar;
import java.util.Locale;
import static com.multicraft.game.MainActivity.UPDATE_LINK;
class WVersionManager implements DialogsCallback {
private final CustomTagHandler customTagHandler;
private final String PREF_IGNORE_VERSION_CODE = "w.ignore.version.code";
private final String PREF_REMINDER_TIME = "w.reminder.time";
private final String PREF_LAUNCH_TIMES = "w.launch.times";
private final AppCompatActivity activity;
private final ActivityListener al;
private DialogsCallback sCallback = null;
private CustomTagHandler customTagHandler;
private String PREF_IGNORE_VERSION_CODE = "w.ignore.version.code";
private String PREF_REMINDER_TIME = "w.reminder.time";
private String PREF_LAUNCH_TIMES = "w.launch.times";
private Activity activity;
private Drawable icon;
private String title;
private String message;
private String updateUrl;
private String versionContentUrl;
private int mVersionCode;
private ActivityListener al;
WVersionManager(Activity act) {
WVersionManager(AppCompatActivity act) {
this.activity = act;
al = (ActivityListener) act;
this.customTagHandler = new CustomTagHandler();
@ -57,38 +54,26 @@ class WVersionManager implements DialogsCallback {
sCallback = callback;
}
private Drawable getDefaultAppIcon() {
return activity.getApplicationInfo().loadIcon(activity.getPackageManager());
}
void checkVersion() {
String versionContentUrl = getVersionContentUrl();
if (versionContentUrl == null) {
Crashlytics.log("Please set versionContentUrl first");
return;
}
Calendar c = Calendar.getInstance();
long currentTimeStamp = c.getTimeInMillis();
long reminderTimeStamp = getReminderTime();
if (currentTimeStamp > reminderTimeStamp) {
// fire request to get update version content
VersionContentRequest request = new VersionContentRequest(activity);
request.execute(getVersionContentUrl());
} else {
VersionContentRequest request = new VersionContentRequest();
request.execute(UPDATE_LINK);
} else
al.isShowUpdateDialog(false);
}
}
void showDialog() {
AlertDialogHelper dialogHelper = new AlertDialogHelper(activity);
dialogHelper.setListener(this);
dialogHelper.setIcon(getIcon());
dialogHelper.setTitle(getTitle());
dialogHelper.setIcon(activity.getResources().getDrawable(R.mipmap.ic_launcher));
dialogHelper.setTitle(activity.getString(R.string.available));
dialogHelper.setMessage(Html.fromHtml(getMessage(), null, getCustomTagHandler()));
dialogHelper.setButtonPositive(getUpdateNowLabel());
dialogHelper.setButtonNeutral(getRemindMeLaterLabel());
dialogHelper.setButtonNegative(getIgnoreThisVersionLabel());
dialogHelper.setButtonPositive(activity.getString(R.string.update));
dialogHelper.setButtonNeutral(activity.getString(R.string.later));
dialogHelper.showAlert("WVersionManager");
}
@ -99,18 +84,6 @@ class WVersionManager implements DialogsCallback {
.apply();
}
private String getUpdateNowLabel() {
return activity.getString(R.string.update);
}
private String getRemindMeLaterLabel() {
return activity.getString(R.string.later);
}
private String getIgnoreThisVersionLabel() {
return activity.getString(R.string.ignore);
}
private String getMessage() {
String defaultMessage = "What's new in this version";
return message != null ? message : defaultMessage;
@ -120,23 +93,6 @@ class WVersionManager implements DialogsCallback {
this.message = message;
}
private String getTitle() {
String defaultTitle = "New Update Available";
return title != null ? title : defaultTitle;
}
public void setTitle(String title) {
this.title = title;
}
private Drawable getIcon() {
return icon != null ? icon : getDefaultAppIcon();
}
public void setIcon(Drawable icon) {
this.icon = icon;
}
String getUpdateUrl() {
return updateUrl != null ? updateUrl : getGooglePlayStoreUrl();
}
@ -145,18 +101,6 @@ class WVersionManager implements DialogsCallback {
this.updateUrl = updateUrl;
}
private String getVersionContentUrl() {
return versionContentUrl;
}
void setVersionContentUrl(String versionContentUrl) {
this.versionContentUrl = versionContentUrl;
}
int getReminderTimer() {
return 1;
}
void updateNow(String url) {
if (url != null) {
try {
@ -164,18 +108,16 @@ class WVersionManager implements DialogsCallback {
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
activity.startActivity(intent);
} catch (Exception e) {
Crashlytics.logException(e);
Bugsnag.notify(e);
}
}
}
void remindMeLater(int reminderTimer) {
void remindMeLater() {
Calendar c = Calendar.getInstance();
c.add(Calendar.MINUTE, reminderTimer);
c.add(Calendar.MINUTE, 1);
long reminderTimeStamp = c.getTimeInMillis();
setReminderTime(reminderTimeStamp);
}
@ -241,22 +183,30 @@ class WVersionManager implements DialogsCallback {
void isShowUpdateDialog(boolean flag);
}
private static class CustomTagHandler implements Html.TagHandler {
@Override
public void handleTag(boolean opening, String tag, Editable output,
XMLReader xmlReader) {
// you may add more tag handler which are not supported by android here
if ("li".equals(tag)) {
if (opening)
output.append(" \u2022 ");
else
output.append("\n");
}
}
}
@SuppressLint("StaticFieldLeak")
private class VersionContentRequest extends AsyncTask<String, Void, String> {
Context context;
VersionContentRequest(Context context) {
this.context = context;
}
@Override
protected String doInBackground(String... uri) {
String path = getVersionContentUrl();
String result = null;
try {
URL u = new URL(path);
URL u = new URL(UPDATE_LINK);
HttpURLConnection c = (HttpURLConnection) u.openConnection();
c.setRequestMethod("GET");
c.setConnectTimeout(5000);
c.connect();
InputStream in = c.getInputStream();
final ByteArrayOutputStream bo = new ByteArrayOutputStream();
@ -266,11 +216,11 @@ class WVersionManager implements DialogsCallback {
result = bo.toString();
bo.close();
} catch (MalformedURLException e) {
Crashlytics.logException(e);
Bugsnag.notify(e);
} catch (ProtocolException e) {
Crashlytics.logException(e);
Bugsnag.notify(e);
} catch (IOException e) {
Crashlytics.logException(e);
// nothing
}
return result;
}
@ -290,11 +240,10 @@ class WVersionManager implements DialogsCallback {
JSONObject json = (JSONObject) new JSONTokener(mResult).nextValue();
mVersionCode = json.optInt("version_code");
String lang = Locale.getDefault().getLanguage();
if (lang.equals("ru")) {
if (lang.equals("ru"))
content = json.optString("content_ru");
} else {
else
content = json.optString("content_en");
}
String packageName = json.optString("package");
setUpdateUrl("market://details?id=" + packageName);
int adsDelay = json.optInt("ads_delay");
@ -311,38 +260,19 @@ class WVersionManager implements DialogsCallback {
.apply();
setMessage(content);
al.isShowUpdateDialog(true);
} else {
} else
al.isShowUpdateDialog(false);
}
} else {
} else
al.isShowUpdateDialog(false);
}
} catch (JSONException e) {
Crashlytics.logException(e);
Bugsnag.notify(e);
al.isShowUpdateDialog(false);
} catch (Exception e) {
Crashlytics.logException(e);
Bugsnag.notify(e);
al.isShowUpdateDialog(false);
}
} else {
} else
al.isShowUpdateDialog(false);
}
}
}
private class CustomTagHandler implements Html.TagHandler {
@Override
public void handleTag(boolean opening, String tag, Editable output,
XMLReader xmlReader) {
// you may add more tag handler which are not supported by android here
if ("li".equals(tag)) {
if (opening) {
output.append(" \u2022 ");
} else {
output.append("\n");
}
}
}
}
}

View File

Before

Width:  |  Height:  |  Size: 7.2 KiB

After

Width:  |  Height:  |  Size: 7.2 KiB

View File

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

View File

@ -1,5 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@android:id/background">
<shape>

View File

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

View File

Before

Width:  |  Height:  |  Size: 134 B

After

Width:  |  Height:  |  Size: 134 B

View File

@ -1,9 +1,20 @@
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/bg">
<ImageView
android:id="@+id/imageView"
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_marginLeft="80dp"
android:layout_marginTop="25dp"
android:layout_marginRight="80dp"
android:contentDescription="@string/loading"
app:srcCompat="@drawable/logo" />
<ProgressBar
android:id="@+id/PB1"
style="@style/CustomProgressBar"
@ -19,11 +30,9 @@
<ProgressBar
android:id="@+id/PB2"
style="@style/IndeterminateProgressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_width="75dp"
android:layout_height="75dp"
android:layout_centerInParent="true"
android:layout_marginLeft="90dp"
android:layout_marginRight="90dp"
android:indeterminate="true"
android:visibility="gone" />

View File

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/gdprTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:gravity="center"
android:textSize="16sp" />

View File

@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<EditText xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/editText"
android:layout_width="match_parent"
android:layout_height="50dp" />

View File

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

View File

Before

Width:  |  Height:  |  Size: 5.1 KiB

After

Width:  |  Height:  |  Size: 5.1 KiB

View File

Before

Width:  |  Height:  |  Size: 47 KiB

After

Width:  |  Height:  |  Size: 47 KiB

View File

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

View File

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 134 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 134 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 134 B

View File

@ -7,20 +7,19 @@
<string name="notification_title">Загрузка MultiCraft</string>
<string name="notification_description">Осталось меньше минуты&#8230;</string>
<string name="restart">Произошла ошибка, игра будет перезапущена автоматически</string>
<string name="no_space">Недостаточно места для записи файлов игры, пожалуйста освободите место SD карте</string>
<string name="no_space">Недостаточно места для записи файлов игры, пожалуйста освободите место в памяти</string>
<!-- разрешения -->
<string name="explain">Разрешение на запись необходимо для распаковки текстур и игровых файлов.</string>
<string name="location">Доступ к местоположению обеспечивает Вам лучшее взаимодействие с игрой</string>
<string name="close_game">Закрыть игру</string>
<string name="settings">Настройки</string>
<string name="denied">Вы не можете играть в MultiCraft без разрешения на запись. \nПожалуйста, включите его в [Настройки] -> [Разрешения]></string>
<!-- диалог оценки -->
<string name="rta_dialog_title">Оцените MultiCraft!</string>
<string name="rate_title">Название</string>
<string name="rate_description">Описание</string>
<string name="rate_submit">ОЦЕНИТЬ</string>
<string name="sad">Нам жаль, что Вам не понравилась игра!</string>
<!-- обновление -->
<string name="available">Доступна Новая Версия!</string>
<string name="ignore">Игнорировать</string>
<string name="later">Позже</string>
<string name="update">Обновить</string>

View File

@ -1,19 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="AppTheme" parent="android:Theme.Material.Light.NoActionBar.Fullscreen">
<item name="android:windowNoTitle">true</item>
</style>
<style name="RateMe" parent="android:Theme.Material.Light.Dialog" />
<style name="DialogTheme" parent="android:Theme.Material.Light.Dialog" />
<style name="Theme.Transparent" parent="@android:style/Theme.Material.NoActionBar.Fullscreen">
<item name="android:windowNoTitle">true</item>
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowIsTranslucent">true</item>
</style>
<style name="CustomLollipopDialogStyle" parent="android:Theme.Material.Light.Dialog.Alert" />
<style name="IndeterminateProgressBar" parent="android:Widget.Material.ProgressBar.Large" />
</resources>
</resources>

View File

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="ic_launcher_background">#FFFFFF</color>
</resources>

View File

@ -3,21 +3,17 @@
<string name="app_name" translatable="false">MultiCraft</string>
<string name="ver" translatable="false">1.6.0</string>
<!-- preparation for start -->
<!-- preparation for start -->
<string name="rm_old">Preparing to update&#8230;</string>
<string name="loading">Loading&#8230;</string>
<string name="notification_title">Loading MultiCraft</string>
<string name="notification_description">Less than 1 minute&#8230;</string>
<string name="restart">Unexpected issue, the game will be restarted automatically</string>
<string name="no_space">No space left for game files, please free space on SD card</string>
<string name="no_space">No space left for game files, please free space in the memory</string>
<!-- permission block -->
<string name="explain">Storage permissions is necessary to unpack textures and game data.</string>
<string name="location">Location permission provide you better interaction with game</string>
<string name="close_game">Close game</string>
<string name="settings">App settings</string>
<string name="denied">You cannot play MultiCraft without storage permission. \nPlease turn on it at [Settings] -> [Permissions]></string>
<!-- rate input_dialog -->
<string name="rta_dialog_title">Please, rate MultiCraft!</string>
<string name="rate_title">Title</string>
@ -26,6 +22,7 @@
<string name="sad">We are sorry that you did not like the game!</string>
<!--update input_dialog -->
<string name="available">New Version Available!</string>
<string name="update">Update</string>
<string name="later">Later</string>
<string name="ignore">Ignore</string>
@ -36,8 +33,8 @@
<string name="conn_mobile">Mobile Data</string>
<!-- GDPR -->
<string name="gdpr_main_text" translatable="false"><b>We care about your privacy and data security. We keep this app free by showing ads.</b>\n\n<b>Can we continue to use your data to tailor ads for you?</b>\n\n<small>Our partners will collect data and use a unique identifier on your device to show you ads. By agreeing, you confirm that you are 16 years old. You can learn how we and our partners collect and use data on\n<b><a href="https://www.appodeal.com/privacy-policy">Privacy Policy</a></b>.</small></string>
<string name="gdpr_agree" translatable="false">Agree</string>
<string name="gdpr_disagree" translatable="false">Disagree</string>
<string name="gdpr_main_text" translatable="false"><b>We care about your privacy and data security. We keep this app free by showing ads.\n<big>Can we continue to use your data to tailor ads for you?</big></b>\n\n<small>Our partners will collect data and use a unique identifier on your device to show you ads. By agreeing, you confirm that you are 16 years old. You can learn how we and our partners collect and use data on <a href="https://www.appodeal.com/privacy-policy">Privacy Policy</a>.</small></string>
<string name="gdpr_agree" translatable="false">Yes, I allow</string>
<string name="gdpr_disagree" translatable="false">No</string>
</resources>

View File

@ -1,25 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<resources xmlns:tools="http://schemas.android.com/tools">
<style name="AppTheme" parent="android:Theme.Holo.Light.NoActionBar.Fullscreen">
<item name="android:windowNoTitle">true</item>
<style name="AppTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
<item name="windowActionBar">false</item>
<item name="android:windowFullscreen">true</item>
<item name="android:windowLayoutInDisplayCutoutMode" tools:targetApi="p">shortEdges
</item>
</style>
<style name="DialogTheme" parent="android:Theme.Holo.Light.Dialog" />
<style name="RateMe" parent="android:Theme.Holo.Light.Dialog" />
<style name="Theme.Transparent" parent="android:Theme.Holo.Light.NoActionBar.Fullscreen">
<item name="android:windowNoTitle">true</item>
<style name="InputTheme" parent="Theme.AppCompat.DayNight.Dialog">
<item name="windowNoTitle">true</item>
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowIsTranslucent">true</item>
</style>
<style name="CustomProgressBar" parent="android:Widget.ProgressBar.Horizontal">
<style name="CustomProgressBar" parent="Widget.AppCompat.ProgressBar.Horizontal">
<item name="android:indeterminateOnly">false</item>
<item name="android:progressDrawable">@drawable/custom_progress_bar</item>
<item name="android:minHeight">10dip</item>
<item name="android:maxHeight">20dip</item>
</style>
<style name="IndeterminateProgressBar" parent="android:Widget.Holo.ProgressBar.Large" />
<style name="IndeterminateProgressBar" parent="Widget.AppCompat.ProgressBar" />
</resources>
</resources>

View File

@ -6,4 +6,7 @@
<certificates src="user" />
</trust-anchors>
</base-config>
</network-security-config>
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">127.0.0.1</domain>
</domain-config>
</network-security-config>

View File

@ -4,12 +4,9 @@ buildscript {
repositories {
google()
jcenter()
maven { url 'https://maven.fabric.io/public' }
}
dependencies {
classpath 'com.android.tools.build:gradle:3.5.1'
classpath 'com.google.gms:google-services:4.3.2'
classpath 'io.fabric.tools:gradle:1.31.1'
classpath 'com.android.tools.build:gradle:3.5.2'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
@ -19,7 +16,6 @@ allprojects {
repositories {
google()
jcenter()
flatDir { dirs 'libs-aar' }
}
}