diff --git a/android/src/main/java/SuperTuxKartActivity.java b/android/src/main/java/SuperTuxKartActivity.java index f4aaabc0b..9d7177371 100644 --- a/android/src/main/java/SuperTuxKartActivity.java +++ b/android/src/main/java/SuperTuxKartActivity.java @@ -2,9 +2,13 @@ package org.supertuxkart.stk_dbg; import org.supertuxkart.stk_dbg.STKEditText; import org.libsdl.app.SDLActivity; +import org.libsdl.app.SDL; +import android.app.AlertDialog; +import android.app.AlertDialog.Builder; import android.content.ActivityNotFoundException; import android.content.Context; +import android.content.DialogInterface; import android.content.Intent; import android.content.pm.PackageManager; import android.content.res.Configuration; @@ -12,15 +16,26 @@ import android.graphics.Rect; import android.net.Uri; import android.os.Build; import android.os.Bundle; +import android.os.Process; import android.text.Editable; import android.text.TextWatcher; +import android.view.Display; +import android.view.Gravity; import android.view.inputmethod.InputMethodManager; import android.view.KeyEvent; import android.view.MotionEvent; +import android.view.ViewGroup; import android.view.ViewGroup.MarginLayoutParams; import android.view.ViewTreeObserver.OnGlobalLayoutListener; import android.view.View; +import android.view.Window; +import android.view.WindowManager; +import android.view.WindowManager.LayoutParams; import android.widget.FrameLayout; +import android.widget.LinearLayout; +import android.widget.ProgressBar; +import android.widget.TextView; +import android.util.DisplayMetrics; import java.util.Set; @@ -31,6 +46,8 @@ import org.minidns.record.TXT; public class SuperTuxKartActivity extends SDLActivity { + private AlertDialog m_progress_dialog; + private ProgressBar m_progress_bar; private STKEditText m_stk_edittext; private int m_bottom_y; // ------------------------------------------------------------------------ @@ -40,6 +57,60 @@ public class SuperTuxKartActivity extends SDLActivity // ------------------------------------------------------------------------ private native static void addDNSSrvRecords(String name, int weight); // ------------------------------------------------------------------------ + private void showExtractProgressPrivate() + { + WindowManager wm = + (WindowManager)getSystemService(Context.WINDOW_SERVICE); + DisplayMetrics display_metrics = new DisplayMetrics(); + wm.getDefaultDisplay().getMetrics(display_metrics); + int padding = display_metrics.widthPixels / 64; + + LinearLayout ll = new LinearLayout(this); + ll.setOrientation(LinearLayout.VERTICAL); + ll.setPadding(padding, padding, padding, padding); + ll.setGravity(Gravity.CENTER); + + LinearLayout.LayoutParams ll_param = new LinearLayout.LayoutParams( + ViewGroup.LayoutParams.WRAP_CONTENT, + ViewGroup.LayoutParams.WRAP_CONTENT); + ll_param.gravity = Gravity.CENTER; + TextView tv = new TextView(this); + tv.setText("Extracting game data..."); + tv.setLayoutParams(ll_param); + + ll_param = new LinearLayout.LayoutParams( + display_metrics.widthPixels, + LinearLayout.LayoutParams.WRAP_CONTENT); + ll_param.gravity = Gravity.CENTER; + ll.setLayoutParams(ll_param); + + m_progress_bar = new ProgressBar(this, null, + android.R.attr.progressBarStyleHorizontal); + m_progress_bar.setIndeterminate(false); + m_progress_bar.setPadding(0, padding, 0, padding); + m_progress_bar.setLayoutParams(ll_param); + ll.addView(tv); + ll.addView(m_progress_bar); + + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setCancelable(false); + builder.setView(ll); + + m_progress_dialog = builder.create(); + m_progress_dialog.show(); + Window window = m_progress_dialog.getWindow(); + if (window != null) + { + WindowManager.LayoutParams layout_params = + new WindowManager.LayoutParams(); + layout_params.copyFrom( + m_progress_dialog.getWindow().getAttributes()); + layout_params.width = WindowManager.LayoutParams.MATCH_PARENT; + layout_params.height = LinearLayout.LayoutParams.WRAP_CONTENT; + m_progress_dialog.getWindow().setAttributes(layout_params); + } + } + // ------------------------------------------------------------------------ private void hideKeyboardNative(final boolean clear_text) { if (m_stk_edittext == null) @@ -90,6 +161,8 @@ public class SuperTuxKartActivity extends SDLActivity public void onCreate(Bundle instance) { super.onCreate(instance); + m_progress_dialog = null; + m_progress_bar = null; m_bottom_y = 0; final View root = getWindow().getDecorView().findViewById( android.R.id.content); @@ -252,4 +325,57 @@ public class SuperTuxKartActivity extends SDLActivity return getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK; } + // ------------------------------------------------------------------------ + public void showExtractProgress(final int progress) + { + runOnUiThread(new Runnable() + { + @Override + public void run() + { + if (progress == -1) + { + if (m_progress_dialog != null) + { + m_progress_dialog.dismiss(); + m_progress_dialog = null; + m_progress_bar = null; + } + AlertDialog.Builder error = + new AlertDialog.Builder(SDL.getContext()); + error.setMessage("Check remaining device space or " + + "reinstall SuperTuxKart."); + error.setTitle("Extract game data error"); + error.setPositiveButton("Exit", + new DialogInterface.OnClickListener() + { + @Override + public void onClick(DialogInterface dialog, + int id) + { + android.os.Process.killProcess( + android.os.Process.myPid()); + } + }); + error.setCancelable(false); + error.create().show(); + return; + } + if (progress == 0 && m_progress_dialog == null) + showExtractProgressPrivate(); + else if (progress == 100 && m_progress_dialog != null) + { + m_progress_dialog.dismiss(); + m_progress_dialog = null; + m_progress_bar = null; + } + else if (m_progress_bar != null && + m_progress_bar.getProgress() != progress) + { + m_progress_bar.setProgress(progress); + } + } + }); + + } } diff --git a/src/io/assets_android.cpp b/src/io/assets_android.cpp index ce8a21522..3a304090b 100644 --- a/src/io/assets_android.cpp +++ b/src/io/assets_android.cpp @@ -19,7 +19,6 @@ #include "io/assets_android.hpp" #include "io/file_manager.hpp" #include "utils/log.hpp" -#include "utils/progress_bar_android.hpp" #include #include @@ -28,7 +27,7 @@ #ifdef ANDROID #include #include - +#include #endif //----------------------------------------------------------------------------- @@ -37,7 +36,6 @@ AssetsAndroid::AssetsAndroid(FileManager* file_manager) { m_file_manager = file_manager; - m_progress_bar = NULL; } //----------------------------------------------------------------------------- @@ -227,17 +225,20 @@ void AssetsAndroid::init() { if (hasAssets()) { - m_progress_bar = new ProgressBarAndroid(); - m_progress_bar->draw(0.01f); + setProgressBar(0); removeData(); extractData(); - + if (!m_file_manager->fileExists(m_stk_dir + "/.extracted")) { - Log::fatal("AssetsAndroid", "Fatal error: Assets were not " + Log::error("AssetsAndroid", "Fatal error: Assets were not " "extracted properly"); + setProgressBar(-1); + // setProgressBar(-1) will show the error dialog and the + // android ui thread will exit stk + while (true) + StkTime::sleep(1); } - delete m_progress_bar; } } @@ -304,14 +305,9 @@ void AssetsAndroid::extractData() assert(lines_count > 0); float pos = 0.01f + (float)(current_line) / lines_count * 0.99f; - m_progress_bar->draw(pos); + setProgressBar(pos * 100.0f); current_line++; - if (m_progress_bar->closeEventReceived()) - { - success = false; - } - if (!success) break; } @@ -329,10 +325,61 @@ void AssetsAndroid::extractData() if (success) { touchFile(m_stk_dir + "/.extracted"); + // Dismiss android dialog + setProgressBar(100); } #endif } +//----------------------------------------------------------------------------- +/** A function set progress bar using java JNI + * \param progress progress 0-100 + */ +void AssetsAndroid::setProgressBar(int progress) +{ +#ifdef ANDROID + JNIEnv* env = (JNIEnv*)SDL_AndroidGetJNIEnv(); + if (env == NULL) + { + Log::error("AssetsAndroid", + "setProgressBar unable to SDL_AndroidGetJNIEnv."); + return; + } + + jobject native_activity = (jobject)SDL_AndroidGetActivity(); + if (native_activity == NULL) + { + Log::error("AssetsAndroid", + "setProgressBar unable to SDL_AndroidGetActivity."); + return; + } + + jclass class_native_activity = env->GetObjectClass(native_activity); + if (class_native_activity == NULL) + { + Log::error("AssetsAndroid", + "setProgressBar unable to find object class."); + env->DeleteLocalRef(native_activity); + return; + } + + jmethodID method_id = env->GetMethodID(class_native_activity, + "showExtractProgress", "(I)V"); + if (method_id == NULL) + { + Log::error("AssetsAndroid", + "setProgressBar unable to find method id."); + env->DeleteLocalRef(class_native_activity); + env->DeleteLocalRef(native_activity); + return; + } + + env->CallVoidMethod(native_activity, method_id, progress); + env->DeleteLocalRef(class_native_activity); + env->DeleteLocalRef(native_activity); +#endif +} + //----------------------------------------------------------------------------- /** A function that extracts selected file or directory from apk file * \param dir_name Directory to extract from assets diff --git a/src/io/assets_android.hpp b/src/io/assets_android.hpp index 5f0caacca..290ac18ea 100644 --- a/src/io/assets_android.hpp +++ b/src/io/assets_android.hpp @@ -21,13 +21,11 @@ #include class FileManager; -class ProgressBarAndroid; class AssetsAndroid { private: FileManager* m_file_manager; - ProgressBarAndroid* m_progress_bar; std::string m_stk_dir; void extractData(); @@ -37,7 +35,7 @@ private: void touchFile(std::string path); bool isWritable(std::string path); std::string getPreferredPath(const std::vector& paths); - + void setProgressBar(int progress); public: AssetsAndroid(FileManager* file_manager); ~AssetsAndroid() {};