mirror of
https://github.com/topjohnwu/Magisk.git
synced 2024-11-28 04:25:27 +00:00
Add saving logs feature for installation
This commit is contained in:
parent
49c672ac4d
commit
3a74729ecc
@ -11,6 +11,7 @@ import android.widget.Button;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ScrollView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.topjohnwu.magisk.asyncs.FlashZip;
|
||||
import com.topjohnwu.magisk.asyncs.InstallMagisk;
|
||||
@ -19,6 +20,14 @@ import com.topjohnwu.magisk.container.CallbackList;
|
||||
import com.topjohnwu.magisk.utils.Const;
|
||||
import com.topjohnwu.magisk.utils.Shell;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnClick;
|
||||
@ -27,32 +36,50 @@ public class FlashActivity extends Activity {
|
||||
|
||||
@BindView(R.id.toolbar) Toolbar toolbar;
|
||||
@BindView(R.id.txtLog) TextView flashLogs;
|
||||
@BindView(R.id.button_panel) LinearLayout buttonPanel;
|
||||
@BindView(R.id.reboot) Button reboot;
|
||||
@BindView(R.id.button_panel) public LinearLayout buttonPanel;
|
||||
@BindView(R.id.reboot) public Button reboot;
|
||||
@BindView(R.id.scrollView) ScrollView sv;
|
||||
|
||||
private List<String> logs;
|
||||
|
||||
@OnClick(R.id.no_thanks)
|
||||
public void dismiss() {
|
||||
void dismiss() {
|
||||
finish();
|
||||
}
|
||||
|
||||
@OnClick(R.id.reboot)
|
||||
public void reboot() {
|
||||
void reboot() {
|
||||
Shell.su_raw("reboot");
|
||||
}
|
||||
|
||||
@OnClick(R.id.save_logs)
|
||||
void saveLogs() {
|
||||
Calendar now = Calendar.getInstance();
|
||||
String filename = String.format(Locale.US,
|
||||
"install_log_%04d%02d%02d_%02d:%02d:%02d.log",
|
||||
now.get(Calendar.YEAR), now.get(Calendar.MONTH) + 1,
|
||||
now.get(Calendar.DAY_OF_MONTH), now.get(Calendar.HOUR_OF_DAY),
|
||||
now.get(Calendar.MINUTE), now.get(Calendar.SECOND));
|
||||
|
||||
File logFile = new File(Const.EXTERNAL_PATH + "/logs", filename);
|
||||
logFile.getParentFile().mkdirs();
|
||||
try (FileWriter writer = new FileWriter(logFile)) {
|
||||
for (String s : logs) {
|
||||
writer.write(s);
|
||||
writer.write('\n');
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return;
|
||||
}
|
||||
MagiskManager.toast(logFile.getPath(), Toast.LENGTH_LONG);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_flash);
|
||||
ButterKnife.bind(this);
|
||||
CallbackList<String> rootShellOutput = new CallbackList<String>() {
|
||||
@Override
|
||||
public synchronized void onAddElement() {
|
||||
flashLogs.setText(TextUtils.join("\n", this));
|
||||
sv.postDelayed(() -> sv.fullScroll(ScrollView.FOCUS_DOWN), 10);
|
||||
}
|
||||
};
|
||||
setSupportActionBar(toolbar);
|
||||
ActionBar ab = getSupportActionBar();
|
||||
if (ab != null) {
|
||||
@ -63,6 +90,16 @@ public class FlashActivity extends Activity {
|
||||
if (!Shell.rootAccess())
|
||||
reboot.setVisibility(View.GONE);
|
||||
|
||||
logs = new ArrayList<>();
|
||||
List<String> console = new CallbackList<String>() {
|
||||
@Override
|
||||
public synchronized void onAddElement(String e) {
|
||||
logs.add(e);
|
||||
flashLogs.setText(TextUtils.join("\n", this));
|
||||
sv.postDelayed(() -> sv.fullScroll(ScrollView.FOCUS_DOWN), 10);
|
||||
}
|
||||
};
|
||||
|
||||
// We must receive a Uri of the target zip
|
||||
Intent intent = getIntent();
|
||||
Uri uri = intent.getData();
|
||||
@ -70,35 +107,17 @@ public class FlashActivity extends Activity {
|
||||
boolean keepEnc = intent.getBooleanExtra(Const.Key.FLASH_SET_ENC, false);
|
||||
boolean keepVerity = intent.getBooleanExtra(Const.Key.FLASH_SET_VERITY, false);
|
||||
|
||||
switch (getIntent().getStringExtra(Const.Key.FLASH_ACTION)) {
|
||||
switch (intent.getStringExtra(Const.Key.FLASH_ACTION)) {
|
||||
case Const.Value.FLASH_ZIP:
|
||||
new FlashZip(this, uri, rootShellOutput)
|
||||
.setCallBack(() -> buttonPanel.setVisibility(View.VISIBLE))
|
||||
.exec();
|
||||
new FlashZip(this, uri, console, logs).exec();
|
||||
break;
|
||||
case Const.Value.PATCH_BOOT:
|
||||
new InstallMagisk(this, rootShellOutput, uri, keepEnc, keepVerity, (Uri) intent.getParcelableExtra(Const.Key.FLASH_SET_BOOT))
|
||||
.setCallBack(() -> buttonPanel.setVisibility(View.VISIBLE))
|
||||
new InstallMagisk(this, console, logs, uri, keepEnc, keepVerity, (Uri) intent.getParcelableExtra(Const.Key.FLASH_SET_BOOT))
|
||||
.exec();
|
||||
break;
|
||||
case Const.Value.FLASH_MAGISK:
|
||||
String boot = intent.getStringExtra(Const.Key.FLASH_SET_BOOT);
|
||||
if (getMagiskManager().remoteMagiskVersionCode < 1370) {
|
||||
// Use legacy installation method
|
||||
Shell.su_raw(
|
||||
"echo \"BOOTIMAGE=" + boot + "\" > /dev/.magisk",
|
||||
"echo \"KEEPFORCEENCRYPT=" + keepEnc + "\" >> /dev/.magisk",
|
||||
"echo \"KEEPVERITY=" + keepVerity + "\" >> /dev/.magisk"
|
||||
);
|
||||
new FlashZip(this, uri, rootShellOutput)
|
||||
.setCallBack(() -> buttonPanel.setVisibility(View.VISIBLE))
|
||||
new InstallMagisk(this, console, logs, uri, keepEnc, keepVerity, intent.getStringExtra(Const.Key.FLASH_SET_BOOT))
|
||||
.exec();
|
||||
} else {
|
||||
// Use new installation method
|
||||
new InstallMagisk(this, rootShellOutput, uri, keepEnc, keepVerity, boot)
|
||||
.setCallBack(() -> buttonPanel.setVisibility(View.VISIBLE))
|
||||
.exec();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
package com.topjohnwu.magisk;
|
||||
|
||||
import android.Manifest;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.design.widget.Snackbar;
|
||||
|
@ -3,9 +3,10 @@ package com.topjohnwu.magisk.asyncs;
|
||||
import android.app.Activity;
|
||||
import android.net.Uri;
|
||||
import android.text.TextUtils;
|
||||
import android.view.View;
|
||||
|
||||
import com.topjohnwu.magisk.FlashActivity;
|
||||
import com.topjohnwu.magisk.MagiskManager;
|
||||
import com.topjohnwu.magisk.R;
|
||||
import com.topjohnwu.magisk.utils.Const;
|
||||
import com.topjohnwu.magisk.utils.Shell;
|
||||
import com.topjohnwu.magisk.utils.Utils;
|
||||
@ -25,12 +26,13 @@ public class FlashZip extends ParallelTask<Void, Void, Integer> {
|
||||
|
||||
private Uri mUri;
|
||||
private File mCachedFile;
|
||||
private List<String> mList;
|
||||
private List<String> console, logs;
|
||||
|
||||
public FlashZip(Activity context, Uri uri, List<String> list) {
|
||||
public FlashZip(Activity context, Uri uri, List<String> console, List<String> logs) {
|
||||
super(context);
|
||||
mUri = uri;
|
||||
mList = list;
|
||||
this.console = console;
|
||||
this.logs = logs;
|
||||
mCachedFile = new File(context.getCacheDir(), "install.zip");
|
||||
}
|
||||
|
||||
@ -44,7 +46,7 @@ public class FlashZip extends ParallelTask<Void, Void, Integer> {
|
||||
protected Integer doInBackground(Void... voids) {
|
||||
MagiskManager mm = MagiskManager.get();
|
||||
try {
|
||||
mList.add("- Copying zip to temp directory");
|
||||
console.add("- Copying zip to temp directory");
|
||||
|
||||
mCachedFile.delete();
|
||||
try (
|
||||
@ -55,48 +57,52 @@ public class FlashZip extends ParallelTask<Void, Void, Integer> {
|
||||
InputStream buf= new BufferedInputStream(in);
|
||||
Utils.inToOut(buf, out);
|
||||
} catch (FileNotFoundException e) {
|
||||
mList.add("! Invalid Uri");
|
||||
console.add("! Invalid Uri");
|
||||
throw e;
|
||||
} catch (IOException e) {
|
||||
mList.add("! Cannot copy to cache");
|
||||
console.add("! Cannot copy to cache");
|
||||
throw e;
|
||||
}
|
||||
if (!unzipAndCheck()) return 0;
|
||||
mList.add("- Installing " + Utils.getNameFromUri(mm, mUri));
|
||||
Shell.su(mList,
|
||||
console.add("- Installing " + Utils.getNameFromUri(mm, mUri));
|
||||
Shell.getShell().run(console, logs,
|
||||
"cd " + mCachedFile.getParent(),
|
||||
"BOOTMODE=true sh update-binary dummy 1 " + mCachedFile +
|
||||
" && echo 'Success!' || echo 'Failed!'"
|
||||
"BOOTMODE=true sh update-binary dummy 1 " + mCachedFile + " || echo 'Failed!'"
|
||||
);
|
||||
if (TextUtils.equals(mList.get(mList.size() - 1), "Success!"))
|
||||
return 1;
|
||||
|
||||
if (TextUtils.equals(console.get(console.size() - 1), "Failed!"))
|
||||
return -1;
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
console.add("- All done!");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// -1 = error, manual install; 0 = invalid zip; 1 = success
|
||||
@Override
|
||||
protected void onPostExecute(Integer result) {
|
||||
MagiskManager mm = MagiskManager.get();
|
||||
FlashActivity activity = (FlashActivity) getActivity();
|
||||
Shell.su_raw(
|
||||
"rm -rf " + mCachedFile.getParent(),
|
||||
"rm -rf " + Const.TMP_FOLDER_PATH
|
||||
);
|
||||
switch (result) {
|
||||
case -1:
|
||||
mList.add(mm.getString(R.string.install_error));
|
||||
console.add("! Installation failed");
|
||||
Utils.showUriSnack(getActivity(), mUri);
|
||||
break;
|
||||
case 0:
|
||||
mList.add(mm.getString(R.string.invalid_zip));
|
||||
console.add("! This zip is not a Magisk Module!");
|
||||
break;
|
||||
case 1:
|
||||
// Success
|
||||
new LoadModules().exec();
|
||||
break;
|
||||
}
|
||||
super.onPostExecute(result);
|
||||
activity.reboot.setVisibility(result > 0 ? View.VISIBLE : View.GONE);
|
||||
activity.buttonPanel.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
|
@ -5,8 +5,10 @@ import android.content.res.AssetManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.text.TextUtils;
|
||||
import android.view.View;
|
||||
|
||||
import com.topjohnwu.crypto.SignBoot;
|
||||
import com.topjohnwu.magisk.FlashActivity;
|
||||
import com.topjohnwu.magisk.MagiskManager;
|
||||
import com.topjohnwu.magisk.container.TarEntry;
|
||||
import com.topjohnwu.magisk.utils.Const;
|
||||
@ -35,27 +37,28 @@ public class InstallMagisk extends ParallelTask<Void, Void, Boolean> {
|
||||
private static final int DIRECT_MODE = 1;
|
||||
|
||||
private Uri mBootImg, mZip;
|
||||
private List<String> mList;
|
||||
private List<String> console, logs;
|
||||
private String mBootLocation;
|
||||
private boolean mKeepEnc, mKeepVerity;
|
||||
private int mode;
|
||||
|
||||
private InstallMagisk(Activity context, List<String> list, Uri zip, boolean enc, boolean verity) {
|
||||
private InstallMagisk(Activity context, List<String> console, List<String> logs, Uri zip, boolean enc, boolean verity) {
|
||||
super(context);
|
||||
mList = list;
|
||||
this.console = console;
|
||||
this.logs = logs;
|
||||
mZip = zip;
|
||||
mKeepEnc = enc;
|
||||
mKeepVerity = verity;
|
||||
}
|
||||
|
||||
public InstallMagisk(Activity context, List<String> list, Uri zip, boolean enc, boolean verity, Uri boot) {
|
||||
this(context, list, zip, enc, verity);
|
||||
public InstallMagisk(Activity context, List<String> console, List<String> logs, Uri zip, boolean enc, boolean verity, Uri boot) {
|
||||
this(context, console, logs, zip, enc, verity);
|
||||
mBootImg = boot;
|
||||
mode = PATCH_MODE;
|
||||
}
|
||||
|
||||
public InstallMagisk(Activity context, List<String> list, Uri zip, boolean enc, boolean verity, String boot) {
|
||||
this(context, list, zip, enc, verity);
|
||||
public InstallMagisk(Activity context, List<String> console, List<String> logs, Uri zip, boolean enc, boolean verity, String boot) {
|
||||
this(context, console, logs, zip, enc, verity);
|
||||
mBootLocation = boot;
|
||||
mode = DIRECT_MODE;
|
||||
}
|
||||
@ -77,11 +80,11 @@ public class InstallMagisk extends ParallelTask<Void, Void, Boolean> {
|
||||
else if (abis.contains("arm64-v8a")) arch = "arm64";
|
||||
else if (abis.contains("x86")) arch = "x86";
|
||||
else arch = "arm";
|
||||
mList.add("- Device platform: " + arch);
|
||||
console.add("- Device platform: " + arch);
|
||||
|
||||
try {
|
||||
// Unzip files
|
||||
mList.add("- Extracting files");
|
||||
console.add("- Extracting files");
|
||||
try (InputStream in = mm.getContentResolver().openInputStream(mZip)) {
|
||||
if (in == null) throw new FileNotFoundException();
|
||||
BufferedInputStream buf = new BufferedInputStream(in);
|
||||
@ -95,17 +98,17 @@ public class InstallMagisk extends ParallelTask<Void, Void, Boolean> {
|
||||
ZipUtils.unzip(buf, install, "META-INF/com/google/android/update-binary", true);
|
||||
buf.close();
|
||||
} catch (FileNotFoundException e) {
|
||||
mList.add("! Invalid Uri");
|
||||
console.add("! Invalid Uri");
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
mList.add("! Cannot unzip zip");
|
||||
console.add("! Cannot unzip zip");
|
||||
throw e;
|
||||
}
|
||||
|
||||
File boot = new File(install, "boot.img");
|
||||
switch (mode) {
|
||||
case PATCH_MODE:
|
||||
mList.add("- Use boot image: " + boot);
|
||||
console.add("- Use boot image: " + boot);
|
||||
// Copy boot image to local
|
||||
try (
|
||||
InputStream in = mm.getContentResolver().openInputStream(mBootImg);
|
||||
@ -129,19 +132,19 @@ public class InstallMagisk extends ParallelTask<Void, Void, Boolean> {
|
||||
}
|
||||
Utils.inToOut(source, out);
|
||||
} catch (FileNotFoundException e) {
|
||||
mList.add("! Invalid Uri");
|
||||
console.add("! Invalid Uri");
|
||||
throw e;
|
||||
} catch (IOException e) {
|
||||
mList.add("! Copy failed");
|
||||
console.add("! Copy failed");
|
||||
throw e;
|
||||
}
|
||||
break;
|
||||
case DIRECT_MODE:
|
||||
mList.add("- Use boot image: " + mBootLocation);
|
||||
console.add("- Use boot image: " + mBootLocation);
|
||||
if (boot.createNewFile()) {
|
||||
Shell.su("cat " + mBootLocation + " > " + boot);
|
||||
} else {
|
||||
mList.add("! Dump boot image failed");
|
||||
console.add("! Dump boot image failed");
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
@ -153,10 +156,10 @@ public class InstallMagisk extends ParallelTask<Void, Void, Boolean> {
|
||||
try (InputStream in = new FileInputStream(boot)) {
|
||||
isSigned = SignBoot.verifySignature(in, null);
|
||||
if (isSigned) {
|
||||
mList.add("- Signed boot image detected");
|
||||
console.add("- Signed boot image detected");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
mList.add("! Unable to check signature");
|
||||
console.add("! Unable to check signature");
|
||||
throw e;
|
||||
}
|
||||
|
||||
@ -168,12 +171,12 @@ public class InstallMagisk extends ParallelTask<Void, Void, Boolean> {
|
||||
shell = Shell.getShell();
|
||||
|
||||
// Patch boot image
|
||||
shell.run(mList, null,
|
||||
shell.run(console, logs,
|
||||
"cd " + install,
|
||||
"KEEPFORCEENCRYPT=" + mKeepEnc + " KEEPVERITY=" + mKeepVerity + " sh " +
|
||||
"update-binary indep boot_patch.sh " + boot + " || echo 'Failed!'");
|
||||
|
||||
if (TextUtils.equals(mList.get(mList.size() - 1), "Failed!"))
|
||||
if (TextUtils.equals(console.get(console.size() - 1), "Failed!"))
|
||||
return false;
|
||||
|
||||
shell.run(null, null,
|
||||
@ -185,7 +188,7 @@ public class InstallMagisk extends ParallelTask<Void, Void, Boolean> {
|
||||
File patched_boot = new File(install.getParent(), "new-boot.img");
|
||||
|
||||
if (isSigned) {
|
||||
mList.add("- Signing boot image");
|
||||
console.add("- Signing boot image");
|
||||
File signed = new File(install.getParent(), "signed.img");
|
||||
AssetManager assets = mm.getAssets();
|
||||
try (
|
||||
@ -217,15 +220,15 @@ public class InstallMagisk extends ParallelTask<Void, Void, Boolean> {
|
||||
}
|
||||
break;
|
||||
}
|
||||
mList.add("");
|
||||
mList.add("*********************************");
|
||||
mList.add(" Patched Boot Image is placed in ");
|
||||
mList.add(" " + dest + " ");
|
||||
mList.add("*********************************");
|
||||
console.add("");
|
||||
console.add("*********************************");
|
||||
console.add(" Patched Boot Image is placed in ");
|
||||
console.add(" " + dest + " ");
|
||||
console.add("*********************************");
|
||||
break;
|
||||
case DIRECT_MODE:
|
||||
// Direct flash boot image and patch dtbo if possible
|
||||
Shell.su(mList,
|
||||
Shell.getShell().run(console, logs,
|
||||
"rm -rf /data/magisk/*",
|
||||
"mkdir -p /data/magisk 2>/dev/null",
|
||||
"mv -f " + install + "/* /data/magisk",
|
||||
@ -238,7 +241,7 @@ public class InstallMagisk extends ParallelTask<Void, Void, Boolean> {
|
||||
return false;
|
||||
}
|
||||
|
||||
mList.add("- All done!");
|
||||
console.add("- All done!");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
@ -248,6 +251,11 @@ public class InstallMagisk extends ParallelTask<Void, Void, Boolean> {
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Boolean result) {
|
||||
super.onPostExecute(result);
|
||||
FlashActivity activity = (FlashActivity) getActivity();
|
||||
if (!result) {
|
||||
console.add("! Installation failed");
|
||||
activity.reboot.setVisibility(View.GONE);
|
||||
}
|
||||
activity.buttonPanel.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
|
@ -12,11 +12,11 @@ public abstract class CallbackList<E> extends ArrayList<E> {
|
||||
handler = new Handler();
|
||||
}
|
||||
|
||||
public abstract void onAddElement();
|
||||
public abstract void onAddElement(E e);
|
||||
|
||||
public synchronized boolean add(E e) {
|
||||
boolean ret = super.add(e);
|
||||
handler.post(this::onAddElement);
|
||||
handler.post(() -> onAddElement(e));
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
@ -50,6 +50,14 @@
|
||||
android:layout_weight="1"
|
||||
android:text="@string/close" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/save_logs"
|
||||
style="?android:borderlessButtonStyle"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="50dp"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/menuSaveLog" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/reboot"
|
||||
style="?android:borderlessButtonStyle"
|
||||
|
@ -5,7 +5,7 @@
|
||||
<item
|
||||
android:id="@+id/menu_save"
|
||||
android:icon="@drawable/ic_save"
|
||||
android:title="@string/menuSaveToSd"
|
||||
android:title="@string/menuSaveLog"
|
||||
app:showAsAction="ifRoom"/>
|
||||
|
||||
<item
|
||||
|
@ -53,7 +53,6 @@
|
||||
<string name="not_installed">غير مثبت</string>
|
||||
|
||||
<!--Log Fragment-->
|
||||
<string name="menuSaveToSd">حفظ إلى بطاقة ذاكرة SD</string>
|
||||
<string name="menuReload">إعادة تحميل</string>
|
||||
<string name="menuClearLog">حذف السجل الآن</string>
|
||||
<string name="logs_cleared">تم حذف السجل بنجاح</string>
|
||||
|
@ -49,7 +49,7 @@
|
||||
<string name="not_installed">Nenainstalováno</string>
|
||||
|
||||
<!--Log Fragment-->
|
||||
<string name="menuSaveToSd">Uložit na SD</string>
|
||||
<string name="menuSaveLog">Uložit log</string>
|
||||
<string name="menuReload">Aktualizovat</string>
|
||||
<string name="menuClearLog">Smazat Log</string>
|
||||
<string name="logs_cleared">Log byl smazán</string>
|
||||
|
@ -56,7 +56,7 @@
|
||||
<string name="not_installed">Nicht installiert</string>
|
||||
|
||||
<!--Log Fragment-->
|
||||
<string name="menuSaveToSd">Log auf SD-Karte speichern</string>
|
||||
<string name="menuSaveLog">Log auf speichern</string>
|
||||
<string name="menuReload">Log erneut laden</string>
|
||||
<string name="menuClearLog">Log löschen</string>
|
||||
<string name="logs_cleared">Log gelöscht</string>
|
||||
|
@ -52,7 +52,7 @@
|
||||
<string name="not_installed">Μη εγκατεστημένη</string>
|
||||
|
||||
<!--Log Fragment-->
|
||||
<string name="menuSaveToSd">Αποθήκευση σε SD</string>
|
||||
<string name="menuSaveLog">"Αποθήκευση καταγραφής "</string>
|
||||
<string name="menuReload">Επαναφόρτωση</string>
|
||||
<string name="menuClearLog">Εκκαθάριση αρχείου καταγραφής τώρα</string>
|
||||
<string name="logs_cleared">Το αρχείο καταγραφής εκκαθαρίστηκε επιτυχώς</string>
|
||||
|
@ -56,7 +56,7 @@
|
||||
<string name="not_installed">No Instalado</string>
|
||||
|
||||
<!--Log Fragment-->
|
||||
<string name="menuSaveToSd">Guardar en la SD</string>
|
||||
<string name="menuSaveLog">Guardar registro</string>
|
||||
<string name="menuReload">Recargar</string>
|
||||
<string name="menuClearLog">Limpiar registro ahora</string>
|
||||
<string name="logs_cleared">Registro limpiado correctamente</string>
|
||||
|
@ -56,7 +56,7 @@
|
||||
<string name="not_installed">Pole installitud</string>
|
||||
|
||||
<!--Log Fragment-->
|
||||
<string name="menuSaveToSd">Salvesta SD-kaardile</string>
|
||||
<string name="menuSaveLog">Salvesta logi</string>
|
||||
<string name="menuReload">Laadi uuesti</string>
|
||||
<string name="menuClearLog">Tühjenda logi nüüd</string>
|
||||
<string name="logs_cleared">Logi edukalt tühjendatud</string>
|
||||
|
@ -48,7 +48,7 @@
|
||||
<string name="installed">Installé</string>
|
||||
<string name="not_installed">Non installé</string>
|
||||
<!--Log Fragment-->
|
||||
<string name="menuSaveToSd">Enregistrer sur SD</string>
|
||||
<string name="menuSaveLog">Enregistrer journal</string>
|
||||
<string name="menuReload">Actualiser</string>
|
||||
<string name="menuClearLog">Effacer le journal maintenant</string>
|
||||
<string name="logs_cleared">Journal effacé avec succès</string>
|
||||
|
@ -56,7 +56,7 @@
|
||||
<string name="not_installed">Nije instalirano</string>
|
||||
|
||||
<!--Log Fragment-->
|
||||
<string name="menuSaveToSd">Spremi na SD karticu</string>
|
||||
<string name="menuSaveLog">"Spremi zapisnik "</string>
|
||||
<string name="menuReload">Ponovno učitaj</string>
|
||||
<string name="menuClearLog">Očisti zapisnik sada</string>
|
||||
<string name="logs_cleared">Zapisnik je uspješno izbrisan</string>
|
||||
|
@ -56,7 +56,7 @@
|
||||
<string name="not_installed">Non installato</string>
|
||||
|
||||
<!--Log Fragment-->
|
||||
<string name="menuSaveToSd">Salva nella SD</string>
|
||||
<string name="menuSaveLog">Salva registro</string>
|
||||
<string name="menuReload">Ricarica</string>
|
||||
<string name="menuClearLog">Pulisci registro eventi</string>
|
||||
<string name="logs_cleared">Registro eventi creato correttamente</string>
|
||||
|
@ -49,7 +49,7 @@
|
||||
<string name="not_installed">未インストール</string>
|
||||
|
||||
<!--Log Fragment-->
|
||||
<string name="menuSaveToSd">SDカードに保存</string>
|
||||
<string name="menuSaveLog">ログ保存</string>
|
||||
<string name="menuReload">リロード</string>
|
||||
<string name="menuClearLog">ログを消去する</string>
|
||||
<string name="logs_cleared">ログは正常にクリアされました</string>
|
||||
|
@ -49,7 +49,7 @@
|
||||
<string name="not_installed">설치되지 않음</string>
|
||||
|
||||
<!--Log Fragment-->
|
||||
<string name="menuSaveToSd">SD 카드에 저장</string>
|
||||
<string name="menuSaveLog">저장 로그</string>
|
||||
<string name="menuReload">다시 불러오기</string>
|
||||
<string name="menuClearLog">지금 로그 비우기</string>
|
||||
<string name="logs_cleared">로그가 성공적으로 비워짐</string>
|
||||
|
@ -56,7 +56,7 @@
|
||||
<string name="not_installed">Niet geïnstalleerd</string>
|
||||
|
||||
<!--Log Fragment-->
|
||||
<string name="menuSaveToSd">Opslaan op SD-kaart</string>
|
||||
<string name="menuSaveLog">Opslaan log</string>
|
||||
<string name="menuReload">Herladen</string>
|
||||
<string name="menuClearLog">Log nu wissen</string>
|
||||
<string name="logs_cleared">Log succesvol gewist</string>
|
||||
|
@ -59,7 +59,7 @@
|
||||
<string name="not_installed">Nie zainstalowany</string>
|
||||
|
||||
<!--Log Fragment-->
|
||||
<string name="menuSaveToSd">Zapisz na SD</string>
|
||||
<string name="menuSaveLog">Zapisz log</string>
|
||||
<string name="menuReload">Załaduj ponownie</string>
|
||||
<string name="menuClearLog">Wyczyść Log</string>
|
||||
<string name="logs_cleared">Log wyczyszczony</string>
|
||||
|
@ -59,7 +59,7 @@
|
||||
<string name="not_installed">Não Instalado</string>
|
||||
|
||||
<!--Log Fragment-->
|
||||
<string name="menuSaveToSd">Salvar no SD</string>
|
||||
<string name="menuSaveLog">Salvar registro</string>
|
||||
<string name="menuReload">Recarregar</string>
|
||||
<string name="menuClearLog">Limpar registro agora</string>
|
||||
<string name="logs_cleared">Registro limpado com sucesso</string>
|
||||
|
@ -55,7 +55,7 @@
|
||||
<string name="not_installed">Não Instalado</string>
|
||||
|
||||
<!--Log Fragment-->
|
||||
<string name="menuSaveToSd">Gravar no SD</string>
|
||||
<string name="menuSaveLog">Gravar registo</string>
|
||||
<string name="menuReload">Recarregar</string>
|
||||
<string name="menuClearLog">Limpar registo agora</string>
|
||||
<string name="logs_cleared">Registo limpo com sucesso</string>
|
||||
@ -91,9 +91,11 @@
|
||||
<string name="settings_reboot_toast">Reinicie para aplicar definições</string>
|
||||
<string name="release_notes">Notas da atualização</string>
|
||||
<string name="repo_cache_cleared">Cache do repositório apagado</string>
|
||||
<string name="safetyNet_hide_notice">Esta aplicação usa SafetyNet
\nJá manipulado pelo MagiskHide por padrão</string>
|
||||
<string name="safetyNet_hide_notice">Esta aplicação usa SafetyNet
|
||||
\nJá manipulado pelo MagiskHide por padrão</string>
|
||||
<string name="process_error">Erro no processo</string>
|
||||
<string name="internal_storage">O zip foi guardado em:
\n[Armazenamento interno]%1$s</string>
|
||||
<string name="internal_storage">O zip foi guardado em:
|
||||
\n[Armazenamento interno]%1$s</string>
|
||||
<string name="zip_download_msg">A transferir ficheiro zip (%1$d%%) …</string>
|
||||
<string name="zip_process_title">A processar</string>
|
||||
<string name="zip_process_msg">A processar ficheiro zip …</string>
|
||||
@ -170,7 +172,8 @@
|
||||
<string name="deny">Negar</string>
|
||||
<string name="prompt">Perguntar</string>
|
||||
<string name="grant">Permitir</string>
|
||||
<string name="su_warning">Concede acesso total ao seu dispositivo.
\nNegue se não tiver certeza!</string>
|
||||
<string name="su_warning">Concede acesso total ao seu dispositivo.
|
||||
\nNegue se não tiver certeza!</string>
|
||||
<string name="forever">Sempre</string>
|
||||
<string name="once">Uma vez</string>
|
||||
<string name="tenmin">10 minutos</string>
|
||||
|
@ -49,7 +49,7 @@
|
||||
<string name="not_installed">Nu este instalat</string>
|
||||
|
||||
<!--Log Fragment-->
|
||||
<string name="menuSaveToSd">Salvare pe cardul SD</string>
|
||||
<string name="menuSaveLog">Salvare jurnal</string>
|
||||
<string name="menuReload">Reîncărcare</string>
|
||||
<string name="menuClearLog">Șterge jurnal acum</string>
|
||||
<string name="logs_cleared">Jurnal şters</string>
|
||||
|
@ -56,7 +56,7 @@
|
||||
<string name="not_installed">Не установлен</string>
|
||||
|
||||
<!--Log Fragment-->
|
||||
<string name="menuSaveToSd">Сохранить на карту памяти</string>
|
||||
<string name="menuSaveLog">"Сохранить историю "</string>
|
||||
<string name="menuReload">Обновить</string>
|
||||
<string name="menuClearLog">Очистить историю сейчас</string>
|
||||
<string name="logs_cleared">История успешно очищена</string>
|
||||
|
@ -54,7 +54,7 @@
|
||||
<string name="not_installed">Inte installerad</string>
|
||||
|
||||
<!--Log Fragment-->
|
||||
<string name="menuSaveToSd">Spara till SD-kort</string>
|
||||
<string name="menuSaveLog">Spara loggen</string>
|
||||
<string name="menuReload">Uppdatera</string>
|
||||
<string name="menuClearLog">Rensa loggen</string>
|
||||
<string name="logs_cleared">Loggen rensad</string>
|
||||
|
@ -54,7 +54,7 @@
|
||||
<string name="not_installed">Yüklenmemiş</string>
|
||||
|
||||
<!--Log Fragment-->
|
||||
<string name="menuSaveToSd">"SD Kart\'a kaydet"</string>
|
||||
<string name="menuSaveLog">Günlüğü kaydet</string>
|
||||
<string name="menuReload">Yenile</string>
|
||||
<string name="menuClearLog">Günlüğü temizle</string>
|
||||
<string name="logs_cleared">Günlük başarıyla temizlendi</string>
|
||||
|
@ -55,7 +55,7 @@
|
||||
<string name="not_installed">Не встановлено</string>
|
||||
|
||||
<!--Log Fragment-->
|
||||
<string name="menuSaveToSd">Зберегти на карту пам\'яті</string>
|
||||
<string name="menuSaveLog">Зберегти логи</string>
|
||||
<string name="menuReload">Оновити</string>
|
||||
<string name="menuClearLog">Очистити логи</string>
|
||||
<string name="logs_cleared">Логи очищено</string>
|
||||
|
@ -49,7 +49,7 @@
|
||||
<string name="not_installed">Chưa được cài đặt</string>
|
||||
|
||||
<!--Log Fragment-->
|
||||
<string name="menuSaveToSd">Lưu vào thẻ nhớ</string>
|
||||
<string name="menuSaveLog">Lưu nhật ký</string>
|
||||
<string name="menuReload">Tải lại</string>
|
||||
<string name="menuClearLog">Xoá nhật ký ngay</string>
|
||||
<string name="logs_cleared">Đã xoá nhật ký thành công</string>
|
||||
|
@ -55,7 +55,7 @@
|
||||
<string name="not_installed">未安装</string>
|
||||
|
||||
<!--Log Fragment-->
|
||||
<string name="menuSaveToSd">保存到内置存储</string>
|
||||
<string name="menuSaveLog">保存日志</string>
|
||||
<string name="menuReload">刷新</string>
|
||||
<string name="menuClearLog">清除日志</string>
|
||||
<string name="logs_cleared">日志已成功清除</string>
|
||||
|
@ -47,7 +47,7 @@
|
||||
<string name="not_installed">未安裝</string>
|
||||
|
||||
<!--Log Fragment-->
|
||||
<string name="menuSaveToSd">保存到 SD 卡</string>
|
||||
<string name="menuSaveLog">保存日誌</string>
|
||||
<string name="menuReload">重載</string>
|
||||
<string name="menuClearLog">清除日誌</string>
|
||||
<string name="logs_cleared">日誌已成功清除</string>
|
||||
|
@ -59,7 +59,7 @@
|
||||
<string name="not_installed">Not Installed</string>
|
||||
|
||||
<!--Log Fragment-->
|
||||
<string name="menuSaveToSd">Save to SD</string>
|
||||
<string name="menuSaveLog">Save log</string>
|
||||
<string name="menuReload">Reload</string>
|
||||
<string name="menuClearLog">Clear log now</string>
|
||||
<string name="logs_cleared">Log successfully cleared</string>
|
||||
|
Loading…
Reference in New Issue
Block a user