Compare commits

..

7 Commits

Author SHA1 Message Date
topjohnwu
5d62e066e2 Bump version 2017-02-22 05:06:19 +08:00
topjohnwu
e94219c5a3 Add notification settings 2017-02-22 04:58:03 +08:00
topjohnwu
8ed9634adf Fix Samsung crash 2017-02-22 04:13:21 +08:00
topjohnwu
0aefa9599f Version bump 2017-02-21 03:52:35 +08:00
c727
e279cf0575 update strings-de 2017-02-20 13:40:01 -06:00
topjohnwu
a3f0ef8e77 Many improvements and bug fixes
Close #114
2017-02-21 03:38:37 +08:00
topjohnwu
8eba05ed4a Potentially fix Samsung crash and change colors 2017-02-20 20:11:07 +08:00
41 changed files with 339 additions and 253 deletions

View File

@@ -8,8 +8,8 @@ android {
applicationId "com.topjohnwu.magisk"
minSdkVersion 21
targetSdkVersion 25
versionCode 23
versionName "4.2"
versionCode 25
versionName "4.2.6"
jackOptions {
enabled true
jackInProcess true
@@ -47,10 +47,10 @@ repositories {
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
compile 'com.android.support:recyclerview-v7:25.1.1'
compile 'com.android.support:cardview-v7:25.1.1'
compile 'com.android.support:design:25.1.1'
compile 'com.android.support:support-v4:25.1.1'
compile 'com.android.support:recyclerview-v7:25.2.0'
compile 'com.android.support:cardview-v7:25.2.0'
compile 'com.android.support:design:25.2.0'
compile 'com.android.support:support-v4:25.2.0'
compile 'com.jakewharton:butterknife:8.5.1'
compile 'com.github.clans:fab:1.6.4'
compile 'com.thoughtbot:expandablerecyclerview:1.4'

View File

@@ -6,6 +6,7 @@ import android.net.Uri;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.support.annotation.Nullable;
import android.support.design.widget.Snackbar;
import android.support.v7.widget.CardView;
import android.view.LayoutInflater;
import android.view.View;
@@ -19,6 +20,7 @@ import android.widget.TextView;
import com.topjohnwu.magisk.asyncs.ProcessMagiskZip;
import com.topjohnwu.magisk.components.AlertDialogBuilder;
import com.topjohnwu.magisk.components.Fragment;
import com.topjohnwu.magisk.components.SnackbarMaker;
import com.topjohnwu.magisk.receivers.DownloadReceiver;
import com.topjohnwu.magisk.utils.CallbackEvent;
import com.topjohnwu.magisk.utils.Shell;
@@ -34,6 +36,7 @@ import java.util.Locale;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import butterknife.Unbinder;
public class InstallFragment extends Fragment implements CallbackEvent.Listener<Void> {
@@ -41,108 +44,126 @@ public class InstallFragment extends Fragment implements CallbackEvent.Listener<
private static final String UNINSTALLER = "magisk_uninstaller.sh";
private Unbinder unbinder;
@BindView(R.id.current_version_title) TextView currentVersionTitle;
@BindView(R.id.install_title) TextView installTitle;
@BindView(R.id.block_spinner) Spinner spinner;
@BindView(R.id.detect_bootimage) Button detectButton;
@BindView(R.id.flash_button) CardView flashButton;
@BindView(R.id.install_button) CardView installButton;
@BindView(R.id.install_text) TextView installText;
@BindView(R.id.uninstall_button) CardView uninstallButton;
@BindView(R.id.keep_force_enc) CheckBox keepEncChkbox;
@BindView(R.id.keep_verity) CheckBox keepVerityChkbox;
@OnClick(R.id.detect_bootimage)
public void toAutoDetect() {
if (magiskManager.bootBlock != null) {
spinner.setSelection(0);
}
}
@OnClick(R.id.install_button)
public void install() {
String bootImage = null;
if (magiskManager.blockList != null) {
int idx = spinner.getSelectedItemPosition();
if (magiskManager.bootBlock != null) {
if (idx > 0) {
bootImage = magiskManager.blockList.get(idx - 1);
}
} else {
if (idx > 0) {
bootImage = magiskManager.blockList.get(idx - 1);
} else {
SnackbarMaker.make(getActivity(), R.string.manual_boot_image, Snackbar.LENGTH_LONG);
}
}
}
final String finalBootImage = bootImage;
String filename = "Magisk-v" + magiskManager.remoteMagiskVersion + ".zip";
new AlertDialogBuilder(getActivity())
.setTitle(getString(R.string.repo_install_title, getString(R.string.magisk)))
.setMessage(getString(R.string.repo_install_msg, filename))
.setCancelable(true)
.setPositiveButton(Shell.rootAccess() ? R.string.install : R.string.download,
(dialogInterface, i) -> Utils.dlAndReceive(
getActivity(),
new DownloadReceiver() {
private String boot = finalBootImage;
private boolean enc = keepEncChkbox.isChecked();
private boolean verity = keepVerityChkbox.isChecked();
@Override
public void onDownloadDone(Uri uri) {
new ProcessMagiskZip(getActivity(), uri, boot, enc, verity).exec();
}
},
magiskManager.magiskLink,
Utils.getLegalFilename(filename)))
.setNeutralButton(R.string.release_notes, (dialog, which) -> {
magiskManager.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(magiskManager.releaseNoteLink)));
})
.setNegativeButton(R.string.no_thanks, null)
.show();
}
@OnClick(R.id.uninstall_button)
public void uninstall() {
new AlertDialogBuilder(getActivity())
.setTitle(R.string.uninstall_magisk_title)
.setMessage(R.string.uninstall_magisk_msg)
.setPositiveButton(R.string.yes, (dialogInterface, i) -> {
try {
InputStream in = magiskManager.getAssets().open(UNINSTALLER);
File uninstaller = new File(magiskManager.getCacheDir(), UNINSTALLER);
FileOutputStream out = new FileOutputStream(uninstaller);
byte[] bytes = new byte[1024];
int read;
while ((read = in.read(bytes)) != -1) {
out.write(bytes, 0, read);
}
in.close();
out.close();
ProgressDialog progress = new ProgressDialog(getActivity());
progress.setTitle(R.string.reboot);
progress.show();
new CountDownTimer(5000, 1000) {
@Override
public void onTick(long millisUntilFinished) {
progress.setMessage(getString(R.string.reboot_countdown, millisUntilFinished / 1000));
}
@Override
public void onFinish() {
progress.setMessage(getString(R.string.reboot_countdown, 0));
Shell.su(true, "mv -f " + uninstaller + " /cache/" + UNINSTALLER,
"reboot");
}
}.start();
} catch (IOException e) {
e.printStackTrace();
}
})
.setNegativeButton(R.string.no_thanks, null)
.show();
}
private Unbinder unbinder;
private MagiskManager magiskManager;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_install, container, false);
unbinder = ButterKnife.bind(this, v);
detectButton.setOnClickListener(v1 -> toAutoDetect());
if (getApplication().magiskVersion < 0)
magiskManager = getApplication();
if (magiskManager.magiskVersion < 0) {
currentVersionTitle.setText(getString(R.string.current_magisk_title, getString(R.string.version_none)));
else
currentVersionTitle.setText(getString(R.string.current_magisk_title, "v" + getApplication().magiskVersionString));
installTitle.setText(getString(R.string.install_magisk_title, "v" + String.format(Locale.US, "%.1f", getApplication().remoteMagiskVersion)));
flashButton.setOnClickListener(v1 -> {
String bootImage;
if (getApplication().bootBlock != null) {
if (spinner.getSelectedItemPosition() > 0)
bootImage = getApplication().blockList.get(spinner.getSelectedItemPosition() - 1);
else
bootImage = getApplication().bootBlock;
} else {
bootImage = getApplication().blockList.get(spinner.getSelectedItemPosition());
}
String filename = "Magisk-v" + getApplication().remoteMagiskVersion + ".zip";
new AlertDialogBuilder(getActivity())
.setTitle(getString(R.string.repo_install_title, getString(R.string.magisk)))
.setMessage(getString(R.string.repo_install_msg, filename))
.setCancelable(true)
.setPositiveButton(R.string.install, (dialogInterface, i) -> Utils.dlAndReceive(
getActivity(),
new DownloadReceiver() {
private String boot = bootImage;
private boolean enc = keepEncChkbox.isChecked();
private boolean verity = keepVerityChkbox.isChecked();
@Override
public void onDownloadDone(Uri uri) {
new ProcessMagiskZip(getActivity(), uri, boot, enc, verity).exec();
}
},
getApplication().magiskLink,
Utils.getLegalFilename(filename)))
.setNeutralButton(R.string.release_notes, (dialog, which) -> {
getActivity().startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(getApplication().releaseNoteLink)));
})
.setNegativeButton(R.string.no_thanks, null)
.show();
});
if (getApplication().magiskVersion < 10.3) {
uninstallButton.setVisibility(View.GONE);
} else {
uninstallButton.setOnClickListener(vi -> {
new AlertDialogBuilder(getActivity())
.setTitle(R.string.uninstall_magisk_title)
.setMessage(R.string.uninstall_magisk_msg)
.setPositiveButton(R.string.yes, (dialogInterface, i) -> {
try {
InputStream in = getActivity().getAssets().open(UNINSTALLER);
File uninstaller = new File(getActivity().getCacheDir().getAbsolutePath() + "/" + UNINSTALLER);
FileOutputStream out = new FileOutputStream(uninstaller);
byte[] bytes = new byte[1024];
int read;
while ((read = in.read(bytes)) != -1)
out.write(bytes, 0, read);
in.close();
out.close();
ProgressDialog progress = new ProgressDialog(getActivity());
progress.setTitle(R.string.reboot);
progress.show();
new CountDownTimer(5000, 1000) {
@Override
public void onTick(long millisUntilFinished) {
progress.setMessage(getString(R.string.reboot_countdown, millisUntilFinished / 1000));
}
@Override
public void onFinish() {
progress.setMessage(getString(R.string.reboot_countdown, 0));
Shell.su(true, "cp -af " + uninstaller + " /cache/" + UNINSTALLER,
"reboot");
}
}.start();
} catch (IOException e) {
e.printStackTrace();
}
})
.setNegativeButton(R.string.no_thanks, null)
.show();
});
currentVersionTitle.setText(getString(R.string.current_magisk_title, "v" + magiskManager.magiskVersionString));
}
installTitle.setText(getString(R.string.install_magisk_title, "v" + String.format(Locale.US, "%.1f", magiskManager.remoteMagiskVersion)));
if (getApplication().blockDetectionDone.isTriggered) {
updateUI();
}
updateUI();
return v;
}
@@ -152,19 +173,33 @@ public class InstallFragment extends Fragment implements CallbackEvent.Listener<
}
private void updateUI() {
List<String> items = new ArrayList<>(getApplication().blockList);
if (getApplication().bootBlock != null)
items.add(0, getString(R.string.auto_detect, getApplication().bootBlock));
ArrayAdapter<String> adapter = new ArrayAdapter<>(getActivity(),
android.R.layout.simple_spinner_item, items);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
toAutoDetect();
}
if (magiskManager.blockList == null || !Shell.rootAccess()) {
uninstallButton.setVisibility(View.GONE);
installText.setText(R.string.download);
detectButton.setEnabled(false);
keepEncChkbox.setEnabled(false);
keepVerityChkbox.setEnabled(false);
spinner.setEnabled(false);
} else {
uninstallButton.setVisibility(magiskManager.magiskVersion > 10.3 ? View.VISIBLE : View.GONE);
installText.setText(R.string.download_install);
detectButton.setEnabled(true);
keepEncChkbox.setEnabled(true);
keepVerityChkbox.setEnabled(true);
spinner.setEnabled(true);
private void toAutoDetect() {
if (getApplication().bootBlock != null) {
spinner.setSelection(0);
List<String> items = new ArrayList<>();
if (magiskManager.bootBlock != null) {
items.add(getString(R.string.auto_detect, magiskManager.bootBlock));
} else {
items.add(getString(R.string.cannot_auto_detect));
}
items.addAll(magiskManager.blockList);
ArrayAdapter<String> adapter = new ArrayAdapter<>(getActivity(),
android.R.layout.simple_spinner_item, items);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
toAutoDetect();
}
}
@@ -172,12 +207,12 @@ public class InstallFragment extends Fragment implements CallbackEvent.Listener<
public void onStart() {
super.onStart();
getActivity().setTitle(R.string.install);
getApplication().blockDetectionDone.register(this);
magiskManager.blockDetectionDone.register(this);
}
@Override
public void onStop() {
getApplication().blockDetectionDone.unRegister(this);
magiskManager.blockDetectionDone.unRegister(this);
super.onStop();
}

View File

@@ -71,8 +71,9 @@ public class MagiskHideFragment extends Fragment implements CallbackEvent.Listen
}
};
if (getApplication().magiskHideDone.isTriggered)
if (getApplication().magiskHideDone.isTriggered) {
onTrigger(getApplication().magiskHideDone);
}
return view;
}

View File

@@ -162,8 +162,9 @@ public class MagiskLogFragment extends Fragment {
return false;
}
if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))
if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
return false;
}
Calendar now = Calendar.getInstance();
String filename = String.format(
@@ -175,8 +176,9 @@ public class MagiskLogFragment extends Fragment {
targetFile = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/MagiskManager/" + filename);
if ((!targetFile.getParentFile().exists() && !targetFile.getParentFile().mkdirs())
|| (targetFile.exists() && !targetFile.delete()))
|| (targetFile.exists() && !targetFile.delete())) {
return false;
}
List<String> in = Utils.readFile(MAGISK_LOG);
@@ -214,10 +216,11 @@ public class MagiskLogFragment extends Fragment {
break;
case 2:
bool = (boolean) o;
if (bool)
if (bool) {
Toast.makeText(getActivity(), targetFile.toString(), Toast.LENGTH_LONG).show();
else
} else {
Toast.makeText(getActivity(), getString(R.string.logs_save_failed), Toast.LENGTH_LONG).show();
}
break;
}
}

View File

@@ -25,6 +25,7 @@ public class MagiskManager extends Application {
public static final String MAGISK_HIDE_PATH = "/magisk/.core/magiskhide/";
public static final String TMP_FOLDER_PATH = "/dev/tmp";
public static final String MAGISK_PATH = "/magisk";
public static final String INTENT_SECTION = "section";
// Events
public final CallbackEvent<Void> blockDetectionDone = new CallbackEvent<>();
@@ -62,6 +63,7 @@ public class MagiskManager extends Application {
public boolean magiskHide;
public boolean isDarkTheme;
public boolean updateNotification;
public int suRequestTimeout;
public int suLogTimeout = 14;
public int suAccessState;
@@ -91,6 +93,7 @@ public class MagiskManager extends Application {
devLogging = prefs.getBoolean("developer_logging", false);
shellLogging = prefs.getBoolean("shell_logging", false);
magiskHide = prefs.getBoolean("magiskhide", false);
updateNotification = prefs.getBoolean("notification", true);
// Always start a new root shell manually, just for safety
Shell.init();
updateMagiskInfo();
@@ -100,6 +103,7 @@ public class MagiskManager extends Application {
prefs.edit()
.putBoolean("dark_theme", isDarkTheme)
.putBoolean("magiskhide", magiskHide)
.putBoolean("notification", updateNotification)
.putBoolean("busybox", Utils.commandExists("busybox"))
.putBoolean("hosts", new File("/magisk/.core/hosts").exists())
.putBoolean("disable", Utils.itemExist(MAGISK_DISABLE_FILE))
@@ -124,9 +128,9 @@ public class MagiskManager extends Application {
}
if (isSuClient) {
ret = Shell.sh("getprop persist.sys.root_access");
if (Utils.isValidShellResponse(ret))
if (Utils.isValidShellResponse(ret)) {
suAccessState = Integer.parseInt(ret.get(0));
else {
} else {
Shell.su(true, "setprop persist.sys.root_access 3");
suAccessState = 3;
}
@@ -159,8 +163,9 @@ public class MagiskManager extends Application {
magiskHideStarted = false;
}
if (!magiskHide && magiskHideStarted)
if (magiskHideStarted) {
magiskHide = true;
}
}

View File

@@ -29,8 +29,6 @@ import butterknife.ButterKnife;
public class MainActivity extends Activity
implements NavigationView.OnNavigationItemSelectedListener, CallbackEvent.Listener<Void> {
public static final String SECTION = "section";
private final Handler mDrawerHandler = new Handler();
private SharedPreferences prefs;
private int mDrawerItem;
@@ -79,7 +77,7 @@ public class MainActivity extends Activity
toggle.syncState();
if (savedInstanceState == null)
navigate(getIntent().getStringExtra(SECTION));
navigate(getIntent().getStringExtra(MagiskManager.INTENT_SECTION));
navigationView.setNavigationItemSelectedListener(this);
getApplicationContext().reloadMainActivity.register(this);
@@ -95,13 +93,13 @@ public class MainActivity extends Activity
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
navigate(savedInstanceState.getInt(SECTION, R.id.status));
navigate(savedInstanceState.getInt(MagiskManager.INTENT_SECTION, R.id.status));
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt(SECTION, mDrawerItem);
outState.putInt(MagiskManager.INTENT_SECTION, mDrawerItem);
}
@Override
@@ -133,14 +131,16 @@ public class MainActivity extends Activity
private void checkHideSection() {
Menu menu = navigationView.getMenu();
if (Shell.rootAccess()) {
menu.findItem(R.id.magiskhide).setVisible(
getApplicationContext().magiskVersion >= 8 && prefs.getBoolean("magiskhide", false));
menu.findItem(R.id.modules).setVisible(getApplicationContext().magiskVersion >= 4);
menu.findItem(R.id.downloads).setVisible(getApplicationContext().magiskVersion >= 4);
menu.findItem(R.id.log).setVisible(true);
menu.findItem(R.id.superuser).setVisible(getApplicationContext().isSuClient);
}
menu.findItem(R.id.magiskhide).setVisible(
Shell.rootAccess() && getApplicationContext().magiskVersion >= 8
&& prefs.getBoolean("magiskhide", false));
menu.findItem(R.id.modules).setVisible(
Shell.rootAccess() && getApplicationContext().magiskVersion >= 4);
menu.findItem(R.id.downloads).setVisible(
Shell.rootAccess() && getApplicationContext().magiskVersion >= 4);
menu.findItem(R.id.log).setVisible(Shell.rootAccess());
menu.findItem(R.id.superuser).setVisible(
Shell.rootAccess() && getApplicationContext().isSuClient);
menu.findItem(R.id.install).setVisible(getApplicationContext().remoteMagiskVersion > 0);
}
@@ -181,6 +181,7 @@ public class MainActivity extends Activity
}
public void navigate(int itemId) {
int bak = mDrawerItem;
mDrawerItem = itemId;
navigationView.setCheckedItem(itemId);
switch (itemId) {
@@ -207,9 +208,11 @@ public class MainActivity extends Activity
break;
case R.id.settings:
startActivity(new Intent(this, SettingsActivity.class));
mDrawerItem = bak;
break;
case R.id.app_about:
startActivity(new Intent(this, AboutActivity.class));
mDrawerItem = bak;
break;
}
}

View File

@@ -133,10 +133,11 @@ public class ReposFragment extends Fragment implements CallbackEvent.Listener<Vo
for (Repo repo : getApplication().repoMap.values()) {
Module module = getApplication().moduleMap.get(repo.getId());
if (module != null) {
if (repo.getVersionCode() > module.getVersionCode())
if (repo.getVersionCode() > module.getVersionCode()) {
mUpdateRepos.add(repo);
else
} else {
mInstalledRepos.add(repo);
}
} else {
mOthersRepos.add(repo);
}

View File

@@ -112,10 +112,12 @@ public class SettingsActivity extends Activity {
prefScreen.removePreference(magiskCategory);
prefScreen.removePreference(suCategory);
} else {
if (!getApplication().isSuClient)
if (!getApplication().isSuClient) {
prefScreen.removePreference(suCategory);
if (getApplication().magiskVersion < 11)
}
if (getApplication().magiskVersion < 11) {
prefScreen.removePreference(magiskCategory);
}
if (getApplication().disabled) {
busybox.setEnabled(false);
magiskHide.setEnabled(false);
@@ -147,7 +149,6 @@ public class SettingsActivity extends Activity {
if (getApplication().isDarkTheme != enabled) {
getApplication().isDarkTheme = enabled;
getApplication().reloadMainActivity.trigger();
getActivity().finish();
getActivity().recreate();
}
break;
@@ -196,9 +197,12 @@ public class SettingsActivity extends Activity {
.setPositiveButton(R.string.understand, (dialog, which) -> new MagiskHide().enable())
.setCancelable(false)
.show();
} else new MagiskHide().enable();
} else
} else {
new MagiskHide().enable();
}
} else {
new MagiskHide().disable();
}
break;
case "hosts":
enabled = prefs.getBoolean("hosts", false);

View File

@@ -31,7 +31,7 @@ public class SplashActivity extends Activity{
magiskManager.init();
// Initialize the update check service, notify every 3 hours
if (!"install".equals(getIntent().getStringExtra(MainActivity.SECTION))) {
if (!"install".equals(getIntent().getStringExtra(MagiskManager.INTENT_SECTION))) {
ComponentName service = new ComponentName(magiskManager, UpdateCheckService.class);
JobInfo jobInfo = new JobInfo.Builder(UPDATE_SERVICE_ID, service)
.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
@@ -60,8 +60,11 @@ public class SplashActivity extends Activity{
@Override
protected void onPostExecute(Void v) {
super.onPostExecute(v);
Intent intent = getIntent().setClass(magiskManager, MainActivity.class)
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
String section = getIntent().getStringExtra(MagiskManager.INTENT_SECTION);
Intent intent = new Intent(magiskManager, MainActivity.class);
if (section != null) {
intent.putExtra(MagiskManager.INTENT_SECTION, section);
}
startActivity(intent);
finish();
}

View File

@@ -2,7 +2,6 @@ package com.topjohnwu.magisk;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.widget.SwipeRefreshLayout;
import android.view.LayoutInflater;
import android.view.View;
@@ -22,6 +21,7 @@ import com.topjohnwu.magisk.utils.Utils;
import butterknife.BindColor;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import butterknife.Unbinder;
public class StatusFragment extends Fragment implements CallbackEvent.Listener<Void> {
@@ -53,7 +53,22 @@ public class StatusFragment extends Fragment implements CallbackEvent.Listener<V
@BindColor(R.color.grey500) int colorNeutral;
@BindColor(R.color.blue500) int colorInfo;
@BindColor(android.R.color.transparent) int trans;
int defaultColor;
@OnClick(R.id.safetyNet_container)
public void safetyNet() {
safetyNetProgress.setVisibility(View.VISIBLE);
safetyNetContainer.setBackgroundColor(trans);
safetyNetIcon.setImageResource(0);
safetyNetStatusText.setText(R.string.checking_safetyNet_status);
Utils.checkSafetyNet(getApplication());
}
@OnClick(R.id.magisk_status_container)
public void gotoInstall() {
((MainActivity) getActivity()).navigate(R.id.install);
}
private int defaultColor;
@Nullable
@Override
@@ -83,37 +98,13 @@ public class StatusFragment extends Fragment implements CallbackEvent.Listener<V
new CheckUpdates(getActivity()).exec();
});
safetyNetContainer.setOnClickListener(view -> {
safetyNetProgress.setVisibility(View.VISIBLE);
safetyNetContainer.setBackgroundColor(trans);
safetyNetIcon.setImageResource(0);
safetyNetStatusText.setText(R.string.checking_safetyNet_status);
Utils.checkSafetyNet(getApplication());
});
magiskStatusContainer.setOnClickListener(view -> {
((MainActivity) getActivity()).navigationView.setCheckedItem(R.id.install);
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out);
try {
transaction.replace(R.id.content_frame, new InstallFragment(), "install").commit();
} catch (IllegalStateException ignored) {}
});
if (getApplication().magiskVersion < 0 && Shell.rootAccess() && !noDialog) {
noDialog = true;
new AlertDialogBuilder(getActivity())
.setTitle(R.string.no_magisk_title)
.setMessage(R.string.no_magisk_msg)
.setCancelable(true)
.setPositiveButton(R.string.goto_install, (dialogInterface, i) -> {
((MainActivity) getActivity()).navigationView.setCheckedItem(R.id.install);
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out);
try {
transaction.replace(R.id.content_frame, new InstallFragment(), "install").commit();
} catch (IllegalStateException ignored) {}
})
.setPositiveButton(R.string.goto_install, (d, i) -> gotoInstall())
.setNegativeButton(R.string.no_thanks, null)
.show();
}

View File

@@ -109,7 +109,9 @@ public class SuLogAdapter {
@Override
public void onBindGroupViewHolder(LogGroupViewHolder holder, int flatPosition, ExpandableGroup group) {
holder.date.setText(group.getTitle());
if (isGroupExpanded(flatPosition)) holder.expand();
if (isGroupExpanded(flatPosition)) {
holder.expand();
}
}
}

View File

@@ -7,7 +7,7 @@ import android.content.Intent;
import android.support.v4.app.TaskStackBuilder;
import android.support.v7.app.NotificationCompat;
import com.topjohnwu.magisk.MainActivity;
import com.topjohnwu.magisk.MagiskManager;
import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.SplashActivity;
import com.topjohnwu.magisk.utils.Utils;
@@ -48,7 +48,8 @@ public class CheckUpdates extends ParallelTask<Void, Void, Void> {
@Override
protected void onPostExecute(Void v) {
if (magiskManager.magiskVersion < magiskManager.remoteMagiskVersion && showNotification) {
if (magiskManager.magiskVersion < magiskManager.remoteMagiskVersion
&& showNotification && magiskManager.updateNotification) {
NotificationCompat.Builder builder = new NotificationCompat.Builder(magiskManager);
builder.setSmallIcon(R.drawable.ic_magisk)
.setContentTitle(magiskManager.getString(R.string.magisk_update_title))
@@ -56,7 +57,7 @@ public class CheckUpdates extends ParallelTask<Void, Void, Void> {
.setVibrate(new long[]{0, 100, 100, 100})
.setAutoCancel(true);
Intent intent = new Intent(magiskManager, SplashActivity.class);
intent.putExtra(MainActivity.SECTION, "install");
intent.putExtra(MagiskManager.INTENT_SECTION, "install");
TaskStackBuilder stackBuilder = TaskStackBuilder.create(magiskManager);
stackBuilder.addParentStack(SplashActivity.class);
stackBuilder.addNextIntent(intent);

View File

@@ -13,10 +13,9 @@ public class GetBootBlocks extends SerialTask<Void, Void, Void> {
@Override
protected Void doInBackground(Void... params) {
if (Shell.rootAccess()) {
magiskManager.blockList = Shell.su("ls /dev/block | grep mmc");
if (magiskManager.bootBlock == null)
magiskManager.bootBlock = Utils.detectBootImage();
magiskManager.blockList = Shell.su("ls /dev/block | grep mmc");
if (magiskManager.bootBlock == null) {
magiskManager.bootBlock = Utils.detectBootImage();
}
return null;
}

View File

@@ -22,8 +22,9 @@ public class LoadApps extends ParallelTask<Void, Void, Void> {
List<ApplicationInfo> list = pm.getInstalledApplications(0);
for (Iterator<ApplicationInfo> i = list.iterator(); i.hasNext(); ) {
ApplicationInfo info = i.next();
if (ApplicationAdapter.BLACKLIST.contains(info.packageName) || !info.enabled)
if (ApplicationAdapter.BLACKLIST.contains(info.packageName) || !info.enabled) {
i.remove();
}
}
Collections.sort(list, (a, b) -> a.loadLabel(pm).toString().toLowerCase()
.compareTo(b.loadLabel(pm).toString().toLowerCase()));

View File

@@ -96,8 +96,9 @@ public class LoadRepos extends ParallelTask<Void, Void, Void> {
Logger.dev("LoadRepos: Update cached repo " + id);
repo.update(updatedDate);
}
if (repo.getId() != null)
if (repo.getId() != null) {
magiskManager.repoMap.put(id, repo);
}
} catch (BaseModule.CacheModException ignored) {}
}

View File

@@ -21,15 +21,17 @@ public class MagiskHide extends SerialTask<Object, Void, Void> {
protected Void doInBackground(Object... params) {
String command = (String) params[0];
List<String> ret = Shell.su(MagiskManager.MAGISK_HIDE_PATH + command);
if (isList)
if (isList) {
magiskManager.magiskHideList = ret;
}
return null;
}
@Override
protected void onPostExecute(Void v) {
if (isList)
if (isList) {
magiskManager.magiskHideDone.trigger();
}
}
public void add(CharSequence packageName) {
@@ -50,8 +52,7 @@ public class MagiskHide extends SerialTask<Object, Void, Void> {
public void list() {
isList = true;
if (magiskManager == null)
return;
if (magiskManager == null) return;
exec("list");
}

View File

@@ -45,7 +45,8 @@ public class ProcessMagiskZip extends ParallelTask<Void, Void, Boolean> {
ZipUtils.unzip(magiskManager.getContentResolver().openInputStream(mUri), tempdir);
// Running in parallel mode, open new shell
Shell.su(true,
"echo \"BOOTIMAGE=/dev/block/" + mBoot + "\" > /dev/.magisk",
"rm -f /dev/.magisk",
(mBoot != null) ? "echo \"BOOTIMAGE=/dev/block/" + mBoot + "\" >> /dev/.magisk" : "",
"echo \"KEEPFORCEENCRYPT=" + String.valueOf(mEnc) + "\" >> /dev/.magisk",
"echo \"KEEPVERITY=" + String.valueOf(mVerity) + "\" >> /dev/.magisk",
"mkdir -p " + MagiskManager.TMP_FOLDER_PATH,
@@ -66,13 +67,14 @@ public class ProcessMagiskZip extends ParallelTask<Void, Void, Boolean> {
@Override
protected void onPostExecute(Boolean result) {
progressDialog.dismiss();
if (result)
if (result) {
new FlashZip(activity, mUri) {
@Override
protected boolean unzipAndCheck() throws Exception {
// Don't need to check, as it is downloaded in correct form
return true;
}
@Override
protected void onSuccess() {
new SerialTask<Void, Void, Void>(activity) {
@@ -87,7 +89,8 @@ public class ProcessMagiskZip extends ParallelTask<Void, Void, Boolean> {
super.onSuccess();
}
}.exec();
else
} else {
Utils.showUriSnack(activity, mUri);
}
}
}

View File

@@ -103,10 +103,11 @@ public class ProcessRepoZip extends ParallelTask<Void, Void, Boolean> {
protected void onPostExecute(Boolean result) {
progressDialog.dismiss();
if (result) {
if (Shell.rootAccess() && mInstall)
if (Shell.rootAccess() && mInstall) {
new FlashZip(activity, mUri).exec();
else
} else {
Utils.showUriSnack(activity, mUri);
}
} else {
Toast.makeText(activity, R.string.process_error, Toast.LENGTH_LONG).show();

View File

@@ -8,6 +8,6 @@ public class Activity extends AppCompatActivity {
@Override
public MagiskManager getApplicationContext() {
return (MagiskManager) getApplication();
return (MagiskManager) super.getApplicationContext();
}
}

View File

@@ -93,8 +93,9 @@ public class AlertDialogBuilder extends AlertDialog.Builder {
positive.setText(text);
positiveListener = listener;
positive.setOnClickListener((v) -> {
if (positiveListener != null)
if (positiveListener != null) {
positiveListener.onClick(dialog, DialogInterface.BUTTON_POSITIVE);
}
dialog.dismiss();
});
return this;
@@ -112,8 +113,9 @@ public class AlertDialogBuilder extends AlertDialog.Builder {
negative.setText(text);
negativeListener = listener;
negative.setOnClickListener((v) -> {
if (negativeListener != null)
if (negativeListener != null) {
negativeListener.onClick(dialog, DialogInterface.BUTTON_NEGATIVE);
}
dialog.dismiss();
});
return this;
@@ -131,8 +133,9 @@ public class AlertDialogBuilder extends AlertDialog.Builder {
neutral.setText(text);
neutralListener = listener;
neutral.setOnClickListener((v) -> {
if (neutralListener != null)
if (neutralListener != null) {
neutralListener.onClick(dialog, DialogInterface.BUTTON_NEUTRAL);
}
dialog.dismiss();
});
return this;

View File

@@ -3,7 +3,6 @@ package com.topjohnwu.magisk.components;
import android.app.Activity;
import android.support.annotation.StringRes;
import android.support.design.widget.Snackbar;
import android.text.TextUtils;
import android.view.View;
import android.widget.TextView;
@@ -34,8 +33,7 @@ public class SnackbarMaker {
private static void setup(Snackbar snack) {
TextView text = ButterKnife.findById(snack.getView(), android.support.design.R.id.snackbar_text);
text.setMaxLines(2);
text.setEllipsize(TextUtils.TruncateAt.START);
text.setMaxLines(Integer.MAX_VALUE);
}
}

View File

@@ -40,8 +40,9 @@ public class RepoDatabaseHelper extends SQLiteOpenHelper {
public void addRepoMap(ValueSortedMap<String, Repo> map) {
SQLiteDatabase db = getWritableDatabase();
Collection<Repo> list = map.values();
for (Repo repo : list)
for (Repo repo : list) {
db.replace(TABLE_NAME, null, repo.getContentValues());
}
db.close();
}
@@ -54,8 +55,9 @@ public class RepoDatabaseHelper extends SQLiteOpenHelper {
public void removeRepo(ValueSortedMap<String, Repo> map) {
SQLiteDatabase db = getWritableDatabase();
Collection<Repo> list = map.values();
for (Repo repo : list)
for (Repo repo : list) {
db.delete(TABLE_NAME, "id=?", new String[] { repo.getId() });
}
db.close();
}

View File

@@ -22,15 +22,18 @@ public class SuDatabaseHelper extends SQLiteOpenHelper {
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(
"CREATE TABLE IF NOT EXISTS " + TABLE_NAME + " " +
"(uid INT, package_name TEXT, app_name TEXT, policy INT, " +
"until INT, logging INT, notification INT, " +
"PRIMARY KEY(uid))");
onUpgrade(db, 0, DATABASE_VER);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
if (oldVersion == 0) {
db.execSQL(
"CREATE TABLE IF NOT EXISTS " + TABLE_NAME + " " +
"(uid INT, package_name TEXT, app_name TEXT, policy INT, " +
"until INT, logging INT, notification INT, " +
"PRIMARY KEY(uid))");
}
// Currently new database, no upgrading
}
@@ -45,8 +48,9 @@ public class SuDatabaseHelper extends SQLiteOpenHelper {
Policy policy = null;
SQLiteDatabase db = getReadableDatabase();
try (Cursor c = db.query(TABLE_NAME, null, "uid=?", new String[] { String.valueOf(uid) }, null, null, null)) {
if (c.moveToNext())
if (c.moveToNext()) {
policy = new Policy(c);
}
}
db.close();
return policy;

View File

@@ -25,14 +25,17 @@ public class SuLogDatabaseHelper extends SQLiteOpenHelper {
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(
"CREATE TABLE IF NOT EXISTS " + TABLE_NAME + " (id INTEGER PRIMARY KEY AUTOINCREMENT, " +
"from_uid INT, package_name TEXT, app_name TEXT, from_pid INT, " +
"to_uid INT, action INT, time INT, command TEXT)");
onUpgrade(db, 0, DATABASE_VER);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
if (oldVersion == 0) {
db.execSQL(
"CREATE TABLE IF NOT EXISTS " + TABLE_NAME + " (id INTEGER PRIMARY KEY AUTOINCREMENT, " +
"from_uid INT, package_name TEXT, app_name TEXT, from_pid INT, " +
"to_uid INT, action INT, time INT, command TEXT)");
}
// Currently new database, no upgrading
}
@@ -63,8 +66,9 @@ public class SuLogDatabaseHelper extends SQLiteOpenHelper {
db.delete(TABLE_NAME, "time < ?", new String[] { String.valueOf(
System.currentTimeMillis() / 1000 - magiskManager.suLogTimeout * 86400) });
try (Cursor c = db.query(TABLE_NAME, null, selection, null, null, null, "time DESC")) {
while (c.moveToNext())
while (c.moveToNext()) {
ret.add(new SuLogEntry(c));
}
}
db.close();
return ret;

View File

@@ -21,8 +21,9 @@ public class Module extends BaseModule {
setId(path.substring(sep + 1));
}
if (getName() == null)
if (getName() == null) {
setName(getId());
}
Logger.dev("Creating Module, id: " + getId());

View File

@@ -60,10 +60,6 @@ public class Repo extends BaseModule {
return String.format(ZIP_URL, repoName);
}
public String getLogUrl() {
return String.format(FILE_URL, repoName, "changelog.txt");
}
public String getManifestUrl() {
return String.format(FILE_URL, repoName, "module.prop");
}

View File

@@ -12,6 +12,7 @@ public class UpdateCheckService extends JobService {
@Override
protected Void doInBackground(Void... voids) {
magiskManager.updateMagiskInfo();
magiskManager.updateNotification = magiskManager.prefs.getBoolean("notification", true);
return super.doInBackground(voids);
}

View File

@@ -38,10 +38,12 @@ public class SuReceiver extends BroadcastReceiver {
SuDatabaseHelper suDbHelper = new SuDatabaseHelper(context);
policy = suDbHelper.getPolicy(fromUid);
if (policy == null) try {
policy = new Policy(fromUid, context.getPackageManager());
} catch (Throwable throwable) {
return;
if (policy == null) {
try {
policy = new Policy(fromUid, context.getPackageManager());
} catch (Throwable throwable) {
return;
}
}
magiskManager.initSuConfigs();

View File

@@ -76,8 +76,9 @@ public class SuRequestActivity extends Activity implements CallbackEvent.Listene
@Override
public void onEvent(int fileEvent, String path) {
if (fileEvent == FileObserver.DELETE_SELF) {
if (event != null)
if (event != null) {
event.trigger();
}
finish();
}
}
@@ -147,8 +148,9 @@ public class SuRequestActivity extends Activity implements CallbackEvent.Listene
public void onTrigger(CallbackEvent<Policy> event) {
Policy policy = event.getResult();
String response = "socket:DENY";
if (policy != null &&policy.policy == Policy.ALLOW )
if (policy != null &&policy.policy == Policy.ALLOW ) {
response = "socket:ALLOW";
}
try {
socket.getOutputStream().write((response).getBytes());
} catch (Exception ignored) {}
@@ -176,7 +178,7 @@ public class SuRequestActivity extends Activity implements CallbackEvent.Listene
@Override
protected Boolean doInBackground(Void... params) {
try{
try {
socket = new LocalSocket();
socket.connect(new LocalSocketAddress(socketPath, LocalSocketAddress.Namespace.FILESYSTEM));

View File

@@ -10,8 +10,9 @@ public class CallbackEvent<Result> {
private Set<Listener<Result>> listeners;
public void register(Listener<Result> l) {
if (listeners == null)
if (listeners == null) {
listeners = new HashSet<>();
}
listeners.add(l);
}
@@ -20,8 +21,9 @@ public class CallbackEvent<Result> {
}
public void unRegister(Listener<Result> l) {
if (listeners != null)
if (listeners != null) {
listeners.remove(l);
}
}
public void trigger() {
@@ -32,8 +34,9 @@ public class CallbackEvent<Result> {
result = r;
isTriggered = true;
if (listeners != null) {
for (Listener<Result> listener : listeners)
for (Listener<Result> listener : listeners) {
listener.onTrigger(this);
}
}
}

View File

@@ -120,11 +120,13 @@ public class Shell {
StreamGobbler STDOUT;
// Create the default shell if not init
if (!newShell && !isInit)
if (!newShell && !isInit) {
init();
}
if (!newShell && !rootAccess())
if (!newShell && !rootAccess()) {
return null;
}
if (newShell) {
res = Collections.synchronizedList(new ArrayList<String>());

View File

@@ -114,8 +114,9 @@ public class Utils {
"echo \"${BOOTIMAGE##*/}\""
};
List<String> ret = Shell.su(commands);
if (isValidShellResponse(ret))
if (isValidShellResponse(ret)) {
return ret.get(0);
}
return null;
}

View File

@@ -77,10 +77,11 @@ public class WebService {
StringBuilder result = new StringBuilder();
boolean first = true;
for (Map.Entry<String, String> entry : params.entrySet()) {
if (first)
if (first) {
first = false;
else
} else {
result.append("&");
}
result.append(URLEncoder.encode(entry.getKey(), "UTF-8"));
result.append("=");

View File

@@ -112,14 +112,17 @@ public class ZipUtils {
// Remove the top directory from the path
path = entry.getName().substring(entry.getName().indexOf("/") + 1);
// If it's the top folder, ignore it
if (path.isEmpty())
if (path.isEmpty()) {
continue;
}
// Don't include placeholder
if (path.contains("system/placeholder"))
if (path.contains("system/placeholder")) {
continue;
}
dest.putNextEntry(new JarEntry(path));
while((size = source.read(buffer, 0, 2048)) != -1)
while((size = source.read(buffer, 0, 2048)) != -1) {
dest.write(buffer, 0, size);
}
}
source.close();
dest.close();
@@ -149,17 +152,20 @@ public class ZipUtils {
Enumeration<JarEntry> e = zipfile.entries();
while(e.hasMoreElements()) {
entry = e.nextElement();
if (!entry.getName().contains(path) || entry.isDirectory())
if (!entry.getName().contains(path) || entry.isDirectory()){
// Ignore directories, only create files
continue;
}
Logger.dev("ZipUtils: Extracting: " + entry);
is = zipfile.getInputStream(entry);
dest = new File(folder, entry.getName());
if (dest.getParentFile().mkdirs())
if (dest.getParentFile().mkdirs()) {
dest.createNewFile();
}
out = new FileOutputStream(dest);
while ((count = is.read(data, 0, 4096)) != -1)
while ((count = is.read(data, 0, 4096)) != -1) {
out.write(data, 0, count);
}
out.flush();
out.close();
is.close();
@@ -178,16 +184,19 @@ public class ZipUtils {
byte data[] = new byte[4096];
try (JarInputStream zipfile = new JarInputStream(file)) {
while((entry = zipfile.getNextJarEntry()) != null) {
if (!entry.getName().contains(path) || entry.isDirectory())
if (!entry.getName().contains(path) || entry.isDirectory()) {
// Ignore directories, only create files
continue;
}
Logger.dev("ZipUtils: Extracting: " + entry);
dest = new File(folder, entry.getName());
if (dest.getParentFile().mkdirs())
if (dest.getParentFile().mkdirs()) {
dest.createNewFile();
}
out = new FileOutputStream(dest);
while ((count = zipfile.read(data, 0, 4096)) != -1)
while ((count = zipfile.read(data, 0, 4096)) != -1) {
out.write(data, 0, count);
}
out.flush();
out.close();
}

View File

@@ -159,7 +159,7 @@
</android.support.v7.widget.CardView>
<android.support.v7.widget.CardView
android:id="@+id/flash_button"
android:id="@+id/install_button"
android:layout_gravity="center"
android:layout_height="wrap_content"
android:layout_marginBottom="4dp"
@@ -192,7 +192,7 @@
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="@string/download_install"
android:id="@+id/install_text"
android:ems="10"
android:gravity="center"
android:layout_weight="1"

View File

@@ -3,11 +3,10 @@
<!--Welcome Activity-->
<string name="navigation_drawer_open">Navigationsmenü öffnen</string>
<string name="navigation_drawer_close">Navigationsmenü schließen</string>
<string name="modules">Module</string>
<string name="downloads">Download</string>
<string name="superuser">Superuser</string>
@@ -31,8 +30,7 @@
<string name="safetyNet_check_text">SafetyNet-Status abfragen</string>
<string name="checking_safetyNet_status">Prüfe SafetyNet-Status…</string>
<string name="safetyNet_connection_failed">Verbindung zur Google-API fehlgeschlagen</string>
<string name="safetyNet_connection_suspended">Verbindung zur Google-API wurde ausgesetzt</string>
<string name="safetyNet_connection_suspended">Verbindung zur Google-API wurde ausgesetzt</string>
<string name="safetyNet_error">SafetyNet-Status konnte nicht geprüft werden. Ist eine Internetverbindung verfügbar?</string>
<string name="safetyNet_fail">SafetyNet nicht bestanden: \"CTS profile mismatch\"</string>
<string name="safetyNet_pass">SafetyNet bestanden</string>
@@ -47,11 +45,11 @@
<string name="keep_dm_verity">\"dm-verity\"-Test beibehalten</string>
<string name="current_magisk_title">Installierte Magisk-Version: %1$s</string>
<string name="install_magisk_title">Neueste Magisk-Version: %1$s</string>
<string name="uninstall">Deinstallieren</string>
<string name="reboot_countdown">Neustart in %1$d</string>
<string name="uninstall_magisk_title">Magisk deinstallieren</string>
<string name="uninstall_magisk_msg">Dies entfernt alle Module, MagiskSU und verschlüsselt unter Umständen deine Daten, falls nicht bereits verschlüsselt.\nMöchtest du wirklich fortfahren?</string>
<string name="version_none">(keine)</string>
<!--Module Fragment-->
<string name="no_info_provided">(Nichts angegeben)</string>
@@ -99,6 +97,7 @@
<string name="repo_install_msg">Möchtest du %1$s installieren?</string>
<string name="download_install">Herunterladen &amp; installieren</string>
<string name="download">Herunterladen</string>
<string name="goto_install">Zu \"Installieren\" wechseln</string>
<string name="download_file_error">Fehler beim Herunterladen der Datei</string>
<string name="install_error">Fehler bei der Installation!</string>
<string name="invalid_zip">Die Zip-Datei ist kein Magisk-Modul!</string>
@@ -119,11 +118,6 @@
<string name="repo_cache_cleared">Repo-Cache gelöscht</string>
<string name="safetyNet_hide_notice">Diese App benutzt SafetyNet, welches standardmäßig von Magisk Hide gehandhabt</string>
<string name="start_magiskhide">Starte Magisk Hide…</string>
<string name="no_magisksu_title">Du benutzt nicht MagiskSU!</string>
<string name="no_magisksu_msg">Deine root-Lösung wird nicht offiziell unterstützt und Magisk Hide allein ist eventuell nicht ausreichend!\nEventuell benötigst du weitere Programme (z.B. \"suhide\"), um SafetyNet zu bestehen.</string>
<string name="understand">Ich verstehe</string>

View File

@@ -35,7 +35,7 @@
<!--Install Fragment-->
<string name="auto_detect">(自動) %1$s</string>
<string name="boot_image_title">Boot 像位置</string>
<string name="boot_image_title">Boot 像位置</string>
<string name="detect_button">偵測</string>
<string name="advanced_settings_title">高級設置</string>
<string name="keep_force_encryption">保持強制加密</string>
@@ -181,13 +181,17 @@
<string name="target_uid">目標 UID:\u0020</string>
<string name="command">"指令: "</string>
<string name="close">關閉</string>
<string name="internal_storage">Zip 已被儲存到:[內部儲存空間]%1$s</string>
<string name="internal_storage">Zip 已被儲存到:\n[內部儲存空間]%1$s</string>
<string name="ok"></string>
<string name="process_error">處裡失敗</string>
<string name="download">下載</string>
<string name="zip_process_title">處理中</string>
<string name="uninstall_magisk_title">解除安裝 Magisk</string>
<string name="uninstall_magisk_msg">這將會刪除所有模組MagiskSU並有可能在目前未加密的情況下加密的的資料\n你確定要繼續嗎</string>
<string name="uninstall_magisk_msg">這將會刪除所有模組MagiskSU並有可能在目前資料未加密的情況下進行加密\n你確定要繼續嗎</string>
<string name="version_none">(無)</string>
<string name="manual_boot_image">請手動選取 boot 映像位置</string>
<string name="cannot_auto_detect">(無法自動偵測)</string>
<string name="settings_notification_summary">有更新的時候顯示通知</string>
<string name="settings_notification_title">更新通知</string>
</resources>

View File

@@ -13,9 +13,6 @@
<color name="blue500">#2196F3</color>
<color name="yellow500">#FFC107</color>
<color name="dark_primary">#1a237e</color>
<color name="dark_primary_dark">#000000</color>
<color name="dark_secondary_text">#dedede</color>
<color name="su_request_background">#e0e0e0</color>

View File

@@ -38,6 +38,7 @@
<!--Install Fragment-->
<string name="auto_detect">(Auto) %1$s</string>
<string name="cannot_auto_detect">(Cannot auto detect)</string>
<string name="boot_image_title">Boot Image Location</string>
<string name="detect_button">Detect</string>
<string name="advanced_settings_title">Advanced Settings</string>
@@ -124,11 +125,14 @@
<string name="process_error">Process error</string>
<string name="internal_storage">The zip is stored in:\n[Internal Storage]%1$s</string>
<string name="zip_process_title">Processing</string>
<string name="manual_boot_image">Please manually select a boot image!</string>
<!--Settings Activity -->
<string name="settings_general_category">General</string>
<string name="settings_dark_theme_title">Dark Theme</string>
<string name="settings_dark_theme_summary">Enable dark theme</string>
<string name="settings_notification_title">Update Notification</string>
<string name="settings_notification_summary">Show update notifications when new version is available</string>
<string name="settings_clear_cache_title">Clear Repo Cache</string>
<string name="settings_clear_cache_summary">Clear the cached information for online repos, forces the app to refresh online</string>

View File

@@ -15,8 +15,6 @@
</style>
<style name="AppTheme.Dark" parent="Theme.AppCompat.NoActionBar">
<item name="colorPrimary">@color/dark_primary</item>
<item name="colorPrimaryDark">@color/dark_primary_dark</item>
<item name="colorAccent">@color/accent</item>
<item name="colorAccentFallback">@color/accentFallback</item>
<item name="windowActionModeOverlay">true</item>

View File

@@ -10,6 +10,11 @@
android:summary="@string/settings_dark_theme_summary"
android:key="dark_theme" />
<CheckBoxPreference
android:title="@string/settings_notification_title"
android:summary="@string/settings_notification_summary"
android:key="notification" />
<Preference
android:key="clear"
android:title="@string/settings_clear_cache_title"