Update UI callback with prefs listener

This commit is contained in:
topjohnwu 2016-09-27 22:57:20 +08:00
parent 835ef01a70
commit e73497e4b7
13 changed files with 160 additions and 197 deletions

View File

@ -63,7 +63,7 @@ public class AutoRootFragment extends ListFragment {
super.onResume();
initializeElements();
super.onResume();
getActivity().setTitle(R.string.auto_toggle_apps);
getActivity().setTitle(R.string.auto_toggle);
}

View File

@ -211,7 +211,7 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
navFragment = new RootFragment();
break;
case R.id.autoroot:
setTitle(R.string.auto_toggle_apps);
setTitle(R.string.auto_toggle);
tag = "autoroot";
navFragment = new AutoRootFragment();
break;

View File

@ -1,37 +1,22 @@
package com.topjohnwu.magisk;
import android.animation.Animator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.AsyncTask;
import android.preference.PreferenceManager;
import android.support.v7.app.AlertDialog;
import android.support.design.widget.Snackbar;
import android.support.v7.widget.RecyclerView;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.WindowManager;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.topjohnwu.magisk.module.Module;
import com.topjohnwu.magisk.receivers.DownloadReceiver;
import com.topjohnwu.magisk.utils.Async;
import com.topjohnwu.magisk.utils.Shell;
import com.topjohnwu.magisk.utils.Utils;
import com.topjohnwu.magisk.utils.WebWindow;
import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import butterknife.BindView;
@ -39,28 +24,44 @@ import butterknife.ButterKnife;
public class ModulesAdapter extends RecyclerView.Adapter<ModulesAdapter.ViewHolder> {
//@BindView(R.id.expand_layout) LinearLayout expandedLayout;
private final List<Module> mList;
private View viewMain;
private View mView;
private Context context;
private final Utils.ItemClickListener chboxListener;
private final Utils.ItemClickListener deleteBtnListener;
private final Utils.ItemClickListener unDeleteBtnListener;
public ModulesAdapter(List<Module> list, Utils.ItemClickListener chboxListener, Utils.ItemClickListener deleteBtnListener, Utils.ItemClickListener undeleteBtnListener) {
this.mList = list;
this.chboxListener = chboxListener;
this.deleteBtnListener = deleteBtnListener;
this.unDeleteBtnListener = undeleteBtnListener;
private Utils.ItemClickListener chboxListener, deleteBtnListener, unDeleteBtnListener;
public ModulesAdapter(List<Module> list) {
mList = list;
chboxListener = (chk, position) -> {
// On Checkbox change listener
CheckBox chbox = (CheckBox) chk;
if (!chbox.isChecked()) {
mList.get(position).createDisableFile();
Snackbar.make(mView, R.string.disable_file_created, Snackbar.LENGTH_SHORT).show();
} else {
mList.get(position).removeDisableFile();
Snackbar.make(mView, R.string.disable_file_removed, Snackbar.LENGTH_SHORT).show();
}
};
deleteBtnListener = (deleteBtn, position) -> {
// On delete button click listener
mList.get(position).createRemoveFile();
Snackbar.make(mView, R.string.remove_file_created, Snackbar.LENGTH_SHORT).show();
};
unDeleteBtnListener = (undeleteBtn, position) -> {
// On undelete button click listener
mList.get(position).deleteRemoveFile();
Snackbar.make(mView, R.string.remove_file_deleted, Snackbar.LENGTH_SHORT).show();
};
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
viewMain = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_module, parent, false);
mView = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_module, parent, false);
context = parent.getContext();
ButterKnife.bind(this, viewMain);
return new ViewHolder(viewMain);
ButterKnife.bind(this, mView);
return new ViewHolder(mView);
}
@Override

View File

@ -12,17 +12,17 @@ import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.TextView;
import com.ipaulpro.afilechooser.FileInfo;
import com.ipaulpro.afilechooser.utils.FileUtils;
import com.topjohnwu.magisk.module.Module;
import com.topjohnwu.magisk.utils.Async;
import com.topjohnwu.magisk.utils.Logger;
import com.topjohnwu.magisk.utils.Utils;
import java.util.ArrayList;
import java.util.List;
@ -40,15 +40,17 @@ public class ModulesFragment extends Fragment {
private SharedPreferences prefs;
public static List<Module> listModules = new ArrayList<>();
private View viewMain;
private View mView;
private SharedPreferences.OnSharedPreferenceChangeListener listener;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
viewMain = inflater.inflate(R.layout.modules_fragment, container, false);
ButterKnife.bind(this, viewMain);
mView = inflater.inflate(R.layout.modules_fragment, container, false);
ButterKnife.bind(this, mView);
mSwipeRefreshLayout.setRefreshing(true);
fabio.setOnClickListener(v -> {
Intent getContentIntent = FileUtils.createGetContentIntent(null);
getContentIntent.setType("application/zip");
@ -60,21 +62,24 @@ public class ModulesFragment extends Fragment {
mSwipeRefreshLayout.setOnRefreshListener(() -> {
recyclerView.setVisibility(View.GONE);
new Async.LoadModules(getActivity()).executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
new UpdateUI().executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
prefs.edit().putBoolean("ignoreUpdateAlerts", false).apply();
prefs.edit().putBoolean("module_done", false).apply();
new Async.LoadModules(getActivity()).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
});
prefs.registerOnSharedPreferenceChangeListener((sharedPreferences, s) -> {
if (s.contains("updated")) {
viewMain.invalidate();
viewMain.requestLayout();
if (prefs.getBoolean("module_done", false)) {
updateUI();
}
listener = (pref, s) -> {
if (s.equals("module_done")) {
if (pref.getBoolean(s, false)) {
Logger.dh("ModulesFragment: UI refresh triggered");
updateUI();
}
}
});
};
new UpdateUI().executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
return viewMain;
return mView;
}
@Override
@ -82,14 +87,8 @@ public class ModulesFragment extends Fragment {
if (data != null) {
// Get the URI of the selected file
final Uri uri = data.getData();
try {
// Get the file path from the URI
new Async.FlashZIP(getActivity(), uri).executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
FileInfo fileInfo = FileUtils.getFileInfo(getActivity(), uri);
} catch (Exception e) {
Log.e("FileSelectorTestAc...", "File select error", e);
}
// Get the file path from the URI
new Async.FlashZIP(getActivity(), uri).executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
}
}
@ -97,52 +96,26 @@ public class ModulesFragment extends Fragment {
@Override
public void onResume() {
super.onResume();
viewMain = this.getView();
getActivity().setTitle("Modules");
mView = this.getView();
getActivity().setTitle(R.string.modules);
prefs.registerOnSharedPreferenceChangeListener(listener);
}
private class UpdateUI extends AsyncTask<Void, Void, Void> {
// Just for blocking
@Override
protected Void doInBackground(Void... voids) {
return null;
}
@Override
protected void onPostExecute(Void v) {
super.onPostExecute(v);
if (listModules.size() == 0) {
emptyTv.setVisibility(View.VISIBLE);
recyclerView.setVisibility(View.GONE);
} else {
recyclerView.setVisibility(View.VISIBLE);
}
recyclerView.setAdapter(new ModulesAdapter(listModules, (chk, position) -> {
// On Checkbox change listener
CheckBox chbox = (CheckBox) chk;
if (!chbox.isChecked()) {
listModules.get(position).createDisableFile();
Snackbar.make(viewMain, R.string.disable_file_created, Snackbar.LENGTH_SHORT).show();
} else {
listModules.get(position).removeDisableFile();
Snackbar.make(viewMain, R.string.disable_file_removed, Snackbar.LENGTH_SHORT).show();
}
}, (deleteBtn, position) -> {
// On delete button click listener
listModules.get(position).createRemoveFile();
Snackbar.make(viewMain, R.string.remove_file_created, Snackbar.LENGTH_SHORT).show();
}, (undeleteBtn, position) -> {
// On undelete button click listener
listModules.get(position).deleteRemoveFile();
Snackbar.make(viewMain, R.string.remove_file_deleted, Snackbar.LENGTH_SHORT).show();
}));
mSwipeRefreshLayout.setRefreshing(false);
@Override
public void onDestroy() {
super.onDestroy();
prefs.unregisterOnSharedPreferenceChangeListener(listener);
}
private void updateUI() {
if (listModules.size() == 0) {
emptyTv.setVisibility(View.VISIBLE);
recyclerView.setVisibility(View.GONE);
} else {
recyclerView.setVisibility(View.VISIBLE);
recyclerView.setAdapter(new ModulesAdapter(listModules));
}
mSwipeRefreshLayout.setRefreshing(false);
}
}

View File

@ -1,7 +1,7 @@
package com.topjohnwu.magisk;
import android.app.Fragment;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.os.Bundle;
import android.preference.PreferenceManager;
@ -16,14 +16,10 @@ import android.view.ViewGroup;
import android.widget.TextView;
import com.topjohnwu.magisk.module.Repo;
import com.topjohnwu.magisk.module.RepoHelper;
import com.topjohnwu.magisk.utils.Async;
import com.topjohnwu.magisk.utils.Logger;
import com.topjohnwu.magisk.utils.Utils;
import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import butterknife.BindView;
@ -32,37 +28,51 @@ import butterknife.ButterKnife;
public class ReposFragment extends Fragment {
public static List<Repo> mListRepos = new ArrayList<>();
public static List<Repo> mListReposToUpdate = new ArrayList<>();
@BindView(R.id.recyclerView)
RecyclerView recyclerView;
@BindView(R.id.empty_rv)
TextView emptyTv;
@BindView(R.id.swipeRefreshLayout)
SwipeRefreshLayout swipeRefreshLayout;
@BindView(R.id.recyclerView) RecyclerView recyclerView;
@BindView(R.id.empty_rv) TextView emptyTv;
@BindView(R.id.swipeRefreshLayout) SwipeRefreshLayout mSwipeRefreshLayout;
private View mView;
private boolean mCanUpdate;
private boolean alertUpdate;
private boolean ignoreAlertUpdate;
private String alertPackage;
private AlertDialog.Builder builder;
// private SharedPreferences prefs;
private SharedPreferences.OnSharedPreferenceChangeListener listener;
private SharedPreferences prefs;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.repos_fragment, container, false);
mView = view;
ButterKnife.bind(this, view);
swipeRefreshLayout.setOnRefreshListener(() -> {
new Async.LoadRepos(getActivity()).executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
new UpdateUI().executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
ignoreAlertUpdate = false;
mView = inflater.inflate(R.layout.repos_fragment, container, false);
ButterKnife.bind(this, mView);
mSwipeRefreshLayout.setRefreshing(true);
prefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
mSwipeRefreshLayout.setOnRefreshListener(() -> {
recyclerView.setVisibility(View.GONE);
prefs.edit().putBoolean("repo_done", false).apply();
new Async.LoadRepos(getActivity()).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
});
if (prefs.getBoolean("repo_done", false)) {
updateUI();
}
listener = (pref, s) -> {
if (s.equals("repo_done")) {
if (pref.getBoolean(s, false)) {
Logger.dh("ReposFragment: UI refresh triggered");
updateUI();
}
}
};
//LoadRepo(false);
new UpdateUI().executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
setHasOptionsMenu(false);
alertUpdate = false;
// if (mListRepos.size() == 0) {
// emptyTv.setVisibility(View.VISIBLE);
// recyclerView.setVisibility(View.GONE);
@ -71,18 +81,18 @@ public class ReposFragment extends Fragment {
//CheckForUpdates();
//recyclerView.setAdapter(new ReposAdapter(this, mListRepos));
return view;
return mView;
}
private void CheckForUpdates() {
for (int i = 0; i < mListRepos.size(); i++) {
if (mListRepos.get(i).canUpdate()) {
alertUpdate = true;
mListReposToUpdate.add(mListRepos.get(i));
}
}
}
// private void CheckForUpdates() {
// for (int i = 0; i < mListRepos.size(); i++) {
// if (mListRepos.get(i).canUpdate()) {
// alertUpdate = true;
// mListReposToUpdate.add(mListRepos.get(i));
//
// }
// }
// }
@Override
public void onAttachFragment(Fragment childFragment) {
@ -154,52 +164,25 @@ public class ReposFragment extends Fragment {
@Override
public void onResume() {
super.onResume();
//LoadRepo(false);
getActivity().setTitle("Magisk");
getActivity().setTitle(R.string.downloads);
prefs.registerOnSharedPreferenceChangeListener(listener);
}
private class UpdateUI extends AsyncTask<Void, Void, Void> {
@Override
protected Void doInBackground(Void... voids) {
return null;
}
@Override
public void onDestroy() {
super.onDestroy();
prefs.unregisterOnSharedPreferenceChangeListener(listener);
}
@Override
protected void onPostExecute(Void v) {
super.onPostExecute(v);
if (mListRepos.size() == 0) {
emptyTv.setVisibility(View.VISIBLE);
recyclerView.setVisibility(View.GONE);
}
Log.d("Magisk", "ReposFragment: ListRepos size is " + mListRepos.size());
private void updateUI() {
if (mListRepos.size() == 0) {
emptyTv.setVisibility(View.VISIBLE);
recyclerView.setVisibility(View.GONE);
} else {
recyclerView.setVisibility(View.VISIBLE);
recyclerView.setAdapter(new ReposAdapter(mListRepos));
if (swipeRefreshLayout.isRefreshing()) {
swipeRefreshLayout.setRefreshing(false);
//CheckForUpdates();
//NotifyOfAlerts();
}
}
mSwipeRefreshLayout.setRefreshing(false);
}
// private void UpdateUI() {
// Log.d("Magisk", "ReposFragment: UpdateUI Called, size is " + mListRepos.size());
//
// if (mListRepos.size() == 0) {
// emptyTv.setVisibility(View.VISIBLE);
// recyclerView.setVisibility(View.GONE);
//
// }
// Log.d("Magisk", "ReposFragment: ListRepos size is " + mListRepos.size());
// recyclerView.setAdapter(new ReposAdapter(this, mListRepos));
// if (swipeRefreshLayout.isRefreshing()) {
// swipeRefreshLayout.setRefreshing(false);
// CheckForUpdates();
// //NotifyOfAlerts();
// }
//
// }
}

View File

@ -66,8 +66,13 @@ public class SplashActivity extends AppCompatActivity {
// Initialize
Utils.init(this);
defaultPrefs.edit()
.putBoolean("module_done", false)
.putBoolean("repo_done", false)
.apply();
new Async.CheckUpdates(this).executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
new Async.LoadModules(this).executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
new Async.LoadModules(this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
new Async.LoadRepos(this).executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
new Async.BusyboxEnv(this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);

View File

@ -1,6 +1,7 @@
package com.topjohnwu.magisk.module;
import com.topjohnwu.magisk.utils.Logger;
import com.topjohnwu.magisk.utils.RepoHelper;
import com.topjohnwu.magisk.utils.Utils;
public class Module extends BaseModule {

View File

@ -1,40 +1,31 @@
package com.topjohnwu.magisk.utils;
import android.app.ProgressDialog;
import android.content.ContentResolver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Environment;
import android.preference.PreferenceManager;
import android.renderscript.ScriptGroup;
import android.support.v7.app.AlertDialog;
import android.util.Log;
import android.widget.Toast;
import com.ipaulpro.afilechooser.FileInfo;
import com.ipaulpro.afilechooser.utils.FileUtils;
import com.topjohnwu.magisk.ModulesFragment;
import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.ReposFragment;
import com.topjohnwu.magisk.module.Module;
import com.topjohnwu.magisk.module.RepoHelper;
import com.topjohnwu.magisk.receivers.DownloadReceiver;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Collections;
import java.util.List;
@ -157,6 +148,11 @@ public class Async {
return null;
}
@Override
protected void onPostExecute(Void v) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mContext);
prefs.edit().putBoolean("module_done", true).apply();
}
}
public static class LoadRepos extends AsyncTask<Void, Void, Void> {
@ -176,11 +172,16 @@ public class Async {
return null;
}
@Override
protected void onPostExecute(Void v) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mContext);
prefs.edit().putBoolean("repo_done", true).apply();
}
}
public static class FlashZIP extends AsyncTask<Void, Void, Boolean> {
private String mPath, mName;
private String mName;
private Uri mUri;
private ProgressDialog progress;
private File mFile, sdFile;
@ -282,7 +283,7 @@ public class Async {
if (sdFile == null) {
Toast.makeText(mContext, mContext.getString(R.string.install_error), Toast.LENGTH_LONG).show();
} else {
Toast.makeText(mContext, mContext.getString(R.string.manual_install, mPath), Toast.LENGTH_LONG).show();
Toast.makeText(mContext, mContext.getString(R.string.manual_install, mFile.getAbsolutePath()), Toast.LENGTH_LONG).show();
}
return;
}

View File

@ -1,4 +1,4 @@
package com.topjohnwu.magisk.module;
package com.topjohnwu.magisk.utils;
import android.content.Context;
import android.content.SharedPreferences;
@ -7,6 +7,8 @@ import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.topjohnwu.magisk.ModulesFragment;
import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.module.Module;
import com.topjohnwu.magisk.module.Repo;
import com.topjohnwu.magisk.utils.Utils;
import com.topjohnwu.magisk.utils.WebRequest;

View File

@ -82,10 +82,10 @@
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@id/title"
android:layout_alignParentEnd="true"
android:layout_alignParentTop="true"
android:orientation="horizontal"
android:paddingTop="20dp">
android:gravity="end">
<CheckBox

View File

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.SwipeRefreshLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/swipeRefreshLayout"
@ -10,7 +9,8 @@
android:orientation="vertical">
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/llayout"
android:layout_width="match_parent"
@ -47,9 +47,7 @@
android:baselineAlignBottom="false"
android:clickable="true"
android:src="@drawable/ic_add"
app:layout_anchorGravity="bottom|center_horizontal"
app:layout_anchor="@+id/empty_rv"
android:layout_gravity="top|center_horizontal" />
android:layout_gravity="bottom|center_horizontal" />
</android.support.design.widget.CoordinatorLayout>

View File

@ -18,7 +18,7 @@
<item
android:id="@+id/autoroot"
android:icon="@drawable/ic_autoroot"
android:title="@string/auto_toggle_apps"/>
android:title="@string/auto_toggle"/>
<item
android:id="@+id/modules"

View File

@ -7,7 +7,9 @@
<string name="navigation_drawer_open">Open navigation drawer</string>
<string name="navigation_drawer_close">Close navigation drawer</string>
<string name="root">Root</string>
<string name="auto_toggle">Auto-toggle</string>
<string name="modules">Modules</string>
<string name="downloads">Downloads</string>
<string name="log">Log</string>
<!--Magisk Fragment-->
@ -104,7 +106,6 @@
<!--Web Related-->
<string name="pass">MagiskRox666</string>
<string name="some_string">GTYybRBTYf5his9kQ16ZNO7qgkBJ/5MyVe4CGceAOIoXgSnnk8FTd4F1dE9p5Eus</string>
<string name="downloads">Downloads</string>
<string name="url_main">https://api.github.com/orgs/Magisk-Modules-Repo/repos?access_token=</string>
<string name="file_url">https://raw.githubusercontent.com/Magisk-Modules-Repo/%1$s/master/%2$s</string>
<string name="zip_url">https://github.com/Magisk-Modules-Repo/%1$s/archive/master.zip</string>
@ -124,8 +125,6 @@
<string name="settings_hide_root_notification_title">Hide auto-toggle notifications</string>
<!--General Use -->
<string name="auto_toggle">Auto-toggle</string>
<string name="auto_toggle_apps">Auto-toggle List</string>
<string name="toast_error_makedir">Error creating directory, could not download file.</string>
<string name="toast_error_removing_files">Error removing old files, cancelled.</string>
<string name="settings_general_title">General</string>