This commit is contained in:
An Bui 2025-06-24 19:50:04 +07:00
parent ae20fc8b46
commit e96c24cf48
11 changed files with 315 additions and 123 deletions

View file

@ -11,6 +11,7 @@ import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
import androidx.activity.EdgeToEdge;
@ -19,6 +20,7 @@ import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
import com.google.android.material.progressindicator.LinearProgressIndicator;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.vectras.vm.utils.FileUtils;
@ -34,9 +36,13 @@ import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Objects;
import java.util.Timer;
import java.util.TimerTask;
public class ExportRomActivity extends AppCompatActivity {
private Timer _timer = new Timer();
private TimerTask timerTask;
private LinearLayout linearone;
private LinearLayout linearload;
private LinearLayout lineardone;
@ -53,6 +59,14 @@ public class ExportRomActivity extends AppCompatActivity {
public String iconfile = "";
public String diskfile = "";
public String cdromfile = "";
private int folderSize = 0;
private int zipFileSize = 0;
private double zipprogress = 0;
private double zipprogresslast = 0;
private double folderSizeMB = 0;
private LinearProgressIndicator progressBar;
private TextView textviewsettingup;
@Override
protected void onCreate(Bundle savedInstanceState) {
@ -69,6 +83,8 @@ public class ExportRomActivity extends AppCompatActivity {
textviewerrorcontent = findViewById(R.id.textviewerrorcontent);
editauthor = findViewById(R.id.edittext1);
editdesc = findViewById(R.id.edittext2);
progressBar = findViewById(R.id.linearprogress);
textviewsettingup = findViewById(R.id.textviewsettingup);
Button buttondone;
buttondone = findViewById(R.id.materialbutton1);
@ -208,6 +224,39 @@ public class ExportRomActivity extends AppCompatActivity {
FileUtils.writeToFile(new File(String.valueOf(getApplicationContext().getExternalFilesDir("data"))).getPath(), "rom-data.json", new Gson().toJson(mapForGetData));
folderSize = FileUtils.getFolderSize(getRomPath);
folderSizeMB = (folderSize / (1024 * 10.24)) / 2;
timerTask = new TimerTask() {
@Override
public void run() {
runOnUiThread(new Runnable() {
@Override
public void run() {
zipFileSize = FileUtils.getFileSize(FileUtils.getExternalFilesDirectory(getApplicationContext()).getPath() + "/cvbi/" + Objects.requireNonNull(mapForGetData.get("title")).toString() + ".cvbi");
double zipFileSizeMB = zipFileSize / (1024 * 1024);
double currentProgress = (100 / folderSizeMB) * zipFileSizeMB;
if ((100 / folderSizeMB) * zipFileSizeMB < 0) {
if ((int)currentProgress != (int)zipprogresslast) {
zipprogress++ ;
}
} else {
zipprogress = currentProgress;
}
if (zipprogress > 99) {
zipprogress = 99;
}
zipprogresslast = currentProgress;
if (folderSize > 0 || zipFileSize > 0) {
progressBar.setProgressCompat((int) zipprogress, true);
textviewsettingup.setText(String.valueOf((int) zipprogress) + "% completed.");
}
}
});
}
};
_timer.schedule(timerTask, 0, 1000);
Thread t = new Thread() {
@Override
public void run() {
@ -270,6 +319,9 @@ public class ExportRomActivity extends AppCompatActivity {
@Override
public void run() {
UIControler(1, FileUtils.getExternalFilesDirectory(getApplicationContext()).getPath() + "/cvbi/" + Objects.requireNonNull(mapForGetData.get("title")).toString() + ".cvbi");
if (timerTask != null) {
timerTask.cancel();
}
}
});
} catch (Exception e) {

View file

@ -30,6 +30,7 @@ import com.google.android.gms.ads.initialization.InitializationStatus;
import com.google.android.gms.ads.initialization.OnInitializationCompleteListener;
import com.google.android.gms.ads.interstitial.InterstitialAd;
import com.google.android.gms.ads.interstitial.InterstitialAdLoadCallback;
import com.vectras.vm.utils.DialogUtils;
import com.vectras.vm.utils.FileUtils;
import java.io.InputStream;
import java.io.OutputStream;
@ -286,17 +287,8 @@ public class StoreItemActivity extends AppCompatActivity {
@Override
protected void onPostExecute(String unused) {
dismissDialog(DIALOG_DOWNLOAD_PROGRESS);
AlertDialog ad;
ad = new AlertDialog.Builder(activity, R.style.MainDialogTheme).create();
ad.setTitle(getString(R.string.downloaded_successfully));
String fileName = URLUtil.guessFileName(link,null,null);
ad.setMessage(getString(R.string.downloaded_to_path)+AppConfig.downloadsFolder+fileName);
ad.setButton(Dialog.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
return;
}
});
ad.show();
DialogUtils.oneDialog(StoreItemActivity.this, getString(R.string.downloaded_successfully), getString(R.string.downloaded_to_path) + AppConfig.downloadsFolder + fileName, getString(R.string.ok), true, R.drawable.check_24px, true, null, null);
}
}

View file

@ -19,6 +19,7 @@ import com.google.gson.reflect.TypeToken;
import com.vectras.qemu.Config;
import com.vectras.qemu.MainSettingsManager;
import com.vectras.vm.MainRoms.AdapterMainRoms;
import com.vectras.vm.utils.DialogUtils;
import com.vectras.vm.utils.FileUtils;
import com.vectras.vm.utils.JSONUtils;
import com.vectras.vm.utils.UIUtils;
@ -105,61 +106,44 @@ public class VMManager {
}
public static void deleteVMDialog(String _vmName, int _position, Activity _activity) {
AlertDialog ad = new AlertDialog.Builder(_activity, R.style.MainDialogTheme).create();
ad.setTitle(_activity.getString(R.string.remove)+ " " + _vmName);
ad.setMessage(_activity.getString(R.string.are_you_sure));
ad.setButton(Dialog.BUTTON_NEGATIVE, _activity.getString(R.string.remove) + " " + _vmName, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
pendingPosition = _position;
pendingJsonContent = FileUtils.readAFile(AppConfig.maindirpath + "roms-data.json");
pendingPosition = _position;
pendingJsonContent = FileUtils.readAFile(AppConfig.maindirpath + "roms-data.json");
AlertDialog alertDialog = new AlertDialog.Builder(MainActivity.activity, R.style.MainDialogTheme).create();
alertDialog.setTitle(_activity.getString(R.string.keep_files_question_mark));
alertDialog.setMessage(_activity.getString(R.string.do_you_want_to_keep_this_ROM_file_and_CD_ROM_file));
alertDialog.setCancelable(false);
alertDialog.setButton(DialogInterface.BUTTON_POSITIVE, _activity.getString(R.string.keep), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
hideVMIDWithPosition();
}
});
alertDialog.setButton(DialogInterface.BUTTON_NEGATIVE, _activity.getString(R.string.remove_all), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
isKeptSomeFiles = false;
deleteVM();
DialogUtils.threeDialog(_activity, _activity.getString(R.string.remove)+ " " + _vmName, _activity.getString(R.string.remove_vm_content), _activity.getString(R.string.remove_and_do_not_keep_files), _activity.getString(R.string.remove_but_keep_files), _activity.getString(R.string.cancel),true, R.drawable.delete_24px, true,
() -> {
isKeptSomeFiles = false;
deleteVM();
removeInRomsDataJson(_activity, _vmName, _position);
},
() -> {
hideVMIDWithPosition();
removeInRomsDataJson(_activity, _vmName, _position);
},
() -> {
if (isKeptSomeFiles && FileUtils.readAFile(AppConfig.maindirpath + "roms-data.json").contains("{")) {
UIUtils.oneDialog(_activity.getString(R.string.keep), _activity.getString(R.string.kept_some_files), true, false, _activity);
}
}
});
alertDialog.show();
},
null);
}
MainActivity.mMainAdapter = new AdapterMainRoms(MainActivity.activity, MainActivity.data);
MainActivity.data.remove(_position);
MainActivity.mRVMainRoms.setAdapter(MainActivity.mMainAdapter);
MainActivity.mRVMainRoms.setLayoutManager(new GridLayoutManager(MainActivity.activity, 2));
MainActivity.jArray.remove(_position);
try {
Writer output = null;
File jsonFile = new File(AppConfig.maindirpath + "roms-data" + ".json");
output = new BufferedWriter(new FileWriter(jsonFile));
output.write(MainActivity.jArray.toString());
output.close();
} catch (Exception e) {
UIUtils.toastLong(_activity, e.toString());
}
UIUtils.toastLong(_activity, _vmName + _activity.getString(R.string.are_removed_successfully));
if (!FileUtils.readAFile(AppConfig.maindirpath + "roms-data.json").contains("{")) {
MainActivity.mdatasize2();
}
}
});
ad.setButton(Dialog.BUTTON_POSITIVE, _activity.getString(R.string.cancel), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
ad.dismiss();
}
});
ad.show();
public static void removeInRomsDataJson(Activity _activity, String _vmName, int _position) {
MainActivity.mMainAdapter = new AdapterMainRoms(MainActivity.activity, MainActivity.data);
MainActivity.data.remove(_position);
MainActivity.mRVMainRoms.setAdapter(MainActivity.mMainAdapter);
MainActivity.mRVMainRoms.setLayoutManager(new GridLayoutManager(MainActivity.activity, 2));
MainActivity.jArray.remove(_position);
try {
Writer output = null;
File jsonFile = new File(AppConfig.maindirpath + "roms-data" + ".json");
output = new BufferedWriter(new FileWriter(jsonFile));
output.write(MainActivity.jArray.toString());
output.close();
} catch (Exception e) {
UIUtils.toastLong(_activity, e.toString());
}
UIUtils.toastLong(_activity, _vmName + _activity.getString(R.string.are_removed_successfully));
if (!FileUtils.readAFile(AppConfig.maindirpath + "roms-data.json").contains("{")) {
MainActivity.mdatasize2();
}
}
public static String idGenerator() {
@ -621,55 +605,35 @@ public class VMManager {
return true;
//Error code: PROOT_IS_MISSING_0
if (_result.contains("proot\": error=2,")) {
AlertDialog alertDialog = new AlertDialog.Builder(_activity, R.style.MainDialogTheme).create();
alertDialog.setTitle(_activity.getResources().getString(R.string.problem_has_been_detected));
alertDialog.setMessage(_activity.getResources().getString(R.string.error_PROOT_IS_MISSING_0));
alertDialog.setCancelable(false);
alertDialog.setButton(DialogInterface.BUTTON_POSITIVE, _activity.getResources().getString(R.string.continuetext), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
MainActivity.isActivate = false;
FileUtils.deleteDirectory(_activity.getFilesDir().getAbsolutePath() + "/data");
FileUtils.deleteDirectory(_activity.getFilesDir().getAbsolutePath() + "/distro");
FileUtils.deleteDirectory(_activity.getFilesDir().getAbsolutePath() + "/usr");
Intent intent = new Intent();
intent.setClass(_activity, SplashActivity.class);
_activity.startActivity(intent);
_activity.finish();
}
});
alertDialog.setButton(DialogInterface.BUTTON_NEGATIVE, _activity.getResources().getString(R.string.cancel), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
}
});
alertDialog.show();
DialogUtils.twoDialog(_activity, _activity.getResources().getString(R.string.problem_has_been_detected), _activity.getResources().getString(R.string.error_PROOT_IS_MISSING_0), _activity.getString(R.string.continuetext), _activity.getString(R.string.cancel), true, R.drawable.build_24px, true,
() -> {
MainActivity.isActivate = false;
FileUtils.deleteDirectory(_activity.getFilesDir().getAbsolutePath() + "/data");
FileUtils.deleteDirectory(_activity.getFilesDir().getAbsolutePath() + "/distro");
FileUtils.deleteDirectory(_activity.getFilesDir().getAbsolutePath() + "/usr");
Intent intent = new Intent();
intent.setClass(_activity, SplashActivity.class);
_activity.startActivity(intent);
_activity.finish();
},
null, null);
return true;
} else if (_result.contains(") exists") && _result.contains("drive with bus")) {
//Error code: DRIVE_INDEX_0_EXISTS
UIUtils.oneDialog(_activity.getResources().getString(R.string.problem_has_been_detected), _activity.getResources().getString(R.string.error_DRIVE_INDEX_0_EXISTS), true, false, _activity);
DialogUtils.oneDialog(_activity, _activity.getString(R.string.problem_has_been_detected), _activity.getString(R.string.error_DRIVE_INDEX_0_EXISTS), _activity.getString(R.string.ok),true, R.drawable.hard_drive_24px, true,null, null);
return true;
} else if (_result.contains("gtk initialization failed") || _result.contains("x11 not available")) {
//Error code: X11_NOT_AVAILABLE
AlertDialog alertDialog = new AlertDialog.Builder(_activity, R.style.MainDialogTheme).create();
alertDialog.setTitle(_activity.getResources().getString(R.string.problem_has_been_detected));
alertDialog.setMessage(_activity.getResources().getString(R.string.error_X11_NOT_AVAILABLE));
alertDialog.setCancelable(false);
alertDialog.setButton(DialogInterface.BUTTON_POSITIVE, _activity.getResources().getString(R.string.continuetext), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
MainSettingsManager.setVmUi(_activity, "VNC");
UIUtils.oneDialog(_activity.getResources().getString(R.string.done), _activity.getResources().getString(R.string.switched_to_VNC), true, false, _activity);
}
});
alertDialog.setButton(DialogInterface.BUTTON_NEGATIVE, _activity.getResources().getString(R.string.cancel), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
}
});
alertDialog.show();
DialogUtils.twoDialog(_activity, _activity.getString(R.string.problem_has_been_detected), _activity.getString(R.string.error_X11_NOT_AVAILABLE), _activity.getString(R.string.continuetext), _activity.getString(R.string.cancel), true, R.drawable.cast_24px, true,
() -> {
MainSettingsManager.setVmUi(_activity, "VNC");
DialogUtils.oneDialog(_activity, _activity.getString(R.string.done), _activity.getString(R.string.switched_to_VNC), _activity.getString(R.string.ok),true, R.drawable.check_24px, true,null, null);
},
null, null);
return true;
} else if (_result.contains("No such file or directory1")) {
} else if (_result.contains("No such file or directory")) {
//Error code: NO_SUCH_FILE_OR_DIRECTORY
UIUtils.oneDialog(_activity.getResources().getString(R.string.problem_has_been_detected), _activity.getResources().getString(R.string.error_NO_SUCH_FILE_OR_DIRECTORY), true, false, _activity);
DialogUtils.oneDialog(_activity, _activity.getString(R.string.problem_has_been_detected), _activity.getString(R.string.error_NO_SUCH_FILE_OR_DIRECTORY), _activity.getString(R.string.ok),true, R.drawable.file_copy_24px, true,null, null);
_activity.stopService(new Intent(_activity, MainService.class));
return true;
} else {
@ -677,25 +641,18 @@ public class VMManager {
}
}
public static boolean isRomsDataJsonNormal(Boolean _needfix, Context _context) {
public static boolean isRomsDataJsonNormal(Boolean _needfix, Activity _context) {
if (isFileExists(AppConfig.romsdatajson)) {
if (!JSONUtils.isValidFromFile(AppConfig.romsdatajson)) {
if (_needfix) {
AlertDialog alertDialog = new AlertDialog.Builder(_context, R.style.MainDialogTheme).create();
alertDialog.setTitle(_context.getResources().getString(R.string.oops));
alertDialog.setMessage(_context.getResources().getString(R.string.need_fix_json_before_create));
alertDialog.setCancelable(true);
alertDialog.setButton(DialogInterface.BUTTON_POSITIVE, _context.getResources().getString(R.string.continuetext), (dialog, which) -> {
FileUtils.moveAFile(AppConfig.maindirpath + "roms-data.json", AppConfig.maindirpath + "roms-data.old.json");
FileUtils.writeToFile(AppConfig.maindirpath, "roms-data.json", "[]");
startFixRomsDataJson();
fixRomsDataJsonResult(_context);
});
alertDialog.setButton(DialogInterface.BUTTON_NEGATIVE, _context.getResources().getString(R.string.cancel), (dialog, which) -> {
});
alertDialog.show();
DialogUtils.twoDialog(_context, _context.getString(R.string.problem_has_been_detected), _context.getString(R.string.need_fix_json_before_create), _context.getString(R.string.continuetext), _context.getString(R.string.cancel), true, R.drawable.build_24px, true,
() -> {
FileUtils.moveAFile(AppConfig.maindirpath + "roms-data.json", AppConfig.maindirpath + "roms-data.old.json");
FileUtils.writeToFile(AppConfig.maindirpath, "roms-data.json", "[]");
startFixRomsDataJson();
fixRomsDataJsonResult(_context);
},
null, null);
}
return false;
} else {
@ -707,11 +664,11 @@ public class VMManager {
}
}
public static void fixRomsDataJsonResult(Context _context) {
public static void fixRomsDataJsonResult(Activity _context) {
if (restoredVMs == 0) {
UIUtils.oneDialogWithContext(_context.getString(R.string.done), _context.getString(R.string.roms_data_json_fixed_unsuccessfully),true, _context);
DialogUtils.oneDialog(_context, _context.getString(R.string.done), _context.getString(R.string.roms_data_json_fixed_unsuccessfully), _context.getString(R.string.ok),true, R.drawable.error_96px, true,null, null);
} else {
UIUtils.oneDialogWithContext(_context.getString(R.string.done), _context.getString(R.string.roms_data_json_fixed_successfully),true, _context);
DialogUtils.oneDialog(_context, _context.getString(R.string.done), _context.getString(R.string.roms_data_json_fixed_successfully), _context.getString(R.string.ok),true, R.drawable.check_24px, true,null, null);
}
MainActivity.loadDataVbi();
MainActivity.mdatasize2();

View file

@ -0,0 +1,98 @@
package com.vectras.vm.utils;
import android.app.Activity;
import android.content.DialogInterface;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
public class DialogUtils {
public static void oneDialog(Activity _context, String _title, String _message, String _textPositiveButton, boolean _isicon, int _iconid, boolean _cancel, Runnable _onPositive, Runnable _onDismiss) {
MaterialAlertDialogBuilder dialog = new MaterialAlertDialogBuilder(_context);
dialog.setTitle(_title);
dialog.setMessage(_message);
if (_isicon) {
dialog.setIcon(_iconid);
}
if (!_cancel) {
dialog.setCancelable(false);
}
dialog.setPositiveButton(_textPositiveButton, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (_onPositive != null) _onPositive.run();
dialog.dismiss();
}
});
dialog.setOnDismissListener(dialog1 -> {
if (_onDismiss != null) _onDismiss.run();
});
dialog.show();
}
public static void twoDialog(Activity _context, String _title, String _message, String _textPositiveButton, String _textNegativeButton, boolean _isicon, int _iconid, boolean _cancel, Runnable _onPositive, Runnable _onNegative, Runnable _onDismiss) {
MaterialAlertDialogBuilder dialog = new MaterialAlertDialogBuilder(_context);
dialog.setTitle(_title);
dialog.setMessage(_message);
if (_isicon) {
dialog.setIcon(_iconid);
}
if (!_cancel) {
dialog.setCancelable(false);
}
dialog.setPositiveButton(_textPositiveButton, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (_onPositive != null) _onPositive.run();
dialog.dismiss();
}
});
dialog.setNegativeButton(_textNegativeButton, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (_onNegative != null) _onNegative.run();
dialog.dismiss();
}
});
dialog.setOnDismissListener(dialog1 -> {
if (_onDismiss != null) _onDismiss.run();
});
dialog.show();
}
public static void threeDialog(Activity _context, String _title, String _message, String _textPositiveButton, String _textNegativeButton, String _textNeutralButton ,boolean _isicon, int _iconid, boolean _cancel, Runnable _onPositive, Runnable _onNegative, Runnable _onNeutral, Runnable _onDismiss) {
MaterialAlertDialogBuilder dialog = new MaterialAlertDialogBuilder(_context);
dialog.setTitle(_title);
dialog.setMessage(_message);
if (_isicon) {
dialog.setIcon(_iconid);
}
if (!_cancel) {
dialog.setCancelable(false);
}
dialog.setPositiveButton(_textPositiveButton, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (_onPositive != null) _onPositive.run();
dialog.dismiss();
}
});
dialog.setNegativeButton(_textNegativeButton, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (_onNegative != null) _onNegative.run();
dialog.dismiss();
}
});
dialog.setNeutralButton(_textNeutralButton, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (_onNeutral != null) _onNeutral.run();
dialog.dismiss();
}
});
dialog.setOnDismissListener(dialog1 -> {
if (_onDismiss != null) _onDismiss.run();
});
dialog.show();
}
}

View file

@ -22,6 +22,7 @@ import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import android.app.Activity;
@ -733,4 +734,48 @@ public class FileUtils {
list.add(file.getAbsolutePath());
}
}
public static int getFileSize (String _path) {
try {
File file = new File(_path);
return (int) file.length();
} catch (Exception _e) {
return 0;
}
}
public static int getFolderSize(String _path) {
try {
File file;
file = new File(_path);
if (file == null || !file.exists()) {
return 0;
}
if (!file.isDirectory()) {
return (int) file.length();
}
final List<File> dirs = new LinkedList<>();
dirs.add(file);
long result = 0;
while (!dirs.isEmpty()) {
final File dir = dirs.remove(0);
if (!dir.exists()) {
continue;
}
final File[] listFiles = dir.listFiles();
if (listFiles == null || listFiles.length == 0) {
continue;
}
for (final File child : listFiles) {
result += child.length();
if (child.isDirectory()) {
dirs.add(child);
}
}
}
return (int) result;
} catch (Exception _e) {
return 0;
}
}
}