Use native android progress bar for extraction

This commit is contained in:
Benau 2020-07-13 11:04:36 +08:00
parent d8beb5bdb6
commit 097359fcf4
3 changed files with 188 additions and 17 deletions

View File

@ -2,9 +2,13 @@ package org.supertuxkart.stk_dbg;
import org.supertuxkart.stk_dbg.STKEditText; import org.supertuxkart.stk_dbg.STKEditText;
import org.libsdl.app.SDLActivity; 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.ActivityNotFoundException;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.content.res.Configuration; import android.content.res.Configuration;
@ -12,15 +16,26 @@ import android.graphics.Rect;
import android.net.Uri; import android.net.Uri;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.os.Process;
import android.text.Editable; import android.text.Editable;
import android.text.TextWatcher; import android.text.TextWatcher;
import android.view.Display;
import android.view.Gravity;
import android.view.inputmethod.InputMethodManager; import android.view.inputmethod.InputMethodManager;
import android.view.KeyEvent; import android.view.KeyEvent;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.ViewGroup;
import android.view.ViewGroup.MarginLayoutParams; import android.view.ViewGroup.MarginLayoutParams;
import android.view.ViewTreeObserver.OnGlobalLayoutListener; import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.view.View; import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.view.WindowManager.LayoutParams;
import android.widget.FrameLayout; import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.util.DisplayMetrics;
import java.util.Set; import java.util.Set;
@ -31,6 +46,8 @@ import org.minidns.record.TXT;
public class SuperTuxKartActivity extends SDLActivity public class SuperTuxKartActivity extends SDLActivity
{ {
private AlertDialog m_progress_dialog;
private ProgressBar m_progress_bar;
private STKEditText m_stk_edittext; private STKEditText m_stk_edittext;
private int m_bottom_y; private int m_bottom_y;
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
@ -40,6 +57,60 @@ public class SuperTuxKartActivity extends SDLActivity
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
private native static void addDNSSrvRecords(String name, int weight); 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) private void hideKeyboardNative(final boolean clear_text)
{ {
if (m_stk_edittext == null) if (m_stk_edittext == null)
@ -90,6 +161,8 @@ public class SuperTuxKartActivity extends SDLActivity
public void onCreate(Bundle instance) public void onCreate(Bundle instance)
{ {
super.onCreate(instance); super.onCreate(instance);
m_progress_dialog = null;
m_progress_bar = null;
m_bottom_y = 0; m_bottom_y = 0;
final View root = getWindow().getDecorView().findViewById( final View root = getWindow().getDecorView().findViewById(
android.R.id.content); android.R.id.content);
@ -252,4 +325,57 @@ public class SuperTuxKartActivity extends SDLActivity
return getResources().getConfiguration().screenLayout & return getResources().getConfiguration().screenLayout &
Configuration.SCREENLAYOUT_SIZE_MASK; 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);
}
}
});
}
} }

View File

@ -19,7 +19,6 @@
#include "io/assets_android.hpp" #include "io/assets_android.hpp"
#include "io/file_manager.hpp" #include "io/file_manager.hpp"
#include "utils/log.hpp" #include "utils/log.hpp"
#include "utils/progress_bar_android.hpp"
#include <cassert> #include <cassert>
#include <cstdlib> #include <cstdlib>
@ -28,7 +27,7 @@
#ifdef ANDROID #ifdef ANDROID
#include <SDL_system.h> #include <SDL_system.h>
#include <sys/statfs.h> #include <sys/statfs.h>
#include <jni.h>
#endif #endif
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -37,7 +36,6 @@
AssetsAndroid::AssetsAndroid(FileManager* file_manager) AssetsAndroid::AssetsAndroid(FileManager* file_manager)
{ {
m_file_manager = file_manager; m_file_manager = file_manager;
m_progress_bar = NULL;
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -227,17 +225,20 @@ void AssetsAndroid::init()
{ {
if (hasAssets()) if (hasAssets())
{ {
m_progress_bar = new ProgressBarAndroid(); setProgressBar(0);
m_progress_bar->draw(0.01f);
removeData(); removeData();
extractData(); extractData();
if (!m_file_manager->fileExists(m_stk_dir + "/.extracted")) 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"); "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); assert(lines_count > 0);
float pos = 0.01f + (float)(current_line) / lines_count * 0.99f; float pos = 0.01f + (float)(current_line) / lines_count * 0.99f;
m_progress_bar->draw(pos); setProgressBar(pos * 100.0f);
current_line++; current_line++;
if (m_progress_bar->closeEventReceived())
{
success = false;
}
if (!success) if (!success)
break; break;
} }
@ -329,10 +325,61 @@ void AssetsAndroid::extractData()
if (success) if (success)
{ {
touchFile(m_stk_dir + "/.extracted"); touchFile(m_stk_dir + "/.extracted");
// Dismiss android dialog
setProgressBar(100);
} }
#endif #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 /** A function that extracts selected file or directory from apk file
* \param dir_name Directory to extract from assets * \param dir_name Directory to extract from assets

View File

@ -21,13 +21,11 @@
#include <string> #include <string>
class FileManager; class FileManager;
class ProgressBarAndroid;
class AssetsAndroid class AssetsAndroid
{ {
private: private:
FileManager* m_file_manager; FileManager* m_file_manager;
ProgressBarAndroid* m_progress_bar;
std::string m_stk_dir; std::string m_stk_dir;
void extractData(); void extractData();
@ -37,7 +35,7 @@ private:
void touchFile(std::string path); void touchFile(std::string path);
bool isWritable(std::string path); bool isWritable(std::string path);
std::string getPreferredPath(const std::vector<std::string>& paths); std::string getPreferredPath(const std::vector<std::string>& paths);
void setProgressBar(int progress);
public: public:
AssetsAndroid(FileManager* file_manager); AssetsAndroid(FileManager* file_manager);
~AssetsAndroid() {}; ~AssetsAndroid() {};