New log activity

This commit is contained in:
NekoInverter 2020-02-05 21:13:25 +08:00
parent d43eea7ebe
commit 0549f37277
13 changed files with 263 additions and 180 deletions

View File

@ -16,7 +16,6 @@ import android.widget.Button;
import android.widget.ImageView;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@ -24,6 +23,7 @@ import androidx.core.app.ActivityCompat;
import androidx.fragment.app.Fragment;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.snackbar.Snackbar;
import org.meowcat.edxposed.manager.util.NavUtil;
import org.meowcat.edxposed.manager.util.json.XposedTab;
@ -206,7 +206,7 @@ public class BaseAdvancedInstaller extends Fragment {
new Handler().postDelayed(() -> mClickedButton.performClick(), 500);
}
} else {
Toast.makeText(getActivity(), R.string.permissionNotGranted, Toast.LENGTH_LONG).show();
Snackbar.make(getActivity().findViewById(R.id.snackbar), R.string.permissionNotGranted, Snackbar.LENGTH_LONG).show();
}
}
}

View File

@ -1,6 +1,7 @@
package org.meowcat.edxposed.manager;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
@ -14,12 +15,13 @@ import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.FrameLayout;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.ListFragment;
import com.google.android.material.snackbar.Snackbar;
import org.meowcat.edxposed.manager.repo.Module;
import org.meowcat.edxposed.manager.repo.ModuleVersion;
import org.meowcat.edxposed.manager.repo.ReleaseType;
@ -40,6 +42,7 @@ import static org.meowcat.edxposed.manager.XposedApp.WRITE_EXTERNAL_PERMISSION;
public class DownloadDetailsVersionsFragment extends ListFragment {
private DownloadDetailsActivity mActivity;
private View rootView;
@Override
public void onActivityCreated(Bundle savedInstanceState) {
@ -48,6 +51,7 @@ public class DownloadDetailsVersionsFragment extends ListFragment {
if (mActivity == null) {
return;
}
rootView = mActivity.findViewById(R.id.snackbar);
Module module = mActivity.getModule();
if (module == null)
return;
@ -95,7 +99,7 @@ public class DownloadDetailsVersionsFragment extends ListFragment {
if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
DownloadView.mClickedButton.performClick();
} else {
Toast.makeText(getActivity(), R.string.permissionNotGranted, Toast.LENGTH_LONG).show();
Snackbar.make(rootView, R.string.permissionNotGranted, Snackbar.LENGTH_LONG).show();
}
}
}
@ -120,7 +124,7 @@ public class DownloadDetailsVersionsFragment extends ListFragment {
@Override
public void onDownloadFinished(Context context, DownloadsUtil.DownloadInfo info) {
File localFile = new File(info.localFilename);
View rootView = ((Activity) context).findViewById(R.id.snackbar);
if (!localFile.isFile())
return;
@ -128,12 +132,12 @@ public class DownloadDetailsVersionsFragment extends ListFragment {
try {
String actualMd5Sum = HashUtil.md5(localFile);
if (!moduleVersion.md5sum.equals(actualMd5Sum)) {
Toast.makeText(context, context.getString(R.string.download_md5sum_incorrect, actualMd5Sum, moduleVersion.md5sum), Toast.LENGTH_LONG).show();
Snackbar.make(rootView, context.getString(R.string.download_md5sum_incorrect, actualMd5Sum, moduleVersion.md5sum), Snackbar.LENGTH_LONG).show();
DownloadsUtil.removeById(context, info.id);
return;
}
} catch (Exception e) {
Toast.makeText(context, context.getString(R.string.download_could_not_read_file, e.getMessage()), Toast.LENGTH_LONG).show();
Snackbar.make(rootView, context.getString(R.string.download_could_not_read_file, e.getMessage()), Snackbar.LENGTH_LONG).show();
DownloadsUtil.removeById(context, info.id);
return;
}
@ -143,13 +147,13 @@ public class DownloadDetailsVersionsFragment extends ListFragment {
PackageInfo packageInfo = pm.getPackageArchiveInfo(info.localFilename, 0);
if (packageInfo == null) {
Toast.makeText(context, R.string.download_no_valid_apk, Toast.LENGTH_LONG).show();
Snackbar.make(rootView, R.string.download_no_valid_apk, Snackbar.LENGTH_LONG).show();
DownloadsUtil.removeById(context, info.id);
return;
}
if (!packageInfo.packageName.equals(moduleVersion.module.packageName)) {
Toast.makeText(context, context.getString(R.string.download_incorrect_package_name, packageInfo.packageName, moduleVersion.module.packageName), Toast.LENGTH_LONG).show();
Snackbar.make(rootView, context.getString(R.string.download_incorrect_package_name, packageInfo.packageName, moduleVersion.module.packageName), Snackbar.LENGTH_LONG).show();
DownloadsUtil.removeById(context, info.id);
return;
}

View File

@ -7,17 +7,17 @@ import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.HorizontalScrollView;
import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@ -25,29 +25,33 @@ import androidx.appcompat.app.ActionBar;
import androidx.appcompat.widget.Toolbar;
import androidx.core.app.ActivityCompat;
import androidx.core.content.FileProvider;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.snackbar.Snackbar;
import com.google.android.material.tabs.TabLayout;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Objects;
import java.util.Scanner;
public class LogsActivity extends BaseActivity {
private boolean errorLog = false;
private boolean allLog = false;
private File mFileErrorLog = new File(XposedApp.BASE_DIR + "log/error.log");
private File mFileErrorLogOld = new File(
XposedApp.BASE_DIR + "log/error.log.old");
private File mFileErrorLogError = new File(XposedApp.BASE_DIR + "log/all.log");
private File mFileErrorLogOldError = new File(XposedApp.BASE_DIR + "log/all.log.old");
private TextView mTxtLog;
private ScrollView mSVLog;
private HorizontalScrollView mHSVLog;
private File mFileAllLog = new File(XposedApp.BASE_DIR + "log/all.log");
private File mFileAllLogOld = new File(XposedApp.BASE_DIR + "log/all.log.old");
private MenuItem mClickedMenuItem = null;
private LogsAdapter mAdapter;
private RecyclerView mListView;
private Handler handler = new Handler();
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
@ -61,10 +65,6 @@ public class LogsActivity extends BaseActivity {
bar.setDisplayHomeAsUpEnabled(true);
}
setupWindowInsets();
mTxtLog = findViewById(R.id.txtLog);
mTxtLog.setTextIsSelectable(true);
mSVLog = findViewById(R.id.svLog);
mHSVLog = findViewById(R.id.hsvLog);
if (!XposedApp.getPreferences().getBoolean("hide_logcat_warning", false)) {
@SuppressLint("InflateParams") final View dontShowAgainView = getLayoutInflater().inflate(R.layout.dialog_install_warning, null);
@ -83,6 +83,29 @@ public class LogsActivity extends BaseActivity {
.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);
tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
allLog = tab.getPosition() != 0;
reloadErrorLog();
scrollDown();
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
}
@Override
@ -101,17 +124,6 @@ public class LogsActivity extends BaseActivity {
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
mClickedMenuItem = item;
switch (item.getItemId()) {
case R.id.menu_logs:
item.setChecked(true);
errorLog = false;
reloadErrorLog();
break;
case R.id.menu_logs_err:
item.setChecked(true);
errorLog = true;
reloadErrorLog();
scrollDown();
break;
case R.id.menu_scroll_top:
scrollTop();
break;
@ -138,36 +150,32 @@ public class LogsActivity extends BaseActivity {
}
private void scrollTop() {
mSVLog.post(() -> mSVLog.scrollTo(0, 0));
mHSVLog.post(() -> mHSVLog.scrollTo(0, 0));
mListView.smoothScrollToPosition(0);
}
private void scrollDown() {
mSVLog.post(() -> mSVLog.scrollTo(0, mTxtLog.getHeight()));
mHSVLog.post(() -> mHSVLog.scrollTo(0, 0));
mListView.smoothScrollToPosition(mAdapter.getItemCount() - 1);
}
private void reloadErrorLog() {
new LogsReader().execute(errorLog ? mFileErrorLogError : mFileErrorLog);
mSVLog.post(() -> mSVLog.scrollTo(0, mTxtLog.getHeight()));
mHSVLog.post(() -> mHSVLog.scrollTo(0, 0));
new LogsReader().execute(allLog ? mFileAllLog : mFileErrorLog);
}
private void clear() {
try {
new FileOutputStream(errorLog ? mFileErrorLogError : mFileErrorLog).close();
(errorLog ? mFileErrorLogOldError : mFileErrorLogOld).delete();
mTxtLog.setText(R.string.log_is_empty);
Toast.makeText(this, R.string.logs_cleared,
Toast.LENGTH_SHORT).show();
new FileOutputStream(allLog ? mFileAllLog : mFileErrorLog).close();
//noinspection ResultOfMethodCallIgnored
(allLog ? mFileAllLogOld : mFileErrorLogOld).delete();
mAdapter.setEmpty();
Snackbar.make(findViewById(R.id.snackbar), R.string.logs_cleared, Snackbar.LENGTH_SHORT).show();
reloadErrorLog();
} catch (IOException e) {
Toast.makeText(this, getResources().getString(R.string.logs_clear_failed) + "n" + e.getMessage(), Toast.LENGTH_LONG).show();
Snackbar.make(findViewById(R.id.snackbar), getResources().getString(R.string.logs_clear_failed) + "n" + e.getMessage(), Snackbar.LENGTH_LONG).show();
}
}
private void send() {
Uri uri = FileProvider.getUriForFile(this, "org.meowcat.edxposed.manager.fileprovider", errorLog ? mFileErrorLogError : mFileErrorLog);
Uri uri = FileProvider.getUriForFile(this, BuildConfig.APPLICATION_ID + ".fileprovider", allLog ? mFileAllLog : mFileErrorLog);
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_STREAM, uri);
@ -187,20 +195,20 @@ public class LogsActivity extends BaseActivity {
new Handler().postDelayed(() -> onOptionsItemSelected(mClickedMenuItem), 500);
}
} else {
Toast.makeText(this, R.string.permissionNotGranted, Toast.LENGTH_LONG).show();
Snackbar.make(findViewById(R.id.snackbar), R.string.permissionNotGranted, Snackbar.LENGTH_LONG).show();
}
}
}
@SuppressLint("DefaultLocale")
private void save() {
if (ActivityCompat.checkSelfPermission(Objects.requireNonNull(this), Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, XposedApp.WRITE_EXTERNAL_PERMISSION);
return;
}
if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
Toast.makeText(this, R.string.sdcard_not_writable, Toast.LENGTH_LONG).show();
Snackbar.make(findViewById(R.id.snackbar), R.string.sdcard_not_writable, Snackbar.LENGTH_LONG).show();
return;
}
@ -214,7 +222,7 @@ public class LogsActivity extends BaseActivity {
File targetFile = new File(XposedApp.createFolder(), filename);
try {
FileInputStream in = new FileInputStream(errorLog ? mFileErrorLogError : mFileErrorLog);
FileInputStream in = new FileInputStream(allLog ? mFileAllLog : mFileErrorLog);
FileOutputStream out = new FileOutputStream(targetFile);
byte[] buffer = new byte[1024];
int len;
@ -224,93 +232,119 @@ public class LogsActivity extends BaseActivity {
in.close();
out.close();
Toast.makeText(this, targetFile.toString(),
Toast.LENGTH_LONG).show();
Snackbar.make(findViewById(R.id.snackbar), targetFile.toString(), Snackbar.LENGTH_LONG).show();
} catch (IOException e) {
Toast.makeText(this, getResources().getString(R.string.logs_save_failed) + "\n" + e.getMessage(), Toast.LENGTH_LONG).show();
Snackbar.make(findViewById(R.id.snackbar), getResources().getString(R.string.logs_save_failed) + "\n" + e.getMessage(), Snackbar.LENGTH_LONG).show();
}
}
@SuppressLint("StaticFieldLeak")
private class LogsReader extends AsyncTask<File, Integer, String> {
private static final int MAX_LOG_SIZE = 1000 * 1024; // 1000 KB
private class LogsReader extends AsyncTask<File, Integer, ArrayList<String>> {
private ProgressDialog mProgressDialog;
private long skipLargeFile(BufferedReader is, long length) throws IOException {
if (length < MAX_LOG_SIZE)
return 0;
long skipped = length - MAX_LOG_SIZE;
long yetToSkip = skipped;
do {
yetToSkip -= is.skip(yetToSkip);
} while (yetToSkip > 0);
int c;
do {
c = is.read();
if (c == -1)
break;
skipped++;
} while (c != '\n');
return skipped;
}
private Runnable mRunnable = new Runnable() {
@Override
public void run() {
mProgressDialog.show();
}
};
@Override
protected void onPreExecute() {
mTxtLog.setText("");
mProgressDialog = new ProgressDialog(LogsActivity.this);
mProgressDialog.setMessage(getString(R.string.loading));
mProgressDialog.setProgress(0);
mProgressDialog.show();
handler.postDelayed(mRunnable, 500);
}
@Override
protected String doInBackground(File... log) {
protected ArrayList<String> doInBackground(File... log) {
Thread.currentThread().setPriority(Thread.NORM_PRIORITY + 2);
StringBuilder llog = new StringBuilder(15 * 10 * 1024);
if (XposedApp.getPreferences().getBoolean(
"disable_verbose_log", false) && errorLog) {
llog.append(LogsActivity.this.getResources().getString(R.string.logs_verbose_disabled));
return llog.toString();
ArrayList<String> logs = new ArrayList<>();
if (XposedApp.getPreferences().getBoolean("disable_verbose_log", false) && allLog) {
logs.add(LogsActivity.this.getResources().getString(R.string.logs_verbose_disabled));
return logs;
}
try {
File logfile = log[0];
BufferedReader br;
br = new BufferedReader(new FileReader(logfile));
long skipped = skipLargeFile(br, logfile.length());
if (skipped > 0) {
llog.append(LogsActivity.this.getResources().getString(R.string.logs_too_long));
llog.append("\n-----------------\n");
try (Scanner scanner = new Scanner(logfile)) {
while (scanner.hasNextLine()) {
logs.add(scanner.nextLine());
}
}
char[] temp = new char[1024];
int read;
while ((read = br.read(temp)) > 0) {
llog.append(temp, 0, read);
}
br.close();
return logs;
} catch (IOException e) {
llog.append(LogsActivity.this.getResources().getString(R.string.logs_cannot_read));
llog.append(e.getMessage());
logs.add(LogsActivity.this.getResources().getString(R.string.logs_cannot_read));
logs.addAll(Arrays.asList(e.getMessage().split("\n")));
}
return llog.toString();
return logs;
}
@Override
protected void onPostExecute(String llog) {
mProgressDialog.dismiss();
mTxtLog.setText(llog);
protected void onPostExecute(ArrayList<String> logs) {
if (logs.size() == 0) {
mAdapter.setEmpty();
} else {
mAdapter.setLogs(logs);
}
handler.removeCallbacks(mRunnable);//It loaded so fast that no need to show progress
if (mProgressDialog.isShowing()){
mProgressDialog.dismiss();
}
}
}
if (llog.length() == 0)
mTxtLog.setText(R.string.log_is_empty);
private class LogsAdapter extends RecyclerView.Adapter<LogsAdapter.ViewHolder> {
ArrayList<String> logs = new ArrayList<>();
@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);
}
@Override
public void onBindViewHolder(@NonNull LogsAdapter.ViewHolder holder, int position) {
TextView view = holder.textView;
view.setText(logs.get(position));
view.measure(0, 0);
int desiredWidth = view.getMeasuredWidth();
ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
layoutParams.width = desiredWidth;
if (mListView.getWidth() < desiredWidth) {
mListView.requestLayout();
}
}
void setLogs(ArrayList<String> logs) {
this.logs.clear();
this.logs.addAll(logs);
notifyDataSetChanged();
}
void setEmpty() {
logs.clear();
logs.add(getString(R.string.log_is_empty));
notifyDataSetChanged();
}
@Override
public int getItemCount() {
return logs.size();
}
class ViewHolder extends RecyclerView.ViewHolder {
TextView textView;
ViewHolder(View itemView) {
super(itemView);
textView = itemView.findViewById(R.id.log);
}
}
}
}

View File

@ -24,7 +24,6 @@ import android.widget.Filter;
import android.widget.ImageView;
import android.widget.Switch;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.ActionBar;
@ -38,6 +37,8 @@ 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.repo.Module;
import org.meowcat.edxposed.manager.repo.ModuleVersion;
import org.meowcat.edxposed.manager.repo.ReleaseType;
@ -189,7 +190,7 @@ public class ModulesActivity extends BaseActivity implements ModuleUtil.ModuleLi
new Handler().postDelayed(() -> onOptionsItemSelected(mClickedMenuItem), 500);
}
} else {
Toast.makeText(this, R.string.permissionNotGranted, Toast.LENGTH_LONG).show();
Snackbar.make(findViewById(R.id.snackbar), R.string.permissionNotGranted, Snackbar.LENGTH_LONG).show();
}
}
}
@ -212,7 +213,7 @@ public class ModulesActivity extends BaseActivity implements ModuleUtil.ModuleLi
}
if (ModuleUtil.getInstance().getEnabledModules().isEmpty()) {
Toast.makeText(this, getString(R.string.no_enabled_modules), Toast.LENGTH_SHORT).show();
Snackbar.make(findViewById(R.id.snackbar), R.string.no_enabled_modules, Snackbar.LENGTH_SHORT).show();
return false;
}
@ -230,21 +231,21 @@ public class ModulesActivity extends BaseActivity implements ModuleUtil.ModuleLi
in.close();
out.close();
} catch (IOException e) {
Toast.makeText(this, getResources().getString(R.string.logs_save_failed) + "\n" + e.getMessage(), Toast.LENGTH_LONG).show();
Snackbar.make(findViewById(R.id.snackbar), getResources().getString(R.string.logs_save_failed) + "\n" + e.getMessage(), Snackbar.LENGTH_LONG).show();
return false;
}
Toast.makeText(this, enabledModulesPath.toString(), Toast.LENGTH_LONG).show();
Snackbar.make(findViewById(R.id.snackbar), enabledModulesPath.toString(), Snackbar.LENGTH_LONG).show();
return true;
case R.id.export_installed_modules:
if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
Toast.makeText(this, R.string.sdcard_not_writable, Toast.LENGTH_LONG).show();
Snackbar.make(findViewById(R.id.snackbar), R.string.sdcard_not_writable, Snackbar.LENGTH_LONG).show();
return false;
}
Map<String, ModuleUtil.InstalledModule> installedModules = ModuleUtil.getInstance().getModules();
if (installedModules.isEmpty()) {
Toast.makeText(this, getString(R.string.no_installed_modules), Toast.LENGTH_SHORT).show();
Snackbar.make(findViewById(R.id.snackbar), R.string.no_installed_modules, Snackbar.LENGTH_SHORT).show();
return false;
}
@ -262,11 +263,11 @@ public class ModulesActivity extends BaseActivity implements ModuleUtil.ModuleLi
fileOut.close();
} catch (IOException e) {
Toast.makeText(this, getResources().getString(R.string.logs_save_failed) + "\n" + e.getMessage(), Toast.LENGTH_LONG).show();
Snackbar.make(findViewById(R.id.snackbar), getResources().getString(R.string.logs_save_failed) + "\n" + e.getMessage(), Snackbar.LENGTH_LONG).show();
return false;
}
Toast.makeText(this, installedModulesPath.toString(), Toast.LENGTH_LONG).show();
Snackbar.make(findViewById(R.id.snackbar), installedModulesPath.toString(), Snackbar.LENGTH_LONG).show();
return true;
case R.id.import_installed_modules:
return importModules(installedModulesPath);
@ -279,15 +280,14 @@ public class ModulesActivity extends BaseActivity implements ModuleUtil.ModuleLi
private boolean importModules(File path) {
if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
Toast.makeText(this, R.string.sdcard_not_writable, Toast.LENGTH_LONG).show();
Snackbar.make(findViewById(R.id.snackbar), R.string.sdcard_not_writable, Snackbar.LENGTH_LONG).show();
return false;
}
InputStream ips = null;
RepoLoader repoLoader = RepoLoader.getInstance();
List<Module> list = new ArrayList<>();
if (!path.exists()) {
Toast.makeText(this, getString(R.string.no_backup_found),
Toast.LENGTH_LONG).show();
Snackbar.make(findViewById(R.id.snackbar), R.string.no_backup_found, Snackbar.LENGTH_LONG).show();
return false;
}
try {
@ -297,8 +297,7 @@ public class ModulesActivity extends BaseActivity implements ModuleUtil.ModuleLi
}
if (path.length() == 0) {
Toast.makeText(this, R.string.file_is_empty,
Toast.LENGTH_LONG).show();
Snackbar.make(findViewById(R.id.snackbar), R.string.file_is_empty, Snackbar.LENGTH_LONG).show();
return false;
}
@ -311,15 +310,15 @@ public class ModulesActivity extends BaseActivity implements ModuleUtil.ModuleLi
Module m = repoLoader.getModule(line);
if (m == null) {
Toast.makeText(this, getString(R.string.download_details_not_found,
line), Toast.LENGTH_SHORT).show();
Snackbar.make(findViewById(R.id.snackbar), getString(R.string.download_details_not_found,
line), Snackbar.LENGTH_SHORT).show();
} else {
list.add(m);
}
}
br.close();
} catch (ActivityNotFoundException | IOException e) {
Toast.makeText(this, e.toString(), Toast.LENGTH_SHORT).show();
Snackbar.make(findViewById(R.id.snackbar), e.toString(), Snackbar.LENGTH_SHORT).show();
}
for (final Module m : list) {
@ -397,7 +396,7 @@ public class ModulesActivity extends BaseActivity implements ModuleUtil.ModuleLi
if (launchIntent != null) {
startActivity(launchIntent);
} else {
Toast.makeText(this, getString(R.string.module_no_ui), Toast.LENGTH_LONG).show();
Snackbar.make(findViewById(R.id.snackbar), R.string.module_no_ui, Snackbar.LENGTH_LONG).show();
}
return true;
@ -473,7 +472,7 @@ public class ModulesActivity extends BaseActivity implements ModuleUtil.ModuleLi
if (launchIntent != null) {
startActivity(launchIntent);
} else {
Toast.makeText(this, getString(R.string.module_no_ui), Toast.LENGTH_LONG).show();
Snackbar.make(findViewById(R.id.snackbar), R.string.module_no_ui, Snackbar.LENGTH_LONG).show();
}
}
} else {
@ -485,7 +484,7 @@ public class ModulesActivity extends BaseActivity implements ModuleUtil.ModuleLi
if (launchIntent != null) {
startActivity(launchIntent);
} else {
Toast.makeText(this, getString(R.string.module_no_ui), Toast.LENGTH_LONG).show();
Snackbar.make(findViewById(R.id.snackbar), R.string.module_no_ui, Snackbar.LENGTH_LONG).show();
}
}
}

View File

@ -0,0 +1,37 @@
<?xml version="1.0" encoding="utf-8"?>
<font-family xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<font
android:font="@font/exo_regular"
android:fontStyle="normal"
android:fontWeight="400"
app:font="@font/exo_regular"
app:fontStyle="normal"
app:fontWeight="400" />
<font
android:font="@font/exo_regular_italic"
android:fontStyle="italic"
android:fontWeight="400"
app:font="@font/exo_regular_italic"
app:fontStyle="italic"
app:fontWeight="400" />
<font
android:font="@font/exo_bold"
android:fontStyle="normal"
android:fontWeight="500"
app:font="@font/exo_bold"
app:fontStyle="normal"
app:fontWeight="500" />
<font
android:font="@font/exo_bold_italic"
android:fontStyle="italic"
android:fontWeight="500"
app:font="@font/exo_bold_italic"
app:fontStyle="italic"
app:fontWeight="500" />
</font-family>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,44 +1,59 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/snackbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipChildren="false"
android:clipToPadding="false"
tools:context=".LogsActivity">
android:clipToPadding="false">
<include layout="@layout/appbar_layout" />
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">
<RelativeLayout
android:id="@+id/container"
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?colorActionBar"
app:popupTheme="@style/AppTheme.PopupOverlay" />
<com.google.android.material.tabs.TabLayout
android:id="@+id/sliding_tabs"
style="@style/Widget.MaterialComponents.TabLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?colorActionBar"
app:tabMode="fixed">
<com.google.android.material.tabs.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/nav_item_logs_err" />
<com.google.android.material.tabs.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/nav_item_logs" />
</com.google.android.material.tabs.TabLayout>
</com.google.android.material.appbar.AppBarLayout>
<HorizontalScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="?attr/actionBarSize"
android:clipChildren="false"
android:clipToPadding="false"
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior">
<ScrollView
android:id="@+id/svLog"
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:ignore="UselessParent">
android:layout_height="match_parent"
android:clipChildren="false"
android:clipToPadding="false"
android:orientation="vertical" />
</HorizontalScrollView>
<HorizontalScrollView
android:id="@+id/hsvLog"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:id="@+id/txtLog"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="8dp"
android:textIsSelectable="true" />
</HorizontalScrollView>
</ScrollView>
</RelativeLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -0,0 +1,8 @@
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/log"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="monospace"
android:text=""
android:textAppearance="@style/AppearanceFoundation.Caption"
android:textSize="10sp" />

View File

@ -1,25 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<item
android:icon="@drawable/ic_bug"
android:title="@string/Logs"
app:showAsAction="always"
tools:ignore="AlwaysShowAction">
<menu>
<group android:checkableBehavior="single">
<item
android:id="@+id/menu_logs"
android:checked="true"
android:title="@string/nav_item_logs" />
<item
android:id="@+id/menu_logs_err"
android:title="@string/nav_item_logs_err" />
</group>
</menu>
</item>
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/menu_save"
android:icon="@drawable/ic_save"

View File

@ -16,6 +16,11 @@
<item name="preferenceTheme">@style/PreferenceThemeOverlay</item>
</style>
<style name="AppearanceFoundation.Caption" parent="TextAppearance.AppCompat.Caption">
<item name="android:fontFamily">@font/exo</item>
<item name="android:textColor">?attr/colorOnSurface</item>
</style>
<style name="AppThemeMain" parent="AppTheme">
<item name="colorPrimaryDark">@color/colorBackground</item>
</style>