mirror of
https://github.com/xoureldeen/Vectras-VM-Android.git
synced 2026-05-19 08:10:36 +00:00
3.2.2
- Added dialog about Alpine Xfce not supporting 32-bit. - Tiny Vterm will be used instead of Terminal if device is 32-bit. - You can now open Terminal in Advanced setup. - VNC is default if device is 32-bit. - Fixed setup failure on 32-bit devices. - Improved Tiny Vterm.
This commit is contained in:
parent
f7093df107
commit
d3046c50f7
14 changed files with 217 additions and 140 deletions
7
.idea/deploymentTargetSelector.xml
generated
7
.idea/deploymentTargetSelector.xml
generated
|
|
@ -4,14 +4,11 @@
|
|||
<selectionStates>
|
||||
<SelectionState runConfigName="app">
|
||||
<option name="selectionMode" value="DROPDOWN" />
|
||||
<DropdownSelection timestamp="2025-10-09T19:55:30.113124600Z">
|
||||
<DropdownSelection timestamp="2025-10-16T07:18:10.628540500Z">
|
||||
<Target type="DEFAULT_BOOT">
|
||||
<handle>
|
||||
<DeviceId pluginId="FirebaseDirectAccess" identifier="reservation=projects/nguyenbaoanbui-9cba5/deviceSessions/session-2nrdccjx040yd" />
|
||||
<DeviceId pluginId="PhysicalDevice" identifier="serial=8c847fb6" />
|
||||
</handle>
|
||||
<template>
|
||||
<DeviceId pluginId="FirebaseDirectAccess" type="TEMPLATE" identifier="model_id=b0q/33" />
|
||||
</template>
|
||||
</Target>
|
||||
</DropdownSelection>
|
||||
<DialogSelection />
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@ android {
|
|||
applicationId "com.vectras.vm"
|
||||
minSdk minApi
|
||||
targetSdk targetApi
|
||||
versionCode 24
|
||||
versionName "3.2.1"
|
||||
versionCode 25
|
||||
versionName "3.2.2"
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
multiDexEnabled true
|
||||
}
|
||||
|
|
@ -89,7 +89,7 @@ dependencies {
|
|||
// implementation 'com.google.android.gms:play-services-ads:24.6.0'
|
||||
implementation 'com.google.guava:guava:33.5.0-jre'
|
||||
implementation 'com.google.code.gson:gson:2.13.2'
|
||||
implementation 'com.squareup.okhttp3:okhttp:5.2.0'
|
||||
implementation 'com.squareup.okhttp3:okhttp:5.2.1'
|
||||
implementation "androidx.window:window:1.5.0"
|
||||
implementation "commons-io:commons-io:2.20.0"
|
||||
implementation 'org.zeroturnaround:zt-zip:1.17'
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ public class AppConfig {
|
|||
" libusb libaio ncurses-libs curl libnfs gtk+3.0 gtk+3.0-dev fuse libpulse libseccomp jack pipewire liburing" +
|
||||
" mesa-dri-gallium mesa-vulkan-swrast vulkan-loader mesa-utils mesa-egl mesa-gbm mesa-vulkan-ati mesa-vulkan-broadcom mesa-vulkan-freedreno mesa-vulkan-panfrost";
|
||||
|
||||
public static String neededPkgs32bit = "aria2 tar dwm xfce4-terminal libslirp libslirp-dev pulseaudio-dev glib-dev pixman-dev zlib-dev spice-dev" +
|
||||
public static String neededPkgs32bit = "aria2 tar dwm xterm libslirp libslirp-dev pulseaudio-dev glib-dev pixman-dev zlib-dev spice-dev" +
|
||||
" libusbredirparser usbredir-dev libiscsi-dev sdl2 sdl2-dev libepoxy-dev virglrenderer-dev rdma-core" +
|
||||
" libusb ncurses-libs curl libnfs gtk+3.0 fuse libpulse libseccomp jack pipewire liburing";
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import static android.content.Intent.ACTION_OPEN_DOCUMENT;
|
|||
import static android.content.Intent.ACTION_VIEW;
|
||||
import static android.view.View.GONE;
|
||||
|
||||
import com.termux.app.TermuxActivity;
|
||||
import com.termux.app.TermuxService;
|
||||
|
||||
import static com.vectras.vm.utils.UIUtils.UIAlert;
|
||||
|
|
@ -227,7 +228,6 @@ public class SetupQemuActivity extends AppCompatActivity implements View.OnClick
|
|||
} else {
|
||||
extractSystemFiles("alpine21", "distro");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -886,6 +886,14 @@ public class SetupQemuActivity extends AppCompatActivity implements View.OnClick
|
|||
});
|
||||
|
||||
binding.advancedsetup.ivClose.setOnClickListener(v -> linearsimplesetupui.setVisibility(View.VISIBLE));
|
||||
binding.advancedsetup.ivOpenterminal.setOnClickListener(v -> {
|
||||
if (DeviceUtils.is64bit()) {
|
||||
startActivity(new Intent(this, TermuxActivity.class));
|
||||
} else {
|
||||
com.vectras.vterm.TerminalBottomSheetDialog VTERM = new com.vectras.vterm.TerminalBottomSheetDialog(this);
|
||||
VTERM.showVterm();
|
||||
}
|
||||
});
|
||||
|
||||
binding.advancedsetup.ivCopycommandsetup.setOnClickListener(v -> copyToClipboard(binding.advancedsetup.tvCommandsetup.getText().toString()));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import androidx.preference.PreferenceManager;
|
|||
|
||||
import com.vectras.qemu.MainSettingsManager;
|
||||
import com.vectras.vm.home.HomeActivity;
|
||||
import com.vectras.vm.utils.DeviceUtils;
|
||||
import com.vectras.vm.utils.FileUtils;
|
||||
import com.vectras.vm.utils.UIUtils;
|
||||
|
||||
|
|
@ -141,7 +142,7 @@ public class SplashActivity extends AppCompatActivity implements Runnable {
|
|||
} else {
|
||||
startActivity(new Intent(this, SetupQemuActivity.class));
|
||||
//For Android 14+
|
||||
if (Build.VERSION.SDK_INT >= 34) {
|
||||
if (!DeviceUtils.is64bit() || Build.VERSION.SDK_INT >= 34) {
|
||||
MainSettingsManager.setVmUi(this, "VNC");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -65,6 +65,7 @@ import com.vectras.vm.home.romstore.RomStoreFragment;
|
|||
import com.vectras.vm.home.vms.VmsFragment;
|
||||
import com.vectras.vm.logger.VectrasStatus;
|
||||
import com.vectras.vm.settings.UpdaterActivity;
|
||||
import com.vectras.vm.utils.DeviceUtils;
|
||||
import com.vectras.vm.utils.DialogUtils;
|
||||
import com.vectras.vm.utils.FileUtils;
|
||||
import com.vectras.vm.utils.LibraryChecker;
|
||||
|
|
@ -478,9 +479,12 @@ public class HomeActivity extends AppCompatActivity implements RomStoreFragment.
|
|||
} else if (id == R.id.navigation_item_desktop) {
|
||||
DisplaySystem.launchX11(this, true);
|
||||
} else if (id == R.id.navigation_item_terminal) {
|
||||
/*com.vectras.vterm.TerminalBottomSheetDialog VTERM = new com.vectras.vterm.TerminalBottomSheetDialog(activity);
|
||||
VTERM.showVterm();*/
|
||||
startActivity(new Intent(this, TermuxActivity.class));
|
||||
if (DeviceUtils.is64bit()) {
|
||||
startActivity(new Intent(this, TermuxActivity.class));
|
||||
} else {
|
||||
com.vectras.vterm.TerminalBottomSheetDialog VTERM = new com.vectras.vterm.TerminalBottomSheetDialog(this);
|
||||
VTERM.showVterm();
|
||||
}
|
||||
} else if (id == R.id.navigation_item_view_logs) {
|
||||
BottomSheetDialog bottomSheetDialog = new BottomSheetDialog(this);
|
||||
View view = getLayoutInflater().inflate(R.layout.bottomsheetdialog_logger, null);
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import com.vectras.qemu.MainSettingsManager;
|
|||
import com.vectras.qemu.MainVNCActivity;
|
||||
import com.vectras.vm.R;
|
||||
import com.vectras.vm.core.ShellExecutor;
|
||||
import com.vectras.vm.utils.DeviceUtils;
|
||||
import com.vectras.vm.utils.DialogUtils;
|
||||
import com.vectras.vm.utils.FileUtils;
|
||||
import com.vectras.vm.x11.X11Activity;
|
||||
|
|
@ -50,6 +51,17 @@ public class DisplaySystem {
|
|||
null,
|
||||
null
|
||||
);
|
||||
} else if (!DeviceUtils.is64bit()) {
|
||||
DialogUtils.oneDialog(
|
||||
activity,
|
||||
activity.getString(R.string.x11_feature_not_supported),
|
||||
activity.getString(R.string.cpu_not_support_64_xfce),
|
||||
activity.getString(R.string.ok),
|
||||
true, R.drawable.error_96px,
|
||||
true,
|
||||
null,
|
||||
null
|
||||
);
|
||||
} else {
|
||||
// XFCE4 meta-package
|
||||
String xfce4Package = "xfce4";
|
||||
|
|
|
|||
|
|
@ -7,7 +7,9 @@ import com.vectras.vterm.Terminal;
|
|||
|
||||
public class CommandUtils {
|
||||
public static String createForSelectedMirror(boolean _https, String _url, String _beforemain) {
|
||||
String command = "echo \"\" > /etc/apk/repositories && sed -i -e \"1ihttps://xssFjnj58Id/yttGkok69Je/edge/testing\" /etc/apk/repositories && sed -i -e \"1ihttps://xssFjnj58Id/yttGkok69Je/v3.22/community\" /etc/apk/repositories && sed -i -e \"1ihttps://xssFjnj58Id/yttGkok69Je/v3.22/main\" /etc/apk/repositories";
|
||||
String command = "echo \"\" > /etc/apk/repositories && sed -i -e \"1ihttps://xssFjnj58Id/yttGkok69Je/edge/testing\" /etc/apk/repositories && sed -i -e \"1ihttps://xssFjnj58Id/yttGkok69Je/"
|
||||
+ (DeviceUtils.is64bit() ? "v3.22" : "v3.21") + "/community\" /etc/apk/repositories && sed -i -e \"1ihttps://xssFjnj58Id/yttGkok69Je/v3.22/main\" /etc/apk/repositories";
|
||||
|
||||
command = command.replaceAll("/yttGkok69Je", _beforemain);
|
||||
if (!_https)
|
||||
command = command.replaceAll("https://", "http://");
|
||||
|
|
|
|||
|
|
@ -1,20 +1,21 @@
|
|||
package com.vectras.vterm;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.View;
|
||||
import android.view.inputmethod.EditorInfo;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.EditText;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ScrollView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialog;
|
||||
import com.termux.app.TermuxService;
|
||||
import com.vectras.vm.AppConfig;
|
||||
import com.vectras.vm.R;
|
||||
import com.vectras.vterm.view.ZoomableTextView;
|
||||
|
||||
|
|
@ -28,13 +29,16 @@ import java.net.InetAddress;
|
|||
import java.net.NetworkInterface;
|
||||
import java.net.SocketException;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Objects;
|
||||
|
||||
public class TerminalBottomSheetDialog {
|
||||
private ZoomableTextView terminalOutput;
|
||||
private EditText commandInput;
|
||||
private View view;
|
||||
private Activity activity;
|
||||
private BottomSheetDialog bottomSheetDialog;
|
||||
private final ZoomableTextView terminalOutput;
|
||||
private final EditText commandInput;
|
||||
private final View view;
|
||||
private final Activity activity;
|
||||
private final BottomSheetDialog bottomSheetDialog;
|
||||
LinearLayout inputContainer;
|
||||
boolean isAllowAddToResultCommand = true;
|
||||
|
||||
public TerminalBottomSheetDialog(Activity activity) {
|
||||
this.activity = activity;
|
||||
|
|
@ -45,27 +49,20 @@ public class TerminalBottomSheetDialog {
|
|||
|
||||
terminalOutput = view.findViewById(R.id.tvTerminalOutput);
|
||||
commandInput = view.findViewById(R.id.etCommandInput);
|
||||
inputContainer = view.findViewById(R.id.ln_input);
|
||||
|
||||
TextView tvPrompt = view.findViewById(R.id.tvPrompt);
|
||||
updateUserPrompt(tvPrompt);
|
||||
|
||||
// Show the keyboard
|
||||
InputMethodManager imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
imm.showSoftInput(commandInput, InputMethodManager.SHOW_IMPLICIT);
|
||||
|
||||
commandInput.requestFocus();
|
||||
forcusCommandInput();
|
||||
|
||||
// Whenever you modify the text of the EditText, do the following to ensure the cursor is at the end:
|
||||
commandInput.setSelection(commandInput.getText().length());
|
||||
|
||||
// when user click terminal view will open keyboard
|
||||
terminalOutput.setOnClickListener(view -> {
|
||||
// Request focus for the EditText
|
||||
commandInput.requestFocus();
|
||||
|
||||
// Show the keyboard
|
||||
InputMethodManager imm1 = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
imm1.showSoftInput(commandInput, InputMethodManager.SHOW_IMPLICIT);
|
||||
forcusCommandInput();
|
||||
});
|
||||
// Configure the editor to handle the "Done" action on the soft keyboard
|
||||
commandInput.setOnEditorActionListener((v, actionId, event) -> {
|
||||
|
|
@ -78,21 +75,18 @@ public class TerminalBottomSheetDialog {
|
|||
return false;
|
||||
});
|
||||
|
||||
commandInput.setOnKeyListener(new View.OnKeyListener() {
|
||||
public boolean onKey(View v, int keyCode, KeyEvent event) {
|
||||
// If the event is a key-down event on the "enter" button
|
||||
if ((event.getAction() == KeyEvent.ACTION_DOWN) &&
|
||||
(keyCode == KeyEvent.KEYCODE_ENTER)) {
|
||||
activity.runOnUiThread(() -> appendTextAndScroll(commandInput.getText().toString() + "\n"));
|
||||
executeShellCommand(commandInput.getText().toString());
|
||||
commandInput.setText("");
|
||||
activity.runOnUiThread(() -> {
|
||||
commandInput.requestFocus(); // Request focus again
|
||||
});
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
commandInput.setOnKeyListener((v, keyCode, event) -> {
|
||||
// If the event is a key-down event on the "enter" button
|
||||
if ((event.getAction() == KeyEvent.ACTION_DOWN) &&
|
||||
(keyCode == KeyEvent.KEYCODE_ENTER)) {
|
||||
activity.runOnUiThread(() -> appendTextAndScroll(commandInput.getText().toString() + "\n"));
|
||||
executeShellCommand(commandInput.getText().toString());
|
||||
commandInput.setText("");
|
||||
// Request focus again
|
||||
activity.runOnUiThread(commandInput::requestFocus);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -106,9 +100,7 @@ public class TerminalBottomSheetDialog {
|
|||
String username = null;
|
||||
// Update the prompt on the UI thread
|
||||
String finalUsername = username != null ? username : "root";
|
||||
activity.runOnUiThread(() -> {
|
||||
promptView.setText(finalUsername + "@localhost:~$ ");
|
||||
});
|
||||
activity.runOnUiThread(() -> promptView.setText(finalUsername + "@localhost:~$ "));
|
||||
}).start();
|
||||
}
|
||||
|
||||
|
|
@ -117,15 +109,19 @@ public class TerminalBottomSheetDialog {
|
|||
ScrollView scrollView = view.findViewById(R.id.scrollView);
|
||||
|
||||
// Update the text
|
||||
terminalOutput.append(textToAdd);
|
||||
if (textToAdd.contains("@localhost:~$ clear")) {
|
||||
isAllowAddToResultCommand = false;
|
||||
terminalOutput.setText("");
|
||||
} else {
|
||||
if (isAllowAddToResultCommand) {
|
||||
terminalOutput.append(textToAdd);
|
||||
} else {
|
||||
isAllowAddToResultCommand = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Scroll to the bottom
|
||||
scrollView.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
scrollView.fullScroll(ScrollView.FOCUS_DOWN);
|
||||
}
|
||||
});
|
||||
scrollView.post(() -> scrollView.fullScroll(ScrollView.FOCUS_DOWN));
|
||||
}
|
||||
|
||||
private String getLocalIpAddress() {
|
||||
|
|
@ -134,8 +130,8 @@ public class TerminalBottomSheetDialog {
|
|||
NetworkInterface intf = en.nextElement();
|
||||
for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements(); ) {
|
||||
InetAddress inetAddress = enumIpAddr.nextElement();
|
||||
if (!inetAddress.isLoopbackAddress() && inetAddress.getHostAddress().toString().contains(".")) {
|
||||
return inetAddress.getHostAddress().toString();
|
||||
if (!inetAddress.isLoopbackAddress() && Objects.requireNonNull(inetAddress.getHostAddress()).contains(".")) {
|
||||
return inetAddress.getHostAddress();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -150,47 +146,51 @@ public class TerminalBottomSheetDialog {
|
|||
if (checkInstallation())
|
||||
new Thread(() -> {
|
||||
try {
|
||||
// Setup the process builder to start PRoot with environmental variables and commands
|
||||
activity.runOnUiThread(() -> {
|
||||
if (terminalOutput.getVisibility() == View.GONE) terminalOutput.setVisibility(View.VISIBLE);
|
||||
appendTextAndScroll("root@localhost:~$ " + userCommand + "\n");
|
||||
inputContainer.setVisibility(View.GONE);
|
||||
});
|
||||
// Setup the qemuProcess builder to start PRoot with environmental variables and commands
|
||||
ProcessBuilder processBuilder = new ProcessBuilder();
|
||||
|
||||
// Adjust these environment variables as necessary for your app
|
||||
String filesDir = activity.getFilesDir().getAbsolutePath();
|
||||
String nativeLibDir = activity.getApplicationInfo().nativeLibraryDir;
|
||||
String filesDir = AppConfig.internalDataDirPath;
|
||||
|
||||
File tmpDir = new File(activity.getFilesDir(), "tmp");
|
||||
File tmpDir = new File(filesDir, "usr/tmp");
|
||||
|
||||
// Setup environment for the PRoot process
|
||||
// Setup environment for the PRoot qemuProcess
|
||||
processBuilder.environment().put("PROOT_TMP_DIR", tmpDir.getAbsolutePath());
|
||||
processBuilder.environment().put("PROOT_LOADER", nativeLibDir + "/libproot-loader.so");
|
||||
processBuilder.environment().put("PROOT_LOADER_32", nativeLibDir + "/libproot-loader32.so");
|
||||
|
||||
processBuilder.environment().put("HOME", "/root");
|
||||
processBuilder.environment().put("USER", "root");
|
||||
processBuilder.environment().put("PATH", "/bin:/usr/bin:/sbin:/usr/sbin");
|
||||
//processBuilder.environment().put("PATH", "/bin:/usr/bin:/sbin:/usr/sbin");
|
||||
//processBuilder.environment().put("LD_LIBRARY_PATH", TermuxService.PREFIX_PATH + "/lib");
|
||||
processBuilder.environment().put("TERM", "xterm-256color");
|
||||
processBuilder.environment().put("TMPDIR", tmpDir.getAbsolutePath());
|
||||
processBuilder.environment().put("SHELL", "/bin/sh");
|
||||
processBuilder.environment().put("DISPLAY", getLocalIpAddress()+":1");
|
||||
processBuilder.environment().put("PULSE_SERVER", "/run/pulse/native");
|
||||
processBuilder.environment().put("XDG_RUNTIME_DIR", "/run");
|
||||
processBuilder.environment().put("QEMU_AUDIO_DRV", "sdl");
|
||||
processBuilder.environment().put("DISPLAY", ":0");
|
||||
processBuilder.environment().put("PULSE_SERVER", "127.0.0.1");
|
||||
processBuilder.environment().put("XDG_RUNTIME_DIR", "${TMPDIR}");
|
||||
processBuilder.environment().put("SDL_VIDEODRIVER", "x11");
|
||||
|
||||
String[] prootCommand = {
|
||||
nativeLibDir + "/libproot.so", // PRoot binary path
|
||||
"--kill-on-exit",
|
||||
"--link2symlink",
|
||||
"-0",
|
||||
"-r", filesDir + "/distro", // Path to the rootfs
|
||||
"-b", "/dev",
|
||||
"-b", "/proc",
|
||||
"-b", "/sys",
|
||||
"-b", "/sdcard",
|
||||
"-b", "/storage",
|
||||
"-b", "/data",
|
||||
"-w", "/root",
|
||||
"/bin/sh",
|
||||
"--login"// The shell to execute inside PRoot
|
||||
String[] prootCommand = {
|
||||
TermuxService.PREFIX_PATH + "/bin/proot", // PRoot binary path
|
||||
"--kill-on-exit",
|
||||
"--link2symlink",
|
||||
"-0",
|
||||
"-r", filesDir + "/distro", // Path to the rootfs
|
||||
"-b", "/dev",
|
||||
"-b", "/proc",
|
||||
"-b", "/sys",
|
||||
"-b", AppConfig.internalDataDirPath + "distro/root:/dev/shm",
|
||||
"-b", "/sdcard",
|
||||
"-b", "/storage",
|
||||
"-b", "/data",
|
||||
"-b", AppConfig.internalDataDirPath + "usr/tmp:/tmp",
|
||||
"-w", "/root",
|
||||
"/bin/sh",
|
||||
"--login"// The shell to execute inside PRoot
|
||||
};
|
||||
|
||||
processBuilder.command(prootCommand);
|
||||
|
|
@ -210,13 +210,21 @@ public class TerminalBottomSheetDialog {
|
|||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
final String outputLine = line;
|
||||
activity.runOnUiThread(() -> appendTextAndScroll(outputLine + "\n"));
|
||||
activity.runOnUiThread(() -> {
|
||||
appendTextAndScroll(outputLine + "\n");
|
||||
inputContainer.setVisibility(View.VISIBLE);
|
||||
forcusCommandInput();
|
||||
});
|
||||
}
|
||||
|
||||
// Read any errors from the error stream
|
||||
while ((line = errorReader.readLine()) != null) {
|
||||
final String errorLine = line;
|
||||
activity.runOnUiThread(() -> appendTextAndScroll(errorLine + "\n"));
|
||||
activity.runOnUiThread(() -> {
|
||||
appendTextAndScroll(errorLine + "\n");
|
||||
inputContainer.setVisibility(View.VISIBLE);
|
||||
forcusCommandInput();
|
||||
});
|
||||
}
|
||||
|
||||
// Clean up
|
||||
|
|
@ -229,7 +237,11 @@ public class TerminalBottomSheetDialog {
|
|||
} catch (IOException | InterruptedException e) {
|
||||
// Handle exceptions by printing the stack trace in the terminal output
|
||||
final String errorMessage = e.getMessage();
|
||||
activity.runOnUiThread(() -> appendTextAndScroll("Error: " + errorMessage + "n"));
|
||||
activity.runOnUiThread(() -> {
|
||||
appendTextAndScroll("Error: " + errorMessage + "n");
|
||||
inputContainer.setVisibility(View.VISIBLE);
|
||||
forcusCommandInput();
|
||||
});
|
||||
}
|
||||
}).start(); // Execute the command in a separate thread to prevent blocking the UI thread
|
||||
else
|
||||
|
|
@ -245,4 +257,12 @@ public class TerminalBottomSheetDialog {
|
|||
File distro = new File(filesDir, "distro");
|
||||
return distro.exists();
|
||||
}
|
||||
|
||||
private void forcusCommandInput() {
|
||||
commandInput.post(() -> {
|
||||
commandInput.requestFocus();
|
||||
InputMethodManager imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
imm.showSoftInput(commandInput, InputMethodManager.SHOW_IMPLICIT);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -5,6 +5,6 @@
|
|||
android:right="2dp"
|
||||
android:bottom="2dp" />
|
||||
<corners android:radius="2dp" />
|
||||
<solid android:color="@color/cursor" />
|
||||
<solid android:color="#fff" />
|
||||
<size android:height="20dp" android:width="10dp" />
|
||||
</shape>
|
||||
|
|
|
|||
|
|
@ -53,6 +53,14 @@
|
|||
android:textSize="16sp"
|
||||
android:singleLine="true"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_openterminal"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginRight="8dp"
|
||||
android:src="@drawable/terminal_24px"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_close"
|
||||
android:layout_width="wrap_content"
|
||||
|
|
|
|||
|
|
@ -3,72 +3,96 @@
|
|||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:orientation="vertical"
|
||||
android:padding="18dp">
|
||||
android:paddingHorizontal="8dp"
|
||||
android:paddingBottom="8dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/tiny_vterm"
|
||||
style="@style/MaterialAlertDialog.Material3.Title.Text"/>
|
||||
<!-- <TextView-->
|
||||
<!-- android:id="@+id/title"-->
|
||||
<!-- android:layout_width="wrap_content"-->
|
||||
<!-- android:layout_height="wrap_content"-->
|
||||
<!-- android:text="@string/tiny_vterm"-->
|
||||
<!-- style="@style/MaterialAlertDialog.Material3.Title.Text"/>-->
|
||||
|
||||
<com.google.android.material.bottomsheet.BottomSheetDragHandleView
|
||||
android:id="@+id/drag_handle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/mainTerminal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<ScrollView
|
||||
android:id="@+id/scrollView"
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
style="@style/Widget.Material3.CardView.Filled"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fillViewport="true"
|
||||
android:nestedScrollingEnabled="true"
|
||||
android:padding="5dp">
|
||||
|
||||
<LinearLayout
|
||||
app:cardBackgroundColor="#000">
|
||||
<ScrollView
|
||||
android:id="@+id/scrollView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.vectras.vterm.view.ZoomableTextView
|
||||
android:id="@+id/tvTerminalOutput"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textIsSelectable="true"
|
||||
android:textSize="12sp" />
|
||||
android:layout_height="match_parent"
|
||||
android:fillViewport="true"
|
||||
android:nestedScrollingEnabled="true"
|
||||
android:padding="5dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
android:padding="8dp"
|
||||
android:background="#000"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvPrompt"
|
||||
android:layout_width="wrap_content"
|
||||
<com.vectras.vterm.view.ZoomableTextView
|
||||
android:id="@+id/tvTerminalOutput"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom"
|
||||
android:gravity="center_vertical"
|
||||
android:text="user@localhost:~$ "
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
|
||||
android:textSize="12sp" />
|
||||
android:visibility="gone"
|
||||
android:textIsSelectable="true"
|
||||
android:textSize="12sp"
|
||||
android:textColor="#fff"
|
||||
app:fontFamily="@font/jetbrainsmonoregular"
|
||||
tools:visibility="visible"/>
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etCommandInput"
|
||||
android:layout_width="0dp"
|
||||
<LinearLayout
|
||||
android:id="@+id/ln_input"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:focusable="true"
|
||||
android:background="@android:color/transparent"
|
||||
android:focusableInTouchMode="true"
|
||||
android:gravity="center_vertical"
|
||||
android:imeOptions="actionDone"
|
||||
android:inputType="text|textNoSuggestions"
|
||||
android:textCursorDrawable="@drawable/cursor"
|
||||
android:textSize="12sp" />
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvPrompt"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom"
|
||||
android:gravity="center_vertical"
|
||||
android:text="user@localhost:~$ "
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
|
||||
android:textSize="12sp"
|
||||
android:textColor="#fff"
|
||||
app:fontFamily="@font/jetbrainsmonoregular" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etCommandInput"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:focusable="true"
|
||||
android:background="@android:color/transparent"
|
||||
android:focusableInTouchMode="true"
|
||||
android:gravity="center_vertical"
|
||||
android:imeOptions="actionDone"
|
||||
android:inputType="text|textNoSuggestions"
|
||||
android:textCursorDrawable="@drawable/cursor"
|
||||
android:textSize="12sp"
|
||||
android:textColor="#fff"
|
||||
app:fontFamily="@font/jetbrainsmonoregular" />
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</ScrollView>
|
||||
</ScrollView>
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
</RelativeLayout>
|
||||
</LinearLayout>
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
<string name="app_name">Vectras VM</string>
|
||||
|
||||
<!--======================VECTRAS STRINGS====================-->
|
||||
<string name="app_version" translatable="false">3.2.1</string>
|
||||
<string name="app_version" translatable="false">3.2.2</string>
|
||||
<string name="qemu_version" translatable="false">Stable</string>
|
||||
<string name="str_home">Home</string>
|
||||
<string name="str_logger">Logger</string>
|
||||
|
|
@ -574,6 +574,7 @@
|
|||
<string name="could_not_create_dir_to_save_cvbi_content">Something went wrong. Could not create directory to save cvbi file.</string>
|
||||
<string name="quick_start">Quick start</string>
|
||||
<string name="quick_start_description">To start up faster the next time you open Vectras VM if you don\'t remove it from multitasking.</string>
|
||||
<string name="cpu_not_support_64_xfce">Your device\'s Android OS or CPU doesn\'t support 64-bit, which means you can\'t use this feature.</string>
|
||||
|
||||
|
||||
<!--======================TERMUX STRINGS====================-->
|
||||
|
|
|
|||
|
|
@ -5,11 +5,11 @@
|
|||
"url": "https://github.com/xoureldeen/Vectras-VM-Android/releases/v2.9.5",
|
||||
"Message": "<h2>v2.9.5-3dfx</h2><ul><li>Bring back 3dfx support.</li><li>Enhance app execution.</li><li>Added some linux programs in x11 display.</li><li>Added alpine linux (x11).</li><li>Russian language by <a href=\"https://github.com/OFGING\" target=\"_blank\">@OFGING</a></li></ul><br><br>New updates are live!",
|
||||
"cancellable": true,
|
||||
"versionCodeBeta":"24",
|
||||
"versionNameBeta":"3.2.1",
|
||||
"versionNameBetas":"v2.9.5.1-3dfx,v2.9.5.2-3dfx,v2.9.5.3-3dfx,v2.9.5.4-3dfx,v2.9.5.5-3dfx,v2.9.5.6-3dfx,v2.9.5.7-3dfx,v2.9.5.8-3dfx,v2.9.5.9-3dfx,v2.9.5.10-3dfx,v2.9.5.11-3dfx,v2.9.5.12-3dfx,v2.9.5.13-3dfx,3.0.0,3.1.0,3.2.1",
|
||||
"versionCodeBeta":"25",
|
||||
"versionNameBeta":"3.2.2",
|
||||
"versionNameBetas":"v2.9.5.1-3dfx,v2.9.5.2-3dfx,v2.9.5.3-3dfx,v2.9.5.4-3dfx,v2.9.5.5-3dfx,v2.9.5.6-3dfx,v2.9.5.7-3dfx,v2.9.5.8-3dfx,v2.9.5.9-3dfx,v2.9.5.10-3dfx,v2.9.5.11-3dfx,v2.9.5.12-3dfx,v2.9.5.13-3dfx,3.0.0,3.1.0,3.2.1,3.2.2",
|
||||
"sizeBeta": "50 MB",
|
||||
"urlBeta": "https://github.com/AnBui2004/Vectras-VM-Emu-Android/releases",
|
||||
"MessageBeta": "<h2>3.2.1</h2>Bugs fixed.",
|
||||
"MessageBeta": "<h2>3.2.2</h2>Bugs fixed.",
|
||||
"cancellableBeta": true
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue