View binding
This commit is contained in:
parent
f61aadf509
commit
4ee0d48af6
|
|
@ -2,6 +2,9 @@ apply plugin: 'com.android.application'
|
|||
apply plugin: 'com.google.android.gms.oss-licenses-plugin'
|
||||
|
||||
android {
|
||||
viewBinding {
|
||||
enabled = true
|
||||
}
|
||||
compileSdkVersion 28
|
||||
buildToolsVersion "29.0.3"
|
||||
defaultConfig {
|
||||
|
|
|
|||
|
|
@ -6,41 +6,30 @@ import android.content.pm.PackageManager;
|
|||
import android.os.Bundle;
|
||||
import android.text.Html;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.appcompat.app.ActionBar;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
|
||||
import com.google.android.gms.oss.licenses.OssLicensesMenuActivity;
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||
|
||||
import org.meowcat.edxposed.manager.databinding.ActivityAboutBinding;
|
||||
import org.meowcat.edxposed.manager.util.NavUtil;
|
||||
|
||||
public class AboutActivity extends BaseActivity {
|
||||
ActivityAboutBinding binding;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_about);
|
||||
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||
setSupportActionBar(toolbar);
|
||||
toolbar.setNavigationOnClickListener(view -> finish());
|
||||
binding = ActivityAboutBinding.inflate(getLayoutInflater());
|
||||
setContentView(binding.getRoot());
|
||||
setSupportActionBar(binding.appbar.toolbar);
|
||||
binding.appbar.toolbar.setNavigationOnClickListener(view -> finish());
|
||||
ActionBar bar = getSupportActionBar();
|
||||
if (bar != null) {
|
||||
bar.setDisplayHomeAsUpEnabled(true);
|
||||
}
|
||||
setupWindowInsets();
|
||||
View changelogView = findViewById(R.id.changelogView);
|
||||
View licensesView = findViewById(R.id.licensesView);
|
||||
View translatorsView = findViewById(R.id.translatorsView);
|
||||
View sourceCodeView = findViewById(R.id.sourceCodeView);
|
||||
View tgChannelView = findViewById(R.id.tgChannelView);
|
||||
View installerSupportView = findViewById(R.id.installerSupportView);
|
||||
View faqView = findViewById(R.id.faqView);
|
||||
View donateView = findViewById(R.id.donateView);
|
||||
TextView txtModuleSupport = findViewById(R.id.tab_support_module_description);
|
||||
View qqGroupView = findViewById(R.id.qqGroupView);
|
||||
View tgGroupView = findViewById(R.id.tgGroupView);
|
||||
setupWindowInsets(binding.snackbar, binding.nestedScrollView);
|
||||
|
||||
String packageName = getPackageName();
|
||||
String translator = getResources().getString(R.string.translator);
|
||||
|
|
@ -50,9 +39,9 @@ public class AboutActivity extends BaseActivity {
|
|||
final String changes = prefs.getString("changelog", null);
|
||||
|
||||
if (changes == null) {
|
||||
changelogView.setVisibility(View.GONE);
|
||||
binding.changelogView.setVisibility(View.GONE);
|
||||
} else {
|
||||
changelogView.setOnClickListener(v1 -> new MaterialAlertDialogBuilder(this)
|
||||
binding.changelogView.setOnClickListener(v1 -> new MaterialAlertDialogBuilder(this)
|
||||
.setTitle(R.string.changes)
|
||||
.setMessage(Html.fromHtml(changes))
|
||||
.setPositiveButton(android.R.string.ok, null).show());
|
||||
|
|
@ -60,25 +49,25 @@ public class AboutActivity extends BaseActivity {
|
|||
|
||||
try {
|
||||
String version = getPackageManager().getPackageInfo(packageName, 0).versionName;
|
||||
((TextView) findViewById(R.id.app_version)).setText(version);
|
||||
binding.appVersion.setText(version);
|
||||
} catch (PackageManager.NameNotFoundException ignored) {
|
||||
}
|
||||
|
||||
licensesView.setOnClickListener(v12 -> startActivity(new Intent(this, OssLicensesMenuActivity.class)));
|
||||
binding.licensesView.setOnClickListener(v12 -> startActivity(new Intent(this, OssLicensesMenuActivity.class)));
|
||||
|
||||
txtModuleSupport.setText(getString(R.string.support_modules_description,
|
||||
binding.tabSupportModuleDescription.setText(getString(R.string.support_modules_description,
|
||||
getString(R.string.module_support)));
|
||||
|
||||
setupView(installerSupportView, R.string.support_material_xda);
|
||||
setupView(faqView, R.string.support_faq_url);
|
||||
setupView(tgGroupView, R.string.group_telegram_link);
|
||||
setupView(qqGroupView, R.string.group_qq_link);
|
||||
setupView(donateView, R.string.support_donate_url);
|
||||
setupView(sourceCodeView, R.string.about_source);
|
||||
setupView(tgChannelView, R.string.group_telegram_channel_link);
|
||||
setupView(binding.installerSupportView, R.string.support_material_xda);
|
||||
setupView(binding.faqView, R.string.support_faq_url);
|
||||
setupView(binding.tgGroupView, R.string.group_telegram_link);
|
||||
setupView(binding.qqGroupView, R.string.group_qq_link);
|
||||
setupView(binding.donateView, R.string.support_donate_url);
|
||||
setupView(binding.sourceCodeView, R.string.about_source);
|
||||
setupView(binding.tgChannelView, R.string.group_telegram_channel_link);
|
||||
|
||||
if (translator.isEmpty()) {
|
||||
translatorsView.setVisibility(View.GONE);
|
||||
binding.translatorsView.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -86,8 +75,4 @@ public class AboutActivity extends BaseActivity {
|
|||
v.setOnClickListener(v1 -> NavUtil.startURL(this, getString(url)));
|
||||
}
|
||||
|
||||
public void openLink(View view) {
|
||||
NavUtil.startURL(this, view.getTag().toString());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,11 +63,13 @@ public class BaseActivity extends AppCompatActivity {
|
|||
return (configuration.uiMode & Configuration.UI_MODE_NIGHT_YES) > 0;
|
||||
}
|
||||
|
||||
protected void setupWindowInsets() {
|
||||
View rootView = findViewById(R.id.snackbar);
|
||||
protected void setupWindowInsets(View rootView, View secondView) {
|
||||
rootView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
|
||||
ViewCompat.setOnApplyWindowInsetsListener(rootView, (v, insets) -> {
|
||||
rootView.setPadding(insets.getSystemWindowInsetLeft(), insets.getSystemWindowInsetTop(), insets.getSystemWindowInsetRight(), insets.getSystemWindowInsetBottom());
|
||||
if (secondView != null) {
|
||||
secondView.setPadding(0, 0, 0, insets.getSystemWindowInsetBottom());
|
||||
}
|
||||
rootView.setPadding(insets.getSystemWindowInsetLeft(), insets.getSystemWindowInsetTop(), insets.getSystemWindowInsetRight(), insets.getTappableElementInsets().bottom);
|
||||
return insets;
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package org.meowcat.edxposed.manager;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
|
|
@ -8,10 +9,6 @@ import android.text.Html;
|
|||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.Spinner;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
|
@ -21,15 +18,15 @@ import androidx.fragment.app.Fragment;
|
|||
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||
|
||||
import org.meowcat.edxposed.manager.databinding.SingleInstallerViewBinding;
|
||||
import org.meowcat.edxposed.manager.util.NavUtil;
|
||||
import org.meowcat.edxposed.manager.util.json.XposedTab;
|
||||
import org.meowcat.edxposed.manager.util.json.XposedZip;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
public class BaseAdvancedInstaller extends Fragment {
|
||||
private View mClickedButton;
|
||||
SingleInstallerViewBinding binding;
|
||||
|
||||
static BaseAdvancedInstaller newInstance(XposedTab tab) {
|
||||
BaseAdvancedInstaller myFragment = new BaseAdvancedInstaller();
|
||||
|
|
@ -41,75 +38,33 @@ public class BaseAdvancedInstaller extends Fragment {
|
|||
return myFragment;
|
||||
}
|
||||
|
||||
private List<XposedZip> installers() {
|
||||
XposedTab tab = Objects.requireNonNull(getArguments()).getParcelable("tab");
|
||||
return Objects.requireNonNull(tab).installers;
|
||||
}
|
||||
|
||||
private List<XposedZip> uninstallers() {
|
||||
XposedTab tab = Objects.requireNonNull(getArguments()).getParcelable("tab");
|
||||
return Objects.requireNonNull(tab).uninstallers;
|
||||
}
|
||||
|
||||
private String notice() {
|
||||
XposedTab tab = Objects.requireNonNull(getArguments()).getParcelable("tab");
|
||||
return Objects.requireNonNull(tab).notice;
|
||||
}
|
||||
|
||||
protected String author() {
|
||||
XposedTab tab = Objects.requireNonNull(getArguments()).getParcelable("tab");
|
||||
return Objects.requireNonNull(tab).author;
|
||||
}
|
||||
|
||||
private String supportUrl() {
|
||||
XposedTab tab = Objects.requireNonNull(getArguments()).getParcelable("tab");
|
||||
return Objects.requireNonNull(tab).support;
|
||||
}
|
||||
|
||||
protected boolean isStable() {
|
||||
XposedTab tab = Objects.requireNonNull(getArguments()).getParcelable("tab");
|
||||
return Objects.requireNonNull(tab).stable;
|
||||
}
|
||||
|
||||
private boolean isOfficial() {
|
||||
XposedTab tab = Objects.requireNonNull(getArguments()).getParcelable("tab");
|
||||
return Objects.requireNonNull(tab).official;
|
||||
}
|
||||
|
||||
private String description() {
|
||||
XposedTab tab = Objects.requireNonNull(getArguments()).getParcelable("tab");
|
||||
return Objects.requireNonNull(tab).description;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.single_installer_view, container, false);
|
||||
|
||||
final Spinner chooserInstallers = view.findViewById(R.id.chooserInstallers);
|
||||
final Spinner chooserUninstallers = view.findViewById(R.id.chooserUninstallers);
|
||||
final Button btnInstall = view.findViewById(R.id.btnInstall);
|
||||
final Button btnUninstall = view.findViewById(R.id.btnUninstall);
|
||||
ImageView infoInstaller = view.findViewById(R.id.infoInstaller);
|
||||
ImageView infoUninstaller = view.findViewById(R.id.infoUninstaller);
|
||||
TextView noticeTv = view.findViewById(R.id.noticeTv);
|
||||
TextView author = view.findViewById(R.id.author);
|
||||
View showOnXda = view.findViewById(R.id.show_on_xda);
|
||||
View updateDescription = view.findViewById(R.id.updateDescription);
|
||||
TooltipCompat.setTooltipText(infoInstaller, getString(R.string.info));
|
||||
TooltipCompat.setTooltipText(infoUninstaller, getString(R.string.info));
|
||||
Bundle arguments = getArguments();
|
||||
if (arguments == null) {
|
||||
return null;
|
||||
} else if (arguments.getParcelable("tab") == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
XposedTab tab = arguments.getParcelable("tab");
|
||||
|
||||
if (tab == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
binding = SingleInstallerViewBinding.inflate(inflater, container, false);
|
||||
TooltipCompat.setTooltipText(binding.infoInstaller, getString(R.string.info));
|
||||
TooltipCompat.setTooltipText(binding.infoUninstaller, getString(R.string.info));
|
||||
try {
|
||||
chooserInstallers.setAdapter(new XposedZip.MyAdapter(getContext(), installers()));
|
||||
chooserUninstallers.setAdapter(new XposedZip.MyAdapter(getContext(), uninstallers()));
|
||||
binding.chooserInstallers.setAdapter(new XposedZip.MyAdapter(getContext(), tab.installers));
|
||||
binding.chooserUninstallers.setAdapter(new XposedZip.MyAdapter(getContext(), tab.uninstallers));
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
infoInstaller.setOnClickListener(v -> {
|
||||
XposedZip selectedInstaller = (XposedZip) chooserInstallers.getSelectedItem();
|
||||
binding.infoInstaller.setOnClickListener(v -> {
|
||||
XposedZip selectedInstaller = (XposedZip) binding.chooserInstallers.getSelectedItem();
|
||||
String s = getString(R.string.infoInstaller,
|
||||
selectedInstaller.name,
|
||||
selectedInstaller.version);
|
||||
|
|
@ -117,8 +72,8 @@ public class BaseAdvancedInstaller extends Fragment {
|
|||
new MaterialAlertDialogBuilder(Objects.requireNonNull(getContext())).setTitle(R.string.info)
|
||||
.setMessage(s).setPositiveButton(android.R.string.ok, null).show();
|
||||
});
|
||||
infoUninstaller.setOnClickListener(v -> {
|
||||
XposedZip selectedUninstaller = (XposedZip) chooserUninstallers.getSelectedItem();
|
||||
binding.infoUninstaller.setOnClickListener(v -> {
|
||||
XposedZip selectedUninstaller = (XposedZip) binding.chooserUninstallers.getSelectedItem();
|
||||
String s = getString(R.string.infoUninstaller,
|
||||
selectedUninstaller.name,
|
||||
selectedUninstaller.version);
|
||||
|
|
@ -127,59 +82,60 @@ public class BaseAdvancedInstaller extends Fragment {
|
|||
.setMessage(s).setPositiveButton(android.R.string.ok, null).show();
|
||||
});
|
||||
|
||||
btnInstall.setOnClickListener(v -> areYouSure(R.string.warningArchitecture,
|
||||
binding.btnInstall.setOnClickListener(v -> warningArchitecture(
|
||||
(dialog, which) -> {
|
||||
XposedZip selectedInstaller = (XposedZip) chooserInstallers.getSelectedItem();
|
||||
XposedZip selectedInstaller = (XposedZip) binding.chooserInstallers.getSelectedItem();
|
||||
Uri uri = Uri.parse(selectedInstaller.link);
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
|
||||
startActivity(intent);
|
||||
}));
|
||||
|
||||
btnUninstall.setOnClickListener(v -> areYouSure(R.string.warningArchitecture,
|
||||
binding.btnUninstall.setOnClickListener(v -> warningArchitecture(
|
||||
(dialog, which) -> {
|
||||
XposedZip selectedUninstaller = (XposedZip) chooserUninstallers.getSelectedItem();
|
||||
XposedZip selectedUninstaller = (XposedZip) binding.chooserUninstallers.getSelectedItem();
|
||||
Uri uri = Uri.parse(selectedUninstaller.link);
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
|
||||
startActivity(intent);
|
||||
}));
|
||||
|
||||
noticeTv.setText(Html.fromHtml(notice()));
|
||||
author.setText(getString(R.string.download_author, author()));
|
||||
binding.noticeTv.setText(Html.fromHtml(tab.notice));
|
||||
binding.author.setText(getString(R.string.download_author, tab.author));
|
||||
|
||||
try {
|
||||
if (uninstallers().size() == 0) {
|
||||
infoUninstaller.setVisibility(View.GONE);
|
||||
chooserUninstallers.setVisibility(View.GONE);
|
||||
btnUninstall.setVisibility(View.GONE);
|
||||
if (tab.uninstallers.size() == 0) {
|
||||
binding.infoUninstaller.setVisibility(View.GONE);
|
||||
binding.chooserUninstallers.setVisibility(View.GONE);
|
||||
binding.btnUninstall.setVisibility(View.GONE);
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
|
||||
if (!isStable()) {
|
||||
view.findViewById(R.id.warning_unstable).setVisibility(View.VISIBLE);
|
||||
if (!tab.stable) {
|
||||
binding.warningUnstable.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
if (!isOfficial()) {
|
||||
view.findViewById(R.id.warning_unofficial).setVisibility(View.VISIBLE);
|
||||
if (!tab.official) {
|
||||
binding.warningUnofficial.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
showOnXda.setOnClickListener(v -> NavUtil.startURL((AppCompatActivity) getActivity(), supportUrl()));
|
||||
updateDescription.setOnClickListener(v -> new MaterialAlertDialogBuilder(Objects.requireNonNull(getContext()))
|
||||
binding.showOnXda.setOnClickListener(v -> NavUtil.startURL((AppCompatActivity) getActivity(), tab.support));
|
||||
binding.updateDescription.setOnClickListener(v -> new MaterialAlertDialogBuilder(Objects.requireNonNull(getContext()))
|
||||
.setTitle(R.string.changes)
|
||||
.setMessage(Html.fromHtml(description()))
|
||||
.setMessage(Html.fromHtml(tab.description))
|
||||
.setPositiveButton(android.R.string.ok, null).show());
|
||||
|
||||
return view;
|
||||
return binding.getRoot();
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("SameParameterValue")
|
||||
private void areYouSure(int contentTextId, DialogInterface.OnClickListener listener) {
|
||||
new MaterialAlertDialogBuilder(Objects.requireNonNull(getActivity())).setTitle(R.string.areyousure)
|
||||
.setMessage(contentTextId)
|
||||
.setPositiveButton(android.R.string.yes, listener)
|
||||
.setNegativeButton(android.R.string.no, null)
|
||||
.show();
|
||||
private void warningArchitecture(DialogInterface.OnClickListener listener) {
|
||||
Activity activity = getActivity();
|
||||
if (activity != null) {
|
||||
new MaterialAlertDialogBuilder(activity)
|
||||
.setTitle(R.string.areyousure)
|
||||
.setMessage(R.string.warningArchitecture)
|
||||
.setPositiveButton(android.R.string.yes, listener)
|
||||
.setNegativeButton(android.R.string.no, null)
|
||||
.show();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -10,60 +10,56 @@ import androidx.annotation.NonNull;
|
|||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.ActionBar;
|
||||
import androidx.appcompat.widget.SearchView;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.recyclerview.widget.DividerItemDecoration;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
|
||||
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||
|
||||
import org.meowcat.edxposed.manager.adapters.AppAdapter;
|
||||
import org.meowcat.edxposed.manager.adapters.AppHelper;
|
||||
import org.meowcat.edxposed.manager.adapters.BlackListAdapter;
|
||||
import org.meowcat.edxposed.manager.adapters.CompatListAdapter;
|
||||
import org.meowcat.edxposed.manager.databinding.ActivityBlackListBinding;
|
||||
|
||||
public class BlackListActivity extends BaseActivity implements AppAdapter.Callback {
|
||||
private SwipeRefreshLayout mSwipeRefreshLayout;
|
||||
private SearchView mSearchView;
|
||||
private BlackListAdapter mAppAdapter;
|
||||
private SearchView searchView;
|
||||
private CompatListAdapter appAdapter;
|
||||
|
||||
private SearchView.OnQueryTextListener mSearchListener;
|
||||
private SearchView.OnQueryTextListener searchListener;
|
||||
private ActivityBlackListBinding binding;
|
||||
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_black_list);
|
||||
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||
setSupportActionBar(toolbar);
|
||||
toolbar.setNavigationOnClickListener(view -> finish());
|
||||
binding = ActivityBlackListBinding.inflate(getLayoutInflater());
|
||||
setContentView(binding.getRoot());
|
||||
setSupportActionBar(binding.appbar.toolbar);
|
||||
binding.appbar.toolbar.setNavigationOnClickListener(view -> finish());
|
||||
ActionBar bar = getSupportActionBar();
|
||||
if (bar != null) {
|
||||
bar.setDisplayHomeAsUpEnabled(true);
|
||||
}
|
||||
setupWindowInsets();
|
||||
mSwipeRefreshLayout = findViewById(R.id.swipeRefreshLayout);
|
||||
RecyclerView mRecyclerView = findViewById(R.id.recyclerView);
|
||||
|
||||
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
|
||||
final boolean isWhiteListMode = isWhiteListMode();
|
||||
mAppAdapter = new BlackListAdapter(this, isWhiteListMode);
|
||||
mRecyclerView.setAdapter(mAppAdapter);
|
||||
mAppAdapter.setCallback(this);
|
||||
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView.getContext(),
|
||||
setupWindowInsets(binding.snackbar, binding.recyclerView);
|
||||
binding.recyclerView.setLayoutManager(new LinearLayoutManager(this));
|
||||
appAdapter = new CompatListAdapter(this);
|
||||
binding.recyclerView.setAdapter(appAdapter);
|
||||
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(this,
|
||||
DividerItemDecoration.VERTICAL);
|
||||
mRecyclerView.addItemDecoration(dividerItemDecoration);
|
||||
mSwipeRefreshLayout.setRefreshing(true);
|
||||
mSwipeRefreshLayout.setOnRefreshListener(mAppAdapter::refresh);
|
||||
mSearchListener = new SearchView.OnQueryTextListener() {
|
||||
binding.recyclerView.addItemDecoration(dividerItemDecoration);
|
||||
appAdapter.setCallback(this);
|
||||
|
||||
binding.swipeRefreshLayout.setRefreshing(true);
|
||||
binding.swipeRefreshLayout.setOnRefreshListener(appAdapter::refresh);
|
||||
|
||||
searchListener = new SearchView.OnQueryTextListener() {
|
||||
@Override
|
||||
public boolean onQueryTextSubmit(String query) {
|
||||
mAppAdapter.filter(query);
|
||||
appAdapter.filter(query);
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onQueryTextChange(String newText) {
|
||||
mAppAdapter.filter(newText);
|
||||
appAdapter.filter(newText);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
|
@ -72,8 +68,8 @@ public class BlackListActivity extends BaseActivity implements AppAdapter.Callba
|
|||
@Override
|
||||
public boolean onCreateOptionsMenu(@NonNull Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.menu_app_list, menu);
|
||||
mSearchView = (SearchView) menu.findItem(R.id.menu_search).getActionView();
|
||||
mSearchView.setOnQueryTextListener(mSearchListener);
|
||||
searchView = (SearchView) menu.findItem(R.id.menu_search).getActionView();
|
||||
searchView.setOnQueryTextListener(searchListener);
|
||||
return super.onCreateOptionsMenu(menu);
|
||||
}
|
||||
|
||||
|
|
@ -114,9 +110,9 @@ public class BlackListActivity extends BaseActivity implements AppAdapter.Callba
|
|||
|
||||
@Override
|
||||
public void onDataReady() {
|
||||
mSwipeRefreshLayout.setRefreshing(false);
|
||||
String queryStr = mSearchView != null ? mSearchView.getQuery().toString() : "";
|
||||
mAppAdapter.filter(queryStr);
|
||||
binding.swipeRefreshLayout.setRefreshing(false);
|
||||
String queryStr = searchView != null ? searchView.getQuery().toString() : "";
|
||||
appAdapter.filter(queryStr);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -127,10 +123,10 @@ public class BlackListActivity extends BaseActivity implements AppAdapter.Callba
|
|||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
if (mSearchView.isIconified()) {
|
||||
if (searchView.isIconified()) {
|
||||
super.onBackPressed();
|
||||
} else {
|
||||
mSearchView.setIconified(true);
|
||||
searchView.setIconified(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,59 +9,55 @@ import androidx.annotation.NonNull;
|
|||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.ActionBar;
|
||||
import androidx.appcompat.widget.SearchView;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.recyclerview.widget.DividerItemDecoration;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
|
||||
|
||||
import org.meowcat.edxposed.manager.adapters.AppAdapter;
|
||||
import org.meowcat.edxposed.manager.adapters.AppHelper;
|
||||
import org.meowcat.edxposed.manager.adapters.CompatListAdapter;
|
||||
import org.meowcat.edxposed.manager.databinding.ActivityBlackListBinding;
|
||||
|
||||
public class CompatListActivity extends BaseActivity implements AppAdapter.Callback {
|
||||
|
||||
private SwipeRefreshLayout mSwipeRefreshLayout;
|
||||
private SearchView mSearchView;
|
||||
private CompatListAdapter mAppAdapter;
|
||||
private SearchView searchView;
|
||||
private CompatListAdapter appAdapter;
|
||||
|
||||
private SearchView.OnQueryTextListener mSearchListener;
|
||||
private SearchView.OnQueryTextListener searchListener;
|
||||
private ActivityBlackListBinding binding;
|
||||
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_black_list);
|
||||
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||
setSupportActionBar(toolbar);
|
||||
toolbar.setNavigationOnClickListener(view -> finish());
|
||||
binding = ActivityBlackListBinding.inflate(getLayoutInflater());
|
||||
setContentView(binding.getRoot());
|
||||
setSupportActionBar(binding.appbar.toolbar);
|
||||
binding.appbar.toolbar.setNavigationOnClickListener(view -> finish());
|
||||
ActionBar bar = getSupportActionBar();
|
||||
if (bar != null) {
|
||||
bar.setDisplayHomeAsUpEnabled(true);
|
||||
}
|
||||
setupWindowInsets();
|
||||
mSwipeRefreshLayout = findViewById(R.id.swipeRefreshLayout);
|
||||
RecyclerView mRecyclerView = findViewById(R.id.recyclerView);
|
||||
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
|
||||
mAppAdapter = new CompatListAdapter(this);
|
||||
mRecyclerView.setAdapter(mAppAdapter);
|
||||
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView.getContext(),
|
||||
setupWindowInsets(binding.snackbar, binding.recyclerView);
|
||||
binding.recyclerView.setLayoutManager(new LinearLayoutManager(this));
|
||||
appAdapter = new CompatListAdapter(this);
|
||||
binding.recyclerView.setAdapter(appAdapter);
|
||||
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(this,
|
||||
DividerItemDecoration.VERTICAL);
|
||||
mRecyclerView.addItemDecoration(dividerItemDecoration);
|
||||
mAppAdapter.setCallback(this);
|
||||
binding.recyclerView.addItemDecoration(dividerItemDecoration);
|
||||
appAdapter.setCallback(this);
|
||||
|
||||
mSwipeRefreshLayout.setRefreshing(true);
|
||||
mSwipeRefreshLayout.setOnRefreshListener(mAppAdapter::refresh);
|
||||
binding.swipeRefreshLayout.setRefreshing(true);
|
||||
binding.swipeRefreshLayout.setOnRefreshListener(appAdapter::refresh);
|
||||
|
||||
mSearchListener = new SearchView.OnQueryTextListener() {
|
||||
searchListener = new SearchView.OnQueryTextListener() {
|
||||
@Override
|
||||
public boolean onQueryTextSubmit(String query) {
|
||||
mAppAdapter.filter(query);
|
||||
appAdapter.filter(query);
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onQueryTextChange(String newText) {
|
||||
mAppAdapter.filter(newText);
|
||||
appAdapter.filter(newText);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
|
@ -70,16 +66,16 @@ public class CompatListActivity extends BaseActivity implements AppAdapter.Callb
|
|||
@Override
|
||||
public boolean onCreateOptionsMenu(@NonNull Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.menu_app_list, menu);
|
||||
mSearchView = (SearchView) menu.findItem(R.id.menu_search).getActionView();
|
||||
mSearchView.setOnQueryTextListener(mSearchListener);
|
||||
searchView = (SearchView) menu.findItem(R.id.menu_search).getActionView();
|
||||
searchView.setOnQueryTextListener(searchListener);
|
||||
return super.onCreateOptionsMenu(menu);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDataReady() {
|
||||
mSwipeRefreshLayout.setRefreshing(false);
|
||||
String queryStr = mSearchView != null ? mSearchView.getQuery().toString() : "";
|
||||
mAppAdapter.filter(queryStr);
|
||||
binding.swipeRefreshLayout.setRefreshing(false);
|
||||
String queryStr = searchView != null ? searchView.getQuery().toString() : "";
|
||||
appAdapter.filter(queryStr);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -90,10 +86,10 @@ public class CompatListActivity extends BaseActivity implements AppAdapter.Callb
|
|||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
if (mSearchView.isIconified()) {
|
||||
if (searchView.isIconified()) {
|
||||
super.onBackPressed();
|
||||
} else {
|
||||
mSearchView.setIconified(true);
|
||||
searchView.setIconified(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
package org.meowcat.edxposed.manager;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
|
|
@ -8,8 +7,6 @@ import android.content.pm.PackageManager;
|
|||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
|
|
@ -18,6 +15,7 @@ import androidx.appcompat.app.AppCompatDialogFragment;
|
|||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||
import com.topjohnwu.superuser.Shell;
|
||||
|
||||
import org.meowcat.edxposed.manager.databinding.FragmentCompileDialogBinding;
|
||||
import org.meowcat.edxposed.manager.util.ToastUtil;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
|
|
@ -62,11 +60,9 @@ public class CompileDialogFragment extends AppCompatDialogFragment {
|
|||
.setIcon(appInfo.loadIcon(pm))
|
||||
.setTitle(appInfo.loadLabel(pm))
|
||||
.setCancelable(false);
|
||||
@SuppressLint("InflateParams") View customView = LayoutInflater.from(requireContext()).inflate(R.layout.fragment_compile_dialog, null);
|
||||
builder.setView(customView);
|
||||
TextView msgView = customView.findViewById(R.id.message);
|
||||
//ProgressBar progressView = customView.findViewById(R.id.progress);
|
||||
msgView.setText(msg);
|
||||
FragmentCompileDialogBinding binding = FragmentCompileDialogBinding.inflate(LayoutInflater.from(requireContext()), null, false);
|
||||
builder.setView(binding.getRoot());
|
||||
binding.message.setText(msg);
|
||||
AlertDialog alertDialog = builder.create();
|
||||
alertDialog.setCanceledOnTouchOutside(false);
|
||||
return alertDialog;
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@ import androidx.appcompat.app.AppCompatActivity;
|
|||
|
||||
import com.google.android.material.snackbar.Snackbar;
|
||||
|
||||
import org.meowcat.edxposed.manager.databinding.ActivityCrashReportBinding;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
|
@ -22,18 +24,20 @@ import java.util.zip.ZipEntry;
|
|||
import java.util.zip.ZipFile;
|
||||
|
||||
public class CrashReportActivity extends AppCompatActivity {
|
||||
ActivityCrashReportBinding binding;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_crash_report);
|
||||
findViewById(R.id.copyLogs).setOnClickListener(v -> {
|
||||
binding = ActivityCrashReportBinding.inflate(getLayoutInflater());
|
||||
setContentView(binding.getRoot());
|
||||
binding.copyLogs.setOnClickListener(v -> {
|
||||
ClipboardManager clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
|
||||
//Are there any devices without clipboard...?
|
||||
if (clipboard != null) {
|
||||
ClipData clip = ClipData.newPlainText("edcrash", getAllErrorDetailsFromIntent(getIntent()));
|
||||
clipboard.setPrimaryClip(clip);
|
||||
Snackbar.make(findViewById(R.id.snackbar), R.string.copy_toast_msg, Snackbar.LENGTH_SHORT).show();
|
||||
Snackbar.make(binding.snackbar, R.string.copy_toast_msg, Snackbar.LENGTH_SHORT).show();
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -22,17 +22,17 @@ import android.widget.TextView;
|
|||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.ActionBar;
|
||||
import androidx.appcompat.widget.SearchView;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.recyclerview.widget.DividerItemDecoration;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
|
||||
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||
import com.timehop.stickyheadersrecyclerview.StickyRecyclerHeadersAdapter;
|
||||
import com.timehop.stickyheadersrecyclerview.StickyRecyclerHeadersDecoration;
|
||||
|
||||
import org.meowcat.edxposed.manager.adapters.CursorRecyclerViewAdapter;
|
||||
import org.meowcat.edxposed.manager.databinding.ActivityDownloadBinding;
|
||||
import org.meowcat.edxposed.manager.databinding.ItemDownloadBinding;
|
||||
import org.meowcat.edxposed.manager.repo.RepoDb;
|
||||
import org.meowcat.edxposed.manager.repo.RepoDbDefinitions;
|
||||
import org.meowcat.edxposed.manager.util.ModuleUtil;
|
||||
|
|
@ -42,79 +42,73 @@ import java.text.DateFormat;
|
|||
import java.util.Date;
|
||||
|
||||
public class DownloadActivity extends BaseActivity implements RepoLoader.RepoListener, ModuleUtil.ModuleListener, SharedPreferences.OnSharedPreferenceChangeListener {
|
||||
private SharedPreferences mPref;
|
||||
private DownloadsAdapter mAdapter;
|
||||
private String mFilterText;
|
||||
private RepoLoader mRepoLoader;
|
||||
private ModuleUtil mModuleUtil;
|
||||
private int mSortingOrder;
|
||||
private SearchView mSearchView;
|
||||
private SharedPreferences mIgnoredUpdatesPref;
|
||||
private DownloadsAdapter adapter;
|
||||
private String filterText;
|
||||
private RepoLoader repoLoader;
|
||||
private ModuleUtil moduleUtil;
|
||||
private int sortingOrder;
|
||||
private SearchView searchView;
|
||||
private SharedPreferences ignoredUpdatesPref;
|
||||
private boolean changed = false;
|
||||
private BroadcastReceiver connectionListener = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (mRepoLoader != null) {
|
||||
mRepoLoader.triggerReload(true);
|
||||
if (repoLoader != null) {
|
||||
repoLoader.triggerReload(true);
|
||||
}
|
||||
}
|
||||
};
|
||||
private ActivityDownloadBinding binding;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
setContentView(R.layout.activity_download);
|
||||
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||
setSupportActionBar(toolbar);
|
||||
toolbar.setNavigationOnClickListener(view -> finish());
|
||||
binding = ActivityDownloadBinding.inflate(getLayoutInflater());
|
||||
setContentView(binding.getRoot());
|
||||
setSupportActionBar(binding.appbar.toolbar);
|
||||
binding.appbar.toolbar.setNavigationOnClickListener(view -> finish());
|
||||
ActionBar bar = getSupportActionBar();
|
||||
if (bar != null) {
|
||||
bar.setDisplayHomeAsUpEnabled(true);
|
||||
}
|
||||
|
||||
setupWindowInsets();
|
||||
mPref = XposedApp.getPreferences();
|
||||
mRepoLoader = RepoLoader.getInstance();
|
||||
mModuleUtil = ModuleUtil.getInstance();
|
||||
mAdapter = new DownloadsAdapter(this, RepoDb.queryModuleOverview(mSortingOrder, mFilterText));
|
||||
/*mAdapter.setFilterQueryProvider(new FilterQueryProvider() {
|
||||
setupWindowInsets(binding.snackbar, binding.recyclerView);
|
||||
repoLoader = RepoLoader.getInstance();
|
||||
moduleUtil = ModuleUtil.getInstance();
|
||||
adapter = new DownloadsAdapter(this, RepoDb.queryModuleOverview(sortingOrder, filterText));
|
||||
/*adapter.setFilterQueryProvider(new FilterQueryProvider() {
|
||||
@Override
|
||||
public Cursor runQuery(CharSequence constraint) {
|
||||
return RepoDb.queryModuleOverview(mSortingOrder, constraint);
|
||||
return RepoDb.queryModuleOverview(sortingOrder, constraint);
|
||||
}
|
||||
});*/
|
||||
|
||||
mSortingOrder = mPref.getInt("download_sorting_order",
|
||||
RepoDb.SORT_STATUS);
|
||||
sortingOrder = XposedApp.getPreferences().getInt("download_sorting_order", RepoDb.SORT_STATUS);
|
||||
|
||||
mIgnoredUpdatesPref = getSharedPreferences("update_ignored", MODE_PRIVATE);
|
||||
RecyclerView mListView = findViewById(R.id.recyclerView);
|
||||
ignoredUpdatesPref = getSharedPreferences("update_ignored", MODE_PRIVATE);
|
||||
if (Build.VERSION.SDK_INT >= 26) {
|
||||
mListView.setImportantForAutofill(View.IMPORTANT_FOR_AUTOFILL_NO_EXCLUDE_DESCENDANTS);
|
||||
binding.recyclerView.setImportantForAutofill(View.IMPORTANT_FOR_AUTOFILL_NO_EXCLUDE_DESCENDANTS);
|
||||
}
|
||||
final SwipeRefreshLayout refreshLayout = findViewById(R.id.swipeRefreshLayout);
|
||||
refreshLayout.setOnRefreshListener(() -> {
|
||||
mRepoLoader.setSwipeRefreshLayout(refreshLayout);
|
||||
mRepoLoader.triggerReload(true);
|
||||
binding.swipeRefreshLayout.setOnRefreshListener(() -> {
|
||||
repoLoader.setSwipeRefreshLayout(binding.swipeRefreshLayout);
|
||||
repoLoader.triggerReload(true);
|
||||
});
|
||||
mRepoLoader.addListener(this, true);
|
||||
mModuleUtil.addListener(this);
|
||||
mListView.setAdapter(mAdapter);
|
||||
repoLoader.addListener(this, true);
|
||||
moduleUtil.addListener(this);
|
||||
binding.recyclerView.setAdapter(adapter);
|
||||
|
||||
mListView.setLayoutManager(new LinearLayoutManager(this));
|
||||
StickyRecyclerHeadersDecoration headersDecor = new StickyRecyclerHeadersDecoration(mAdapter);
|
||||
mListView.addItemDecoration(headersDecor);
|
||||
mAdapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
|
||||
binding.recyclerView.setLayoutManager(new LinearLayoutManager(this));
|
||||
StickyRecyclerHeadersDecoration headersDecor = new StickyRecyclerHeadersDecoration(adapter);
|
||||
binding.recyclerView.addItemDecoration(headersDecor);
|
||||
adapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
|
||||
@Override
|
||||
public void onChanged() {
|
||||
headersDecor.invalidateHeaders();
|
||||
}
|
||||
});
|
||||
|
||||
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mListView.getContext(),
|
||||
DividerItemDecoration.VERTICAL);
|
||||
mListView.addItemDecoration(dividerItemDecoration);
|
||||
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(this, DividerItemDecoration.VERTICAL);
|
||||
binding.recyclerView.addItemDecoration(dividerItemDecoration);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -122,7 +116,7 @@ public class DownloadActivity extends BaseActivity implements RepoLoader.RepoLis
|
|||
public void onResume() {
|
||||
super.onResume();
|
||||
|
||||
mIgnoredUpdatesPref.registerOnSharedPreferenceChangeListener(this);
|
||||
ignoredUpdatesPref.registerOnSharedPreferenceChangeListener(this);
|
||||
if (changed) {
|
||||
reloadItems();
|
||||
changed = !changed;
|
||||
|
|
@ -142,9 +136,9 @@ public class DownloadActivity extends BaseActivity implements RepoLoader.RepoLis
|
|||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
|
||||
mRepoLoader.removeListener(this);
|
||||
mModuleUtil.removeListener(this);
|
||||
mIgnoredUpdatesPref.unregisterOnSharedPreferenceChangeListener(this);
|
||||
repoLoader.removeListener(this);
|
||||
moduleUtil.removeListener(this);
|
||||
ignoredUpdatesPref.unregisterOnSharedPreferenceChangeListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -152,13 +146,13 @@ public class DownloadActivity extends BaseActivity implements RepoLoader.RepoLis
|
|||
getMenuInflater().inflate(R.menu.menu_download, menu);
|
||||
|
||||
// Setup search button
|
||||
mSearchView = (SearchView) menu.findItem(R.id.menu_search).getActionView();
|
||||
mSearchView.setIconifiedByDefault(true);
|
||||
mSearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
|
||||
searchView = (SearchView) menu.findItem(R.id.menu_search).getActionView();
|
||||
searchView.setIconifiedByDefault(true);
|
||||
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
|
||||
@Override
|
||||
public boolean onQueryTextSubmit(String query) {
|
||||
setFilter(query);
|
||||
mSearchView.clearFocus();
|
||||
searchView.clearFocus();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -172,14 +166,14 @@ public class DownloadActivity extends BaseActivity implements RepoLoader.RepoLis
|
|||
}
|
||||
|
||||
private void setFilter(String filterText) {
|
||||
mFilterText = filterText;
|
||||
this.filterText = filterText;
|
||||
reloadItems();
|
||||
}
|
||||
|
||||
private void reloadItems() {
|
||||
runOnUiThread(() -> {
|
||||
mAdapter.swapCursor(RepoDb.queryModuleOverview(mSortingOrder, mFilterText));
|
||||
mAdapter.notifyDataSetChanged();
|
||||
adapter.swapCursor(RepoDb.queryModuleOverview(sortingOrder, filterText));
|
||||
adapter.notifyDataSetChanged();
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -188,9 +182,9 @@ public class DownloadActivity extends BaseActivity implements RepoLoader.RepoLis
|
|||
if (item.getItemId() == R.id.menu_sort) {
|
||||
new MaterialAlertDialogBuilder(this)
|
||||
.setTitle(R.string.download_sorting_title)
|
||||
.setSingleChoiceItems(R.array.download_sort_order, mSortingOrder, (dialog, which) -> {
|
||||
mSortingOrder = which;
|
||||
mPref.edit().putInt("download_sorting_order", mSortingOrder).apply();
|
||||
.setSingleChoiceItems(R.array.download_sort_order, sortingOrder, (dialog, which) -> {
|
||||
sortingOrder = which;
|
||||
XposedApp.getPreferences().edit().putInt("download_sorting_order", sortingOrder).apply();
|
||||
reloadItems();
|
||||
dialog.dismiss();
|
||||
})
|
||||
|
|
@ -222,23 +216,23 @@ public class DownloadActivity extends BaseActivity implements RepoLoader.RepoLis
|
|||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
if (mSearchView.isIconified()) {
|
||||
if (searchView.isIconified()) {
|
||||
super.onBackPressed();
|
||||
} else {
|
||||
mSearchView.setIconified(true);
|
||||
searchView.setIconified(true);
|
||||
}
|
||||
}
|
||||
|
||||
private class DownloadsAdapter extends CursorRecyclerViewAdapter<DownloadsAdapter.ViewHolder> implements StickyRecyclerHeadersAdapter {
|
||||
private final Context mContext;
|
||||
private final DateFormat mDateFormatter = DateFormat.getDateInstance(DateFormat.SHORT);
|
||||
private final SharedPreferences mPrefs;
|
||||
private final Context context;
|
||||
private final DateFormat dateFormatter = DateFormat.getDateInstance(DateFormat.SHORT);
|
||||
private final SharedPreferences prefs;
|
||||
private String[] sectionHeaders;
|
||||
|
||||
DownloadsAdapter(Context context, Cursor cursor) {
|
||||
super(context, cursor);
|
||||
mContext = context;
|
||||
mPrefs = context.getSharedPreferences("update_ignored", MODE_PRIVATE);
|
||||
this.context = context;
|
||||
prefs = context.getSharedPreferences("update_ignored", MODE_PRIVATE);
|
||||
|
||||
Resources res = context.getResources();
|
||||
sectionHeaders = new String[]{
|
||||
|
|
@ -260,7 +254,7 @@ public class DownloadActivity extends BaseActivity implements RepoLoader.RepoLis
|
|||
long updated = cursor.getLong(RepoDbDefinitions.OverviewColumnsIndexes.UPDATED);
|
||||
boolean isFramework = cursor.getInt(RepoDbDefinitions.OverviewColumnsIndexes.IS_FRAMEWORK) > 0;
|
||||
boolean isInstalled = cursor.getInt(RepoDbDefinitions.OverviewColumnsIndexes.IS_INSTALLED) > 0;
|
||||
boolean updateIgnored = mPrefs.getBoolean(cursor.getString(RepoDbDefinitions.OverviewColumnsIndexes.PKGNAME), false);
|
||||
boolean updateIgnored = prefs.getBoolean(cursor.getString(RepoDbDefinitions.OverviewColumnsIndexes.PKGNAME), false);
|
||||
boolean updateIgnorePreference = XposedApp.getPreferences().getBoolean("ignore_updates", false);
|
||||
boolean hasUpdate = cursor.getInt(RepoDbDefinitions.OverviewColumnsIndexes.HAS_UPDATE) > 0;
|
||||
|
||||
|
|
@ -268,8 +262,8 @@ public class DownloadActivity extends BaseActivity implements RepoLoader.RepoLis
|
|||
hasUpdate = false;
|
||||
}
|
||||
|
||||
if (mSortingOrder != RepoDb.SORT_STATUS) {
|
||||
long timestamp = (mSortingOrder == RepoDb.SORT_UPDATED) ? updated : created;
|
||||
if (sortingOrder != RepoDb.SORT_STATUS) {
|
||||
long timestamp = (sortingOrder == RepoDb.SORT_UPDATED) ? updated : created;
|
||||
long age = System.currentTimeMillis() - timestamp;
|
||||
final long mSecsPerDay = 24 * 60 * 60 * 1000L;
|
||||
if (age < mSecsPerDay)
|
||||
|
|
@ -309,8 +303,8 @@ public class DownloadActivity extends BaseActivity implements RepoLoader.RepoLis
|
|||
@NonNull
|
||||
@Override
|
||||
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_download, parent, false);
|
||||
return new ViewHolder(v);
|
||||
ItemDownloadBinding binding = ItemDownloadBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false);
|
||||
return new ViewHolder(binding);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -322,7 +316,7 @@ public class DownloadActivity extends BaseActivity implements RepoLoader.RepoLis
|
|||
long created = cursor.getLong(RepoDbDefinitions.OverviewColumnsIndexes.CREATED);
|
||||
long updated = cursor.getLong(RepoDbDefinitions.OverviewColumnsIndexes.UPDATED);
|
||||
boolean isInstalled = cursor.getInt(RepoDbDefinitions.OverviewColumnsIndexes.IS_INSTALLED) > 0;
|
||||
boolean updateIgnored = mPrefs.getBoolean(cursor.getString(RepoDbDefinitions.OverviewColumnsIndexes.PKGNAME), false);
|
||||
boolean updateIgnored = prefs.getBoolean(cursor.getString(RepoDbDefinitions.OverviewColumnsIndexes.PKGNAME), false);
|
||||
boolean updateIgnorePreference = XposedApp.getPreferences().getBoolean("ignore_updates", false);
|
||||
boolean hasUpdate = cursor.getInt(RepoDbDefinitions.OverviewColumnsIndexes.HAS_UPDATE) > 0;
|
||||
|
||||
|
|
@ -338,13 +332,13 @@ public class DownloadActivity extends BaseActivity implements RepoLoader.RepoLis
|
|||
|
||||
TextView txtStatus = holder.downloadStatus;
|
||||
if (hasUpdate) {
|
||||
txtStatus.setText(mContext.getString(
|
||||
txtStatus.setText(context.getString(
|
||||
R.string.download_status_update_available,
|
||||
installedVersion, latestVersion));
|
||||
txtStatus.setTextColor(getResources().getColor(R.color.download_status_update_available));
|
||||
txtStatus.setVisibility(View.VISIBLE);
|
||||
} else if (isInstalled) {
|
||||
txtStatus.setText(mContext.getString(
|
||||
txtStatus.setText(context.getString(
|
||||
R.string.download_status_installed, installedVersion));
|
||||
txtStatus.setTextColor(getResources().getColor(R.color.warning));
|
||||
TypedArray typedArray = DownloadActivity.this.getTheme().obtainStyledAttributes(new int[]{android.R.attr.textColorHighlight});
|
||||
|
|
@ -356,8 +350,8 @@ public class DownloadActivity extends BaseActivity implements RepoLoader.RepoLis
|
|||
txtStatus.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
String creationDate = mDateFormatter.format(new Date(created));
|
||||
String updateDate = mDateFormatter.format(new Date(updated));
|
||||
String creationDate = dateFormatter.format(new Date(created));
|
||||
String updateDate = dateFormatter.format(new Date(updated));
|
||||
holder.timestamps.setText(getString(R.string.download_timestamps, creationDate, updateDate));
|
||||
String packageName = cursor.getString(RepoDbDefinitions.OverviewColumnsIndexes.PKGNAME);
|
||||
holder.itemView.setOnClickListener(v -> {
|
||||
|
|
@ -373,12 +367,12 @@ public class DownloadActivity extends BaseActivity implements RepoLoader.RepoLis
|
|||
TextView downloadStatus;
|
||||
TextView timestamps;
|
||||
|
||||
ViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
appName = itemView.findViewById(R.id.title);
|
||||
appDescription = itemView.findViewById(R.id.description);
|
||||
downloadStatus = itemView.findViewById(R.id.downloadStatus);
|
||||
timestamps = itemView.findViewById(R.id.timestamps);
|
||||
ViewHolder(ItemDownloadBinding binding) {
|
||||
super(binding.getRoot());
|
||||
appName = binding.title;
|
||||
appDescription = binding.description;
|
||||
downloadStatus = binding.downloadStatus;
|
||||
timestamps = binding.timestamps;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,18 +11,15 @@ import android.util.Log;
|
|||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.ActionBar;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import androidx.fragment.app.FragmentPagerAdapter;
|
||||
import androidx.viewpager.widget.ViewPager;
|
||||
|
||||
import com.google.android.material.tabs.TabLayout;
|
||||
|
||||
import org.meowcat.edxposed.manager.databinding.ActivityDownloadDetailsBinding;
|
||||
import org.meowcat.edxposed.manager.databinding.ActivityDownloadDetailsNotFoundBinding;
|
||||
import org.meowcat.edxposed.manager.repo.Module;
|
||||
import org.meowcat.edxposed.manager.util.ModuleUtil;
|
||||
import org.meowcat.edxposed.manager.util.RepoLoader;
|
||||
|
|
@ -39,37 +36,37 @@ public class DownloadDetailsActivity extends BaseActivity implements RepoLoader.
|
|||
static final String PLAY_STORE_PACKAGE = "com.android.vending";
|
||||
static final String PLAY_STORE_LINK = "https://play.google.com/store/apps/details?id=%s";
|
||||
private static final String TAG = "DownloadDetailsActivity";
|
||||
private static RepoLoader sRepoLoader = RepoLoader.getInstance();
|
||||
private static ModuleUtil sModuleUtil = ModuleUtil.getInstance();
|
||||
private ViewPager mPager;
|
||||
private String mPackageName;
|
||||
private Module mModule;
|
||||
private ModuleUtil.InstalledModule mInstalledModule;
|
||||
private static RepoLoader repoLoader = RepoLoader.getInstance();
|
||||
private static ModuleUtil moduleUtil = ModuleUtil.getInstance();
|
||||
private String packageName;
|
||||
private Module module;
|
||||
private ModuleUtil.InstalledModule installedModule;
|
||||
private ActivityDownloadDetailsBinding binding;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
|
||||
mPackageName = getModulePackageName();
|
||||
packageName = getModulePackageName();
|
||||
try {
|
||||
mModule = sRepoLoader.getModule(mPackageName);
|
||||
module = repoLoader.getModule(packageName);
|
||||
} catch (Exception e) {
|
||||
Log.i(TAG, "DownloadDetailsActivity -> " + e.getMessage());
|
||||
|
||||
mModule = null;
|
||||
module = null;
|
||||
}
|
||||
|
||||
mInstalledModule = ModuleUtil.getInstance().getModule(mPackageName);
|
||||
installedModule = ModuleUtil.getInstance().getModule(packageName);
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
sRepoLoader.addListener(this, false);
|
||||
sModuleUtil.addListener(this);
|
||||
repoLoader.addListener(this, false);
|
||||
moduleUtil.addListener(this);
|
||||
|
||||
if (mModule != null) {
|
||||
setContentView(R.layout.activity_download_details);
|
||||
if (module != null) {
|
||||
binding = ActivityDownloadDetailsBinding.inflate(getLayoutInflater());
|
||||
setContentView(binding.getRoot());
|
||||
|
||||
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||
setSupportActionBar(toolbar);
|
||||
toolbar.setNavigationOnClickListener(view -> finish());
|
||||
setSupportActionBar(binding.toolbar);
|
||||
binding.toolbar.setNavigationOnClickListener(view -> finish());
|
||||
|
||||
ActionBar ab = getSupportActionBar();
|
||||
|
||||
|
|
@ -81,28 +78,26 @@ public class DownloadDetailsActivity extends BaseActivity implements RepoLoader.
|
|||
|
||||
boolean directDownload = getIntent().getBooleanExtra("direct_download", false);
|
||||
// Updates available => start on the versions page
|
||||
if (mInstalledModule != null && mInstalledModule.isUpdate(sRepoLoader.getLatestVersion(mModule)) || directDownload)
|
||||
mPager.setCurrentItem(DOWNLOAD_VERSIONS);
|
||||
if (installedModule != null && installedModule.isUpdate(repoLoader.getLatestVersion(module)) || directDownload)
|
||||
binding.downloadPager.setCurrentItem(DOWNLOAD_VERSIONS);
|
||||
|
||||
} else {
|
||||
setContentView(R.layout.activity_download_details_not_found);
|
||||
ActivityDownloadDetailsNotFoundBinding binding = ActivityDownloadDetailsNotFoundBinding.inflate(getLayoutInflater());
|
||||
setContentView(binding.getRoot());
|
||||
|
||||
TextView txtMessage = findViewById(android.R.id.message);
|
||||
txtMessage.setText(getResources().getString(R.string.download_details_not_found, mPackageName));
|
||||
binding.message.setText(getResources().getString(R.string.download_details_not_found, packageName));
|
||||
|
||||
findViewById(R.id.reload).setOnClickListener(v -> {
|
||||
binding.reload.setOnClickListener(v -> {
|
||||
v.setEnabled(false);
|
||||
sRepoLoader.triggerReload(true);
|
||||
repoLoader.triggerReload(true);
|
||||
});
|
||||
}
|
||||
setupWindowInsets();
|
||||
setupWindowInsets(binding.snackbar, null);
|
||||
}
|
||||
|
||||
private void setupTabs() {
|
||||
mPager = findViewById(R.id.download_pager);
|
||||
mPager.setAdapter(new SwipeFragmentPagerAdapter(getSupportFragmentManager()));
|
||||
TabLayout mTabLayout = findViewById(R.id.sliding_tabs);
|
||||
mTabLayout.setupWithViewPager(mPager);
|
||||
binding.downloadPager.setAdapter(new SwipeFragmentPagerAdapter(getSupportFragmentManager()));
|
||||
binding.slidingTabs.setupWithViewPager(binding.downloadPager);
|
||||
}
|
||||
|
||||
private String getModulePackageName() {
|
||||
|
|
@ -129,20 +124,20 @@ public class DownloadDetailsActivity extends BaseActivity implements RepoLoader.
|
|||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
sRepoLoader.removeListener(this);
|
||||
sModuleUtil.removeListener(this);
|
||||
repoLoader.removeListener(this);
|
||||
moduleUtil.removeListener(this);
|
||||
}
|
||||
|
||||
public Module getModule() {
|
||||
return mModule;
|
||||
return module;
|
||||
}
|
||||
|
||||
public ModuleUtil.InstalledModule getInstalledModule() {
|
||||
return mInstalledModule;
|
||||
return installedModule;
|
||||
}
|
||||
|
||||
public void gotoPage(int page) {
|
||||
mPager.setCurrentItem(page);
|
||||
binding.downloadPager.setCurrentItem(page);
|
||||
}
|
||||
|
||||
private void reload() {
|
||||
|
|
@ -161,7 +156,7 @@ public class DownloadDetailsActivity extends BaseActivity implements RepoLoader.
|
|||
|
||||
@Override
|
||||
public void onSingleInstalledModuleReloaded(ModuleUtil moduleUtil, String packageName, ModuleUtil.InstalledModule module) {
|
||||
if (packageName.equals(mPackageName))
|
||||
if (this.packageName.equals(packageName))
|
||||
reload();
|
||||
}
|
||||
|
||||
|
|
@ -174,7 +169,7 @@ public class DownloadDetailsActivity extends BaseActivity implements RepoLoader.
|
|||
if (updateIgnorePreference) {
|
||||
SharedPreferences prefs = getSharedPreferences("update_ignored", MODE_PRIVATE);
|
||||
|
||||
boolean ignored = prefs.getBoolean(mModule.packageName, false);
|
||||
boolean ignored = prefs.getBoolean(module.packageName, false);
|
||||
menu.findItem(R.id.ignoreUpdate).setChecked(ignored);
|
||||
} else {
|
||||
menu.removeItem(R.id.ignoreUpdate);
|
||||
|
|
@ -189,10 +184,10 @@ public class DownloadDetailsActivity extends BaseActivity implements RepoLoader.
|
|||
RepoLoader.getInstance().triggerReload(true);
|
||||
return true;
|
||||
case R.id.menu_share:
|
||||
String text = mModule.name + " - ";
|
||||
String text = module.name + " - ";
|
||||
|
||||
if (isPackageInstalled(mPackageName, this)) {
|
||||
String s = getPackageManager().getInstallerPackageName(mPackageName);
|
||||
if (isPackageInstalled(packageName, this)) {
|
||||
String s = getPackageManager().getInstallerPackageName(packageName);
|
||||
boolean playStore;
|
||||
|
||||
try {
|
||||
|
|
@ -202,13 +197,13 @@ public class DownloadDetailsActivity extends BaseActivity implements RepoLoader.
|
|||
}
|
||||
|
||||
if (playStore) {
|
||||
text += String.format(PLAY_STORE_LINK, mPackageName);
|
||||
text += String.format(PLAY_STORE_LINK, packageName);
|
||||
} else {
|
||||
text += String.format(XPOSED_REPO_LINK, mPackageName);
|
||||
text += String.format(XPOSED_REPO_LINK, packageName);
|
||||
}
|
||||
} else {
|
||||
text += String.format(XPOSED_REPO_LINK,
|
||||
mPackageName);
|
||||
packageName);
|
||||
}
|
||||
|
||||
Intent sharingIntent = new Intent(Intent.ACTION_SEND);
|
||||
|
|
@ -219,8 +214,8 @@ public class DownloadDetailsActivity extends BaseActivity implements RepoLoader.
|
|||
case R.id.ignoreUpdate:
|
||||
SharedPreferences prefs = getSharedPreferences("update_ignored", MODE_PRIVATE);
|
||||
|
||||
boolean ignored = prefs.getBoolean(mModule.packageName, false);
|
||||
prefs.edit().putBoolean(mModule.packageName, !ignored).apply();
|
||||
boolean ignored = prefs.getBoolean(module.packageName, false);
|
||||
prefs.edit().putBoolean(module.packageName, !ignored).apply();
|
||||
item.setChecked(!ignored);
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,12 +8,14 @@ import android.util.Pair;
|
|||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.core.view.ViewCompat;
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import org.meowcat.edxposed.manager.databinding.DownloadDetailsBinding;
|
||||
import org.meowcat.edxposed.manager.databinding.DownloadMoreinfoBinding;
|
||||
import org.meowcat.edxposed.manager.repo.Module;
|
||||
import org.meowcat.edxposed.manager.repo.RepoParser;
|
||||
import org.meowcat.edxposed.manager.util.NavUtil;
|
||||
|
|
@ -32,50 +34,47 @@ public class DownloadDetailsFragment extends Fragment {
|
|||
if (module == null) {
|
||||
return null;
|
||||
}
|
||||
final View view = inflater.inflate(R.layout.download_details, container, false);
|
||||
DownloadDetailsBinding binding = DownloadDetailsBinding.inflate(inflater, container, false);
|
||||
ViewCompat.setOnApplyWindowInsetsListener(binding.getRoot(), (v, insets) -> {
|
||||
binding.getRoot().setPadding(0, 0, 0, insets.getSystemWindowInsetBottom());
|
||||
return insets;
|
||||
});
|
||||
binding.downloadTitle.setText(module.name);
|
||||
binding.downloadTitle.setTextIsSelectable(true);
|
||||
|
||||
TextView title = view.findViewById(R.id.download_title);
|
||||
title.setText(module.name);
|
||||
title.setTextIsSelectable(true);
|
||||
|
||||
TextView author = view.findViewById(R.id.download_author);
|
||||
if (module.author != null && !module.author.isEmpty())
|
||||
author.setText(getString(R.string.download_author, module.author));
|
||||
binding.downloadAuthor.setText(getString(R.string.download_author, module.author));
|
||||
else
|
||||
author.setText(R.string.download_unknown_author);
|
||||
binding.downloadAuthor.setText(R.string.download_unknown_author);
|
||||
|
||||
TextView description = view.findViewById(R.id.download_description);
|
||||
if (module.description != null) {
|
||||
if (module.descriptionIsHtml) {
|
||||
description.setText(RepoParser.parseSimpleHtml(getActivity(), module.description, description));
|
||||
description.setTransformationMethod(new LinkTransformationMethod((AppCompatActivity) getActivity()));
|
||||
description.setMovementMethod(LinkMovementMethod.getInstance());
|
||||
binding.downloadDescription.setText(RepoParser.parseSimpleHtml(getActivity(), module.description, binding.downloadDescription));
|
||||
binding.downloadDescription.setTransformationMethod(new LinkTransformationMethod((AppCompatActivity) getActivity()));
|
||||
binding.downloadDescription.setMovementMethod(LinkMovementMethod.getInstance());
|
||||
} else {
|
||||
description.setText(module.description);
|
||||
binding.downloadDescription.setText(module.description);
|
||||
}
|
||||
description.setTextIsSelectable(true);
|
||||
binding.downloadDescription.setTextIsSelectable(true);
|
||||
} else {
|
||||
description.setVisibility(View.GONE);
|
||||
binding.downloadDescription.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
ViewGroup moreInfoContainer = view.findViewById(R.id.download_moreinfo_container);
|
||||
for (Pair<String, String> moreInfoEntry : module.moreInfo) {
|
||||
View moreInfoView = inflater.inflate(R.layout.download_moreinfo, moreInfoContainer, false);
|
||||
TextView txtTitle = moreInfoView.findViewById(android.R.id.title);
|
||||
TextView txtValue = moreInfoView.findViewById(android.R.id.message);
|
||||
DownloadMoreinfoBinding moreinfoBinding = DownloadMoreinfoBinding.inflate(inflater, binding.downloadMoreinfoContainer, false);
|
||||
|
||||
txtTitle.setText(moreInfoEntry.first + ":");
|
||||
txtValue.setText(moreInfoEntry.second);
|
||||
moreinfoBinding.title.setText(moreInfoEntry.first + ":");
|
||||
moreinfoBinding.message.setText(moreInfoEntry.second);
|
||||
|
||||
final Uri link = NavUtil.parseURL(moreInfoEntry.second);
|
||||
if (link != null) {
|
||||
txtValue.setTextColor(txtValue.getLinkTextColors());
|
||||
moreInfoView.setOnClickListener(v -> NavUtil.startURL((AppCompatActivity) getActivity(), link));
|
||||
moreinfoBinding.message.setTextColor(moreinfoBinding.message.getLinkTextColors());
|
||||
moreinfoBinding.getRoot().setOnClickListener(v -> NavUtil.startURL((AppCompatActivity) getActivity(), link));
|
||||
}
|
||||
|
||||
moreInfoContainer.addView(moreInfoView);
|
||||
binding.downloadMoreinfoContainer.addView(moreinfoBinding.getRoot());
|
||||
}
|
||||
|
||||
return view;
|
||||
return binding.getRoot();
|
||||
}
|
||||
}
|
||||
|
|
@ -4,6 +4,7 @@ import android.content.Context;
|
|||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceManager;
|
||||
|
||||
import com.takisoft.preferencex.PreferenceFragmentCompat;
|
||||
|
|
@ -16,7 +17,6 @@ import java.util.Map;
|
|||
|
||||
public class DownloadDetailsSettingsFragment extends PreferenceFragmentCompat {
|
||||
|
||||
|
||||
@Override
|
||||
public void onCreatePreferencesFix(Bundle savedInstanceState, String rootKey) {
|
||||
DownloadDetailsActivity mActivity = (DownloadDetailsActivity) getActivity();
|
||||
|
|
@ -48,11 +48,13 @@ public class DownloadDetailsSettingsFragment extends PreferenceFragmentCompat {
|
|||
editor.putBoolean("no_global", false).apply();
|
||||
}
|
||||
|
||||
findPreference("release_type").setOnPreferenceChangeListener(
|
||||
(preference, newValue) -> {
|
||||
RepoLoader.getInstance().setReleaseTypeLocal(packageName, (String) newValue);
|
||||
return true;
|
||||
});
|
||||
Preference releaseType = findPreference("release_type");
|
||||
if (releaseType != null) {
|
||||
releaseType.setOnPreferenceChangeListener((preference, newValue) -> {
|
||||
RepoLoader.getInstance().setReleaseTypeLocal(packageName, (String) newValue);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -19,8 +19,10 @@ import android.widget.FrameLayout;
|
|||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.core.view.ViewCompat;
|
||||
import androidx.fragment.app.ListFragment;
|
||||
|
||||
import com.google.android.material.snackbar.Snackbar;
|
||||
|
|
@ -44,18 +46,17 @@ import java.text.DateFormat;
|
|||
import java.util.Date;
|
||||
|
||||
public class DownloadDetailsVersionsFragment extends ListFragment {
|
||||
private static View rootView;
|
||||
private DownloadDetailsActivity mActivity;
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
private DownloadDetailsActivity activity;
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
mActivity = (DownloadDetailsActivity) getActivity();
|
||||
if (mActivity == null) {
|
||||
activity = (DownloadDetailsActivity) getActivity();
|
||||
if (activity == null) {
|
||||
return;
|
||||
}
|
||||
rootView = mActivity.findViewById(R.id.snackbar);
|
||||
Module module = mActivity.getModule();
|
||||
Module module = activity.getModule();
|
||||
if (module == null)
|
||||
return;
|
||||
|
||||
|
|
@ -68,25 +69,32 @@ public class DownloadDetailsVersionsFragment extends ListFragment {
|
|||
TextView txtHeader = new TextView(getActivity());
|
||||
txtHeader.setText(R.string.download_test_version_not_shown);
|
||||
txtHeader.setTextColor(getResources().getColor(R.color.warning));
|
||||
txtHeader.setOnClickListener(v -> mActivity.gotoPage(DownloadDetailsActivity.DOWNLOAD_SETTINGS));
|
||||
txtHeader.setOnClickListener(v -> activity.gotoPage(DownloadDetailsActivity.DOWNLOAD_SETTINGS));
|
||||
getListView().addHeaderView(txtHeader);
|
||||
}
|
||||
|
||||
VersionsAdapter sAdapter = new VersionsAdapter(mActivity, mActivity.getInstalledModule());
|
||||
VersionsAdapter sAdapter = new VersionsAdapter(activity, activity.getInstalledModule(), activity.findViewById(R.id.snackbar));
|
||||
for (ModuleVersion version : module.versions) {
|
||||
if (repoLoader.isVersionShown(version))
|
||||
sAdapter.add(version);
|
||||
}
|
||||
setListAdapter(sAdapter);
|
||||
}
|
||||
if (getView() != null) {
|
||||
((FrameLayout) getView()).setClipChildren(false);
|
||||
((FrameLayout) getView()).setClipToPadding(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
((FrameLayout) view).setClipChildren(false);
|
||||
((FrameLayout) view).setClipToPadding(false);
|
||||
((FrameLayout) getListView().getParent()).setClipChildren(false);
|
||||
((FrameLayout) getListView().getParent()).setClipToPadding(false);
|
||||
getListView().setClipToPadding(false);
|
||||
getListView().setClipToPadding(false);
|
||||
ViewCompat.setOnApplyWindowInsetsListener(view, (v, insets) -> {
|
||||
getListView().setPadding(0, 0, 0, insets.getSystemWindowInsetBottom());
|
||||
return insets;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -106,7 +114,7 @@ public class DownloadDetailsVersionsFragment extends ListFragment {
|
|||
Uri uri = data.getData();
|
||||
if (uri != null) {
|
||||
try {
|
||||
OutputStream os = mActivity.getContentResolver().openOutputStream(uri);
|
||||
OutputStream os = activity.getContentResolver().openOutputStream(uri);
|
||||
if (os != null) {
|
||||
FileInputStream in = new FileInputStream(new File(DownloadView.lastInfo.localFilename));
|
||||
byte[] buffer = new byte[1024];
|
||||
|
|
@ -137,9 +145,11 @@ public class DownloadDetailsVersionsFragment extends ListFragment {
|
|||
|
||||
public static class DownloadModuleCallback implements DownloadsUtil.DownloadFinishedCallback {
|
||||
private final ModuleVersion moduleVersion;
|
||||
private View snackbar;
|
||||
|
||||
DownloadModuleCallback(ModuleVersion moduleVersion) {
|
||||
DownloadModuleCallback(ModuleVersion moduleVersion, View snackbar) {
|
||||
this.moduleVersion = moduleVersion;
|
||||
this.snackbar = snackbar;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -152,12 +162,12 @@ public class DownloadDetailsVersionsFragment extends ListFragment {
|
|||
try {
|
||||
String actualMd5Sum = HashUtil.md5(localFile);
|
||||
if (!moduleVersion.md5sum.equals(actualMd5Sum)) {
|
||||
Snackbar.make(rootView, context.getString(R.string.download_md5sum_incorrect, actualMd5Sum, moduleVersion.md5sum), Snackbar.LENGTH_LONG).show();
|
||||
Snackbar.make(snackbar, context.getString(R.string.download_md5sum_incorrect, actualMd5Sum, moduleVersion.md5sum), Snackbar.LENGTH_LONG).show();
|
||||
DownloadsUtil.removeById(context, info.id);
|
||||
return;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Snackbar.make(rootView, context.getString(R.string.download_could_not_read_file, e.getMessage()), Snackbar.LENGTH_LONG).show();
|
||||
Snackbar.make(snackbar, context.getString(R.string.download_could_not_read_file, e.getMessage()), Snackbar.LENGTH_LONG).show();
|
||||
DownloadsUtil.removeById(context, info.id);
|
||||
return;
|
||||
}
|
||||
|
|
@ -167,13 +177,13 @@ public class DownloadDetailsVersionsFragment extends ListFragment {
|
|||
PackageInfo packageInfo = pm.getPackageArchiveInfo(info.localFilename, 0);
|
||||
|
||||
if (packageInfo == null) {
|
||||
Snackbar.make(rootView, R.string.download_no_valid_apk, Snackbar.LENGTH_LONG).show();
|
||||
Snackbar.make(snackbar, R.string.download_no_valid_apk, Snackbar.LENGTH_LONG).show();
|
||||
DownloadsUtil.removeById(context, info.id);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!packageInfo.packageName.equals(moduleVersion.module.packageName)) {
|
||||
Snackbar.make(rootView, context.getString(R.string.download_incorrect_package_name, packageInfo.packageName, moduleVersion.module.packageName), Snackbar.LENGTH_LONG).show();
|
||||
Snackbar.make(snackbar, context.getString(R.string.download_incorrect_package_name, packageInfo.packageName, moduleVersion.module.packageName), Snackbar.LENGTH_LONG).show();
|
||||
DownloadsUtil.removeById(context, info.id);
|
||||
return;
|
||||
}
|
||||
|
|
@ -183,29 +193,31 @@ public class DownloadDetailsVersionsFragment extends ListFragment {
|
|||
}
|
||||
|
||||
private class VersionsAdapter extends ArrayAdapter<ModuleVersion> {
|
||||
private final DateFormat mDateFormatter = DateFormat
|
||||
private final DateFormat dateFormatter = DateFormat
|
||||
.getDateInstance(DateFormat.SHORT);
|
||||
private final int mColorRelTypeStable;
|
||||
private final int mColorRelTypeOthers;
|
||||
private final int mColorInstalled;
|
||||
private final int mColorUpdateAvailable;
|
||||
private final String mTextInstalled;
|
||||
private final String mTextUpdateAvailable;
|
||||
private final long mInstalledVersionCode;
|
||||
private final int colorRelTypeStable;
|
||||
private final int colorRelTypeOthers;
|
||||
private final int colorInstalled;
|
||||
private final int colorUpdateAvailable;
|
||||
private final String textInstalled;
|
||||
private final String textUpdateAvailable;
|
||||
private final long installedVersionCode;
|
||||
private View snackbar;
|
||||
|
||||
VersionsAdapter(Context context, InstalledModule installed) {
|
||||
VersionsAdapter(Context context, InstalledModule installed, View snackbar) {
|
||||
super(context, R.layout.item_version);
|
||||
TypedValue typedValue = new TypedValue();
|
||||
Resources.Theme theme = context.getTheme();
|
||||
theme.resolveAttribute(android.R.attr.textColorPrimary, typedValue, true);
|
||||
int color = ContextCompat.getColor(context, typedValue.resourceId);
|
||||
mColorRelTypeStable = color;
|
||||
mColorRelTypeOthers = getResources().getColor(R.color.warning);
|
||||
mColorInstalled = color;
|
||||
mColorUpdateAvailable = getResources().getColor(R.color.download_status_update_available);
|
||||
mTextInstalled = getString(R.string.download_section_installed) + ":";
|
||||
mTextUpdateAvailable = getString(R.string.download_section_update_available) + ":";
|
||||
mInstalledVersionCode = (installed != null) ? installed.versionCode : -1;
|
||||
colorRelTypeStable = color;
|
||||
colorRelTypeOthers = getResources().getColor(R.color.warning);
|
||||
colorInstalled = color;
|
||||
colorUpdateAvailable = getResources().getColor(R.color.download_status_update_available);
|
||||
textInstalled = getString(R.string.download_section_installed) + ":";
|
||||
textUpdateAvailable = getString(R.string.download_section_update_available) + ":";
|
||||
installedVersionCode = (installed != null) ? installed.versionCode : -1;
|
||||
this.snackbar = snackbar;
|
||||
}
|
||||
|
||||
@SuppressLint("InflateParams")
|
||||
|
|
@ -236,32 +248,32 @@ public class DownloadDetailsVersionsFragment extends ListFragment {
|
|||
holder.txtVersion.setText(item.name);
|
||||
holder.txtRelType.setText(item.relType.getTitleId());
|
||||
holder.txtRelType.setTextColor(item.relType == ReleaseType.STABLE
|
||||
? mColorRelTypeStable : mColorRelTypeOthers);
|
||||
? colorRelTypeStable : colorRelTypeOthers);
|
||||
|
||||
if (item.uploaded > 0) {
|
||||
holder.txtUploadDate.setText(
|
||||
mDateFormatter.format(new Date(item.uploaded)));
|
||||
dateFormatter.format(new Date(item.uploaded)));
|
||||
holder.txtUploadDate.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
holder.txtUploadDate.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
if (item.code <= 0 || mInstalledVersionCode <= 0
|
||||
|| item.code < mInstalledVersionCode) {
|
||||
if (item.code <= 0 || installedVersionCode <= 0
|
||||
|| item.code < installedVersionCode) {
|
||||
holder.txtStatus.setVisibility(View.GONE);
|
||||
} else if (item.code == mInstalledVersionCode) {
|
||||
holder.txtStatus.setText(mTextInstalled);
|
||||
holder.txtStatus.setTextColor(mColorInstalled);
|
||||
} else if (item.code == installedVersionCode) {
|
||||
holder.txtStatus.setText(textInstalled);
|
||||
holder.txtStatus.setTextColor(colorInstalled);
|
||||
holder.txtStatus.setVisibility(View.VISIBLE);
|
||||
} else { // item.code > mInstalledVersionCode
|
||||
holder.txtStatus.setText(mTextUpdateAvailable);
|
||||
holder.txtStatus.setTextColor(mColorUpdateAvailable);
|
||||
} else { // item.code > installedVersionCode
|
||||
holder.txtStatus.setText(textUpdateAvailable);
|
||||
holder.txtStatus.setTextColor(colorUpdateAvailable);
|
||||
holder.txtStatus.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
holder.downloadView.setUrl(item.downloadLink);
|
||||
holder.downloadView.setTitle(mActivity.getModule().name);
|
||||
holder.downloadView.setDownloadFinishedCallback(new DownloadModuleCallback(item));
|
||||
holder.downloadView.setTitle(activity.getModule().name);
|
||||
holder.downloadView.setDownloadFinishedCallback(new DownloadModuleCallback(item, snackbar));
|
||||
|
||||
if (item.changelog != null && !item.changelog.isEmpty()) {
|
||||
holder.txtChangesTitle.setVisibility(View.VISIBLE);
|
||||
|
|
|
|||
|
|
@ -1,65 +1,58 @@
|
|||
package org.meowcat.edxposed.manager;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.ActionBar;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import androidx.fragment.app.FragmentPagerAdapter;
|
||||
import androidx.viewpager.widget.ViewPager;
|
||||
|
||||
import com.google.android.material.checkbox.MaterialCheckBox;
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||
import com.google.android.material.tabs.TabLayout;
|
||||
import com.google.gson.Gson;
|
||||
|
||||
import org.meowcat.edxposed.manager.databinding.ActivityEdDownloadBinding;
|
||||
import org.meowcat.edxposed.manager.databinding.DialogInstallWarningBinding;
|
||||
import org.meowcat.edxposed.manager.util.json.JSONUtils;
|
||||
import org.meowcat.edxposed.manager.util.json.XposedTab;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class EdDownloadActivity extends BaseActivity {
|
||||
|
||||
ActivityEdDownloadBinding binding;
|
||||
private TabsAdapter tabsAdapter;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_ed_download);
|
||||
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||
setSupportActionBar(toolbar);
|
||||
toolbar.setNavigationOnClickListener(view -> finish());
|
||||
binding = ActivityEdDownloadBinding.inflate(getLayoutInflater());
|
||||
setContentView(binding.getRoot());
|
||||
setSupportActionBar(binding.toolbar);
|
||||
binding.toolbar.setNavigationOnClickListener(view -> finish());
|
||||
ActionBar bar = getSupportActionBar();
|
||||
if (bar != null) {
|
||||
bar.setDisplayHomeAsUpEnabled(true);
|
||||
}
|
||||
ViewPager mPager = findViewById(R.id.pager);
|
||||
TabLayout mTabLayout = findViewById(R.id.tab_layout);
|
||||
|
||||
tabsAdapter = new TabsAdapter(getSupportFragmentManager());
|
||||
tabsAdapter.notifyDataSetChanged();
|
||||
mPager.setAdapter(tabsAdapter);
|
||||
mTabLayout.setupWithViewPager(mPager);
|
||||
binding.pager.setAdapter(tabsAdapter);
|
||||
binding.tabLayout.setupWithViewPager(binding.pager);
|
||||
new JSONParser().execute();
|
||||
|
||||
if (!XposedApp.getPreferences().getBoolean("hide_install_warning", false)) {
|
||||
@SuppressLint("InflateParams") final View dontShowAgainView = getLayoutInflater().inflate(R.layout.dialog_install_warning, null);
|
||||
|
||||
DialogInstallWarningBinding binding = DialogInstallWarningBinding.inflate(getLayoutInflater());
|
||||
binding.message.setText(R.string.not_logcat);
|
||||
new MaterialAlertDialogBuilder(this)
|
||||
.setTitle(R.string.install_warning_title)
|
||||
.setView(dontShowAgainView)
|
||||
.setView(binding.getRoot())
|
||||
.setPositiveButton(android.R.string.ok, (dialog, which) -> {
|
||||
MaterialCheckBox checkBox = dontShowAgainView.findViewById(android.R.id.checkbox);
|
||||
if (checkBox.isChecked())
|
||||
if (binding.checkbox.isChecked())
|
||||
XposedApp.getPreferences().edit().putBoolean("hide_install_warning", true).apply();
|
||||
})
|
||||
.setCancelable(false)
|
||||
|
|
@ -78,7 +71,6 @@ public class EdDownloadActivity extends BaseActivity {
|
|||
return super.onCreateOptionsMenu(menu);
|
||||
}
|
||||
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
private class JSONParser extends AsyncTask<Void, Void, String> {
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -17,16 +17,18 @@ import androidx.annotation.NonNull;
|
|||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.ActionBar;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.core.content.FileProvider;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.google.android.material.checkbox.MaterialCheckBox;
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||
import com.google.android.material.snackbar.Snackbar;
|
||||
import com.google.android.material.tabs.TabLayout;
|
||||
|
||||
import org.meowcat.edxposed.manager.databinding.ActivityLogsBinding;
|
||||
import org.meowcat.edxposed.manager.databinding.DialogInstallWarningBinding;
|
||||
import org.meowcat.edxposed.manager.databinding.ItemLogBinding;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
|
|
@ -39,54 +41,48 @@ import java.util.Scanner;
|
|||
|
||||
public class LogsActivity extends BaseActivity {
|
||||
private boolean allLog = false;
|
||||
private File mFileErrorLog = new File(XposedApp.BASE_DIR + "log/error.log");
|
||||
private File mFileErrorLogOld = new File(
|
||||
private File fileErrorLog = new File(XposedApp.BASE_DIR + "log/error.log");
|
||||
private File fileErrorLogOld = new File(
|
||||
XposedApp.BASE_DIR + "log/error.log.old");
|
||||
private File mFileAllLog = new File(XposedApp.BASE_DIR + "log/all.log");
|
||||
private File mFileAllLogOld = new File(XposedApp.BASE_DIR + "log/all.log.old");
|
||||
private LogsAdapter mAdapter;
|
||||
private RecyclerView mListView;
|
||||
private File fileAllLog = new File(XposedApp.BASE_DIR + "log/all.log");
|
||||
private File fileAllLogOld = new File(XposedApp.BASE_DIR + "log/all.log.old");
|
||||
private LogsAdapter adapter;
|
||||
private Handler handler = new Handler();
|
||||
private ActivityLogsBinding binding;
|
||||
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_logs);
|
||||
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||
setSupportActionBar(toolbar);
|
||||
toolbar.setNavigationOnClickListener(view -> finish());
|
||||
binding = ActivityLogsBinding.inflate(getLayoutInflater());
|
||||
setContentView(binding.getRoot());
|
||||
setSupportActionBar(binding.toolbar);
|
||||
binding.toolbar.setNavigationOnClickListener(view -> finish());
|
||||
ActionBar bar = getSupportActionBar();
|
||||
if (bar != null) {
|
||||
bar.setDisplayHomeAsUpEnabled(true);
|
||||
}
|
||||
setupWindowInsets();
|
||||
setupWindowInsets(binding.snackbar, binding.recyclerView);
|
||||
|
||||
if (!XposedApp.getPreferences().getBoolean("hide_logcat_warning", false)) {
|
||||
@SuppressLint("InflateParams") final View dontShowAgainView = getLayoutInflater().inflate(R.layout.dialog_install_warning, null);
|
||||
|
||||
TextView message = dontShowAgainView.findViewById(android.R.id.message);
|
||||
message.setText(R.string.not_logcat);
|
||||
|
||||
DialogInstallWarningBinding binding = DialogInstallWarningBinding.inflate(getLayoutInflater());
|
||||
binding.message.setText(R.string.not_logcat);
|
||||
new MaterialAlertDialogBuilder(this)
|
||||
.setTitle(R.string.install_warning_title)
|
||||
.setView(dontShowAgainView)
|
||||
.setView(binding.getRoot())
|
||||
.setPositiveButton(android.R.string.ok, (dialog, which) -> {
|
||||
MaterialCheckBox checkBox = dontShowAgainView.findViewById(android.R.id.checkbox);
|
||||
if (checkBox.isChecked())
|
||||
if (binding.checkbox.isChecked())
|
||||
XposedApp.getPreferences().edit().putBoolean("hide_logcat_warning", true).apply();
|
||||
})
|
||||
.setCancelable(false)
|
||||
.show();
|
||||
}
|
||||
mAdapter = new LogsAdapter();
|
||||
mListView = findViewById(R.id.recyclerView);
|
||||
mListView.setAdapter(mAdapter);
|
||||
mListView.setLayoutManager(new LinearLayoutManager(this));
|
||||
TabLayout tabLayout = findViewById(R.id.sliding_tabs);
|
||||
adapter = new LogsAdapter();
|
||||
binding.recyclerView.setAdapter(adapter);
|
||||
binding.recyclerView.setLayoutManager(new LinearLayoutManager(this));
|
||||
if (XposedApp.getPreferences().getBoolean("disable_verbose_log", false)) {
|
||||
tabLayout.setVisibility(View.GONE);
|
||||
binding.slidingTabs.setVisibility(View.GONE);
|
||||
}
|
||||
tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
|
||||
binding.slidingTabs.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
|
||||
@Override
|
||||
public void onTabSelected(TabLayout.Tab tab) {
|
||||
allLog = tab.getPosition() != 0;
|
||||
|
|
@ -133,7 +129,7 @@ public class LogsActivity extends BaseActivity {
|
|||
try {
|
||||
send();
|
||||
} catch (Exception e) {
|
||||
Snackbar.make(findViewById(R.id.snackbar), e.getLocalizedMessage(), Snackbar.LENGTH_LONG).show();
|
||||
Snackbar.make(binding.snackbar, e.getLocalizedMessage(), Snackbar.LENGTH_LONG).show();
|
||||
}
|
||||
return true;
|
||||
case R.id.menu_save:
|
||||
|
|
@ -147,32 +143,32 @@ public class LogsActivity extends BaseActivity {
|
|||
}
|
||||
|
||||
private void scrollTop() {
|
||||
mListView.smoothScrollToPosition(0);
|
||||
binding.recyclerView.smoothScrollToPosition(0);
|
||||
}
|
||||
|
||||
private void scrollDown() {
|
||||
mListView.smoothScrollToPosition(mAdapter.getItemCount() - 1);
|
||||
binding.recyclerView.smoothScrollToPosition(adapter.getItemCount() - 1);
|
||||
}
|
||||
|
||||
private void reloadErrorLog() {
|
||||
new LogsReader().execute(allLog ? mFileAllLog : mFileErrorLog);
|
||||
new LogsReader().execute(allLog ? fileAllLog : fileErrorLog);
|
||||
}
|
||||
|
||||
private void clear() {
|
||||
try {
|
||||
new FileOutputStream(allLog ? mFileAllLog : mFileErrorLog).close();
|
||||
new FileOutputStream(allLog ? fileAllLog : fileErrorLog).close();
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
(allLog ? mFileAllLogOld : mFileErrorLogOld).delete();
|
||||
mAdapter.setEmpty();
|
||||
Snackbar.make(findViewById(R.id.snackbar), R.string.logs_cleared, Snackbar.LENGTH_SHORT).show();
|
||||
(allLog ? fileAllLogOld : fileErrorLogOld).delete();
|
||||
adapter.setEmpty();
|
||||
Snackbar.make(binding.snackbar, R.string.logs_cleared, Snackbar.LENGTH_SHORT).show();
|
||||
reloadErrorLog();
|
||||
} catch (IOException e) {
|
||||
Snackbar.make(findViewById(R.id.snackbar), getResources().getString(R.string.logs_clear_failed) + "n" + e.getMessage(), Snackbar.LENGTH_LONG).show();
|
||||
Snackbar.make(binding.snackbar, getResources().getString(R.string.logs_clear_failed) + "n" + e.getMessage(), Snackbar.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
|
||||
private void send() {
|
||||
Uri uri = FileProvider.getUriForFile(this, BuildConfig.APPLICATION_ID + ".fileprovider", allLog ? mFileAllLog : mFileErrorLog);
|
||||
Uri uri = FileProvider.getUriForFile(this, BuildConfig.APPLICATION_ID + ".fileprovider", allLog ? fileAllLog : fileErrorLog);
|
||||
Intent sendIntent = new Intent();
|
||||
sendIntent.setAction(Intent.ACTION_SEND);
|
||||
sendIntent.putExtra(Intent.EXTRA_STREAM, uri);
|
||||
|
|
@ -210,7 +206,7 @@ public class LogsActivity extends BaseActivity {
|
|||
try {
|
||||
OutputStream os = getContentResolver().openOutputStream(uri);
|
||||
if (os != null) {
|
||||
FileInputStream in = new FileInputStream(allLog ? mFileAllLog : mFileErrorLog);
|
||||
FileInputStream in = new FileInputStream(allLog ? fileAllLog : fileErrorLog);
|
||||
byte[] buffer = new byte[1024];
|
||||
int len;
|
||||
while ((len = in.read(buffer)) > 0) {
|
||||
|
|
@ -219,7 +215,7 @@ public class LogsActivity extends BaseActivity {
|
|||
os.close();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Snackbar.make(findViewById(R.id.snackbar), getResources().getString(R.string.logs_save_failed) + "\n" + e.getMessage(), Snackbar.LENGTH_LONG).show();
|
||||
Snackbar.make(binding.snackbar, getResources().getString(R.string.logs_save_failed) + "\n" + e.getMessage(), Snackbar.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -269,9 +265,9 @@ public class LogsActivity extends BaseActivity {
|
|||
@Override
|
||||
protected void onPostExecute(ArrayList<String> logs) {
|
||||
if (logs.size() == 0) {
|
||||
mAdapter.setEmpty();
|
||||
adapter.setEmpty();
|
||||
} else {
|
||||
mAdapter.setLogs(logs);
|
||||
adapter.setLogs(logs);
|
||||
}
|
||||
handler.removeCallbacks(mRunnable);//It loaded so fast that no need to show progress
|
||||
if (mProgressDialog.isShowing()) {
|
||||
|
|
@ -286,8 +282,8 @@ public class LogsActivity extends BaseActivity {
|
|||
@NonNull
|
||||
@Override
|
||||
public LogsAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_log, parent, false);
|
||||
return new LogsAdapter.ViewHolder(v);
|
||||
ItemLogBinding binding = ItemLogBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false);
|
||||
return new LogsAdapter.ViewHolder(binding);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -298,8 +294,8 @@ public class LogsActivity extends BaseActivity {
|
|||
int desiredWidth = view.getMeasuredWidth();
|
||||
ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
|
||||
layoutParams.width = desiredWidth;
|
||||
if (mListView.getWidth() < desiredWidth) {
|
||||
mListView.requestLayout();
|
||||
if (binding.recyclerView.getWidth() < desiredWidth) {
|
||||
binding.recyclerView.requestLayout();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -308,7 +304,7 @@ public class LogsActivity extends BaseActivity {
|
|||
this.logs.clear();
|
||||
this.logs.addAll(logs);
|
||||
notifyDataSetChanged();
|
||||
mListView.scrollToPosition(getItemCount() - 1);
|
||||
binding.recyclerView.scrollToPosition(getItemCount() - 1);
|
||||
}
|
||||
|
||||
void setEmpty() {
|
||||
|
|
@ -325,9 +321,9 @@ public class LogsActivity extends BaseActivity {
|
|||
class ViewHolder extends RecyclerView.ViewHolder {
|
||||
TextView textView;
|
||||
|
||||
ViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
textView = itemView.findViewById(R.id.log);
|
||||
ViewHolder(ItemLogBinding binding) {
|
||||
super(binding.getRoot());
|
||||
textView = binding.log;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,72 +3,66 @@ package org.meowcat.edxposed.manager;
|
|||
import android.annotation.SuppressLint;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.widget.PopupMenu;
|
||||
import androidx.appcompat.widget.TooltipCompat;
|
||||
|
||||
import com.google.android.material.card.MaterialCardView;
|
||||
|
||||
import org.meowcat.edxposed.manager.databinding.ActivityMainBinding;
|
||||
import org.meowcat.edxposed.manager.util.ModuleUtil;
|
||||
import org.meowcat.edxposed.manager.util.RepoLoader;
|
||||
|
||||
public class MainActivity extends BaseActivity implements RepoLoader.RepoListener, ModuleUtil.ModuleListener {
|
||||
|
||||
ActivityMainBinding binding;
|
||||
private RepoLoader mRepoLoader;
|
||||
|
||||
@SuppressLint("PrivateResource")
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_main);
|
||||
binding = ActivityMainBinding.inflate(getLayoutInflater());
|
||||
setContentView(binding.getRoot());
|
||||
|
||||
mRepoLoader = RepoLoader.getInstance();
|
||||
ModuleUtil.getInstance().addListener(this);
|
||||
mRepoLoader.addListener(this, false);
|
||||
findViewById(R.id.activity_main_modules).setOnClickListener(v -> {
|
||||
binding.modules.setOnClickListener(v -> {
|
||||
Intent intent = new Intent();
|
||||
intent.setClass(getApplicationContext(), ModulesActivity.class);
|
||||
startActivity(intent);
|
||||
});
|
||||
findViewById(R.id.activity_main_downloads).setOnClickListener(v -> {
|
||||
binding.downloads.setOnClickListener(v -> {
|
||||
Intent intent = new Intent();
|
||||
intent.setClass(getApplicationContext(), DownloadActivity.class);
|
||||
startActivity(intent);
|
||||
});
|
||||
findViewById(R.id.activity_main_apps).setOnClickListener(v -> {
|
||||
binding.apps.setOnClickListener(v -> {
|
||||
Intent intent = new Intent();
|
||||
intent.setClass(getApplicationContext(), BlackListActivity.class);
|
||||
startActivity(intent);
|
||||
});
|
||||
findViewById(R.id.activity_main_status).setOnClickListener(v -> {
|
||||
binding.status.setOnClickListener(v -> {
|
||||
Intent intent = new Intent();
|
||||
intent.setClass(getApplicationContext(), EdDownloadActivity.class);
|
||||
startActivity(intent);
|
||||
});
|
||||
findViewById(R.id.activity_main_settings).setOnClickListener(v -> {
|
||||
binding.settings.setOnClickListener(v -> {
|
||||
Intent intent = new Intent();
|
||||
intent.setClass(getApplicationContext(), SettingsActivity.class);
|
||||
startActivity(intent);
|
||||
});
|
||||
findViewById(R.id.activity_main_logs).setOnClickListener(v -> {
|
||||
binding.logs.setOnClickListener(v -> {
|
||||
Intent intent = new Intent();
|
||||
intent.setClass(getApplicationContext(), LogsActivity.class);
|
||||
startActivity(intent);
|
||||
});
|
||||
findViewById(R.id.activity_main_about).setOnClickListener(v -> {
|
||||
binding.about.setOnClickListener(v -> {
|
||||
Intent intent = new Intent();
|
||||
intent.setClass(getApplicationContext(), AboutActivity.class);
|
||||
startActivity(intent);
|
||||
});
|
||||
ImageView menu = findViewById(R.id.menu_more);
|
||||
TooltipCompat.setTooltipText(menu, getString(androidx.appcompat.R.string.abc_action_menu_overflow_description));
|
||||
menu.setOnClickListener(v -> {
|
||||
PopupMenu appMenu = new PopupMenu(MainActivity.this, menu);
|
||||
TooltipCompat.setTooltipText(binding.menuMore, getString(androidx.appcompat.R.string.abc_action_menu_overflow_description));
|
||||
binding.menuMore.setOnClickListener(v -> {
|
||||
PopupMenu appMenu = new PopupMenu(MainActivity.this, binding.menuMore);
|
||||
appMenu.inflate(R.menu.menu_installer);
|
||||
appMenu.setOnMenuItemClickListener(this::onOptionsItemSelected);
|
||||
appMenu.show();
|
||||
|
|
@ -79,29 +73,25 @@ public class MainActivity extends BaseActivity implements RepoLoader.RepoListene
|
|||
} catch (NullPointerException e) {
|
||||
installedXposedVersion = null;
|
||||
}
|
||||
MaterialCardView cardView = findViewById(R.id.activity_main_status);
|
||||
TextView title = findViewById(R.id.activity_main_status_title);
|
||||
ImageView icon = findViewById(R.id.activity_main_status_icon);
|
||||
TextView details = findViewById(R.id.activity_main_status_summary);
|
||||
if (installedXposedVersion != null) {
|
||||
int installedXposedVersionInt = extractIntPart(installedXposedVersion);
|
||||
if (installedXposedVersionInt == XposedApp.getXposedVersion()) {
|
||||
String installedXposedVersionStr = installedXposedVersionInt + ".0";
|
||||
title.setText(R.string.Activated);
|
||||
details.setText(installedXposedVersion.replace(installedXposedVersionStr + "-", ""));
|
||||
cardView.setCardBackgroundColor(getResources().getColor(R.color.download_status_update_available));
|
||||
icon.setImageDrawable(getDrawable(R.drawable.ic_check_circle));
|
||||
binding.statusTitle.setText(R.string.Activated);
|
||||
binding.statusSummary.setText(installedXposedVersion.replace(installedXposedVersionStr + "-", ""));
|
||||
binding.status.setCardBackgroundColor(getResources().getColor(R.color.download_status_update_available));
|
||||
binding.statusIcon.setImageDrawable(getDrawable(R.drawable.ic_check_circle));
|
||||
} else {
|
||||
title.setText(R.string.Inactivate);
|
||||
details.setText(R.string.installed_lollipop_inactive);
|
||||
cardView.setCardBackgroundColor(getResources().getColor(R.color.amber_500));
|
||||
icon.setImageDrawable(getDrawable(R.drawable.ic_warning));
|
||||
binding.statusTitle.setText(R.string.Inactivate);
|
||||
binding.statusSummary.setText(R.string.installed_lollipop_inactive);
|
||||
binding.status.setCardBackgroundColor(getResources().getColor(R.color.amber_500));
|
||||
binding.statusIcon.setImageDrawable(getDrawable(R.drawable.ic_warning));
|
||||
}
|
||||
} else {
|
||||
title.setText(R.string.Install);
|
||||
details.setText(R.string.InstallDetail);
|
||||
cardView.setCardBackgroundColor(getResources().getColor(R.color.colorPrimary));
|
||||
icon.setImageDrawable(getDrawable(R.drawable.ic_error));
|
||||
binding.statusTitle.setText(R.string.Install);
|
||||
binding.statusSummary.setText(R.string.InstallDetail);
|
||||
binding.status.setCardBackgroundColor(getResources().getColor(R.color.colorPrimary));
|
||||
binding.statusIcon.setImageDrawable(getDrawable(R.drawable.ic_error));
|
||||
}
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
|
@ -118,45 +108,19 @@ public class MainActivity extends BaseActivity implements RepoLoader.RepoListene
|
|||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
// Inflate the menu; this adds items to the action bar if it is present.
|
||||
getMenuInflater().inflate(R.menu.menu_main, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
|
||||
// Handle action bar item clicks here. The action bar will
|
||||
// automatically handle clicks on the Home/Up button, so long
|
||||
// as you specify a parent activity in AndroidManifest.xml.
|
||||
int id = item.getItemId();
|
||||
|
||||
//noinspection SimplifiableIfStatement
|
||||
if (id == R.id.action_settings) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
private void notifyDataSetChanged() {
|
||||
runOnUiThread(() -> {
|
||||
String frameworkUpdateVersion = mRepoLoader.getFrameworkUpdateVersion();
|
||||
boolean moduleUpdateAvailable = mRepoLoader.hasModuleUpdates();
|
||||
ModuleUtil.getInstance().getEnabledModules().size();
|
||||
TextView description = findViewById(R.id.activity_main_modules_summary);
|
||||
description.setText(String.format(getString(R.string.ModulesDetail), ModuleUtil.getInstance().getEnabledModules().size()));
|
||||
binding.modulesSummary.setText(String.format(getString(R.string.ModulesDetail), ModuleUtil.getInstance().getEnabledModules().size()));
|
||||
if (frameworkUpdateVersion != null) {
|
||||
description = findViewById(R.id.activity_main_status_summary);
|
||||
description.setText(String.format(getString(R.string.welcome_framework_update_available), frameworkUpdateVersion));
|
||||
binding.statusSummary.setText(String.format(getString(R.string.welcome_framework_update_available), frameworkUpdateVersion));
|
||||
}
|
||||
description = findViewById(R.id.activity_main_download_summary);
|
||||
if (moduleUpdateAvailable) {
|
||||
description.setText(R.string.modules_updates_available);
|
||||
binding.downloadSummary.setText(R.string.modules_updates_available);
|
||||
} else {
|
||||
description.setText(R.string.ModuleUptodate);
|
||||
binding.downloadSummary.setText(R.string.ModuleUptodate);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,14 +19,13 @@ import androidx.annotation.NonNull;
|
|||
import androidx.appcompat.app.ActionBar;
|
||||
import androidx.appcompat.widget.SearchView;
|
||||
import androidx.appcompat.widget.SwitchCompat;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.recyclerview.widget.DividerItemDecoration;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
|
||||
|
||||
import com.google.android.material.snackbar.Snackbar;
|
||||
|
||||
import org.meowcat.edxposed.manager.databinding.ActivityModulesBinding;
|
||||
import org.meowcat.edxposed.manager.repo.Module;
|
||||
import org.meowcat.edxposed.manager.repo.ModuleVersion;
|
||||
import org.meowcat.edxposed.manager.repo.ReleaseType;
|
||||
|
|
@ -60,37 +59,36 @@ import static android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS;
|
|||
public class ModulesActivity extends BaseActivity implements ModuleUtil.ModuleListener {
|
||||
|
||||
public static final String SETTINGS_CATEGORY = "de.robv.android.xposed.category.MODULE_SETTINGS";
|
||||
ActivityModulesBinding binding;
|
||||
private int installedXposedVersion;
|
||||
private ApplicationFilter filter;
|
||||
private SearchView mSearchView;
|
||||
private SearchView searchView;
|
||||
private SearchView.OnQueryTextListener mSearchListener;
|
||||
private PackageManager mPm;
|
||||
private PackageManager pm;
|
||||
private DateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault());
|
||||
private ModuleUtil mModuleUtil;
|
||||
private ModuleAdapter mAdapter = null;
|
||||
private RecyclerView mListView;
|
||||
private SwipeRefreshLayout mSwipeRefreshLayout;
|
||||
private ModuleUtil moduleUtil;
|
||||
private ModuleAdapter adapter = null;
|
||||
private Runnable reloadModules = new Runnable() {
|
||||
public void run() {
|
||||
String queryStr = mSearchView != null ? mSearchView.getQuery().toString() : "";
|
||||
String queryStr = searchView != null ? searchView.getQuery().toString() : "";
|
||||
Collection<ModuleUtil.InstalledModule> showList;
|
||||
Collection<ModuleUtil.InstalledModule> fullList = mModuleUtil.getModules().values();
|
||||
Collection<ModuleUtil.InstalledModule> fullList = moduleUtil.getModules().values();
|
||||
if (queryStr.length() == 0) {
|
||||
showList = fullList;
|
||||
} else {
|
||||
showList = new ArrayList<>();
|
||||
String filter = queryStr.toLowerCase();
|
||||
for (ModuleUtil.InstalledModule info : fullList) {
|
||||
if (lowercaseContains(InstallApkUtil.getAppLabel(info.app, mPm), filter)
|
||||
if (lowercaseContains(InstallApkUtil.getAppLabel(info.app, pm), filter)
|
||||
|| lowercaseContains(info.packageName, filter)) {
|
||||
showList.add(info);
|
||||
}
|
||||
}
|
||||
}
|
||||
mAdapter.addAll(showList);
|
||||
mAdapter.notifyDataSetChanged();
|
||||
mModuleUtil.updateModulesList(false);
|
||||
mSwipeRefreshLayout.setRefreshing(false);
|
||||
adapter.addAll(showList);
|
||||
adapter.notifyDataSetChanged();
|
||||
moduleUtil.updateModulesList(false);
|
||||
binding.swipeRefreshLayout.setRefreshing(false);
|
||||
}
|
||||
};
|
||||
private String selectedPackageName;
|
||||
|
|
@ -102,36 +100,33 @@ public class ModulesActivity extends BaseActivity implements ModuleUtil.ModuleLi
|
|||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_modules);
|
||||
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||
setSupportActionBar(toolbar);
|
||||
toolbar.setNavigationOnClickListener(view -> finish());
|
||||
binding = ActivityModulesBinding.inflate(getLayoutInflater());
|
||||
setContentView(binding.getRoot());
|
||||
setSupportActionBar(binding.appbar.toolbar);
|
||||
binding.appbar.toolbar.setNavigationOnClickListener(view -> finish());
|
||||
ActionBar bar = getSupportActionBar();
|
||||
if (bar != null) {
|
||||
bar.setDisplayHomeAsUpEnabled(true);
|
||||
}
|
||||
setupWindowInsets();
|
||||
setupWindowInsets(binding.snackbar, binding.recyclerView);
|
||||
filter = new ApplicationFilter();
|
||||
mModuleUtil = ModuleUtil.getInstance();
|
||||
mPm = getPackageManager();
|
||||
moduleUtil = ModuleUtil.getInstance();
|
||||
pm = getPackageManager();
|
||||
installedXposedVersion = XposedApp.getXposedVersion();
|
||||
if (installedXposedVersion <= 0) {
|
||||
Snackbar.make(findViewById(R.id.snackbar), R.string.xposed_not_active, Snackbar.LENGTH_LONG).setAction(R.string.Settings, v -> {
|
||||
Snackbar.make(binding.snackbar, R.string.xposed_not_active, Snackbar.LENGTH_LONG).setAction(R.string.Settings, v -> {
|
||||
Intent intent = new Intent();
|
||||
intent.setClass(ModulesActivity.this, SettingsActivity.class);
|
||||
startActivity(intent);
|
||||
}).show();
|
||||
}
|
||||
mAdapter = new ModuleAdapter();
|
||||
mModuleUtil.addListener(this);
|
||||
mListView = findViewById(R.id.recyclerView);
|
||||
mListView.setAdapter(mAdapter);
|
||||
mListView.setLayoutManager(new LinearLayoutManager(this));
|
||||
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mListView.getContext(),
|
||||
DividerItemDecoration.VERTICAL);
|
||||
mListView.addItemDecoration(dividerItemDecoration);
|
||||
mSwipeRefreshLayout = findViewById(R.id.swipeRefreshLayout);
|
||||
mSwipeRefreshLayout.setOnRefreshListener(() -> reloadModules.run());
|
||||
adapter = new ModuleAdapter();
|
||||
moduleUtil.addListener(this);
|
||||
binding.recyclerView.setAdapter(adapter);
|
||||
binding.recyclerView.setLayoutManager(new LinearLayoutManager(this));
|
||||
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(this, DividerItemDecoration.VERTICAL);
|
||||
binding.recyclerView.addItemDecoration(dividerItemDecoration);
|
||||
binding.swipeRefreshLayout.setOnRefreshListener(() -> reloadModules.run());
|
||||
reloadModules.run();
|
||||
mSearchListener = new SearchView.OnQueryTextListener() {
|
||||
@Override
|
||||
|
|
@ -152,8 +147,8 @@ public class ModulesActivity extends BaseActivity implements ModuleUtil.ModuleLi
|
|||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.menu_modules, menu);
|
||||
mSearchView = (SearchView) menu.findItem(R.id.menu_search).getActionView();
|
||||
mSearchView.setOnQueryTextListener(mSearchListener);
|
||||
searchView = (SearchView) menu.findItem(R.id.menu_search).getActionView();
|
||||
searchView.setOnQueryTextListener(mSearchListener);
|
||||
return super.onCreateOptionsMenu(menu);
|
||||
}
|
||||
|
||||
|
|
@ -180,7 +175,7 @@ public class ModulesActivity extends BaseActivity implements ModuleUtil.ModuleLi
|
|||
os.close();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Snackbar.make(findViewById(R.id.snackbar), getResources().getString(R.string.logs_save_failed) + "\n" + e.getMessage(), Snackbar.LENGTH_LONG).show();
|
||||
Snackbar.make(binding.snackbar, getResources().getString(R.string.logs_save_failed) + "\n" + e.getMessage(), Snackbar.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -201,7 +196,7 @@ public class ModulesActivity extends BaseActivity implements ModuleUtil.ModuleLi
|
|||
os.close();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Snackbar.make(findViewById(R.id.snackbar), getResources().getString(R.string.logs_save_failed) + "\n" + e.getMessage(), Snackbar.LENGTH_LONG).show();
|
||||
Snackbar.make(binding.snackbar, getResources().getString(R.string.logs_save_failed) + "\n" + e.getMessage(), Snackbar.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -225,7 +220,7 @@ public class ModulesActivity extends BaseActivity implements ModuleUtil.ModuleLi
|
|||
switch (item.getItemId()) {
|
||||
case R.id.export_enabled_modules:
|
||||
if (ModuleUtil.getInstance().getEnabledModules().isEmpty()) {
|
||||
Snackbar.make(findViewById(R.id.snackbar), R.string.no_enabled_modules, Snackbar.LENGTH_SHORT).show();
|
||||
Snackbar.make(binding.snackbar, R.string.no_enabled_modules, Snackbar.LENGTH_SHORT).show();
|
||||
return false;
|
||||
}
|
||||
intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
|
||||
|
|
@ -238,7 +233,7 @@ public class ModulesActivity extends BaseActivity implements ModuleUtil.ModuleLi
|
|||
Map<String, ModuleUtil.InstalledModule> installedModules = ModuleUtil.getInstance().getModules();
|
||||
|
||||
if (installedModules.isEmpty()) {
|
||||
Snackbar.make(findViewById(R.id.snackbar), R.string.no_installed_modules, Snackbar.LENGTH_SHORT).show();
|
||||
Snackbar.make(binding.snackbar, R.string.no_installed_modules, Snackbar.LENGTH_SHORT).show();
|
||||
return false;
|
||||
}
|
||||
intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
|
||||
|
|
@ -271,7 +266,7 @@ public class ModulesActivity extends BaseActivity implements ModuleUtil.ModuleLi
|
|||
Module m = repoLoader.getModule(line);
|
||||
|
||||
if (m == null) {
|
||||
Snackbar.make(findViewById(R.id.snackbar), getString(R.string.download_details_not_found, line), Snackbar.LENGTH_SHORT).show();
|
||||
Snackbar.make(binding.snackbar, getString(R.string.download_details_not_found, line), Snackbar.LENGTH_SHORT).show();
|
||||
} else {
|
||||
list.add(m);
|
||||
}
|
||||
|
|
@ -279,11 +274,11 @@ public class ModulesActivity extends BaseActivity implements ModuleUtil.ModuleLi
|
|||
br.close();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Snackbar.make(findViewById(R.id.snackbar), e.getLocalizedMessage(), Snackbar.LENGTH_SHORT).show();
|
||||
Snackbar.make(binding.snackbar, e.getLocalizedMessage(), Snackbar.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
for (final Module m : list) {
|
||||
if (mModuleUtil.getModule(m.packageName) != null) {
|
||||
if (moduleUtil.getModule(m.packageName) != null) {
|
||||
continue;
|
||||
}
|
||||
ModuleVersion mv = null;
|
||||
|
|
@ -307,20 +302,20 @@ public class ModulesActivity extends BaseActivity implements ModuleUtil.ModuleLi
|
|||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
mModuleUtil.removeListener(this);
|
||||
mListView.setAdapter(null);
|
||||
mAdapter = null;
|
||||
moduleUtil.removeListener(this);
|
||||
binding.recyclerView.setAdapter(null);
|
||||
adapter = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSingleInstalledModuleReloaded(ModuleUtil moduleUtil, String packageName, ModuleUtil.InstalledModule module) {
|
||||
mModuleUtil.updateModulesList(false);
|
||||
moduleUtil.updateModulesList(false);
|
||||
runOnUiThread(reloadModules);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInstalledModulesReloaded(ModuleUtil moduleUtil) {
|
||||
mModuleUtil.updateModulesList(false);
|
||||
moduleUtil.updateModulesList(false);
|
||||
runOnUiThread(reloadModules);
|
||||
}
|
||||
|
||||
|
|
@ -340,7 +335,7 @@ public class ModulesActivity extends BaseActivity implements ModuleUtil.ModuleLi
|
|||
if (launchIntent != null) {
|
||||
startActivity(launchIntent);
|
||||
} else {
|
||||
Snackbar.make(findViewById(R.id.snackbar), R.string.module_no_ui, Snackbar.LENGTH_LONG).show();
|
||||
Snackbar.make(binding.snackbar, R.string.module_no_ui, Snackbar.LENGTH_LONG).show();
|
||||
}
|
||||
return true;
|
||||
|
||||
|
|
@ -404,10 +399,10 @@ public class ModulesActivity extends BaseActivity implements ModuleUtil.ModuleLi
|
|||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
if (mSearchView.isIconified()) {
|
||||
if (searchView.isIconified()) {
|
||||
super.onBackPressed();
|
||||
} else {
|
||||
mSearchView.setIconified(true);
|
||||
searchView.setIconified(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -485,13 +480,13 @@ public class ModulesActivity extends BaseActivity implements ModuleUtil.ModuleLi
|
|||
SwitchCompat mSwitch = holder.mSwitch;
|
||||
mSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> {
|
||||
String packageName = item.packageName;
|
||||
boolean changed = mModuleUtil.isModuleEnabled(packageName) ^ isChecked;
|
||||
boolean changed = moduleUtil.isModuleEnabled(packageName) ^ isChecked;
|
||||
if (changed) {
|
||||
mModuleUtil.setModuleEnabled(packageName, isChecked);
|
||||
mModuleUtil.updateModulesList(true);
|
||||
moduleUtil.setModuleEnabled(packageName, isChecked);
|
||||
moduleUtil.updateModulesList(true);
|
||||
}
|
||||
});
|
||||
mSwitch.setChecked(mModuleUtil.isModuleEnabled(item.packageName));
|
||||
mSwitch.setChecked(moduleUtil.isModuleEnabled(item.packageName));
|
||||
TextView warningText = holder.warningText;
|
||||
|
||||
if (item.minVersion == 0) {
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ import android.annotation.SuppressLint;
|
|||
import android.app.Activity;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
import android.os.FileUtils;
|
||||
import android.view.View;
|
||||
|
|
@ -16,8 +15,8 @@ import androidx.annotation.NonNull;
|
|||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.ActionBar;
|
||||
import androidx.appcompat.app.AppCompatDelegate;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.core.view.ViewCompat;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.SwitchPreferenceCompat;
|
||||
|
||||
|
|
@ -25,57 +24,49 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
|||
import com.takisoft.preferencex.PreferenceFragmentCompat;
|
||||
import com.topjohnwu.superuser.Shell;
|
||||
|
||||
import org.meowcat.edxposed.manager.databinding.ActivitySettingsBinding;
|
||||
import org.meowcat.edxposed.manager.util.RepoLoader;
|
||||
import org.meowcat.edxposed.manager.widget.IntegerListPreference;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Objects;
|
||||
|
||||
public class SettingsActivity extends BaseActivity {
|
||||
ActivitySettingsBinding binding;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_settings);
|
||||
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||
setSupportActionBar(toolbar);
|
||||
toolbar.setNavigationOnClickListener(view -> finish());
|
||||
binding = ActivitySettingsBinding.inflate(getLayoutInflater());
|
||||
setContentView(binding.getRoot());
|
||||
setSupportActionBar(binding.appbar.toolbar);
|
||||
binding.appbar.toolbar.setNavigationOnClickListener(view -> finish());
|
||||
ActionBar bar = getSupportActionBar();
|
||||
if (bar != null) {
|
||||
bar.setDisplayHomeAsUpEnabled(true);
|
||||
}
|
||||
setupWindowInsets();
|
||||
setupWindowInsets(binding.snackbar, null);
|
||||
if (savedInstanceState == null) {
|
||||
getSupportFragmentManager().beginTransaction()
|
||||
.add(R.id.container, SettingsFragment.newInstance(findViewById(R.id.snackbar))).commit();
|
||||
.add(R.id.container, new SettingsFragment()).commit();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings({"ResultOfMethodCallIgnored", "deprecation"})
|
||||
public static class SettingsFragment extends PreferenceFragmentCompat implements Preference.OnPreferenceClickListener, SharedPreferences.OnSharedPreferenceChangeListener {
|
||||
static final File mDisableResourcesFlag = new File(XposedApp.BASE_DIR + "conf/disable_resources");
|
||||
static final File mDynamicModulesFlag = new File(XposedApp.BASE_DIR + "conf/dynamicmodules");
|
||||
static final File mDeoptBootFlag = new File(XposedApp.BASE_DIR + "conf/deoptbootimage");
|
||||
static final File mWhiteListModeFlag = new File(XposedApp.BASE_DIR + "conf/usewhitelist");
|
||||
static final File mBlackWhiteListModeFlag = new File(XposedApp.BASE_DIR + "conf/blackwhitelist");
|
||||
static final File mDisableVerboseLogsFlag = new File(XposedApp.BASE_DIR + "conf/disable_verbose_log");
|
||||
static final File mDisableModulesLogsFlag = new File(XposedApp.BASE_DIR + "conf/disable_modules_log");
|
||||
static final File mVerboseLogProcessID = new File(XposedApp.BASE_DIR + "log/all.pid");
|
||||
static final File mModulesLogProcessID = new File(XposedApp.BASE_DIR + "log/error.pid");
|
||||
View rootView;
|
||||
private Preference stopVerboseLog;
|
||||
private Preference stopLog;
|
||||
public static class SettingsFragment extends PreferenceFragmentCompat {
|
||||
static final File disableResourcesFlag = new File(XposedApp.BASE_DIR + "conf/disable_resources");
|
||||
static final File dynamicModulesFlag = new File(XposedApp.BASE_DIR + "conf/dynamicmodules");
|
||||
static final File deoptBootFlag = new File(XposedApp.BASE_DIR + "conf/deoptbootimage");
|
||||
static final File whiteListModeFlag = new File(XposedApp.BASE_DIR + "conf/usewhitelist");
|
||||
static final File blackWhiteListModeFlag = new File(XposedApp.BASE_DIR + "conf/blackwhitelist");
|
||||
static final File disableVerboseLogsFlag = new File(XposedApp.BASE_DIR + "conf/disable_verbose_log");
|
||||
static final File disableModulesLogsFlag = new File(XposedApp.BASE_DIR + "conf/disable_modules_log");
|
||||
static final File verboseLogProcessID = new File(XposedApp.BASE_DIR + "log/all.pid");
|
||||
static final File modulesLogProcessID = new File(XposedApp.BASE_DIR + "log/error.pid");
|
||||
|
||||
static SettingsFragment newInstance(View rootView) {
|
||||
SettingsFragment fragment = new SettingsFragment();
|
||||
fragment.setRootView(rootView);
|
||||
return fragment;
|
||||
}
|
||||
|
||||
@SuppressWarnings("SameParameterValue")
|
||||
@SuppressLint({"WorldReadableFiles", "WorldWriteableFiles"})
|
||||
static void setFilePermissionsFromMode(String name, int mode) {
|
||||
int perms = FileUtils.S_IRUSR | FileUtils.S_IWUSR
|
||||
|
|
@ -89,331 +80,337 @@ public class SettingsActivity extends BaseActivity {
|
|||
FileUtils.setPermissions(name, perms, -1, -1);
|
||||
}
|
||||
|
||||
void setRootView(View rootView) {
|
||||
this.rootView = rootView;
|
||||
}
|
||||
|
||||
@SuppressLint({"ObsoleteSdkInt", "WorldReadableFiles"})
|
||||
@Override
|
||||
public void onCreatePreferencesFix(Bundle savedInstanceState, String rootKey) {
|
||||
addPreferencesFromResource(R.xml.prefs);
|
||||
|
||||
stopVerboseLog = findPreference("stop_verbose_log");
|
||||
stopLog = findPreference("stop_log");
|
||||
|
||||
findPreference("release_type_global").setOnPreferenceChangeListener((preference, newValue) -> {
|
||||
RepoLoader.getInstance().setReleaseTypeGlobal((String) newValue);
|
||||
return true;
|
||||
});
|
||||
|
||||
SwitchPreferenceCompat prefWhiteListMode = findPreference("white_list_switch");
|
||||
Objects.requireNonNull(prefWhiteListMode).setChecked(mWhiteListModeFlag.exists());
|
||||
prefWhiteListMode.setOnPreferenceChangeListener((preference, newValue) -> {
|
||||
boolean enabled = (Boolean) newValue;
|
||||
if (enabled) {
|
||||
FileOutputStream fos = null;
|
||||
try {
|
||||
fos = new FileOutputStream(mWhiteListModeFlag.getPath());
|
||||
setFilePermissionsFromMode(mWhiteListModeFlag.getPath(), MODE_WORLD_READABLE);
|
||||
} catch (FileNotFoundException e) {
|
||||
Toast.makeText(getActivity(), e.getMessage(), Toast.LENGTH_SHORT).show();
|
||||
} finally {
|
||||
if (fos != null) {
|
||||
try {
|
||||
fos.close();
|
||||
} catch (IOException e) {
|
||||
Toast.makeText(getActivity(), e.getMessage(), Toast.LENGTH_SHORT).show();
|
||||
try {
|
||||
mWhiteListModeFlag.createNewFile();
|
||||
} catch (IOException e1) {
|
||||
Toast.makeText(getActivity(), e1.getMessage(), Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
mWhiteListModeFlag.delete();
|
||||
}
|
||||
return (enabled == mWhiteListModeFlag.exists());
|
||||
});
|
||||
|
||||
SwitchPreferenceCompat prefVerboseLogs = findPreference("disable_verbose_log");
|
||||
Objects.requireNonNull(prefVerboseLogs).setChecked(mDisableVerboseLogsFlag.exists());
|
||||
prefVerboseLogs.setOnPreferenceChangeListener((preference, newValue) -> {
|
||||
boolean enabled = (Boolean) newValue;
|
||||
if (enabled) {
|
||||
FileOutputStream fos = null;
|
||||
try {
|
||||
fos = new FileOutputStream(mDisableVerboseLogsFlag.getPath());
|
||||
setFilePermissionsFromMode(mDisableVerboseLogsFlag.getPath(), MODE_WORLD_READABLE);
|
||||
} catch (FileNotFoundException e) {
|
||||
Toast.makeText(getActivity(), e.getMessage(), Toast.LENGTH_SHORT).show();
|
||||
} finally {
|
||||
if (fos != null) {
|
||||
try {
|
||||
fos.close();
|
||||
} catch (IOException e) {
|
||||
Toast.makeText(getActivity(), e.getMessage(), Toast.LENGTH_SHORT).show();
|
||||
try {
|
||||
mDisableVerboseLogsFlag.createNewFile();
|
||||
} catch (IOException e1) {
|
||||
Toast.makeText(getActivity(), e1.getMessage(), Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
mDisableVerboseLogsFlag.delete();
|
||||
}
|
||||
return (enabled == mDisableVerboseLogsFlag.exists());
|
||||
});
|
||||
|
||||
SwitchPreferenceCompat prefModulesLogs = findPreference("disable_modules_log");
|
||||
Objects.requireNonNull(prefModulesLogs).setChecked(mDisableModulesLogsFlag.exists());
|
||||
prefModulesLogs.setOnPreferenceChangeListener((preference, newValue) -> {
|
||||
boolean enabled = (Boolean) newValue;
|
||||
if (enabled) {
|
||||
FileOutputStream fos = null;
|
||||
try {
|
||||
fos = new FileOutputStream(mDisableModulesLogsFlag.getPath());
|
||||
setFilePermissionsFromMode(mDisableModulesLogsFlag.getPath(), MODE_WORLD_READABLE);
|
||||
} catch (FileNotFoundException e) {
|
||||
Toast.makeText(getActivity(), e.getMessage(), Toast.LENGTH_SHORT).show();
|
||||
} finally {
|
||||
if (fos != null) {
|
||||
try {
|
||||
fos.close();
|
||||
} catch (IOException e) {
|
||||
Toast.makeText(getActivity(), e.getMessage(), Toast.LENGTH_SHORT).show();
|
||||
try {
|
||||
mDisableModulesLogsFlag.createNewFile();
|
||||
} catch (IOException e1) {
|
||||
Toast.makeText(getActivity(), e1.getMessage(), Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
mDisableModulesLogsFlag.delete();
|
||||
}
|
||||
return (enabled == mDisableModulesLogsFlag.exists());
|
||||
});
|
||||
|
||||
SwitchPreferenceCompat prefBlackWhiteListMode = findPreference("black_white_list_switch");
|
||||
Objects.requireNonNull(prefBlackWhiteListMode).setChecked(mBlackWhiteListModeFlag.exists());
|
||||
prefBlackWhiteListMode.setOnPreferenceChangeListener((preference, newValue) -> {
|
||||
boolean enabled = (Boolean) newValue;
|
||||
if (enabled) {
|
||||
FileOutputStream fos = null;
|
||||
try {
|
||||
fos = new FileOutputStream(mBlackWhiteListModeFlag.getPath());
|
||||
setFilePermissionsFromMode(mBlackWhiteListModeFlag.getPath(), MODE_WORLD_READABLE);
|
||||
} catch (FileNotFoundException e) {
|
||||
Toast.makeText(getActivity(), e.getMessage(), Toast.LENGTH_SHORT).show();
|
||||
} finally {
|
||||
if (fos != null) {
|
||||
try {
|
||||
fos.close();
|
||||
} catch (IOException e) {
|
||||
Toast.makeText(getActivity(), e.getMessage(), Toast.LENGTH_SHORT).show();
|
||||
try {
|
||||
mBlackWhiteListModeFlag.createNewFile();
|
||||
} catch (IOException e1) {
|
||||
Toast.makeText(getActivity(), e1.getMessage(), Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
mBlackWhiteListModeFlag.delete();
|
||||
}
|
||||
return (enabled == mBlackWhiteListModeFlag.exists());
|
||||
});
|
||||
|
||||
SwitchPreferenceCompat prefEnableDeopt = findPreference("enable_boot_image_deopt");
|
||||
Objects.requireNonNull(prefEnableDeopt).setChecked(mDeoptBootFlag.exists());
|
||||
prefEnableDeopt.setOnPreferenceChangeListener((preference, newValue) -> {
|
||||
boolean enabled = (Boolean) newValue;
|
||||
if (enabled) {
|
||||
FileOutputStream fos = null;
|
||||
try {
|
||||
fos = new FileOutputStream(mDeoptBootFlag.getPath());
|
||||
setFilePermissionsFromMode(mDeoptBootFlag.getPath(), MODE_WORLD_READABLE);
|
||||
} catch (FileNotFoundException e) {
|
||||
Toast.makeText(getActivity(), e.getMessage(), Toast.LENGTH_SHORT).show();
|
||||
} finally {
|
||||
if (fos != null) {
|
||||
try {
|
||||
fos.close();
|
||||
} catch (IOException e) {
|
||||
Toast.makeText(getActivity(), e.getMessage(), Toast.LENGTH_SHORT).show();
|
||||
try {
|
||||
mDeoptBootFlag.createNewFile();
|
||||
} catch (IOException e1) {
|
||||
Toast.makeText(getActivity(), e1.getMessage(), Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
mDeoptBootFlag.delete();
|
||||
}
|
||||
return (enabled == mDeoptBootFlag.exists());
|
||||
});
|
||||
|
||||
SwitchPreferenceCompat prefDynamicResources = findPreference("is_dynamic_modules");
|
||||
Objects.requireNonNull(prefDynamicResources).setChecked(mDynamicModulesFlag.exists());
|
||||
prefDynamicResources.setOnPreferenceChangeListener((preference, newValue) -> {
|
||||
boolean enabled = (Boolean) newValue;
|
||||
if (enabled) {
|
||||
FileOutputStream fos = null;
|
||||
try {
|
||||
fos = new FileOutputStream(mDynamicModulesFlag.getPath());
|
||||
setFilePermissionsFromMode(mDynamicModulesFlag.getPath(), MODE_WORLD_READABLE);
|
||||
} catch (FileNotFoundException e) {
|
||||
Toast.makeText(getActivity(), e.getMessage(), Toast.LENGTH_SHORT).show();
|
||||
} finally {
|
||||
if (fos != null) {
|
||||
try {
|
||||
fos.close();
|
||||
} catch (IOException e) {
|
||||
Toast.makeText(getActivity(), e.getMessage(), Toast.LENGTH_SHORT).show();
|
||||
try {
|
||||
mDynamicModulesFlag.createNewFile();
|
||||
} catch (IOException e1) {
|
||||
Toast.makeText(getActivity(), e1.getMessage(), Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
mDynamicModulesFlag.delete();
|
||||
}
|
||||
return (enabled == mDynamicModulesFlag.exists());
|
||||
});
|
||||
|
||||
SwitchPreferenceCompat prefDisableResources = findPreference("disable_resources");
|
||||
Objects.requireNonNull(prefDisableResources).setChecked(mDisableResourcesFlag.exists());
|
||||
prefDisableResources.setOnPreferenceChangeListener((preference, newValue) -> {
|
||||
boolean enabled = (Boolean) newValue;
|
||||
if (enabled) {
|
||||
FileOutputStream fos = null;
|
||||
try {
|
||||
fos = new FileOutputStream(mDisableResourcesFlag.getPath());
|
||||
setFilePermissionsFromMode(mDisableResourcesFlag.getPath(), MODE_WORLD_READABLE);
|
||||
} catch (FileNotFoundException e) {
|
||||
Toast.makeText(getActivity(), e.getMessage(), Toast.LENGTH_SHORT).show();
|
||||
} finally {
|
||||
if (fos != null) {
|
||||
try {
|
||||
fos.close();
|
||||
} catch (IOException e) {
|
||||
Toast.makeText(getActivity(), e.getMessage(), Toast.LENGTH_SHORT).show();
|
||||
try {
|
||||
mDisableResourcesFlag.createNewFile();
|
||||
} catch (IOException e1) {
|
||||
Toast.makeText(getActivity(), e1.getMessage(), Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
mDisableResourcesFlag.delete();
|
||||
}
|
||||
return (enabled == mDisableResourcesFlag.exists());
|
||||
});
|
||||
|
||||
SwitchPreferenceCompat transparent_status_bar = findPreference("transparent_status_bar");
|
||||
Objects.requireNonNull(transparent_status_bar).setOnPreferenceChangeListener((preference, newValue) -> {
|
||||
boolean enabled = (Boolean) newValue;
|
||||
Activity activity = getActivity();
|
||||
if (activity != null && !XposedApp.getPreferences().getBoolean("black_dark_theme", false)) {
|
||||
if (enabled) {
|
||||
Objects.requireNonNull(getActivity()).getWindow().setStatusBarColor(ContextCompat.getColor(activity, R.color.colorActionBar));
|
||||
} else {
|
||||
Objects.requireNonNull(getActivity()).getWindow().setStatusBarColor(ContextCompat.getColor(activity, R.color.colorPrimaryDark));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
Preference compat_mode = findPreference("compat_mode");
|
||||
if (compat_mode != null) {
|
||||
compat_mode.setOnPreferenceClickListener(preference -> {
|
||||
Intent intent = new Intent();
|
||||
intent.setClass(Objects.requireNonNull(getContext()), CompatListActivity.class);
|
||||
Objects.requireNonNull(getActivity()).startActivity(intent);
|
||||
Preference stopVerboseLog = findPreference("stop_verbose_log");
|
||||
if (stopVerboseLog != null) {
|
||||
stopVerboseLog.setOnPreferenceClickListener(preference -> {
|
||||
areYouSure(R.string.stop_verbose_log_summary, (dialog, which) -> Shell.su("kill $(cat " + verboseLogProcessID.getAbsolutePath() + ")").exec());
|
||||
return true;
|
||||
});
|
||||
}
|
||||
Preference stopLog = findPreference("stop_log");
|
||||
if (stopLog != null) {
|
||||
stopLog.setOnPreferenceClickListener(preference -> {
|
||||
areYouSure(R.string.stop_log_summary, (dialog, which) -> Shell.su("kill $(cat " + modulesLogProcessID.getAbsolutePath() + ")").exec());
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
|
||||
getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
|
||||
getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
|
||||
if (key.contains("theme") || key.equals("ignore_chinese")) {
|
||||
AppCompatDelegate.setDefaultNightMode(XposedApp.getPreferences().getInt("theme", 0));
|
||||
Objects.requireNonNull(getActivity()).recreate();
|
||||
Preference releaseType = findPreference("release_type_global");
|
||||
if (releaseType != null) {
|
||||
releaseType.setOnPreferenceChangeListener((preference, newValue) -> {
|
||||
RepoLoader.getInstance().setReleaseTypeGlobal((String) newValue);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceClick(Preference preference) {
|
||||
SettingsActivity act = (SettingsActivity) getActivity();
|
||||
if (act == null)
|
||||
return false;
|
||||
|
||||
if (preference.getKey().equals(stopVerboseLog.getKey())) {
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
areYouSure(R.string.stop_verbose_log_summary, (dialog, which) -> Shell.su("kill $(cat " + mVerboseLogProcessID.getAbsolutePath() + ")").exec());
|
||||
SwitchPreferenceCompat prefWhiteListMode = findPreference("white_list_switch");
|
||||
if (prefWhiteListMode != null) {
|
||||
prefWhiteListMode.setChecked(whiteListModeFlag.exists());
|
||||
prefWhiteListMode.setOnPreferenceChangeListener((preference, newValue) -> {
|
||||
boolean enabled = (Boolean) newValue;
|
||||
if (enabled) {
|
||||
FileOutputStream fos = null;
|
||||
try {
|
||||
fos = new FileOutputStream(whiteListModeFlag.getPath());
|
||||
setFilePermissionsFromMode(whiteListModeFlag.getPath(), MODE_WORLD_READABLE);
|
||||
} catch (FileNotFoundException e) {
|
||||
Toast.makeText(getActivity(), e.getMessage(), Toast.LENGTH_SHORT).show();
|
||||
} finally {
|
||||
if (fos != null) {
|
||||
try {
|
||||
fos.close();
|
||||
} catch (IOException e) {
|
||||
Toast.makeText(getActivity(), e.getMessage(), Toast.LENGTH_SHORT).show();
|
||||
try {
|
||||
whiteListModeFlag.createNewFile();
|
||||
} catch (IOException e1) {
|
||||
Toast.makeText(getActivity(), e1.getMessage(), Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
whiteListModeFlag.delete();
|
||||
}
|
||||
};
|
||||
} else if (preference.getKey().equals(stopLog.getKey())) {
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
areYouSure(R.string.stop_log_summary, (dialog, which) -> Shell.su("kill $(cat " + mModulesLogProcessID.getAbsolutePath() + ")").exec());
|
||||
}
|
||||
};
|
||||
return (enabled == whiteListModeFlag.exists());
|
||||
});
|
||||
}
|
||||
|
||||
SwitchPreferenceCompat prefVerboseLogs = findPreference("disable_verbose_log");
|
||||
if (prefVerboseLogs != null) {
|
||||
prefVerboseLogs.setChecked(disableVerboseLogsFlag.exists());
|
||||
prefVerboseLogs.setOnPreferenceChangeListener((preference, newValue) -> {
|
||||
boolean enabled = (Boolean) newValue;
|
||||
if (enabled) {
|
||||
FileOutputStream fos = null;
|
||||
try {
|
||||
fos = new FileOutputStream(disableVerboseLogsFlag.getPath());
|
||||
setFilePermissionsFromMode(disableVerboseLogsFlag.getPath(), MODE_WORLD_READABLE);
|
||||
} catch (FileNotFoundException e) {
|
||||
Toast.makeText(getActivity(), e.getMessage(), Toast.LENGTH_SHORT).show();
|
||||
} finally {
|
||||
if (fos != null) {
|
||||
try {
|
||||
fos.close();
|
||||
} catch (IOException e) {
|
||||
Toast.makeText(getActivity(), e.getMessage(), Toast.LENGTH_SHORT).show();
|
||||
try {
|
||||
disableVerboseLogsFlag.createNewFile();
|
||||
} catch (IOException e1) {
|
||||
Toast.makeText(getActivity(), e1.getMessage(), Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
disableVerboseLogsFlag.delete();
|
||||
}
|
||||
return (enabled == disableVerboseLogsFlag.exists());
|
||||
});
|
||||
}
|
||||
|
||||
SwitchPreferenceCompat prefModulesLogs = findPreference("disable_modules_log");
|
||||
if (prefModulesLogs != null) {
|
||||
prefModulesLogs.setChecked(disableModulesLogsFlag.exists());
|
||||
prefModulesLogs.setOnPreferenceChangeListener((preference, newValue) -> {
|
||||
boolean enabled = (Boolean) newValue;
|
||||
if (enabled) {
|
||||
FileOutputStream fos = null;
|
||||
try {
|
||||
fos = new FileOutputStream(disableModulesLogsFlag.getPath());
|
||||
setFilePermissionsFromMode(disableModulesLogsFlag.getPath(), MODE_WORLD_READABLE);
|
||||
} catch (FileNotFoundException e) {
|
||||
Toast.makeText(getActivity(), e.getMessage(), Toast.LENGTH_SHORT).show();
|
||||
} finally {
|
||||
if (fos != null) {
|
||||
try {
|
||||
fos.close();
|
||||
} catch (IOException e) {
|
||||
Toast.makeText(getActivity(), e.getMessage(), Toast.LENGTH_SHORT).show();
|
||||
try {
|
||||
disableModulesLogsFlag.createNewFile();
|
||||
} catch (IOException e1) {
|
||||
Toast.makeText(getActivity(), e1.getMessage(), Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
disableModulesLogsFlag.delete();
|
||||
}
|
||||
return (enabled == disableModulesLogsFlag.exists());
|
||||
});
|
||||
}
|
||||
|
||||
SwitchPreferenceCompat prefBlackWhiteListMode = findPreference("black_white_list_switch");
|
||||
if (prefBlackWhiteListMode != null) {
|
||||
prefBlackWhiteListMode.setChecked(blackWhiteListModeFlag.exists());
|
||||
prefBlackWhiteListMode.setOnPreferenceChangeListener((preference, newValue) -> {
|
||||
boolean enabled = (Boolean) newValue;
|
||||
if (enabled) {
|
||||
FileOutputStream fos = null;
|
||||
try {
|
||||
fos = new FileOutputStream(blackWhiteListModeFlag.getPath());
|
||||
setFilePermissionsFromMode(blackWhiteListModeFlag.getPath(), MODE_WORLD_READABLE);
|
||||
} catch (FileNotFoundException e) {
|
||||
Toast.makeText(getActivity(), e.getMessage(), Toast.LENGTH_SHORT).show();
|
||||
} finally {
|
||||
if (fos != null) {
|
||||
try {
|
||||
fos.close();
|
||||
} catch (IOException e) {
|
||||
Toast.makeText(getActivity(), e.getMessage(), Toast.LENGTH_SHORT).show();
|
||||
try {
|
||||
blackWhiteListModeFlag.createNewFile();
|
||||
} catch (IOException e1) {
|
||||
Toast.makeText(getActivity(), e1.getMessage(), Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
blackWhiteListModeFlag.delete();
|
||||
}
|
||||
return (enabled == blackWhiteListModeFlag.exists());
|
||||
});
|
||||
}
|
||||
|
||||
SwitchPreferenceCompat prefEnableDeopt = findPreference("enable_boot_image_deopt");
|
||||
if (prefEnableDeopt != null) {
|
||||
prefEnableDeopt.setChecked(deoptBootFlag.exists());
|
||||
prefEnableDeopt.setOnPreferenceChangeListener((preference, newValue) -> {
|
||||
boolean enabled = (Boolean) newValue;
|
||||
if (enabled) {
|
||||
FileOutputStream fos = null;
|
||||
try {
|
||||
fos = new FileOutputStream(deoptBootFlag.getPath());
|
||||
setFilePermissionsFromMode(deoptBootFlag.getPath(), MODE_WORLD_READABLE);
|
||||
} catch (FileNotFoundException e) {
|
||||
Toast.makeText(getActivity(), e.getMessage(), Toast.LENGTH_SHORT).show();
|
||||
} finally {
|
||||
if (fos != null) {
|
||||
try {
|
||||
fos.close();
|
||||
} catch (IOException e) {
|
||||
Toast.makeText(getActivity(), e.getMessage(), Toast.LENGTH_SHORT).show();
|
||||
try {
|
||||
deoptBootFlag.createNewFile();
|
||||
} catch (IOException e1) {
|
||||
Toast.makeText(getActivity(), e1.getMessage(), Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
deoptBootFlag.delete();
|
||||
}
|
||||
return (enabled == deoptBootFlag.exists());
|
||||
});
|
||||
}
|
||||
|
||||
SwitchPreferenceCompat prefDynamicResources = findPreference("is_dynamic_modules");
|
||||
if (prefDynamicResources != null) {
|
||||
prefDynamicResources.setChecked(dynamicModulesFlag.exists());
|
||||
prefDynamicResources.setOnPreferenceChangeListener((preference, newValue) -> {
|
||||
boolean enabled = (Boolean) newValue;
|
||||
if (enabled) {
|
||||
FileOutputStream fos = null;
|
||||
try {
|
||||
fos = new FileOutputStream(dynamicModulesFlag.getPath());
|
||||
setFilePermissionsFromMode(dynamicModulesFlag.getPath(), MODE_WORLD_READABLE);
|
||||
} catch (FileNotFoundException e) {
|
||||
Toast.makeText(getActivity(), e.getMessage(), Toast.LENGTH_SHORT).show();
|
||||
} finally {
|
||||
if (fos != null) {
|
||||
try {
|
||||
fos.close();
|
||||
} catch (IOException e) {
|
||||
Toast.makeText(getActivity(), e.getMessage(), Toast.LENGTH_SHORT).show();
|
||||
try {
|
||||
dynamicModulesFlag.createNewFile();
|
||||
} catch (IOException e1) {
|
||||
Toast.makeText(getActivity(), e1.getMessage(), Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
dynamicModulesFlag.delete();
|
||||
}
|
||||
return (enabled == dynamicModulesFlag.exists());
|
||||
});
|
||||
}
|
||||
|
||||
SwitchPreferenceCompat prefDisableResources = findPreference("disable_resources");
|
||||
if (prefDisableResources != null) {
|
||||
prefDisableResources.setChecked(disableResourcesFlag.exists());
|
||||
prefDisableResources.setOnPreferenceChangeListener((preference, newValue) -> {
|
||||
boolean enabled = (Boolean) newValue;
|
||||
if (enabled) {
|
||||
FileOutputStream fos = null;
|
||||
try {
|
||||
fos = new FileOutputStream(disableResourcesFlag.getPath());
|
||||
setFilePermissionsFromMode(disableResourcesFlag.getPath(), MODE_WORLD_READABLE);
|
||||
} catch (FileNotFoundException e) {
|
||||
Toast.makeText(getActivity(), e.getMessage(), Toast.LENGTH_SHORT).show();
|
||||
} finally {
|
||||
if (fos != null) {
|
||||
try {
|
||||
fos.close();
|
||||
} catch (IOException e) {
|
||||
Toast.makeText(getActivity(), e.getMessage(), Toast.LENGTH_SHORT).show();
|
||||
try {
|
||||
disableResourcesFlag.createNewFile();
|
||||
} catch (IOException e1) {
|
||||
Toast.makeText(getActivity(), e1.getMessage(), Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
disableResourcesFlag.delete();
|
||||
}
|
||||
return (enabled == disableResourcesFlag.exists());
|
||||
});
|
||||
}
|
||||
|
||||
SwitchPreferenceCompat transparent = findPreference("transparent_status_bar");
|
||||
if (transparent != null) {
|
||||
transparent.setOnPreferenceChangeListener((preference, newValue) -> {
|
||||
boolean enabled = (Boolean) newValue;
|
||||
Activity activity = getActivity();
|
||||
if (activity != null && !XposedApp.getPreferences().getBoolean("black_dark_theme", false)) {
|
||||
if (enabled) {
|
||||
activity.getWindow().setStatusBarColor(ContextCompat.getColor(activity, R.color.colorActionBar));
|
||||
} else {
|
||||
activity.getWindow().setStatusBarColor(ContextCompat.getColor(activity, R.color.colorPrimaryDark));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
Preference compat_mode = findPreference("compat_mode");
|
||||
if (compat_mode != null) {
|
||||
compat_mode.setOnPreferenceClickListener(preference -> {
|
||||
Activity activity = getActivity();
|
||||
if (activity != null) {
|
||||
Intent intent = new Intent();
|
||||
intent.setClass(activity, CompatListActivity.class);
|
||||
activity.startActivity(intent);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
IntegerListPreference theme = findPreference("theme");
|
||||
if (theme != null) {
|
||||
theme.setOnPreferenceChangeListener((preference, newValue) -> {
|
||||
AppCompatDelegate.setDefaultNightMode(Integer.parseInt((String) newValue));
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
SwitchPreferenceCompat black_dark_theme = findPreference("black_dark_theme");
|
||||
if (black_dark_theme != null) {
|
||||
black_dark_theme.setOnPreferenceChangeListener((preference, newValue) -> {
|
||||
Activity activity = getActivity();
|
||||
if (activity != null) {
|
||||
activity.recreate();
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void areYouSure(int contentTextId, DialogInterface.OnClickListener listener) {
|
||||
new MaterialAlertDialogBuilder(Objects.requireNonNull(getActivity())).setTitle(R.string.areyousure)
|
||||
.setMessage(contentTextId)
|
||||
.setPositiveButton(android.R.string.yes, listener)
|
||||
.setNegativeButton(android.R.string.no, null)
|
||||
.show();
|
||||
Activity activity = getActivity();
|
||||
if (activity != null) {
|
||||
new MaterialAlertDialogBuilder(activity)
|
||||
.setTitle(R.string.areyousure)
|
||||
.setMessage(contentTextId)
|
||||
.setPositiveButton(android.R.string.yes, listener)
|
||||
.setNegativeButton(android.R.string.no, null)
|
||||
.show();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
if (rootView == null) {
|
||||
return;
|
||||
}
|
||||
//ActionBarShadowController.attachToRecyclerView((AppCompatActivity) getActivity(), getListView());
|
||||
((LinearLayout) ((FrameLayout) rootView.findViewById(R.id.container)).getChildAt(0)).setClipToPadding(false);
|
||||
((LinearLayout) ((FrameLayout) rootView.findViewById(R.id.container)).getChildAt(0)).setClipChildren(false);
|
||||
((FrameLayout) ((LinearLayout) view).getChildAt(0)).setClipChildren(false);
|
||||
((FrameLayout) ((LinearLayout) view).getChildAt(0)).setClipToPadding(false);
|
||||
((LinearLayout) view).setClipToPadding(false);
|
||||
((LinearLayout) view).setClipChildren(false);
|
||||
((FrameLayout) getListView().getParent()).setClipChildren(false);
|
||||
((FrameLayout) getListView().getParent()).setClipToPadding(false);
|
||||
ViewCompat.setOnApplyWindowInsetsListener(view, (v, insets) -> {
|
||||
getListView().setPadding(0, 0, 0, insets.getSystemWindowInsetBottom());
|
||||
return insets;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,14 +11,15 @@ import android.util.Log;
|
|||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||
|
||||
import org.meowcat.edxposed.manager.databinding.StatusInstallerBinding;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
|
|
@ -27,28 +28,25 @@ import java.lang.reflect.Method;
|
|||
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
public class StatusInstallerFragment extends Fragment {
|
||||
private static StatusInstallerBinding binding;
|
||||
private static String updateLink;
|
||||
|
||||
private static AppCompatActivity sActivity;
|
||||
private static String mUpdateLink;
|
||||
private static View mUpdateView;
|
||||
private static View mUpdateButton;
|
||||
static void setUpdate(final String link, final String changelog, Context context) {
|
||||
updateLink = link;
|
||||
|
||||
static void setUpdate(final String link, final String changelog, Context mContext) {
|
||||
mUpdateLink = link;
|
||||
|
||||
mUpdateView.setVisibility(View.VISIBLE);
|
||||
mUpdateButton.setVisibility(View.VISIBLE);
|
||||
mUpdateButton.setOnClickListener(v -> new MaterialAlertDialogBuilder(sActivity)
|
||||
binding.updateView.setVisibility(View.VISIBLE);
|
||||
binding.clickToUpdate.setVisibility(View.VISIBLE);
|
||||
binding.clickToUpdate.setOnClickListener(v -> new MaterialAlertDialogBuilder(context)
|
||||
.setTitle(R.string.changes)
|
||||
.setMessage(Html.fromHtml(changelog))
|
||||
.setPositiveButton(R.string.update, (dialog, which) -> update(mContext))
|
||||
.setPositiveButton(R.string.update, (dialog, which) -> update(context))
|
||||
.setNegativeButton(R.string.later, null).show());
|
||||
}
|
||||
|
||||
private static void update(Context mContext) {
|
||||
Uri uri = Uri.parse(mUpdateLink);
|
||||
private static void update(Context context) {
|
||||
Uri uri = Uri.parse(updateLink);
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
|
||||
mContext.startActivity(intent);
|
||||
context.startActivity(intent);
|
||||
}
|
||||
|
||||
private static String getCompleteArch() {
|
||||
|
|
@ -73,6 +71,7 @@ public class StatusInstallerFragment extends Fragment {
|
|||
return info + " (" + getArch() + ")";
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
private static String getArch() {
|
||||
if (Build.CPU_ABI.equals("arm64-v8a")) {
|
||||
return "arm64";
|
||||
|
|
@ -91,20 +90,10 @@ public class StatusInstallerFragment extends Fragment {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
sActivity = (AppCompatActivity) getActivity();
|
||||
}
|
||||
|
||||
@SuppressLint("WorldReadableFiles")
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
View v = inflater.inflate(R.layout.status_installer, container, false);
|
||||
|
||||
mUpdateView = v.findViewById(R.id.updateView);
|
||||
mUpdateButton = v.findViewById(R.id.click_to_update);
|
||||
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
binding = StatusInstallerBinding.inflate(inflater, container, false);
|
||||
|
||||
String installedXposedVersion;
|
||||
try {
|
||||
|
|
@ -113,31 +102,24 @@ public class StatusInstallerFragment extends Fragment {
|
|||
installedXposedVersion = null;
|
||||
}
|
||||
|
||||
TextView api = v.findViewById(R.id.api);
|
||||
TextView framework = v.findViewById(R.id.framework);
|
||||
TextView manager = v.findViewById(R.id.manager);
|
||||
TextView androidSdk = v.findViewById(R.id.android_version);
|
||||
TextView manufacturer = v.findViewById(R.id.ic_manufacturer);
|
||||
TextView cpu = v.findViewById(R.id.cpu);
|
||||
|
||||
String mAppVer = "v" + BuildConfig.VERSION_NAME + " (" + BuildConfig.VERSION_CODE + ")";
|
||||
manager.setText(mAppVer);
|
||||
binding.manager.setText(mAppVer);
|
||||
if (installedXposedVersion != null) {
|
||||
int installedXposedVersionInt = extractIntPart(installedXposedVersion);
|
||||
String installedXposedVersionStr = installedXposedVersionInt + ".0";
|
||||
api.setText(installedXposedVersionStr);
|
||||
framework.setText(installedXposedVersion.replace(installedXposedVersionStr + "-", ""));
|
||||
binding.api.setText(installedXposedVersionStr);
|
||||
binding.framework.setText(installedXposedVersion.replace(installedXposedVersionStr + "-", ""));
|
||||
}
|
||||
|
||||
androidSdk.setText(getString(R.string.android_sdk, getAndroidVersion(), Build.VERSION.RELEASE, Build.VERSION.SDK_INT));
|
||||
manufacturer.setText(getUIFramework());
|
||||
cpu.setText(getCompleteArch());
|
||||
binding.androidVersion.setText(getString(R.string.android_sdk, getAndroidVersion(), Build.VERSION.RELEASE, Build.VERSION.SDK_INT));
|
||||
binding.manufacturer.setText(getUIFramework());
|
||||
binding.cpu.setText(getCompleteArch());
|
||||
|
||||
determineVerifiedBootState(v);
|
||||
return v;
|
||||
determineVerifiedBootState(binding);
|
||||
return binding.getRoot();
|
||||
}
|
||||
|
||||
private void determineVerifiedBootState(View v) {
|
||||
private void determineVerifiedBootState(StatusInstallerBinding binding) {
|
||||
try {
|
||||
@SuppressLint("PrivateApi") Class<?> c = Class.forName("android.os.SystemProperties");
|
||||
Method m = c.getDeclaredMethod("get", String.class, String.class);
|
||||
|
|
@ -150,17 +132,16 @@ public class StatusInstallerFragment extends Fragment {
|
|||
boolean verified = !propSystemVerified.equals("0");
|
||||
boolean detected = !propState.isEmpty() || fileDmVerityModule.exists();
|
||||
|
||||
TextView tv = v.findViewById(R.id.dmverity);
|
||||
if (verified) {
|
||||
tv.setText(R.string.verified_boot_active);
|
||||
tv.setTextColor(getResources().getColor(R.color.warning));
|
||||
binding.dmverity.setText(R.string.verified_boot_active);
|
||||
binding.dmverity.setTextColor(getResources().getColor(R.color.warning));
|
||||
} else if (detected) {
|
||||
tv.setText(R.string.verified_boot_deactivated);
|
||||
v.findViewById(R.id.dmverity_explanation).setVisibility(View.GONE);
|
||||
binding.dmverity.setText(R.string.verified_boot_deactivated);
|
||||
binding.dmverityExplanation.setVisibility(View.GONE);
|
||||
} else {
|
||||
tv.setText(R.string.verified_boot_none);
|
||||
tv.setTextColor(getResources().getColor(R.color.warning));
|
||||
v.findViewById(R.id.dmverity_explanation).setVisibility(View.GONE);
|
||||
binding.dmverity.setText(R.string.verified_boot_none);
|
||||
binding.dmverity.setTextColor(getResources().getColor(R.color.warning));
|
||||
binding.dmverityExplanation.setVisibility(View.GONE);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e(XposedApp.TAG, "Could not detect Verified Boot state", e);
|
||||
|
|
@ -241,7 +222,7 @@ public class StatusInstallerFragment extends Fragment {
|
|||
case 28:
|
||||
return "Pie";
|
||||
case 29:
|
||||
return "Q";
|
||||
return "Ten";
|
||||
case 30:
|
||||
return "R";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,17 +47,16 @@ public class XposedApp extends de.robv.android.xposed.installer.XposedApp implem
|
|||
? "/data/user_de/0/" + BuildConfig.APPLICATION_ID + "/" : BASE_DIR_LEGACY;
|
||||
public static final String ENABLED_MODULES_LIST_FILE = (Build.VERSION.SDK_INT >= 24
|
||||
? "/data/user_de/0/" + BuildConfig.APPLICATION_ID + "/" : BASE_DIR_LEGACY) + "conf/enabled_modules.list";
|
||||
public static int WRITE_EXTERNAL_PERMISSION = 69;
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
private static XposedApp mInstance = null;
|
||||
private static Thread mUiThread;
|
||||
private static Handler mMainHandler;
|
||||
private SharedPreferences mPref;
|
||||
private AppCompatActivity mCurrentActivity = null;
|
||||
private boolean mIsUiLoaded = false;
|
||||
private static XposedApp instance = null;
|
||||
private static Thread uiThread;
|
||||
private static Handler mainHandler;
|
||||
private SharedPreferences pref;
|
||||
private AppCompatActivity currentActivity = null;
|
||||
private boolean isUiLoaded = false;
|
||||
|
||||
public static XposedApp getInstance() {
|
||||
return mInstance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
public static InstallZipUtil.XposedProp getXposedProp() {
|
||||
|
|
@ -65,35 +64,19 @@ public class XposedApp extends de.robv.android.xposed.installer.XposedApp implem
|
|||
}
|
||||
|
||||
public static void runOnUiThread(Runnable action) {
|
||||
if (Thread.currentThread() != mUiThread) {
|
||||
mMainHandler.post(action);
|
||||
if (Thread.currentThread() != uiThread) {
|
||||
mainHandler.post(action);
|
||||
} else {
|
||||
action.run();
|
||||
}
|
||||
}
|
||||
|
||||
public static File createFolder() {
|
||||
File dir = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Download/EdXposedManager/");
|
||||
|
||||
if (!dir.exists()) dir.mkdir();
|
||||
|
||||
return dir;
|
||||
}
|
||||
|
||||
// public static void postOnUiThread(Runnable action) {
|
||||
// mMainHandler.post(action);
|
||||
// }
|
||||
|
||||
public static Integer getXposedVersion() {
|
||||
return getActiveXposedVersion();
|
||||
}
|
||||
|
||||
public static SharedPreferences getPreferences() {
|
||||
return mInstance.mPref;
|
||||
}
|
||||
|
||||
public static String getDownloadPath() {
|
||||
return getPreferences().getString("download_location", Environment.getExternalStorageDirectory() + "/Download/EdXposedManager/");
|
||||
return instance.pref;
|
||||
}
|
||||
|
||||
public static void mkdirAndChmod(String dir, int permissions) {
|
||||
|
|
@ -134,11 +117,11 @@ public class XposedApp extends de.robv.android.xposed.installer.XposedApp implem
|
|||
}
|
||||
}
|
||||
|
||||
mInstance = this;
|
||||
mUiThread = Thread.currentThread();
|
||||
mMainHandler = new Handler();
|
||||
instance = this;
|
||||
uiThread = Thread.currentThread();
|
||||
mainHandler = new Handler();
|
||||
|
||||
mPref = PreferenceManager.getDefaultSharedPreferences(this);
|
||||
pref = PreferenceManager.getDefaultSharedPreferences(this);
|
||||
|
||||
de.robv.android.xposed.installer.XposedApp.getInstance().reloadXposedProp();
|
||||
createDirectories();
|
||||
|
|
@ -151,8 +134,8 @@ public class XposedApp extends de.robv.android.xposed.installer.XposedApp implem
|
|||
@SuppressLint("SimpleDateFormat") DateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
|
||||
Date date = new Date();
|
||||
|
||||
if (!Objects.requireNonNull(mPref.getString("date", "")).equals(dateFormat.format(date))) {
|
||||
mPref.edit().putString("date", dateFormat.format(date)).apply();
|
||||
if (!Objects.requireNonNull(pref.getString("date", "")).equals(dateFormat.format(date))) {
|
||||
pref.edit().putString("date", dateFormat.format(date)).apply();
|
||||
|
||||
try {
|
||||
Log.i(TAG, String.format("EdXposedManager - %s - %s", BuildConfig.VERSION_CODE, getPackageManager().getPackageInfo(getPackageName(), 0).versionName));
|
||||
|
|
@ -160,7 +143,7 @@ public class XposedApp extends de.robv.android.xposed.installer.XposedApp implem
|
|||
}
|
||||
}
|
||||
|
||||
if (mPref.getBoolean("force_english", false)) {
|
||||
if (pref.getBoolean("force_english", false)) {
|
||||
Resources res = getResources();
|
||||
DisplayMetrics dm = res.getDisplayMetrics();
|
||||
android.content.res.Configuration conf = res.getConfiguration();
|
||||
|
|
@ -189,11 +172,12 @@ public class XposedApp extends de.robv.android.xposed.installer.XposedApp implem
|
|||
File[] files = file.listFiles();
|
||||
if (files != null) for (File f : file.listFiles()) delete(f);
|
||||
}
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
file.delete();
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("JavaReflectionMemberAccess")
|
||||
@SuppressWarnings({"JavaReflectionMemberAccess", "OctalInteger"})
|
||||
@SuppressLint({"PrivateApi", "NewApi"})
|
||||
private void createDirectories() {
|
||||
FileUtils.setPermissions(BASE_DIR, 00777, -1, -1);
|
||||
|
|
@ -216,7 +200,7 @@ public class XposedApp extends de.robv.android.xposed.installer.XposedApp implem
|
|||
final boolean isLoading = RepoLoader.getInstance().isLoading() || ModuleUtil.getInstance().isLoading();
|
||||
runOnUiThread(() -> {
|
||||
synchronized (XposedApp.this) {
|
||||
if (mCurrentActivity != null) {
|
||||
if (currentActivity != null) {
|
||||
if (refreshLayout != null)
|
||||
refreshLayout.setRefreshing(isLoading);
|
||||
}
|
||||
|
|
@ -226,12 +210,12 @@ public class XposedApp extends de.robv.android.xposed.installer.XposedApp implem
|
|||
|
||||
@Override
|
||||
public synchronized void onActivityCreated(@NonNull Activity activity, Bundle savedInstanceState) {
|
||||
if (mIsUiLoaded) {
|
||||
if (isUiLoaded) {
|
||||
return;
|
||||
}
|
||||
|
||||
RepoLoader.getInstance().triggerFirstLoadIfNecessary();
|
||||
mIsUiLoaded = true;
|
||||
isUiLoaded = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -241,13 +225,13 @@ public class XposedApp extends de.robv.android.xposed.installer.XposedApp implem
|
|||
|
||||
@Override
|
||||
public synchronized void onActivityResumed(@NonNull Activity activity) {
|
||||
mCurrentActivity = (AppCompatActivity) activity;
|
||||
currentActivity = (AppCompatActivity) activity;
|
||||
updateProgressIndicator(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void onActivityPaused(Activity activity) {
|
||||
mCurrentActivity = null;
|
||||
currentActivity = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -4,47 +4,49 @@ import android.content.Context;
|
|||
import android.database.Cursor;
|
||||
import android.database.DataSetObserver;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
public abstract class CursorRecyclerViewAdapter<VH extends RecyclerView.ViewHolder> extends RecyclerView.Adapter<VH> {
|
||||
|
||||
private Context mContext;
|
||||
@SuppressWarnings("FieldCanBeLocal")
|
||||
private Context context;
|
||||
|
||||
private Cursor mCursor;
|
||||
private Cursor cursor;
|
||||
|
||||
private boolean mDataValid;
|
||||
private boolean dataValid;
|
||||
|
||||
private int mRowIdColumn;
|
||||
private int rowIdColumn;
|
||||
|
||||
private DataSetObserver mDataSetObserver;
|
||||
private DataSetObserver dataSetObserver;
|
||||
|
||||
public CursorRecyclerViewAdapter(Context context, Cursor cursor) {
|
||||
mContext = context;
|
||||
mCursor = cursor;
|
||||
mDataValid = cursor != null;
|
||||
mRowIdColumn = mDataValid ? mCursor.getColumnIndex("_id") : -1;
|
||||
mDataSetObserver = new NotifyingDataSetObserver();
|
||||
if (mCursor != null) {
|
||||
mCursor.registerDataSetObserver(mDataSetObserver);
|
||||
this.context = context;
|
||||
this.cursor = cursor;
|
||||
dataValid = cursor != null;
|
||||
rowIdColumn = dataValid ? cursor.getColumnIndex("_id") : -1;
|
||||
dataSetObserver = new NotifyingDataSetObserver();
|
||||
if (this.cursor != null) {
|
||||
this.cursor.registerDataSetObserver(dataSetObserver);
|
||||
}
|
||||
}
|
||||
|
||||
public Cursor getCursor() {
|
||||
return mCursor;
|
||||
return cursor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
if (mDataValid && mCursor != null) {
|
||||
return mCursor.getCount();
|
||||
if (dataValid && cursor != null) {
|
||||
return cursor.getCount();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getItemId(int position) {
|
||||
if (mDataValid && mCursor != null && mCursor.moveToPosition(position)) {
|
||||
return mCursor.getLong(mRowIdColumn);
|
||||
if (dataValid && cursor != null && cursor.moveToPosition(position)) {
|
||||
return cursor.getLong(rowIdColumn);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -57,14 +59,14 @@ public abstract class CursorRecyclerViewAdapter<VH extends RecyclerView.ViewHold
|
|||
public abstract void onBindViewHolder(VH viewHolder, Cursor cursor);
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(VH viewHolder, int position) {
|
||||
if (!mDataValid) {
|
||||
public void onBindViewHolder(@NonNull VH viewHolder, int position) {
|
||||
if (!dataValid) {
|
||||
throw new IllegalStateException("this should only be called when the cursor is valid");
|
||||
}
|
||||
if (!mCursor.moveToPosition(position)) {
|
||||
if (!cursor.moveToPosition(position)) {
|
||||
throw new IllegalStateException("couldn't move cursor to position " + position);
|
||||
}
|
||||
onBindViewHolder(viewHolder, mCursor);
|
||||
onBindViewHolder(viewHolder, cursor);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -84,24 +86,24 @@ public abstract class CursorRecyclerViewAdapter<VH extends RecyclerView.ViewHold
|
|||
* closed.
|
||||
*/
|
||||
public Cursor swapCursor(Cursor newCursor) {
|
||||
if (newCursor == mCursor) {
|
||||
if (newCursor == cursor) {
|
||||
return null;
|
||||
}
|
||||
final Cursor oldCursor = mCursor;
|
||||
if (oldCursor != null && mDataSetObserver != null) {
|
||||
oldCursor.unregisterDataSetObserver(mDataSetObserver);
|
||||
final Cursor oldCursor = cursor;
|
||||
if (oldCursor != null && dataSetObserver != null) {
|
||||
oldCursor.unregisterDataSetObserver(dataSetObserver);
|
||||
}
|
||||
mCursor = newCursor;
|
||||
if (mCursor != null) {
|
||||
if (mDataSetObserver != null) {
|
||||
mCursor.registerDataSetObserver(mDataSetObserver);
|
||||
cursor = newCursor;
|
||||
if (cursor != null) {
|
||||
if (dataSetObserver != null) {
|
||||
cursor.registerDataSetObserver(dataSetObserver);
|
||||
}
|
||||
mRowIdColumn = newCursor.getColumnIndexOrThrow("_id");
|
||||
mDataValid = true;
|
||||
rowIdColumn = newCursor.getColumnIndexOrThrow("_id");
|
||||
dataValid = true;
|
||||
notifyDataSetChanged();
|
||||
} else {
|
||||
mRowIdColumn = -1;
|
||||
mDataValid = false;
|
||||
rowIdColumn = -1;
|
||||
dataValid = false;
|
||||
notifyDataSetChanged();
|
||||
//There is no notifyDataSetInvalidated() method in RecyclerView.Adapter
|
||||
}
|
||||
|
|
@ -112,14 +114,14 @@ public abstract class CursorRecyclerViewAdapter<VH extends RecyclerView.ViewHold
|
|||
@Override
|
||||
public void onChanged() {
|
||||
super.onChanged();
|
||||
mDataValid = true;
|
||||
dataValid = true;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInvalidated() {
|
||||
super.onInvalidated();
|
||||
mDataValid = false;
|
||||
dataValid = false;
|
||||
notifyDataSetChanged();
|
||||
//There is no notifyDataSetInvalidated() method in RecyclerView.Adapter
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
package org.meowcat.edxposed.manager.receivers;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
|
|
@ -32,8 +31,7 @@ public class BootReceiver extends BroadcastReceiver {
|
|||
return netInfo != null && netInfo.isConnectedOrConnecting();
|
||||
}
|
||||
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
private class CheckUpdates extends AsyncTask<Void, Void, Void> {
|
||||
private static class CheckUpdates extends AsyncTask<Void, Void, Void> {
|
||||
|
||||
@Override
|
||||
protected Void doInBackground(Void... params) {
|
||||
|
|
|
|||
|
|
@ -10,10 +10,15 @@ import org.meowcat.edxposed.manager.util.DownloadsUtil;
|
|||
public class DownloadReceiver extends BroadcastReceiver {
|
||||
@Override
|
||||
public void onReceive(final Context context, final Intent intent) {
|
||||
String action = intent.getAction();
|
||||
if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(action)) {
|
||||
long downloadId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, 0);
|
||||
DownloadsUtil.triggerDownloadFinishedCallback(context, downloadId);
|
||||
try {
|
||||
String action = intent.getAction();
|
||||
if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(action)) {
|
||||
long downloadId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, 0);
|
||||
DownloadsUtil.triggerDownloadFinishedCallback(context, downloadId);
|
||||
}
|
||||
} catch (Exception e) {//Flyme
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -12,7 +12,7 @@ import org.meowcat.edxposed.manager.util.NotificationUtil;
|
|||
import java.util.Objects;
|
||||
|
||||
public class PackageChangeReceiver extends BroadcastReceiver {
|
||||
private static ModuleUtil mModuleUtil = null;
|
||||
private static ModuleUtil moduleUtil = null;
|
||||
|
||||
private static String getPackageName(Intent intent) {
|
||||
Uri uri = intent.getData();
|
||||
|
|
@ -49,22 +49,22 @@ public class PackageChangeReceiver extends BroadcastReceiver {
|
|||
return;
|
||||
}
|
||||
|
||||
mModuleUtil = getModuleUtilInstance();
|
||||
moduleUtil = getModuleUtilInstance();
|
||||
|
||||
InstalledModule module = ModuleUtil.getInstance().reloadSingleModule(packageName);
|
||||
if (module == null
|
||||
|| intent.getAction().equals(Intent.ACTION_PACKAGE_REMOVED)) {
|
||||
// Package being removed, disable it if it was a previously active
|
||||
// Xposed mod
|
||||
if (mModuleUtil.isModuleEnabled(packageName)) {
|
||||
mModuleUtil.setModuleEnabled(packageName, false);
|
||||
mModuleUtil.updateModulesList(false);
|
||||
if (moduleUtil.isModuleEnabled(packageName)) {
|
||||
moduleUtil.setModuleEnabled(packageName, false);
|
||||
moduleUtil.updateModulesList(false);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (mModuleUtil.isModuleEnabled(packageName)) {
|
||||
mModuleUtil.updateModulesList(false);
|
||||
if (moduleUtil.isModuleEnabled(packageName)) {
|
||||
moduleUtil.updateModulesList(false);
|
||||
NotificationUtil.showModulesUpdatedNotification();
|
||||
} else {
|
||||
NotificationUtil.showNotActivatedNotification(packageName, module.getAppName());
|
||||
|
|
@ -72,9 +72,9 @@ public class PackageChangeReceiver extends BroadcastReceiver {
|
|||
}
|
||||
|
||||
private ModuleUtil getModuleUtilInstance() {
|
||||
if (mModuleUtil == null) {
|
||||
mModuleUtil = ModuleUtil.getInstance();
|
||||
if (moduleUtil == null) {
|
||||
moduleUtil = ModuleUtil.getInstance();
|
||||
}
|
||||
return mModuleUtil;
|
||||
return moduleUtil;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,13 +37,13 @@ public final class RepoDb extends SQLiteOpenHelper {
|
|||
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
private static Context context;
|
||||
private static SQLiteDatabase sDb;
|
||||
private static SQLiteDatabase db;
|
||||
|
||||
static {
|
||||
RepoDb instance = new RepoDb(XposedApp.getInstance());
|
||||
sDb = instance.getWritableDatabase();
|
||||
sDb.execSQL("PRAGMA foreign_keys=ON");
|
||||
instance.createTempTables(sDb);
|
||||
db = instance.getWritableDatabase();
|
||||
db.execSQL("PRAGMA foreign_keys=ON");
|
||||
instance.createTempTables(db);
|
||||
}
|
||||
|
||||
private RepoDb(Context context) {
|
||||
|
|
@ -56,22 +56,22 @@ public final class RepoDb extends SQLiteOpenHelper {
|
|||
}
|
||||
|
||||
public static void beginTransation() {
|
||||
sDb.beginTransaction();
|
||||
db.beginTransaction();
|
||||
}
|
||||
|
||||
public static void setTransactionSuccessful() {
|
||||
sDb.setTransactionSuccessful();
|
||||
db.setTransactionSuccessful();
|
||||
}
|
||||
|
||||
public static void endTransation() {
|
||||
sDb.endTransaction();
|
||||
db.endTransaction();
|
||||
}
|
||||
|
||||
private static String getString(@SuppressWarnings("SameParameterValue") String table, @SuppressWarnings("SameParameterValue") String searchColumn, String searchValue, @SuppressWarnings("SameParameterValue") String resultColumn) {
|
||||
String[] projection = new String[]{resultColumn};
|
||||
String where = searchColumn + " = ?";
|
||||
String[] whereArgs = new String[]{searchValue};
|
||||
Cursor c = sDb.query(table, projection, where, whereArgs, null, null, null, "1");
|
||||
Cursor c = db.query(table, projection, where, whereArgs, null, null, null, "1");
|
||||
if (c.moveToFirst()) {
|
||||
String result = c.getString(c.getColumnIndexOrThrow(resultColumn));
|
||||
c.close();
|
||||
|
|
@ -86,12 +86,12 @@ public final class RepoDb extends SQLiteOpenHelper {
|
|||
public static long insertRepository(String url) {
|
||||
ContentValues values = new ContentValues();
|
||||
values.put(RepositoriesColumns.URL, url);
|
||||
return sDb.insertOrThrow(RepositoriesColumns.TABLE_NAME, null, values);
|
||||
return db.insertOrThrow(RepositoriesColumns.TABLE_NAME, null, values);
|
||||
}
|
||||
|
||||
public static void deleteRepositories() {
|
||||
if (sDb != null)
|
||||
sDb.delete(RepositoriesColumns.TABLE_NAME, null, null);
|
||||
if (db != null)
|
||||
db.delete(RepositoriesColumns.TABLE_NAME, null, null);
|
||||
}
|
||||
|
||||
public static Map<Long, Repository> getRepositories() {
|
||||
|
|
@ -105,7 +105,7 @@ public final class RepoDb extends SQLiteOpenHelper {
|
|||
RepositoriesColumns.VERSION,
|
||||
};
|
||||
|
||||
Cursor c = sDb.query(RepositoriesColumns.TABLE_NAME, projection, null, null, null, null, RepositoriesColumns._ID);
|
||||
Cursor c = db.query(RepositoriesColumns.TABLE_NAME, projection, null, null, null, null, RepositoriesColumns._ID);
|
||||
while (c.moveToNext()) {
|
||||
Repository repo = new Repository();
|
||||
long id = c.getLong(c.getColumnIndexOrThrow(RepositoriesColumns._ID));
|
||||
|
|
@ -125,13 +125,13 @@ public final class RepoDb extends SQLiteOpenHelper {
|
|||
values.put(RepositoriesColumns.TITLE, repository.name);
|
||||
values.put(RepositoriesColumns.PARTIAL_URL, repository.partialUrl);
|
||||
values.put(RepositoriesColumns.VERSION, repository.version);
|
||||
sDb.update(RepositoriesColumns.TABLE_NAME, values, RepositoriesColumns._ID + " = ?", new String[]{Long.toString(repoId)});
|
||||
db.update(RepositoriesColumns.TABLE_NAME, values, RepositoriesColumns._ID + " = ?", new String[]{Long.toString(repoId)});
|
||||
}
|
||||
|
||||
public static void updateRepositoryVersion(long repoId, String version) {
|
||||
ContentValues values = new ContentValues();
|
||||
values.put(RepositoriesColumns.VERSION, version);
|
||||
sDb.update(RepositoriesColumns.TABLE_NAME, values, RepositoriesColumns._ID + " = ?", new String[]{Long.toString(repoId)});
|
||||
db.update(RepositoriesColumns.TABLE_NAME, values, RepositoriesColumns._ID + " = ?", new String[]{Long.toString(repoId)});
|
||||
}
|
||||
|
||||
@SuppressWarnings("UnusedReturnValue")
|
||||
|
|
@ -150,9 +150,9 @@ public final class RepoDb extends SQLiteOpenHelper {
|
|||
|
||||
ModuleVersion latestVersion = RepoLoader.getInstance().getLatestVersion(mod);
|
||||
|
||||
sDb.beginTransaction();
|
||||
db.beginTransaction();
|
||||
try {
|
||||
long moduleId = sDb.insertOrThrow(ModulesColumns.TABLE_NAME, null, values);
|
||||
long moduleId = db.insertOrThrow(ModulesColumns.TABLE_NAME, null, values);
|
||||
|
||||
long latestVersionId = -1;
|
||||
for (ModuleVersion version : mod.versions) {
|
||||
|
|
@ -164,7 +164,7 @@ public final class RepoDb extends SQLiteOpenHelper {
|
|||
if (latestVersionId > -1) {
|
||||
values = new ContentValues();
|
||||
values.put(ModulesColumns.LATEST_VERSION, latestVersionId);
|
||||
sDb.update(ModulesColumns.TABLE_NAME, values, ModulesColumns._ID + " = ?", new String[]{Long.toString(moduleId)});
|
||||
db.update(ModulesColumns.TABLE_NAME, values, ModulesColumns._ID + " = ?", new String[]{Long.toString(moduleId)});
|
||||
}
|
||||
|
||||
for (Pair<String, String> moreInfoEntry : mod.moreInfo) {
|
||||
|
|
@ -173,11 +173,11 @@ public final class RepoDb extends SQLiteOpenHelper {
|
|||
|
||||
// TODO Add mod.screenshots
|
||||
|
||||
sDb.setTransactionSuccessful();
|
||||
db.setTransactionSuccessful();
|
||||
return moduleId;
|
||||
|
||||
} finally {
|
||||
sDb.endTransaction();
|
||||
db.endTransaction();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -192,7 +192,7 @@ public final class RepoDb extends SQLiteOpenHelper {
|
|||
values.put(ModuleVersionsColumns.CHANGELOG_IS_HTML, version.changelogIsHtml);
|
||||
values.put(ModuleVersionsColumns.RELTYPE, version.relType.ordinal());
|
||||
values.put(ModuleVersionsColumns.UPLOADED, version.uploaded);
|
||||
return sDb.insertOrThrow(ModuleVersionsColumns.TABLE_NAME, null,
|
||||
return db.insertOrThrow(ModuleVersionsColumns.TABLE_NAME, null,
|
||||
values);
|
||||
}
|
||||
|
||||
|
|
@ -202,15 +202,15 @@ public final class RepoDb extends SQLiteOpenHelper {
|
|||
values.put(MoreInfoColumns.MODULE_ID, moduleId);
|
||||
values.put(MoreInfoColumns.LABEL, title);
|
||||
values.put(MoreInfoColumns.VALUE, value);
|
||||
return sDb.insertOrThrow(MoreInfoColumns.TABLE_NAME, null, values);
|
||||
return db.insertOrThrow(MoreInfoColumns.TABLE_NAME, null, values);
|
||||
}
|
||||
|
||||
public static void deleteAllModules(long repoId) {
|
||||
sDb.delete(ModulesColumns.TABLE_NAME, ModulesColumns.REPO_ID + " = ?", new String[]{Long.toString(repoId)});
|
||||
db.delete(ModulesColumns.TABLE_NAME, ModulesColumns.REPO_ID + " = ?", new String[]{Long.toString(repoId)});
|
||||
}
|
||||
|
||||
public static void deleteModule(long repoId, String packageName) {
|
||||
sDb.delete(ModulesColumns.TABLE_NAME, ModulesColumns.REPO_ID + " = ? AND " + ModulesColumns.PKGNAME + " = ?", new String[]{Long.toString(repoId), packageName});
|
||||
db.delete(ModulesColumns.TABLE_NAME, ModulesColumns.REPO_ID + " = ? AND " + ModulesColumns.PKGNAME + " = ?", new String[]{Long.toString(repoId), packageName});
|
||||
}
|
||||
|
||||
public static Module getModuleByPackageName(String packageName) {
|
||||
|
|
@ -232,7 +232,7 @@ public final class RepoDb extends SQLiteOpenHelper {
|
|||
String where = ModulesColumns.PREFERRED + " = 1 AND " + ModulesColumns.PKGNAME + " = ?";
|
||||
String[] whereArgs = new String[]{packageName};
|
||||
|
||||
Cursor c = sDb.query(ModulesColumns.TABLE_NAME, projection, where, whereArgs, null, null, null, "1");
|
||||
Cursor c = db.query(ModulesColumns.TABLE_NAME, projection, where, whereArgs, null, null, null, "1");
|
||||
if (!c.moveToFirst()) {
|
||||
c.close();
|
||||
return null;
|
||||
|
|
@ -267,7 +267,7 @@ public final class RepoDb extends SQLiteOpenHelper {
|
|||
where = ModuleVersionsColumns.MODULE_ID + " = ?";
|
||||
whereArgs = new String[]{Long.toString(moduleId)};
|
||||
|
||||
c = sDb.query(ModuleVersionsColumns.TABLE_NAME, projection, where, whereArgs, null, null, null);
|
||||
c = db.query(ModuleVersionsColumns.TABLE_NAME, projection, where, whereArgs, null, null, null);
|
||||
while (c.moveToNext()) {
|
||||
ModuleVersion version = new ModuleVersion(mod);
|
||||
version.name = c.getString(c.getColumnIndexOrThrow(ModuleVersionsColumns.NAME));
|
||||
|
|
@ -291,7 +291,7 @@ public final class RepoDb extends SQLiteOpenHelper {
|
|||
where = MoreInfoColumns.MODULE_ID + " = ?";
|
||||
whereArgs = new String[]{Long.toString(moduleId)};
|
||||
|
||||
c = sDb.query(MoreInfoColumns.TABLE_NAME, projection, where, whereArgs, null, null, MoreInfoColumns._ID);
|
||||
c = db.query(MoreInfoColumns.TABLE_NAME, projection, where, whereArgs, null, null, MoreInfoColumns._ID);
|
||||
while (c.moveToNext()) {
|
||||
String label = c.getString(c.getColumnIndexOrThrow(MoreInfoColumns.LABEL));
|
||||
String value = c.getString(c.getColumnIndexOrThrow(MoreInfoColumns.VALUE));
|
||||
|
|
@ -308,7 +308,7 @@ public final class RepoDb extends SQLiteOpenHelper {
|
|||
|
||||
public static void updateModuleLatestVersion(String packageName) {
|
||||
int maxShownReleaseType = RepoLoader.getInstance().getMaxShownReleaseType(packageName).ordinal();
|
||||
sDb.execSQL("UPDATE " + ModulesColumns.TABLE_NAME
|
||||
db.execSQL("UPDATE " + ModulesColumns.TABLE_NAME
|
||||
+ " SET " + ModulesColumns.LATEST_VERSION
|
||||
+ " = (SELECT " + ModuleVersionsColumns._ID + " FROM " + ModuleVersionsColumns.TABLE_NAME + " AS v"
|
||||
+ " WHERE v." + ModuleVersionsColumns.MODULE_ID
|
||||
|
|
@ -319,17 +319,17 @@ public final class RepoDb extends SQLiteOpenHelper {
|
|||
}
|
||||
|
||||
public static void updateAllModulesLatestVersion() {
|
||||
sDb.beginTransaction();
|
||||
db.beginTransaction();
|
||||
try {
|
||||
String[] projection = new String[]{ModulesColumns.PKGNAME};
|
||||
Cursor c = sDb.query(true, ModulesColumns.TABLE_NAME, projection, null, null, null, null, null, null);
|
||||
Cursor c = db.query(true, ModulesColumns.TABLE_NAME, projection, null, null, null, null, null, null);
|
||||
while (c.moveToNext()) {
|
||||
updateModuleLatestVersion(c.getString(0));
|
||||
}
|
||||
c.close();
|
||||
sDb.setTransactionSuccessful();
|
||||
db.setTransactionSuccessful();
|
||||
} finally {
|
||||
sDb.endTransaction();
|
||||
db.endTransaction();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -339,15 +339,15 @@ public final class RepoDb extends SQLiteOpenHelper {
|
|||
values.put(InstalledModulesColumns.PKGNAME, installed.packageName);
|
||||
values.put(InstalledModulesColumns.VERSION_CODE, installed.versionCode);
|
||||
values.put(InstalledModulesColumns.VERSION_NAME, installed.versionName);
|
||||
return sDb.insertOrThrow(InstalledModulesColumns.TABLE_NAME, null, values);
|
||||
return db.insertOrThrow(InstalledModulesColumns.TABLE_NAME, null, values);
|
||||
}
|
||||
|
||||
public static void deleteInstalledModule(String packageName) {
|
||||
sDb.delete(InstalledModulesColumns.TABLE_NAME, InstalledModulesColumns.PKGNAME + " = ?", new String[]{packageName});
|
||||
db.delete(InstalledModulesColumns.TABLE_NAME, InstalledModulesColumns.PKGNAME + " = ?", new String[]{packageName});
|
||||
}
|
||||
|
||||
public static void deleteAllInstalledModules() {
|
||||
sDb.delete(InstalledModulesColumns.TABLE_NAME, null, null);
|
||||
db.delete(InstalledModulesColumns.TABLE_NAME, null, null);
|
||||
}
|
||||
|
||||
public static Cursor queryModuleOverview(int sortingOrder,
|
||||
|
|
@ -413,7 +413,7 @@ public final class RepoDb extends SQLiteOpenHelper {
|
|||
sbOrder.append(OverviewColumns.PKGNAME);
|
||||
|
||||
// Query
|
||||
Cursor c = sDb.query(
|
||||
Cursor c = db.query(
|
||||
ModulesColumns.TABLE_NAME + " AS m"
|
||||
+ " LEFT JOIN " + ModuleVersionsColumns.TABLE_NAME + " AS v"
|
||||
+ " ON v." + ModuleVersionsColumns._ID + " = m." + ModulesColumns.LATEST_VERSION
|
||||
|
|
@ -439,7 +439,7 @@ public final class RepoDb extends SQLiteOpenHelper {
|
|||
String[] projection = new String[]{InstalledModulesUpdatesColumns.LATEST_NAME};
|
||||
String where = ModulesColumns.PKGNAME + (framework ? " = ?" : " != ?");
|
||||
String[] whereArgs = new String[]{ModuleUtil.getInstance().getFrameworkPackageName()};
|
||||
Cursor c = sDb.query(InstalledModulesUpdatesColumns.VIEW_NAME, projection, where, whereArgs, null, null, null, "1");
|
||||
Cursor c = db.query(InstalledModulesUpdatesColumns.VIEW_NAME, projection, where, whereArgs, null, null, null, "1");
|
||||
String latestVersion = null;
|
||||
if (c.moveToFirst())
|
||||
latestVersion = c.getString(c.getColumnIndexOrThrow(InstalledModulesUpdatesColumns.LATEST_NAME));
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ public class RepoParser {
|
|||
public final static String TAG = XposedApp.TAG;
|
||||
private final static String NS = null;
|
||||
private final XmlPullParser parser;
|
||||
private RepoParserCallback mCallback;
|
||||
private RepoParserCallback callback;
|
||||
private boolean mRepoEventTriggered = false;
|
||||
|
||||
private RepoParser(InputStream is, RepoParserCallback callback) throws XmlPullParserException, IOException {
|
||||
|
|
@ -41,7 +41,7 @@ public class RepoParser {
|
|||
parser = factory.newPullParser();
|
||||
parser.setInput(is, null);
|
||||
parser.nextTag();
|
||||
mCallback = callback;
|
||||
this.callback = callback;
|
||||
}
|
||||
|
||||
public static void parse(InputStream is, RepoParserCallback callback) throws XmlPullParserException, IOException {
|
||||
|
|
@ -113,13 +113,13 @@ public class RepoParser {
|
|||
triggerRepoEvent(repository);
|
||||
Module module = readModule(repository);
|
||||
if (module != null)
|
||||
mCallback.onNewModule(module);
|
||||
callback.onNewModule(module);
|
||||
break;
|
||||
case "remove-module":
|
||||
triggerRepoEvent(repository);
|
||||
String packageName = readRemoveModule();
|
||||
if (packageName != null)
|
||||
mCallback.onRemoveModule(packageName);
|
||||
callback.onRemoveModule(packageName);
|
||||
break;
|
||||
default:
|
||||
//skip(true);
|
||||
|
|
@ -128,14 +128,14 @@ public class RepoParser {
|
|||
}
|
||||
}
|
||||
|
||||
mCallback.onCompleted(repository);
|
||||
callback.onCompleted(repository);
|
||||
}
|
||||
|
||||
private void triggerRepoEvent(Repository repository) {
|
||||
if (mRepoEventTriggered)
|
||||
return;
|
||||
|
||||
mCallback.onRepositoryMetadata(repository);
|
||||
callback.onRepositoryMetadata(repository);
|
||||
mRepoEventTriggered = true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -29,60 +29,6 @@ public class JSONUtils {
|
|||
return sb.toString();
|
||||
}
|
||||
|
||||
// private static String getLatestVersion() throws IOException {
|
||||
// String site = getFileContent("http://dl-xda.xposed.info/framework/sdk" + Build.VERSION.SDK_INT + "/arm/");
|
||||
//
|
||||
// Pattern pattern = Pattern.compile("(href=\")([^?\"]*)\\.zip");
|
||||
// Matcher matcher = pattern.matcher(site);
|
||||
// String last = "";
|
||||
// while (matcher.find()) {
|
||||
// if (matcher.group().contains("test")) continue;
|
||||
// last = matcher.group();
|
||||
// }
|
||||
// last = last.replace("href=\"", "");
|
||||
// String[] file = last.split("-");
|
||||
//
|
||||
// return file[1].replace("v", "");
|
||||
// }
|
||||
//
|
||||
// public static String listZip() {
|
||||
// String latest;
|
||||
// try {
|
||||
// latest = getLatestVersion();
|
||||
// } catch (IOException e) {
|
||||
// // Got 404 response; no official Xposed zips available
|
||||
// return "";
|
||||
// }
|
||||
//
|
||||
// StringBuilder newJson = new StringBuilder(",\"" + Build.VERSION.SDK_INT + "\": [");
|
||||
// String[] arch = new String[]{
|
||||
// "arm",
|
||||
// "arm64",
|
||||
// "x86"
|
||||
// };
|
||||
//
|
||||
// for (String a : arch) {
|
||||
// newJson.append(installerToString(latest, a)).append(",");
|
||||
// }
|
||||
//
|
||||
// newJson = new StringBuilder(newJson.substring(0, newJson.length() - 1));
|
||||
// newJson.append("]");
|
||||
//
|
||||
// return newJson.toString();
|
||||
// }
|
||||
//
|
||||
// private static String installerToString(String latest, String architecture) {
|
||||
// String filename = "xposed-v" + latest + "-sdk" + Build.VERSION.SDK_INT + "-" + architecture;
|
||||
//
|
||||
// XposedZip installer = new XposedZip();
|
||||
// installer.name = filename;
|
||||
// installer.version = latest;
|
||||
// installer.architecture = architecture;
|
||||
// installer.link = "http://dl-xda.xposed.info/framework/sdk" + Build.VERSION.SDK_INT + "/" + architecture + "/" + filename + ".zip";
|
||||
//
|
||||
// return new Gson().toJson(installer);
|
||||
// }
|
||||
|
||||
public class XposedJson {
|
||||
public List<XposedTab> tabs;
|
||||
public ApkRelease apk;
|
||||
|
|
|
|||
|
|
@ -48,31 +48,6 @@ public class XposedTab implements Parcelable {
|
|||
official = in.readByte() != 0;
|
||||
}
|
||||
|
||||
// public String getNotice() {
|
||||
// if (notice == null) return "";
|
||||
// return notice.get(Integer.toString(Build.VERSION.SDK_INT));
|
||||
// }
|
||||
|
||||
// public String getCompatibility() {
|
||||
// if (compatibility == null) return "";
|
||||
// return compatibility.get(Integer.toString(Build.VERSION.SDK_INT));
|
||||
// }
|
||||
//
|
||||
// public String getIncompatibility() {
|
||||
// if (incompatibility == null) return "";
|
||||
// return incompatibility.get(Integer.toString(Build.VERSION.SDK_INT));
|
||||
// }
|
||||
|
||||
// public String getSupport() {
|
||||
// if (support == null) return "";
|
||||
// return support.get(Integer.toString(Build.VERSION.SDK_INT));
|
||||
// }
|
||||
//
|
||||
// public List<XposedZip> getInstallers() {
|
||||
// if (support == null) return new ArrayList<>();
|
||||
// return installers.get(Integer.toString(Build.VERSION.SDK_INT));
|
||||
// }
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ public class XposedZip {
|
|||
List<XposedZip> list;
|
||||
|
||||
public MyAdapter(Context context, List<XposedZip> objects) {
|
||||
super(context, android.R.layout.simple_dropdown_item_1line, objects);
|
||||
super(context, android.R.layout.simple_spinner_dropdown_item, objects);
|
||||
this.context = context;
|
||||
this.list = objects;
|
||||
}
|
||||
|
|
@ -57,7 +57,7 @@ public class XposedZip {
|
|||
return row;
|
||||
}
|
||||
|
||||
private class ItemHolder {
|
||||
private static class ItemHolder {
|
||||
TextView name;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,67 +6,60 @@ import android.content.Intent;
|
|||
import android.util.AttributeSet;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import org.meowcat.edxposed.manager.R;
|
||||
import org.meowcat.edxposed.manager.databinding.DownloadViewBinding;
|
||||
import org.meowcat.edxposed.manager.util.DownloadsUtil;
|
||||
import org.meowcat.edxposed.manager.util.DownloadsUtil.DownloadFinishedCallback;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class DownloadView extends LinearLayout {
|
||||
public static DownloadsUtil.DownloadInfo lastInfo = null;
|
||||
private final Button btnDownload;
|
||||
private final Button btnDownloadCancel;
|
||||
private final Button btnInstall;
|
||||
private final Button btnSave;
|
||||
private final ProgressBar progressBar;
|
||||
private final TextView txtInfo;
|
||||
public Fragment fragment;
|
||||
private DownloadsUtil.DownloadInfo mInfo = null;
|
||||
private String mUrl = null;
|
||||
private String mTitle = null;
|
||||
private DownloadFinishedCallback mCallback = null;
|
||||
private DownloadViewBinding binding;
|
||||
private final Runnable refreshViewRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (mUrl == null) {
|
||||
btnDownload.setVisibility(View.GONE);
|
||||
btnSave.setVisibility(View.GONE);
|
||||
btnDownloadCancel.setVisibility(View.GONE);
|
||||
btnInstall.setVisibility(View.GONE);
|
||||
progressBar.setVisibility(View.GONE);
|
||||
txtInfo.setVisibility(View.VISIBLE);
|
||||
txtInfo.setText(R.string.download_view_no_url);
|
||||
binding.btnDownload.setVisibility(View.GONE);
|
||||
binding.btnSave.setVisibility(View.GONE);
|
||||
binding.btnDownloadCancel.setVisibility(View.GONE);
|
||||
binding.btnInstall.setVisibility(View.GONE);
|
||||
binding.progress.setVisibility(View.GONE);
|
||||
binding.txtInfo.setVisibility(View.VISIBLE);
|
||||
binding.txtInfo.setText(R.string.download_view_no_url);
|
||||
} else if (mInfo == null) {
|
||||
btnDownload.setVisibility(View.VISIBLE);
|
||||
btnSave.setVisibility(View.VISIBLE);
|
||||
btnDownloadCancel.setVisibility(View.GONE);
|
||||
btnInstall.setVisibility(View.GONE);
|
||||
progressBar.setVisibility(View.GONE);
|
||||
txtInfo.setVisibility(View.GONE);
|
||||
binding.btnDownload.setVisibility(View.VISIBLE);
|
||||
binding.btnSave.setVisibility(View.VISIBLE);
|
||||
binding.btnDownloadCancel.setVisibility(View.GONE);
|
||||
binding.btnInstall.setVisibility(View.GONE);
|
||||
binding.progress.setVisibility(View.GONE);
|
||||
binding.txtInfo.setVisibility(View.GONE);
|
||||
} else {
|
||||
switch (mInfo.status) {
|
||||
case DownloadManager.STATUS_PENDING:
|
||||
case DownloadManager.STATUS_PAUSED:
|
||||
case DownloadManager.STATUS_RUNNING:
|
||||
btnDownload.setVisibility(View.GONE);
|
||||
btnSave.setVisibility(View.GONE);
|
||||
btnDownloadCancel.setVisibility(View.VISIBLE);
|
||||
btnInstall.setVisibility(View.GONE);
|
||||
progressBar.setVisibility(View.VISIBLE);
|
||||
txtInfo.setVisibility(View.VISIBLE);
|
||||
binding.btnDownload.setVisibility(View.GONE);
|
||||
binding.btnSave.setVisibility(View.GONE);
|
||||
binding.btnDownloadCancel.setVisibility(View.VISIBLE);
|
||||
binding.btnInstall.setVisibility(View.GONE);
|
||||
binding.progress.setVisibility(View.VISIBLE);
|
||||
binding.txtInfo.setVisibility(View.VISIBLE);
|
||||
if (mInfo.totalSize <= 0 || mInfo.status != DownloadManager.STATUS_RUNNING) {
|
||||
progressBar.setIndeterminate(true);
|
||||
txtInfo.setText(R.string.download_view_waiting);
|
||||
binding.progress.setIndeterminate(true);
|
||||
binding.txtInfo.setText(R.string.download_view_waiting);
|
||||
} else {
|
||||
progressBar.setIndeterminate(false);
|
||||
progressBar.setMax(mInfo.totalSize);
|
||||
progressBar.setProgress(mInfo.bytesDownloaded);
|
||||
txtInfo.setText(getContext().getString(
|
||||
binding.progress.setIndeterminate(false);
|
||||
binding.progress.setMax(mInfo.totalSize);
|
||||
binding.progress.setProgress(mInfo.bytesDownloaded);
|
||||
binding.txtInfo.setText(getContext().getString(
|
||||
R.string.download_view_running,
|
||||
mInfo.bytesDownloaded / 1024,
|
||||
mInfo.totalSize / 1024));
|
||||
|
|
@ -74,53 +67,45 @@ public class DownloadView extends LinearLayout {
|
|||
break;
|
||||
|
||||
case DownloadManager.STATUS_FAILED:
|
||||
btnDownload.setVisibility(View.VISIBLE);
|
||||
btnSave.setVisibility(View.VISIBLE);
|
||||
btnDownloadCancel.setVisibility(View.GONE);
|
||||
btnInstall.setVisibility(View.GONE);
|
||||
progressBar.setVisibility(View.GONE);
|
||||
txtInfo.setVisibility(View.VISIBLE);
|
||||
txtInfo.setText(getContext().getString(
|
||||
binding.btnDownload.setVisibility(View.VISIBLE);
|
||||
binding.btnSave.setVisibility(View.VISIBLE);
|
||||
binding.btnDownloadCancel.setVisibility(View.GONE);
|
||||
binding.btnInstall.setVisibility(View.GONE);
|
||||
binding.progress.setVisibility(View.GONE);
|
||||
binding.txtInfo.setVisibility(View.VISIBLE);
|
||||
binding.txtInfo.setText(getContext().getString(
|
||||
R.string.download_view_failed, mInfo.reason));
|
||||
break;
|
||||
|
||||
case DownloadManager.STATUS_SUCCESSFUL:
|
||||
btnDownload.setVisibility(View.GONE);
|
||||
btnSave.setVisibility(View.VISIBLE);
|
||||
btnDownloadCancel.setVisibility(View.GONE);
|
||||
btnInstall.setVisibility(View.VISIBLE);
|
||||
progressBar.setVisibility(View.GONE);
|
||||
txtInfo.setVisibility(View.VISIBLE);
|
||||
txtInfo.setText(R.string.download_view_successful);
|
||||
binding.btnDownload.setVisibility(View.GONE);
|
||||
binding.btnSave.setVisibility(View.VISIBLE);
|
||||
binding.btnDownloadCancel.setVisibility(View.GONE);
|
||||
binding.btnInstall.setVisibility(View.VISIBLE);
|
||||
binding.progress.setVisibility(View.GONE);
|
||||
binding.txtInfo.setVisibility(View.VISIBLE);
|
||||
binding.txtInfo.setText(R.string.download_view_successful);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
private String mTitle = null;
|
||||
private DownloadFinishedCallback mCallback = null;
|
||||
|
||||
public DownloadView(Context context, final AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
setFocusable(false);
|
||||
setOrientation(LinearLayout.VERTICAL);
|
||||
|
||||
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
Objects.requireNonNull(inflater).inflate(R.layout.download_view, this, true);
|
||||
binding = DownloadViewBinding.inflate(LayoutInflater.from(context), this);
|
||||
|
||||
btnDownload = findViewById(R.id.btnDownload);
|
||||
btnDownloadCancel = findViewById(R.id.btnDownloadCancel);
|
||||
btnInstall = findViewById(R.id.btnInstall);
|
||||
btnSave = findViewById(R.id.save);
|
||||
|
||||
btnDownload.setOnClickListener(v -> {
|
||||
binding.btnDownload.setOnClickListener(v -> {
|
||||
mInfo = DownloadsUtil.addModule(getContext(), mTitle, mUrl, mCallback);
|
||||
refreshViewFromUiThread();
|
||||
if (mInfo != null)
|
||||
new DownloadMonitor().start();
|
||||
});
|
||||
|
||||
btnSave.setOnClickListener(v -> {
|
||||
binding.btnSave.setOnClickListener(v -> {
|
||||
lastInfo = mInfo;
|
||||
mInfo = DownloadsUtil.addModule(getContext(), mTitle, mUrl, (context1, info) -> {
|
||||
Intent exportIntent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
|
||||
|
|
@ -134,7 +119,7 @@ public class DownloadView extends LinearLayout {
|
|||
new DownloadMonitor().start();
|
||||
});
|
||||
|
||||
btnDownloadCancel.setOnClickListener(v -> {
|
||||
binding.btnDownloadCancel.setOnClickListener(v -> {
|
||||
if (mInfo == null)
|
||||
return;
|
||||
|
||||
|
|
@ -142,16 +127,13 @@ public class DownloadView extends LinearLayout {
|
|||
// UI update will happen automatically by the DownloadMonitor
|
||||
});
|
||||
|
||||
btnInstall.setOnClickListener(v -> {
|
||||
binding.btnInstall.setOnClickListener(v -> {
|
||||
if (mCallback == null)
|
||||
return;
|
||||
|
||||
mCallback.onDownloadFinished(getContext(), mInfo);
|
||||
});
|
||||
|
||||
progressBar = findViewById(R.id.progress);
|
||||
txtInfo = findViewById(R.id.txtInfo);
|
||||
|
||||
refreshViewFromUiThread();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import android.util.AttributeSet;
|
|||
|
||||
import com.takisoft.preferencex.SimpleMenuPreference;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public class IntegerListPreference extends SimpleMenuPreference {
|
||||
public IntegerListPreference(Context context) {
|
||||
super(context);
|
||||
|
|
@ -15,7 +16,7 @@ public class IntegerListPreference extends SimpleMenuPreference {
|
|||
super(context, attrs);
|
||||
}
|
||||
|
||||
public static int getIntValue(String value) {
|
||||
private static int getIntValue(String value) {
|
||||
if (value == null)
|
||||
return 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -8,16 +8,20 @@
|
|||
android:clipChildren="false"
|
||||
android:clipToPadding="false">
|
||||
|
||||
<include layout="@layout/appbar_layout" />
|
||||
<include
|
||||
android:id="@+id/appbar"
|
||||
layout="@layout/appbar_layout" />
|
||||
|
||||
<androidx.core.widget.NestedScrollView
|
||||
android:id="@+id/nestedScrollView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false"
|
||||
android:orientation="vertical"
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior"
|
||||
tools:ignore="UseCompoundDrawables,ContentDescription">
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
|
|
|||
|
|
@ -7,7 +7,9 @@
|
|||
android:clipChildren="false"
|
||||
android:clipToPadding="false">
|
||||
|
||||
<include layout="@layout/appbar_layout" />
|
||||
<include
|
||||
android:id="@+id/appbar"
|
||||
layout="@layout/appbar_layout" />
|
||||
|
||||
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||
android:id="@+id/swipeRefreshLayout"
|
||||
|
|
@ -21,7 +23,9 @@
|
|||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recyclerView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
android:layout_height="match_parent"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false" />
|
||||
|
||||
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,9 @@
|
|||
android:clipChildren="false"
|
||||
android:clipToPadding="false">
|
||||
|
||||
<include layout="@layout/appbar_layout" />
|
||||
<include
|
||||
android:id="@+id/appbar"
|
||||
layout="@layout/appbar_layout" />
|
||||
|
||||
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||
android:id="@+id/swipeRefreshLayout"
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@
|
|||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
<HorizontalScrollView
|
||||
android:id="@+id/horizontalScrollView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:clipChildren="false"
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@
|
|||
</RelativeLayout>
|
||||
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
android:id="@+id/activity_main_status"
|
||||
android:id="@+id/status"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="16dp"
|
||||
|
|
@ -73,7 +73,7 @@
|
|||
android:paddingBottom="20dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/activity_main_status_icon"
|
||||
android:id="@+id/status_icon"
|
||||
android:layout_width="28dp"
|
||||
android:layout_height="28dp"
|
||||
android:layout_centerVertical="true"
|
||||
|
|
@ -82,21 +82,21 @@
|
|||
app:srcCompat="@drawable/ic_check_circle" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/activity_main_status_title"
|
||||
android:id="@+id/status_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="25dp"
|
||||
android:layout_toEndOf="@id/activity_main_status_icon"
|
||||
android:layout_toEndOf="@id/status_icon"
|
||||
android:text="@string/Activated"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
|
||||
android:textColor="@android:color/white" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/activity_main_status_summary"
|
||||
android:id="@+id/status_summary"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/activity_main_status_title"
|
||||
android:layout_alignStart="@id/activity_main_status_title"
|
||||
android:layout_below="@id/status_title"
|
||||
android:layout_alignStart="@id/status_title"
|
||||
android:layout_marginTop="5dp"
|
||||
android:text="@string/ActivatedDetail"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Small"
|
||||
|
|
@ -105,7 +105,7 @@
|
|||
</com.google.android.material.card.MaterialCardView>
|
||||
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
android:id="@+id/activity_main_modules"
|
||||
android:id="@+id/modules"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="16dp"
|
||||
|
|
@ -124,7 +124,7 @@
|
|||
android:paddingBottom="16dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/activity_main_modules_icon"
|
||||
android:id="@+id/modules_icon"
|
||||
android:layout_width="28dp"
|
||||
android:layout_height="28dp"
|
||||
android:layout_centerVertical="true"
|
||||
|
|
@ -132,20 +132,20 @@
|
|||
app:srcCompat="@drawable/ic_apps" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/activity_main_modules_title"
|
||||
android:id="@+id/modules_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="25dp"
|
||||
android:layout_toEndOf="@id/activity_main_modules_icon"
|
||||
android:layout_toEndOf="@id/modules_icon"
|
||||
android:text="@string/Modules"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Medium" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/activity_main_modules_summary"
|
||||
android:id="@+id/modules_summary"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/activity_main_modules_title"
|
||||
android:layout_alignStart="@id/activity_main_modules_title"
|
||||
android:layout_below="@id/modules_title"
|
||||
android:layout_alignStart="@id/modules_title"
|
||||
android:layout_marginTop="2dp"
|
||||
android:text="@string/ModulesDetail"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Small"
|
||||
|
|
@ -154,7 +154,7 @@
|
|||
</com.google.android.material.card.MaterialCardView>
|
||||
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
android:id="@+id/activity_main_downloads"
|
||||
android:id="@+id/downloads"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="16dp"
|
||||
|
|
@ -173,7 +173,7 @@
|
|||
android:paddingBottom="16dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/activity_main_downloads_icon"
|
||||
android:id="@+id/downloads_icon"
|
||||
android:layout_width="28dp"
|
||||
android:layout_height="28dp"
|
||||
android:layout_centerVertical="true"
|
||||
|
|
@ -181,20 +181,20 @@
|
|||
app:srcCompat="@drawable/ic_get_app" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/activity_main_downloads_title"
|
||||
android:id="@+id/downloads_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="25dp"
|
||||
android:layout_toEndOf="@id/activity_main_downloads_icon"
|
||||
android:layout_toEndOf="@id/downloads_icon"
|
||||
android:text="@string/Downloads"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Medium" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/activity_main_download_summary"
|
||||
android:id="@+id/download_summary"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/activity_main_downloads_title"
|
||||
android:layout_alignStart="@id/activity_main_downloads_title"
|
||||
android:layout_below="@id/downloads_title"
|
||||
android:layout_alignStart="@id/downloads_title"
|
||||
android:layout_marginTop="2dp"
|
||||
android:text="@string/ModuleUpgradable"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Small"
|
||||
|
|
@ -203,7 +203,7 @@
|
|||
</com.google.android.material.card.MaterialCardView>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/activity_main_apps"
|
||||
android:id="@+id/apps"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="16dp"
|
||||
|
|
@ -229,7 +229,7 @@
|
|||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/activity_main_logs"
|
||||
android:id="@+id/logs"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="16dp"
|
||||
|
|
@ -255,7 +255,7 @@
|
|||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/activity_main_settings"
|
||||
android:id="@+id/settings"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="16dp"
|
||||
|
|
@ -281,7 +281,7 @@
|
|||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/activity_main_about"
|
||||
android:id="@+id/about"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="16dp"
|
||||
|
|
|
|||
|
|
@ -7,7 +7,9 @@
|
|||
android:clipChildren="false"
|
||||
android:clipToPadding="false">
|
||||
|
||||
<include layout="@layout/appbar_layout" />
|
||||
<include
|
||||
android:id="@+id/appbar"
|
||||
layout="@layout/appbar_layout" />
|
||||
|
||||
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||
android:id="@+id/swipeRefreshLayout"
|
||||
|
|
|
|||
|
|
@ -7,7 +7,9 @@
|
|||
android:clipChildren="false"
|
||||
android:clipToPadding="false">
|
||||
|
||||
<include layout="@layout/appbar_layout" />
|
||||
<include
|
||||
android:id="@+id/appbar"
|
||||
layout="@layout/appbar_layout" />
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/container"
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
android:theme="@style/Widget.AppCompat.Button.Colored" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/save"
|
||||
android:id="@+id/btnSave"
|
||||
style="@style/Widget.MaterialComponents.Button.OutlinedButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
|
|
|
|||
|
|
@ -3,9 +3,7 @@
|
|||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginBottom="8dp">
|
||||
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
|
|
@ -203,7 +201,7 @@
|
|||
android:paddingBottom="8dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/ic_manufacturer"
|
||||
android:id="@+id/manufacturer"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Subhead" />
|
||||
|
|
|
|||
Loading…
Reference in New Issue