From 3d8dca43b4528db9c1493cc7f2be14cdf936ce25 Mon Sep 17 00:00:00 2001 From: An Bui <91354810+AnBui2004@users.noreply.github.com> Date: Thu, 1 Jan 2026 23:13:48 +0700 Subject: [PATCH] 3.5.9 - VNC has been improved. - Bugs fixed. --- app/build.gradle | 4 +- .../com/vectras/qemu/MainVNCActivity.java | 47 +++++++++++++------ .../main/java/com/vectras/vm/MainService.java | 8 ++-- app/src/main/java/com/vectras/vm/RomInfo.java | 3 +- .../com/vectras/vm/VMCreatorActivity.java | 2 +- .../main/java/com/vectras/vm/VMManager.java | 27 +++++++++++ .../com/vectras/vm/main/MainActivity.java | 10 ++-- .../com/vectras/vm/main/core/MainStartVM.java | 9 +++- .../settings/X11DisplaySettingsActivity.java | 1 + web/data/UpdateConfig.json | 8 ++-- 10 files changed, 90 insertions(+), 29 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 4e6586c..9fe7fe2 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -15,8 +15,8 @@ android { applicationId "com.vectras.vm" minSdk minApi targetSdk targetApi - versionCode 62 - versionName "3.5.8" + versionCode 63 + versionName "3.5.9" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" multiDexEnabled true diff --git a/app/src/main/java/com/vectras/qemu/MainVNCActivity.java b/app/src/main/java/com/vectras/qemu/MainVNCActivity.java index 336d6d1..45f7007 100644 --- a/app/src/main/java/com/vectras/qemu/MainVNCActivity.java +++ b/app/src/main/java/com/vectras/qemu/MainVNCActivity.java @@ -289,10 +289,6 @@ public class MainVNCActivity extends VncCanvasActivity { } public void onDestroy() { - if (NetworkUtils.isPortOpen("127.0.0.1", Config.QMPPort, 100) && started) { - startActivity(new Intent(this, MainVNCActivity.class)); - overridePendingTransition(0, 0); - } super.onDestroy(); this.stopTimeListener(); //Terminal.killQemuProcess(); @@ -669,8 +665,13 @@ public class MainVNCActivity extends VncCanvasActivity { if (event.getAction() == KeyEvent.ACTION_MULTIPLE && event.getKeyCode() == KeyEvent.KEYCODE_UNKNOWN) { vncCanvas.sendText(event.getCharacters()); return true; - } else - return super.dispatchKeyEvent(event); + } else { + try { + return super.dispatchKeyEvent(event); + } catch (ClassCastException e) { + return true; + } + } } @@ -803,6 +804,8 @@ public class MainVNCActivity extends VncCanvasActivity { } else { // Try reconnect. if (Config.forceRefeshVNCDisplay) { + startActivity(new Intent(this, MainVNCActivity.class)); + overridePendingTransition(0, 0); finish(); } else { tryReconnect(); @@ -818,9 +821,17 @@ public class MainVNCActivity extends VncCanvasActivity { public void run() { count++; - if (!isFinishing() && !isConnected && count < retryLimit) { + if (!isFinishing() && !isDestroyed() && !isConnected && count < retryLimit) { // Do not attempt to reconnect while connected. - reconnect(); + if (Config.forceRefeshVNCDisplay) { + runOnUiThread(() -> { + startActivity(new Intent(MainVNCActivity.this, MainVNCActivity.class)); + overridePendingTransition(0, 0); + finish(); + }); + } else { + reconnect(); + } new Handler(Looper.getMainLooper()).postDelayed(this, 1000); } } @@ -836,9 +847,13 @@ public class MainVNCActivity extends VncCanvasActivity { case MotionEvent.ACTION_DOWN: case MotionEvent.ACTION_POINTER_DOWN: if (pointerCount == 3) { - MotionEvent e = MotionEvent.obtain(1000, 1000, MotionEvent.ACTION_DOWN, vncCanvas.mouseX, vncCanvas.mouseY, - 0); - ((TouchpadInputHandler) VncCanvasActivity.inputHandler).middleClick(e); + try { + MotionEvent e = MotionEvent.obtain(1000, 1000, MotionEvent.ACTION_DOWN, vncCanvas.mouseX, vncCanvas.mouseY, + 0); + ((TouchpadInputHandler) VncCanvasActivity.inputHandler).middleClick(e); + } catch (Exception e) { + VMManager.sendMiddleMouseKey(); + } } else if (pointerCount == 2) { MotionEvent e = MotionEvent.obtain(1000, 1000, MotionEvent.ACTION_DOWN, vncCanvas.mouseX, vncCanvas.mouseY, 0); @@ -1056,9 +1071,13 @@ public class MainVNCActivity extends VncCanvasActivity { }); bindingDesktopControls.rightClickBtn.setOnClickListener(v -> { - MotionEvent e = MotionEvent.obtain(1000, 1000, MotionEvent.ACTION_DOWN, vncCanvas.mouseX, vncCanvas.mouseY, - 0); - ((TouchpadInputHandler) VncCanvasActivity.inputHandler).rightClick(e); + try { + MotionEvent e = MotionEvent.obtain(1000, 1000, MotionEvent.ACTION_DOWN, vncCanvas.mouseX, vncCanvas.mouseY, + 0); + ((TouchpadInputHandler) VncCanvasActivity.inputHandler).rightClick(e); + } catch (Exception e) { + VMManager.sendRightMouseKey(); + } }); bindingDesktopControls.middleBtn.setOnClickListener(v -> { diff --git a/app/src/main/java/com/vectras/vm/MainService.java b/app/src/main/java/com/vectras/vm/MainService.java index 594ced0..5772ab7 100644 --- a/app/src/main/java/com/vectras/vm/MainService.java +++ b/app/src/main/java/com/vectras/vm/MainService.java @@ -29,6 +29,7 @@ public class MainService extends Service { super.onCreate(); service = this; createNotificationChannel(); + Intent stopSelf = new Intent(this, MainService.class); stopSelf.setAction("STOP"); PendingIntent pStopSelf = PendingIntent.getService( @@ -42,15 +43,16 @@ public class MainService extends Service { .addAction(R.drawable.round_logout_24, "Stop", pStopSelf) .build(); + startForeground(NOTIFICATION_ID, notification); + if (env != null) { if (service != null) { Terminal vterm = new Terminal(activityContext); vterm.executeShellCommand2(env, true, activityContext); } - } else + } else { Log.e(TAG, "env is null"); - - startForeground(NOTIFICATION_ID, notification); + } } public static void stopService() { diff --git a/app/src/main/java/com/vectras/vm/RomInfo.java b/app/src/main/java/com/vectras/vm/RomInfo.java index 663222b..1ec5f8d 100644 --- a/app/src/main/java/com/vectras/vm/RomInfo.java +++ b/app/src/main/java/com/vectras/vm/RomInfo.java @@ -29,6 +29,7 @@ import com.vectras.vm.network.RequestNetworkController; import com.vectras.vm.utils.DialogUtils; import com.vectras.vm.utils.FileUtils; import com.vectras.vm.utils.ImageUtils; +import com.vectras.vm.utils.JSONUtils; import java.io.File; import java.io.IOException; @@ -327,7 +328,7 @@ public class RomInfo extends AppCompatActivity { @Override public void onResponse(String tag, String response, HashMap responseHeaders) { Log.i(TAG, response); - if (!response.isEmpty()) { + if (!response.isEmpty() && JSONUtils.isValidFromString(response)) { HashMap map = new Gson().fromJson( response, new TypeToken>() { }.getType() diff --git a/app/src/main/java/com/vectras/vm/VMCreatorActivity.java b/app/src/main/java/com/vectras/vm/VMCreatorActivity.java index aedfe38..c04afb2 100644 --- a/app/src/main/java/com/vectras/vm/VMCreatorActivity.java +++ b/app/src/main/java/com/vectras/vm/VMCreatorActivity.java @@ -230,7 +230,7 @@ public class VMCreatorActivity extends AppCompatActivity { binding.collapsingToolbarLayout.setTitle(getString(R.string.edit)); created = true; binding.addRomBtn.setText(R.string.save_changes); - binding.title.setText(current.itemName); + if (current.itemName != null) binding.title.setText(current.itemName); binding.drive.setText(current.itemPath); binding.cdrom.setText(current.imgCdrom); thumbnailPath = current.itemIcon; diff --git a/app/src/main/java/com/vectras/vm/VMManager.java b/app/src/main/java/com/vectras/vm/VMManager.java index 18dd3e2..5cab167 100644 --- a/app/src/main/java/com/vectras/vm/VMManager.java +++ b/app/src/main/java/com/vectras/vm/VMManager.java @@ -245,6 +245,9 @@ public class VMManager { listmapForRemoveVM.clear(); listmapForRemoveVM = new Gson().fromJson(pendingJsonContent, new TypeToken>>() { }.getType()); + + if (pendingPosition > listmapForCreateNewVM.size() - 1) return; + if (listmapForRemoveVM.get(pendingPosition).containsKey("vmID")) { pendingVMID = Objects.requireNonNull(listmapForRemoveVM.get(pendingPosition).get("vmID")).toString(); FileUtils.deleteDirectory(Config.getCacheDir() + "/" + pendingVMID); @@ -1231,6 +1234,30 @@ public class VMManager { }).start(); } + public static void sendRightMouseKey() { + new Thread(() -> { + try { + keyDown("right"); + Thread.sleep(50); + keyUp("right"); + } catch (InterruptedException e) { + Log.d(TAG, "sendRightMouseKey: " + e.getMessage()); + } + }).start(); + } + + public static void sendMiddleMouseKey() { + new Thread(() -> { + try { + keyDown("middle"); + Thread.sleep(50); + keyUp("middle"); + } catch (InterruptedException e) { + Log.d(TAG, "sendMiddleMouseKey: " + e.getMessage()); + } + }).start(); + } + public static void keyDown(String key) { QmpClient.sendCommand(sendKeyCommand(key, true)); } diff --git a/app/src/main/java/com/vectras/vm/main/MainActivity.java b/app/src/main/java/com/vectras/vm/main/MainActivity.java index 2d99c97..f89fe5e 100644 --- a/app/src/main/java/com/vectras/vm/main/MainActivity.java +++ b/app/src/main/java/com/vectras/vm/main/MainActivity.java @@ -27,6 +27,7 @@ import androidx.appcompat.app.AppCompatActivity; import androidx.coordinatorlayout.widget.CoordinatorLayout; import androidx.core.view.GravityCompat; import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; import androidx.recyclerview.widget.LinearLayoutManager; import com.google.android.material.behavior.HideViewOnScrollBehavior; @@ -234,9 +235,12 @@ public class MainActivity extends AppCompatActivity implements RomStoreFragment. bindingContent.searchbar.setEnabled(false); } - getSupportFragmentManager().beginTransaction() - .replace(bindingContent.containerView.getId(), selectedFragment) - .commit(); + FragmentManager fragmentManager = getSupportFragmentManager(); + if (!fragmentManager.isStateSaved()) { + fragmentManager.beginTransaction() + .replace(bindingContent.containerView.getId(), selectedFragment) + .commit(); + } currentBottomBarSelectedItemId = id; return true; }); diff --git a/app/src/main/java/com/vectras/vm/main/core/MainStartVM.java b/app/src/main/java/com/vectras/vm/main/core/MainStartVM.java index fb5c4ee..82a6595 100644 --- a/app/src/main/java/com/vectras/vm/main/core/MainStartVM.java +++ b/app/src/main/java/com/vectras/vm/main/core/MainStartVM.java @@ -2,6 +2,7 @@ package com.vectras.vm.main.core; import static android.os.Build.VERSION.SDK_INT; +import android.app.Activity; import android.content.Context; import android.content.Intent; import android.os.Build; @@ -228,7 +229,13 @@ public class MainStartVM { if (isStopNow || VMManager.isQemuStopedWithError || FileUtils.isFileExists(Config.getLocalQMPSocketPath())) { handlerForLaunch.removeCallbacks(this); - progressDialog.dismiss(); + if (context instanceof Activity activity) { + if (!activity.isFinishing() && !activity.isDestroyed()) { + if (progressDialog != null && progressDialog.isShowing()) { + progressDialog.dismiss(); + } + } + } if (!isStopNow && !VMManager.isQemuStopedWithError) { if (MainSettingsManager.getVmUi(context).equals("VNC")) { diff --git a/app/src/main/java/com/vectras/vm/settings/X11DisplaySettingsActivity.java b/app/src/main/java/com/vectras/vm/settings/X11DisplaySettingsActivity.java index a26aade..6b3fe57 100644 --- a/app/src/main/java/com/vectras/vm/settings/X11DisplaySettingsActivity.java +++ b/app/src/main/java/com/vectras/vm/settings/X11DisplaySettingsActivity.java @@ -59,6 +59,7 @@ public class X11DisplaySettingsActivity extends AppCompatActivity { intent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK); } else { DialogUtils.needInstallTermuxX11(this); + return; } } startActivity(intent); diff --git a/web/data/UpdateConfig.json b/web/data/UpdateConfig.json index ac7e517..aa52dcf 100644 --- a/web/data/UpdateConfig.json +++ b/web/data/UpdateConfig.json @@ -5,11 +5,11 @@ "url": "https://github.com/xoureldeen/Vectras-VM-Android/releases", "Message": "

3.5.0

\n3dfx is back!", "cancellable": true, - "versionCodeBeta":"62", - "versionNameBeta":"3.5.8", - "versionNameBetas":"3.0.0,3.1.0,3.2.1,3.2.2,3.2.3,3.2.4,3.2.5,3.2.6,3.2.7,3.2.8,3.2.9,3.2.10,3.3.1,3.3.2,3.3.3,3.3.4,3.3.5,3.3.6,3.3.7,3.3.8,3.3.9,3.4.1,3.4.2,3.4.3,3.4.4,3.4.5,3.4.6,3.4.7,3.4.8,3.4.9,3.5.1,3.5.2,3.5.3,3.5.4,3.5.5,3.5.6,3.5.7,3.5.8", + "versionCodeBeta":"63", + "versionNameBeta":"3.5.9", + "versionNameBetas":"3.0.0,3.1.0,3.2.1,3.2.2,3.2.3,3.2.4,3.2.5,3.2.6,3.2.7,3.2.8,3.2.9,3.2.10,3.3.1,3.3.2,3.3.3,3.3.4,3.3.5,3.3.6,3.3.7,3.3.8,3.3.9,3.4.1,3.4.2,3.4.3,3.4.4,3.4.5,3.4.6,3.4.7,3.4.8,3.4.9,3.5.1,3.5.2,3.5.3,3.5.4,3.5.5,3.5.6,3.5.7,3.5.8,3.5.9", "sizeBeta": "43 MB", "urlBeta": "https://github.com/AnBui2004/Vectras-VM-Emu-Android/releases", - "MessageBeta": "

3.5.8

Bugs fixed.", + "MessageBeta": "

3.5.9

Bugs fixed.", "cancellableBeta": true }