diff --git a/build/android/src/main/AndroidManifest.xml b/build/android/src/main/AndroidManifest.xml new file mode 100644 index 00000000..751587a4 --- /dev/null +++ b/build/android/src/main/AndroidManifest.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build/android/src/main/java/mobi/MultiCraft/GameActivity.java b/build/android/src/main/java/mobi/MultiCraft/GameActivity.java new file mode 100644 index 00000000..ddd4c7f9 --- /dev/null +++ b/build/android/src/main/java/mobi/MultiCraft/GameActivity.java @@ -0,0 +1,113 @@ +package mobi.MultiCraft; + +import android.app.NativeActivity; +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.view.View; +import android.view.WindowManager; + +public class GameActivity extends NativeActivity { + static { + System.loadLibrary("gmp"); + System.loadLibrary("multicraft"); + } + + private int messageReturnCode; + private String messageReturnValue; + + public static native void putMessageBoxResult(String text); + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); +// startAd(this, true); + messageReturnCode = -1; + messageReturnValue = ""; + makeFullScreen(); + } + + + public 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) { + makeFullScreen(); + } + } + + @Override + protected void onRestart() { + super.onRestart(); +// startAd(this, false); + } + + @Override + protected void onResume() { + super.onResume(); + makeFullScreen(); + } + + @Override + protected void onStop() { + super.onStop(); +// stopAd(); + } + + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + if (requestCode == 101) { + if (resultCode == RESULT_OK) { + String text = data.getStringExtra("text"); + messageReturnCode = 0; + messageReturnValue = text; + } else { + messageReturnCode = 1; + } + } + } + + public void copyAssets() { + } + + public void showDialog(String acceptButton, String hint, String current, int editType) { + Intent intent = new Intent(this, InputDialogActivity.class); + Bundle params = new Bundle(); + params.putString("acceptButton", acceptButton); + params.putString("hint", hint); + params.putString("current", current); + params.putInt("editType", editType); + intent.putExtras(params); + startActivityForResult(intent, 101); + messageReturnValue = ""; + messageReturnCode = -1; + } + + public int getDialogState() { + return messageReturnCode; + } + + public String getDialogValue() { + messageReturnCode = -1; + return messageReturnValue; + } + + public float getDensity() { + return getResources().getDisplayMetrics().density; + } + + public int getDisplayWidth() { + return getResources().getDisplayMetrics().widthPixels; + } + + public int getDisplayHeight() { + return getResources().getDisplayMetrics().heightPixels; + } +} \ No newline at end of file diff --git a/build/android/src/main/java/mobi/MultiCraft/InputDialogActivity.java b/build/android/src/main/java/mobi/MultiCraft/InputDialogActivity.java new file mode 100644 index 00000000..823dddd3 --- /dev/null +++ b/build/android/src/main/java/mobi/MultiCraft/InputDialogActivity.java @@ -0,0 +1,75 @@ +package mobi.MultiCraft; + +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; + + +public class InputDialogActivity extends Activity { + private AlertDialog alertDialog; + + @SuppressLint("InflateParams") + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + Bundle b = getIntent().getExtras(); + int editType = b.getInt("editType"); + final AlertDialog.Builder builder = new AlertDialog.Builder(this); + LayoutInflater inflater = this.getLayoutInflater(); + View dialogView = inflater.inflate(R.layout.dialog, null); + builder.setView(dialogView); + final EditText editText = (EditText) dialogView.findViewById(R.id.editText); + final InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); + 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; + } + }); + 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(); + finish(); + } + }); + } + + public void pushResult(String text) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP && text.matches(".*[А-я].*")) { + text = Transliteration.toLatin(text); + } + Intent resultData = new Intent(); + resultData.putExtra("text", text); + setResult(Activity.RESULT_OK, resultData); + alertDialog.dismiss(); + finish(); + } +} \ No newline at end of file diff --git a/build/android/src/main/java/mobi/MultiCraft/MainActivity.java b/build/android/src/main/java/mobi/MultiCraft/MainActivity.java new file mode 100644 index 00000000..6dee623b --- /dev/null +++ b/build/android/src/main/java/mobi/MultiCraft/MainActivity.java @@ -0,0 +1,370 @@ +package mobi.MultiCraft; + +import android.Manifest; +import android.annotation.SuppressLint; +import android.app.Activity; +import android.app.ProgressDialog; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.pm.PackageManager; +import android.graphics.drawable.Drawable; +import android.os.AsyncTask; +import android.os.Build; +import android.os.Bundle; +import android.os.Environment; +import android.os.StatFs; +import android.support.annotation.NonNull; +import android.support.v4.app.ActivityCompat; +import android.util.Log; +import android.view.View; +import android.view.WindowManager; +import android.widget.ProgressBar; +import android.widget.Toast; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import static mobi.MultiCraft.PreferencesHelper.TAG_BUILD_NUMBER; +import static mobi.MultiCraft.PreferencesHelper.TAG_SHORTCUT_CREATED; +import static mobi.MultiCraft.PreferencesHelper.getBuildNumber; +import static mobi.MultiCraft.PreferencesHelper.isCreateShortcut; +import static mobi.MultiCraft.PreferencesHelper.loadSettings; +import static mobi.MultiCraft.PreferencesHelper.saveSettings; + +public class MainActivity extends Activity { + public final static String TAG = "Error"; + public final static String CREATE_SHORTCUT = "com.android.launcher.action.INSTALL_SHORTCUT"; + public final static String FILES = Environment.getExternalStorageDirectory() + "/Files.zip"; + public final static String WORLDS = Environment.getExternalStorageDirectory() + "/worlds.zip"; + public final static String GAMES = Environment.getExternalStorageDirectory() + "/games.zip"; + public final static String NOMEDIA = ".nomedia"; + private final static int REQUEST_STORAGE = 0; + private ProgressDialog mProgressDialog; + private String dataFolder = "/Android/data/mobi.MultiCraft/files/"; + private String unzipLocation = Environment.getExternalStorageDirectory() + dataFolder; + private ProgressBar mProgressBar; + private Utilities util; + private BroadcastReceiver myReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + int progress = intent.getIntExtra(UnzipService.ACTION_PROGRESS, 0); + if (progress >= 0) { + mProgressBar.setVisibility(View.VISIBLE); + mProgressBar.setProgress(progress); + } else { + util.createNomedia(); + runGame(); + } + } + }; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + loadSettings(this); + IntentFilter filter = new IntentFilter(UnzipService.ACTION_UPDATE); + registerReceiver(myReceiver, filter); + if (!isTaskRoot()) { + finish(); + return; + } + + + if (ActivityCompat.checkSelfPermission(this, + Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { + requestStoragePermission(); + } else { + init(); + } + } + + public 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) { + makeFullScreen(); + } + } + + @Override + protected void onDestroy() { + super.onDestroy(); + dismissProgressDialog(); + unregisterReceiver(myReceiver); + } + + @Override + protected void onResume() { + super.onResume(); + makeFullScreen(); + } + + private void addShortcut() { + saveSettings(TAG_SHORTCUT_CREATED, false); + Intent shortcutIntent = new Intent(getApplicationContext(), MainActivity.class); + shortcutIntent.setAction(Intent.ACTION_MAIN); + Intent addIntent = new Intent(); + addIntent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent); + addIntent.putExtra(Intent.EXTRA_SHORTCUT_NAME, getString(R.string.app_name)); + addIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, + Intent.ShortcutIconResource.fromContext(getApplicationContext(), R.drawable.ic_launcher)); + addIntent.setAction(CREATE_SHORTCUT); + getApplicationContext().sendBroadcast(addIntent); + } + + @SuppressWarnings("deprecation") + public void init() { + setContentView(R.layout.activity_main); + if (isCreateShortcut()) + addShortcut(); + mProgressBar = (ProgressBar) findViewById(R.id.PB1); + Drawable draw; + draw = getResources().getDrawable(R.drawable.custom_progress_bar); + mProgressBar.setProgressDrawable(draw); + util = new Utilities(); + util.createDataFolder(); + util.checkVersion(); + } + + private void requestPermissionAfterExplain() { + Toast.makeText(this, R.string.explain, Toast.LENGTH_LONG).show(); + ActivityCompat.requestPermissions(MainActivity.this, + new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_STORAGE); + } + + private void requestStoragePermission() { + if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) { + requestPermissionAfterExplain(); + } else { + ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, + REQUEST_STORAGE); + } + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, + @NonNull int[] grantResults) { + + // Check if the only required permission has been granted + if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { + init(); + } else { + requestStoragePermission(); + } + } + + private void showSpinnerDialog(int message) { + if (mProgressDialog == null) { + mProgressDialog = new ProgressDialog(MainActivity.this); + mProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER); + mProgressDialog.setCancelable(false); + } + mProgressDialog.setMessage(getString(message)); + mProgressDialog.show(); + } + + private void dismissProgressDialog() { + if (mProgressDialog != null && mProgressDialog.isShowing()) { + mProgressDialog.dismiss(); + } + } + + public void runGame() { + util.deleteZip(FILES); + util.deleteZip(WORLDS); + util.deleteZip(GAMES); + Intent intent = new Intent(MainActivity.this, GameActivity.class); + intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK); + startActivity(intent); + } + + private void startUnzipService(String[] file) throws IOException { + // Start MyIntentService + Intent intentMyIntentService = new Intent(this, UnzipService.class); + intentMyIntentService.putExtra(UnzipService.EXTRA_KEY_IN_FILE, file); + intentMyIntentService.putExtra(UnzipService.EXTRA_KEY_IN_LOCATION, unzipLocation); + startService(intentMyIntentService); + + } + + private class DeleteTask extends AsyncTask { + String location; + + @Override + protected void onPreExecute() { + super.onPreExecute(); + showSpinnerDialog(R.string.rm_old); + } + + @Override + protected Void doInBackground(String... params) { + location = params[0]; + for (String p : params) { + util.deleteFiles(p); + } + return null; + } + + @Override + protected void onPostExecute(Void result) { + if (isFinishing()) + return; + dismissProgressDialog(); + if (unzipLocation.equals(location)) { + new CopyZip().execute(FILES, WORLDS, GAMES); + } else { + new CopyZip().execute(FILES, GAMES); + } + } + + + } + + private class CopyZip extends AsyncTask { + String[] zips; + + @Override + protected void onPreExecute() { + super.onPreExecute(); + } + + @Override + protected String doInBackground(String... params) { + zips = params; + for (String s : zips) { + copyAssets(s); + } + return "Done"; + + } + + @Override + protected void onPostExecute(String result) { + if (util.getAvailableSpaceInMB() > 15) { + try { + startUnzipService(zips); + } catch (IOException e) { + Log.e(TAG, "unzip failed: " + e.getMessage()); + } + } else + Toast.makeText(MainActivity.this, R.string.not_enough_space, Toast.LENGTH_LONG).show(); + } + + private void copyAssets(String zipName) { + String filename = zipName.substring(zipName.lastIndexOf("/") + 1); + InputStream in; + OutputStream out; + try { + in = getAssets().open(filename); + out = new FileOutputStream(zipName); + copyFile(in, out); + in.close(); + out.flush(); + out.close(); + } catch (IOException e) { + Log.e(TAG, "Failed to copy asset file: " + e.getMessage()); + } + } + + private void copyFile(InputStream in, OutputStream out) throws IOException { + byte[] buffer = new byte[1024]; + int read; + while ((read = in.read(buffer)) != -1) { + out.write(buffer, 0, read); + } + } + } + + private class Utilities { + + private void createDataFolder() { + File folder = new File(unzipLocation); + if (!(folder.exists())) + folder.mkdirs(); + } + + private void deleteZip(String fileName) { + File file = new File(fileName); + if (file.exists()) + file.delete(); + } + + private void startDeletion(boolean isAll) { + if (isAll) { + new DeleteTask().execute(unzipLocation); + } else { + new DeleteTask().execute(unzipLocation + "textures", unzipLocation + "games/MultiCraft", unzipLocation + "builtin", + unzipLocation + "fonts", unzipLocation + "debug.txt"); + } + } + + @SuppressWarnings("deprecation") + @SuppressLint("NewApi") + private long getAvailableSpaceInMB() { + final long SIZE_KB = 1024L; + final long SIZE_MB = SIZE_KB * SIZE_KB; + long availableSpace; + StatFs stat = new StatFs(Environment.getExternalStorageDirectory().getPath()); + if (Build.VERSION.SDK_INT > 17) { + availableSpace = stat.getAvailableBlocksLong() * stat.getBlockSizeLong(); + } else { + availableSpace = (long) stat.getAvailableBlocks() * (long) stat.getBlockSize(); + } + return availableSpace / SIZE_MB; + } + + private boolean isFolderEmpty(String folder) { + File location = new File(folder); + File[] contents = location.listFiles(); + return contents == null || contents.length == 0; + } + + public void checkVersion() { + if (isFolderEmpty(unzipLocation)) { + saveSettings(TAG_BUILD_NUMBER, getString(R.string.ver)); + startDeletion(true); + } else if (getBuildNumber().equals(getString(R.string.ver))) { + runGame(); + } else { + saveSettings(TAG_BUILD_NUMBER, getString(R.string.ver)); + startDeletion(false); + } + } + + private void deleteFiles(String path) { + File file = new File(path); + if (file.exists()) { + String deleteCmd = "rm -r " + path; + Runtime runtime = Runtime.getRuntime(); + try { + runtime.exec(deleteCmd); + } catch (IOException e) { + Log.e(TAG, "delete files failed: " + e.getLocalizedMessage()); + } + } + } + + public void createNomedia() { + File myFile = new File(unzipLocation, NOMEDIA); + if (!myFile.exists()) + try { + myFile.createNewFile(); + } catch (IOException e) { + Log.e(TAG, "nomedia has not been created: " + e.getMessage()); + } + } + } +} \ No newline at end of file diff --git a/build/android/src/main/java/mobi/MultiCraft/PreferencesHelper.java b/build/android/src/main/java/mobi/MultiCraft/PreferencesHelper.java new file mode 100644 index 00000000..4329e215 --- /dev/null +++ b/build/android/src/main/java/mobi/MultiCraft/PreferencesHelper.java @@ -0,0 +1,40 @@ +package mobi.MultiCraft; + +import android.content.Context; +import android.content.SharedPreferences; + +public class PreferencesHelper { + public static final String SETTINGS = "settings"; + public static final String TAG_SHORTCUT_CREATED = "createShortcut"; + public static final String TAG_BUILD_NUMBER = "buildNumber"; + private static boolean createShortcut; + private static String buildNumber; + private static SharedPreferences settings; + + public static boolean isCreateShortcut() { + return createShortcut; + } + + public static String getBuildNumber() { + return buildNumber; + } + + public static void loadSettings(final Context context) { + settings = context.getSharedPreferences(SETTINGS, Context.MODE_PRIVATE); + createShortcut = settings.getBoolean(TAG_SHORTCUT_CREATED, true); + buildNumber = settings.getString(TAG_BUILD_NUMBER, "0"); + } + + public static void saveSettings(String tag, boolean bool) { + SharedPreferences.Editor editor = settings.edit(); + editor.putBoolean(tag, bool); + editor.apply(); + } + + public static void saveSettings(String tag, String value) { + SharedPreferences.Editor editor = settings.edit(); + editor.putString(tag, value); + editor.apply(); + } + +} \ No newline at end of file diff --git a/build/android/src/main/java/mobi/MultiCraft/Transliteration.java b/build/android/src/main/java/mobi/MultiCraft/Transliteration.java new file mode 100644 index 00000000..27ceeb1b --- /dev/null +++ b/build/android/src/main/java/mobi/MultiCraft/Transliteration.java @@ -0,0 +1,72 @@ +package mobi.MultiCraft; + +public class Transliteration { + + private static final String[] CHAR_TABLE = new String[81]; + private static final char START_CHAR = 'Ё'; + + + static { + CHAR_TABLE['А' - START_CHAR] = "A"; + CHAR_TABLE['Б' - START_CHAR] = "B"; + CHAR_TABLE['В' - START_CHAR] = "V"; + CHAR_TABLE['Г' - START_CHAR] = "G"; + CHAR_TABLE['Д' - START_CHAR] = "D"; + CHAR_TABLE['Е' - START_CHAR] = "E"; + CHAR_TABLE['Ё' - START_CHAR] = "E"; + CHAR_TABLE['Ж' - START_CHAR] = "ZH"; + CHAR_TABLE['З' - START_CHAR] = "Z"; + CHAR_TABLE['И' - START_CHAR] = "I"; + CHAR_TABLE['Й' - START_CHAR] = "J"; + CHAR_TABLE['К' - START_CHAR] = "K"; + CHAR_TABLE['Л' - START_CHAR] = "L"; + CHAR_TABLE['М' - START_CHAR] = "M"; + CHAR_TABLE['Н' - START_CHAR] = "N"; + CHAR_TABLE['О' - START_CHAR] = "O"; + CHAR_TABLE['П' - START_CHAR] = "P"; + CHAR_TABLE['Р' - START_CHAR] = "R"; + CHAR_TABLE['С' - START_CHAR] = "TS"; + CHAR_TABLE['Т' - START_CHAR] = "T"; + CHAR_TABLE['У' - START_CHAR] = "U"; + CHAR_TABLE['Ф' - START_CHAR] = "F"; + CHAR_TABLE['Х' - START_CHAR] = "H"; + CHAR_TABLE['Ц' - START_CHAR] = "C"; + CHAR_TABLE['Ч' - START_CHAR] = "CH"; + CHAR_TABLE['Ш' - START_CHAR] = "SH"; + CHAR_TABLE['Щ' - START_CHAR] = "SHCH"; + CHAR_TABLE['Ъ' - START_CHAR] = ""; + CHAR_TABLE['Ы' - START_CHAR] = "Y"; + CHAR_TABLE['Ь' - START_CHAR] = ""; + CHAR_TABLE['Э' - START_CHAR] = "E"; + CHAR_TABLE['Ю' - START_CHAR] = "U"; + CHAR_TABLE['Я' - START_CHAR] = "YA"; + + for (int i = 0; i < CHAR_TABLE.length; i++) { + char idx = (char) ((char) i + START_CHAR); + char lower = new String(new char[]{idx}).toLowerCase().charAt(0); + if (CHAR_TABLE[i] != null) { + CHAR_TABLE[lower - START_CHAR] = CHAR_TABLE[i].toLowerCase(); + } + } + } + + /** + * Переводит русский текст в транслит. В результирующей строке + * каждая русская буква будет заменена на соответствующую английскую. + * Не русские символы останутся прежними. + */ + public static String toLatin(String text) { + char charBuffer[] = text.toCharArray(); + StringBuilder sb = new StringBuilder(text.length()); + for (char symbol : charBuffer) { + int i = symbol - START_CHAR; + if (i >= 0 && i < CHAR_TABLE.length) { + String replace = CHAR_TABLE[i]; + sb.append(replace == null ? symbol : replace); + } else { + sb.append(symbol); + } + } + return sb.toString(); + } +} diff --git a/build/android/src/main/java/mobi/MultiCraft/UnzipService.java b/build/android/src/main/java/mobi/MultiCraft/UnzipService.java new file mode 100644 index 00000000..d3add5ab --- /dev/null +++ b/build/android/src/main/java/mobi/MultiCraft/UnzipService.java @@ -0,0 +1,113 @@ +package mobi.MultiCraft; + +import android.app.IntentService; +import android.app.Notification; +import android.app.NotificationManager; +import android.content.Context; +import android.content.Intent; +import android.util.Log; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; +import java.util.zip.ZipInputStream; + +public class UnzipService extends IntentService { + public static final String ACTION_UPDATE = "mobi.MultiCraft.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"; + public final String TAG = UnzipService.class.getSimpleName(); + private NotificationManager mNotifyManager; + private int id = 1; + + public UnzipService() { + super("mobi.MultiCraft.UnzipService"); + } + + private void isDir(String dir, String unzipLocation) { + File f = new File(unzipLocation + dir); + + if (!f.isDirectory()) { + f.mkdirs(); + } + } + + @Override + protected void onHandleIntent(Intent intent) { + mNotifyManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); + Notification.Builder mBuilder = new Notification.Builder(this); + mBuilder.setContentTitle(getString(R.string.notification_title)) + .setContentText(getString(R.string.notification_description)).setSmallIcon(R.drawable.update); + String[] file = intent.getStringArrayExtra(EXTRA_KEY_IN_FILE); + String location = intent.getStringExtra(EXTRA_KEY_IN_LOCATION); + + mNotifyManager.notify(id, mBuilder.build()); + 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); + } + f_out.close(); + zin.closeEntry(); + f_out.close(); + } + } + zin.close(); + } catch (FileNotFoundException e) { + Log.e(TAG, e.getMessage()); + } + } catch (IOException e) { + Log.e(TAG, e.getLocalizedMessage()); + } + } + } + + private void publishProgress(int progress) { + Intent intentUpdate = new Intent(ACTION_UPDATE); + intentUpdate.putExtra(ACTION_PROGRESS, progress); + sendBroadcast(intentUpdate); + } + + private int getSummarySize(String[] zips) { + int size = 0; + for (String z : zips) { + try { + ZipFile zipSize = new ZipFile(z); + size += zipSize.size(); + } catch (IOException e) { + Log.e(TAG, e.getLocalizedMessage()); + } + } + return size; + } + + @Override + public void onDestroy() { + super.onDestroy(); + mNotifyManager.cancel(id); + publishProgress(-1); + } +} \ No newline at end of file diff --git a/build/android/src/main/res/drawable-xhdpi/ic_launcher.png b/build/android/src/main/res/drawable-xhdpi/ic_launcher.png new file mode 100644 index 00000000..45760d62 Binary files /dev/null and b/build/android/src/main/res/drawable-xhdpi/ic_launcher.png differ diff --git a/build/android/src/main/res/drawable-xhdpi/update.png b/build/android/src/main/res/drawable-xhdpi/update.png new file mode 100644 index 00000000..63fe67f2 Binary files /dev/null and b/build/android/src/main/res/drawable-xhdpi/update.png differ diff --git a/build/android/src/main/res/drawable/background.png b/build/android/src/main/res/drawable/background.png new file mode 100644 index 00000000..1ae046e1 Binary files /dev/null and b/build/android/src/main/res/drawable/background.png differ diff --git a/build/android/src/main/res/drawable/bg.xml b/build/android/src/main/res/drawable/bg.xml new file mode 100644 index 00000000..840f22ba --- /dev/null +++ b/build/android/src/main/res/drawable/bg.xml @@ -0,0 +1,4 @@ + + \ No newline at end of file diff --git a/build/android/src/main/res/drawable/custom_progress_bar.xml b/build/android/src/main/res/drawable/custom_progress_bar.xml new file mode 100644 index 00000000..ec233f27 --- /dev/null +++ b/build/android/src/main/res/drawable/custom_progress_bar.xml @@ -0,0 +1,14 @@ + + + + + + + + + \ No newline at end of file diff --git a/build/android/src/main/res/drawable/logo.png b/build/android/src/main/res/drawable/logo.png new file mode 100644 index 00000000..218ebd01 Binary files /dev/null and b/build/android/src/main/res/drawable/logo.png differ diff --git a/build/android/src/main/res/layout/activity_main.xml b/build/android/src/main/res/layout/activity_main.xml new file mode 100644 index 00000000..a910225b --- /dev/null +++ b/build/android/src/main/res/layout/activity_main.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/build/android/src/main/res/layout/dialog.xml b/build/android/src/main/res/layout/dialog.xml new file mode 100644 index 00000000..9d0bd333 --- /dev/null +++ b/build/android/src/main/res/layout/dialog.xml @@ -0,0 +1,5 @@ + + \ No newline at end of file diff --git a/build/android/src/main/res/values-ru/strings.xml b/build/android/src/main/res/values-ru/strings.xml new file mode 100644 index 00000000..4107373b --- /dev/null +++ b/build/android/src/main/res/values-ru/strings.xml @@ -0,0 +1,11 @@ + + + + + Подготовка к обновлению… + Загрузка… + Загрузка MultiCraft + Осталось меньше минуты… + Недостаточно места для распаковки.\nОсвободите пространство в памяти устройства! + Для корректной работы, игре требуется разрешение записывать в память устройтсва. + \ No newline at end of file diff --git a/build/android/src/main/res/values-v21/styles.xml b/build/android/src/main/res/values-v21/styles.xml new file mode 100644 index 00000000..2417cf7b --- /dev/null +++ b/build/android/src/main/res/values-v21/styles.xml @@ -0,0 +1,10 @@ + + + + + + \ No newline at end of file diff --git a/build/android/src/main/res/values/strings.xml b/build/android/src/main/res/values/strings.xml new file mode 100644 index 00000000..bad627b6 --- /dev/null +++ b/build/android/src/main/res/values/strings.xml @@ -0,0 +1,19 @@ + + + + MultiCraft + 1.1.3 + 312077575425 + + + Preparing to update… + Loading… + Loading MultiCraft + Less than 1 minute… + + + Not enough space for unpack game data.\nPlease free some space on the storage memory! + + + Game need permission to write files to storage memory. + \ No newline at end of file diff --git a/build/android/src/main/res/values/styles.xml b/build/android/src/main/res/values/styles.xml new file mode 100644 index 00000000..a127de09 --- /dev/null +++ b/build/android/src/main/res/values/styles.xml @@ -0,0 +1,10 @@ + + + + + + \ No newline at end of file