v2.9.5.5-3dfx

- Rounded corners if the search list in Rom store has only 1 result.
- Removed the possibility of memory leak in Rom store and in VM creator.
- Reduced errors when selecting files in unexpected places and errors when getting file path in VM creator.
- Show error dialog when invalid file path in VM creator.
- When selecting thumbnail in VM creator, it opens image picker instead of selecting file.
- Thumbnails are now forced to be copied to VM instead of used directly outside even if Copy file is disabled in Settings.
- When selecting Mouse mode in VNC screen, it opens mode selection dialog directly instead of opening UI Mode dialog.
This commit is contained in:
An Bui 2025-08-28 14:18:41 +07:00
parent 8daa483e3d
commit 899802f2de
16 changed files with 838 additions and 1169 deletions

View file

@ -38,17 +38,14 @@ public class CqcmActivity extends AppCompatActivity {
setContentView(R.layout.activity_cqcm);
UIUtils.setOnApplyWindowInsetsListener(findViewById(R.id.main));
buttonallow = findViewById(R.id.buttonallow);
buttonallow.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (shouldShowRequestPermissionRationale(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
intent.setData(Uri.parse("package:" + getPackageName()));
startActivity(intent);
Toast.makeText(getApplicationContext(), getResources().getString(R.string.find_and_allow_access_to_storage_in_settings), Toast.LENGTH_LONG).show();
} else {
ActivityCompat.requestPermissions(CqcmActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1000);
}
buttonallow.setOnClickListener(v -> {
if (shouldShowRequestPermissionRationale(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
intent.setData(Uri.parse("package:" + getPackageName()));
startActivity(intent);
Toast.makeText(getApplicationContext(), getResources().getString(R.string.find_and_allow_access_to_storage_in_settings), Toast.LENGTH_LONG).show();
} else {
ActivityCompat.requestPermissions(CqcmActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1000);
}
});
}

File diff suppressed because it is too large Load diff

View file

@ -16,6 +16,7 @@ import android.widget.Button;
import android.widget.TextView;
import com.google.android.material.textfield.TextInputEditText;
import com.google.android.material.textfield.TextInputLayout;
import com.vectras.qemu.Config;
import com.vectras.vm.AppConfig;
import com.vectras.vm.CustomRomActivity;
@ -30,6 +31,9 @@ public class CreateImageDialogFragment extends DialogFragment {
public boolean customRom = false;
public String folder = AppConfig.vmFolder + CustomRomActivity.vmID + "/";
public String filename = "disk";
public TextInputEditText drive;
public TextInputLayout driveLayout;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
@ -53,14 +57,14 @@ public class CreateImageDialogFragment extends DialogFragment {
TextInputEditText imageName = view.findViewById(R.id.name);
if (customRom)
imageName.setText(CustomRomActivity.title.getText().toString());
imageName.setText(filename);
TextView createPath = view.findViewById(R.id.createPath);
createPath.setText(folder);
if (customRom)
createPath.append(CustomRomActivity.title.getText().toString() + ".qcow2");
createPath.append(filename + ".qcow2");
Button createQcow2Btn = view.findViewById(R.id.createQcow2Btn);
@ -91,26 +95,23 @@ public class CreateImageDialogFragment extends DialogFragment {
imageName.addTextChangedListener(afterTextChangedListener);
imageSize.addTextChangedListener(afterTextChangedListener);
createQcow2Btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
File vDir = new File(folder);
if (!vDir.exists()) {
vDir.mkdirs();
}
Terminal vterm = new Terminal(getActivity());
vterm.executeShellCommand("qemu-img create -f qcow2 \"" + folder + imageName.getText().toString() + ".qcow2\" " +
imageSize.getText().toString() + "G", true, getActivity());
if (customRom)
CustomRomActivity.drive.setText(folder + imageName.getText().toString() + ".qcow2");
try {
CustomRomActivity.driveLayout.setEndIconDrawable(R.drawable.more_vert_24px);
} catch (Exception e) {
throw new RuntimeException(e);
}
dismiss();
createQcow2Btn.setOnClickListener(v -> {
File vDir = new File(folder);
if (!vDir.exists()) {
vDir.mkdirs();
}
Terminal vterm = new Terminal(getActivity());
vterm.executeShellCommand("qemu-img create -f qcow2 \"" + folder + imageName.getText().toString() + ".qcow2\" " +
imageSize.getText().toString() + "G", true, getActivity());
if (customRom) {
if(drive != null)
drive.setText(folder + imageName.getText().toString() + ".qcow2");
if(driveLayout != null)
driveLayout.setEndIconDrawable(R.drawable.more_vert_24px);
}
dismiss();
});
builder.setView(view);

View file

@ -1,5 +1,6 @@
package com.vectras.vm.Roms;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
@ -20,7 +21,6 @@ import com.bumptech.glide.Glide;
import com.vectras.vm.AppConfig;
import com.vectras.vm.RomInfo;
import com.vectras.vm.RomsManagerActivity;
import com.vectras.vm.R;
import java.io.File;
@ -33,12 +33,14 @@ import java.util.Objects;
public class AdapterRomStoreSearch extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
Context context;
private final LayoutInflater inflater;
static List<DataRoms> dataRom = Collections.emptyList();
private final String TAG = "AdapterRomStoreSearch";
// create constructor to innitilize context and data sent from MainActivity
public AdapterRomStoreSearch(Context context, List<DataRoms> data) {
this.context = context;
inflater = LayoutInflater.from(context);
dataRom = data;
}
@ -52,13 +54,14 @@ public class AdapterRomStoreSearch extends RecyclerView.Adapter<RecyclerView.Vie
}
// Bind data
@SuppressLint("SetTextI18n")
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, final int position) {
// Get current position of item in recyclerview to bind data and assign values from list
final MyHolder myHolder = (MyHolder) holder;
final DataRoms current = dataRom.get(position);
Glide.with(RomsManagerActivity.activity).load(current.romIcon).placeholder(R.drawable.ic_computer_180dp_with_padding).error(R.drawable.ic_computer_180dp_with_padding).into(myHolder.ivIcon);
Glide.with(context).load(current.romIcon).placeholder(R.drawable.ic_computer_180dp_with_padding).error(R.drawable.ic_computer_180dp_with_padding).into(myHolder.ivIcon);
myHolder.textName.setText(current.romName);
myHolder.textSize.setText(current.romArch + " - " + current.fileSize);
if (current.romAvail) {
@ -66,7 +69,7 @@ public class AdapterRomStoreSearch extends RecyclerView.Adapter<RecyclerView.Vie
notifyItemRangeChanged(0, dataRom.size());
Intent intent = new Intent();
intent.setClass(RomsManagerActivity.activity, RomInfo.class);
intent.setClass(context, RomInfo.class);
intent.putExtra("title", current.romName);
intent.putExtra("shortdesc", current.romSize);
intent.putExtra("getrom", current.romUrl);
@ -79,7 +82,7 @@ public class AdapterRomStoreSearch extends RecyclerView.Adapter<RecyclerView.Vie
intent.putExtra("verified", current.verified);
intent.putExtra("creator", current.creator);
intent.putExtra("size", current.fileSize);
RomsManagerActivity.activity.startActivity(intent);
context.startActivity(intent);
if (!current.romPath.endsWith(".cvbi")) {
//Save image to icon folder
@ -109,16 +112,18 @@ public class AdapterRomStoreSearch extends RecyclerView.Adapter<RecyclerView.Vie
}
});
} else {
myHolder.textAvail.setText(RomsManagerActivity.sUnavailable);
myHolder.textAvail.setText(context.getString(R.string.unavailable));
myHolder.textAvail.setTextColor(Color.RED);
}
if (position == 0) {
myHolder.linearItem.setBackground(AppCompatResources.getDrawable(RomsManagerActivity.activity, R.drawable.object_shape_top_on_surface));
if (dataRom.size() == 1) {
myHolder.linearItem.setBackground(AppCompatResources.getDrawable(context, R.drawable.object_shape_single_on_surface));
} else if (position == 0) {
myHolder.linearItem.setBackground(AppCompatResources.getDrawable(context, R.drawable.object_shape_top_on_surface));
} else if (position == dataRom.size() - 1) {
myHolder.linearItem.setBackground(AppCompatResources.getDrawable(RomsManagerActivity.activity, R.drawable.object_shape_bottom_on_surface));
myHolder.linearItem.setBackground(AppCompatResources.getDrawable(context, R.drawable.object_shape_bottom_on_surface));
} else {
myHolder.linearItem.setBackground(AppCompatResources.getDrawable(RomsManagerActivity.activity, R.drawable.object_shape_middle_on_surface));
myHolder.linearItem.setBackground(AppCompatResources.getDrawable(context, R.drawable.object_shape_middle_on_surface));
}
}

View file

@ -1,5 +1,6 @@
package com.vectras.vm.Roms;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
@ -20,7 +21,6 @@ import com.bumptech.glide.Glide;
import com.vectras.vm.AppConfig;
import com.vectras.vm.RomInfo;
import com.vectras.vm.RomsManagerActivity;
import com.vectras.vm.R;
import java.io.File;
@ -33,12 +33,14 @@ import java.util.Objects;
public class AdapterRoms extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
Context context;
private final LayoutInflater inflater;
static List<DataRoms> dataRom = Collections.emptyList();
private final String TAG = "AdapterRoms";
// create constructor to innitilize context and data sent from MainActivity
public AdapterRoms(Context context, List<DataRoms> data) {
this.context = context;
inflater = LayoutInflater.from(context);
dataRom = data;
}
@ -52,13 +54,14 @@ public class AdapterRoms extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
}
// Bind data
@SuppressLint("SetTextI18n")
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, final int position) {
// Get current position of item in recyclerview to bind data and assign values from list
final MyHolder myHolder = (MyHolder) holder;
final DataRoms current = dataRom.get(position);
Glide.with(RomsManagerActivity.activity).load(current.romIcon).placeholder(R.drawable.ic_computer_180dp_with_padding).error(R.drawable.ic_computer_180dp_with_padding).into(myHolder.ivIcon);
Glide.with(context).load(current.romIcon).placeholder(R.drawable.ic_computer_180dp_with_padding).error(R.drawable.ic_computer_180dp_with_padding).into(myHolder.ivIcon);
myHolder.textName.setText(current.romName);
myHolder.textSize.setText(current.romArch + " - " + current.fileSize);
if (current.romAvail) {
@ -66,7 +69,7 @@ public class AdapterRoms extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
notifyItemRangeChanged(0, dataRom.size());
Intent intent = new Intent();
intent.setClass(RomsManagerActivity.activity, RomInfo.class);
intent.setClass(context, RomInfo.class);
intent.putExtra("title", current.romName);
intent.putExtra("shortdesc", current.romSize);
intent.putExtra("getrom", current.romUrl);
@ -79,7 +82,7 @@ public class AdapterRoms extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
intent.putExtra("verified", current.verified);
intent.putExtra("creator", current.creator);
intent.putExtra("size", current.fileSize);
RomsManagerActivity.activity.startActivity(intent);
context.startActivity(intent);
if (!current.romPath.endsWith(".cvbi")) {
//Save image to icon folder
@ -109,16 +112,18 @@ public class AdapterRoms extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
}
});
} else {
myHolder.textAvail.setText(RomsManagerActivity.sUnavailable);
myHolder.textAvail.setText(context.getString(R.string.unavailable));
myHolder.textAvail.setTextColor(Color.RED);
}
if (position == 0) {
myHolder.linearItem.setBackground(AppCompatResources.getDrawable(RomsManagerActivity.activity, R.drawable.object_shape_top));
if (dataRom.size() == 1) {
myHolder.linearItem.setBackground(AppCompatResources.getDrawable(context, R.drawable.object_shape_single));
} else if (position == 0) {
myHolder.linearItem.setBackground(AppCompatResources.getDrawable(context, R.drawable.object_shape_top));
} else if (position == dataRom.size() - 1) {
myHolder.linearItem.setBackground(AppCompatResources.getDrawable(RomsManagerActivity.activity, R.drawable.object_shape_bottom));
myHolder.linearItem.setBackground(AppCompatResources.getDrawable(context, R.drawable.object_shape_bottom));
} else {
myHolder.linearItem.setBackground(AppCompatResources.getDrawable(RomsManagerActivity.activity, R.drawable.object_shape_middle));
myHolder.linearItem.setBackground(AppCompatResources.getDrawable(context, R.drawable.object_shape_middle));
}
}

View file

@ -1,5 +1,6 @@
package com.vectras.vm;
import android.annotation.SuppressLint;
import android.os.Build;
import android.os.Bundle;
import android.os.StrictMode;
@ -9,22 +10,16 @@ import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.search.SearchBar;
import com.google.android.material.search.SearchView;
import com.google.common.reflect.TypeToken;
import com.google.gson.Gson;
import com.vectras.vm.Roms.AdapterRomStoreSearch;
import com.vectras.vm.Roms.AdapterRoms;
import com.vectras.vm.Roms.DataRoms;
import com.vectras.vm.databinding.ActivityRomsManagerBinding;
import com.vectras.vm.utils.UIUtils;
import java.lang.reflect.Type;
@ -35,22 +30,14 @@ import java.util.stream.Collectors;
public class RomsManagerActivity extends AppCompatActivity {
ActivityRomsManagerBinding binding;
private RequestNetwork net;
private RequestNetwork.RequestListener _net_request_listener;
private String contentJSON = "[]";
public static RomsManagerActivity activity;
public static String license;
private SearchView searchView;
private RecyclerView romsSearch;
private AdapterRoms mAdapter;
private AdapterRomStoreSearch mAdapterSearch;
private List<DataRoms> data = new ArrayList<>();
private List<DataRoms> dataSearch = new ArrayList<>();
private LinearLayout linearload;
private LinearLayout linearnothinghere;
public static String sAvailable = "";
public static String sUnavailable = "";
public static String sInstalled = "";
public static boolean isFinishNow = false;
@Override
@ -75,43 +62,21 @@ public class RomsManagerActivity extends AppCompatActivity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
activity = this;
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
sAvailable = getResources().getString(R.string.available);
sUnavailable = getResources().getString(R.string.unavailable);
sInstalled = getResources().getString(R.string.installed);
UIUtils.edgeToEdge(this);
setContentView(R.layout.activity_roms_manager);
binding = ActivityRomsManagerBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
UIUtils.setOnApplyWindowInsetsListenerTop(findViewById(R.id.appbar));
UIUtils.setOnApplyWindowInsetsListenerBottom(findViewById(R.id.romsRv));
UIUtils.setOnApplyWindowInsetsListenerBottom(findViewById(R.id.romsSearch));
UIUtils.setOnApplyWindowInsetsListenerBottom(findViewById(R.id.linear_search_emty));
linearload = findViewById(R.id.linearload);
linearnothinghere = findViewById(R.id.linearnothinghere);
Button buttontryagain = findViewById(R.id.buttontryagain);
RecyclerView mRVRoms = findViewById(R.id.romsRv);
romsSearch = findViewById(R.id.romsSearch);
binding.searchBar.setNavigationOnClickListener(v -> onBackPressed());
mRVRoms = findViewById(R.id.romsRv);
mAdapter = new AdapterRoms(this, data);
mRVRoms.setAdapter(mAdapter);
mRVRoms.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
romsSearch = findViewById(R.id.romsSearch);
mAdapterSearch = new AdapterRomStoreSearch(this, dataSearch);
romsSearch.setAdapter(mAdapterSearch);
romsSearch.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
SearchBar searchBar = findViewById(R.id.search_bar);
searchBar.setNavigationOnClickListener(v -> onBackPressed());
searchView = findViewById(R.id.searchView);
searchView.getEditText().addTextChangedListener(new TextWatcher() {
binding.searchView.getEditText().addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@ -133,19 +98,18 @@ public class RomsManagerActivity extends AppCompatActivity {
if (!response.isEmpty())
contentJSON = response;
loadData();
loadDataSearch();
linearload.setVisibility(View.GONE);
binding.linearload.setVisibility(View.GONE);
}
@Override
public void onErrorResponse(String tag, String message) {
linearload.setVisibility(View.GONE);
linearnothinghere.setVisibility(View.VISIBLE);
binding.linearload.setVisibility(View.GONE);
binding.linearnothinghere.setVisibility(View.VISIBLE);
}
};
buttontryagain.setOnClickListener(v -> {
linearload.setVisibility(View.VISIBLE);
binding.buttontryagain.setOnClickListener(v -> {
binding.linearload.setVisibility(View.VISIBLE);
net.startRequestNetwork(RequestNetworkController.GET,AppConfig.vectrasRaw + "vroms-store.json","",_net_request_listener);
});
@ -159,38 +123,45 @@ public class RomsManagerActivity extends AppCompatActivity {
isFinishNow = false;
}
@Override
public void onBackPressed() {
if (binding.searchView.isShowing())
binding.searchView.hide();
else
super.onBackPressed();
}
@SuppressLint("NotifyDataSetChanged")
private void loadData() {
try {
List<DataRoms> dataRoms;
Gson gson = new Gson();
Type listType = new TypeToken<List<DataRoms>>() {}.getType();
dataRoms = gson.fromJson(contentJSON, listType);
AdapterRoms mAdapter = new AdapterRoms(this, data);
binding.romsRv.setAdapter(mAdapter);
binding.romsRv.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
data.clear();
data.addAll(dataRoms);
mAdapter.notifyDataSetChanged();
} catch (Exception e) {
linearload.setVisibility(View.GONE);
linearnothinghere.setVisibility(View.VISIBLE);
}
}
mAdapterSearch = new AdapterRomStoreSearch(this, dataSearch);
binding.romsSearch.setAdapter(mAdapterSearch);
binding.romsSearch.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
List<DataRoms> dataRoms = new ArrayList<>();
private void loadDataSearch() {
List<DataRoms> dataRoms;
try {
Gson gson = new Gson();
Type listType = new TypeToken<List<DataRoms>>() {}.getType();
dataRoms = gson.fromJson(contentJSON, listType);
dataSearch.clear();
dataSearch.addAll(dataRoms);
mAdapterSearch.notifyDataSetChanged();
} catch (Exception e) {
linearload.setVisibility(View.GONE);
linearnothinghere.setVisibility(View.VISIBLE);
binding.linearload.setVisibility(View.GONE);
binding.linearnothinghere.setVisibility(View.VISIBLE);
}
data.clear();
data.addAll(dataRoms);
mAdapter.notifyDataSetChanged();
dataSearch.clear();
dataSearch.addAll(dataRoms);
mAdapterSearch.notifyDataSetChanged();
}
@SuppressLint("NotifyDataSetChanged")
private void search(String keyword) {
try {
// Extract data from json and store into ArrayList as class objects
@ -225,18 +196,10 @@ public class RomsManagerActivity extends AppCompatActivity {
}
if (dataSearch.isEmpty())
romsSearch.setVisibility(View.GONE);
binding.romsSearch.setVisibility(View.GONE);
else
romsSearch.setVisibility(View.VISIBLE);
binding.romsSearch.setVisibility(View.VISIBLE);
mAdapterSearch.notifyDataSetChanged();
}
@Override
public void onBackPressed() {
if (searchView.isShowing())
searchView.hide();
else
super.onBackPressed();
}
}

View file

@ -29,6 +29,7 @@ import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.vectras.qemu.Config;
import com.vectras.qemu.MainSettingsManager;
import com.vectras.qemu.MainVNCActivity;
import com.vectras.qemu.utils.QmpClient;
import com.vectras.vm.MainRoms.AdapterMainRoms;
import com.vectras.vm.utils.DialogUtils;
@ -941,11 +942,7 @@ public class VMManager {
if (isMainVNCActivity) {
_view.findViewById(R.id.ln_mouse).setOnClickListener(v -> {
final Dialog alertDialog = new Dialog(_activity, R.style.MainDialogTheme);
alertDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
Objects.requireNonNull(alertDialog.getWindow()).setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));
alertDialog.setContentView(R.layout.dialog_setting);
alertDialog.show();
MainVNCActivity.activity.onMouseMode();
_dialog.dismiss();
});
} else {

View file

@ -21,6 +21,7 @@ import android.widget.Toast;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
@ -40,6 +41,8 @@ import androidx.annotation.NonNull;
import com.vectras.vm.MainActivity;
import com.vectras.vm.AppConfig;
import com.vectras.vm.R;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
@ -51,6 +54,7 @@ import java.io.OutputStreamWriter;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Objects;
/**
*
@ -241,10 +245,6 @@ public class FileUtils {
}
}
}
return null;
}
@ -391,6 +391,8 @@ public class FileUtils {
}
private static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) {
if (uri == null) return null;
Cursor cursor = null;
final String column = "_data";
final String[] projection = {column};
@ -668,6 +670,62 @@ public class FileUtils {
}
public static void copyFileFromUri(Context context, Uri sourceUri, String destFile) throws IOException {
File file = new File(destFile);
if (!Objects.requireNonNull(file.getParentFile()).exists()) {
file.getParentFile().mkdirs();
}
try (InputStream inputStream = context.getContentResolver().openInputStream(sourceUri); OutputStream outputStream = new FileOutputStream(destFile)) {
byte[] buffer = new byte[32 * 1024];
if (DeviceUtils.totalMemoryCapacity(context) < 3L * 1024 * 1024 * 1024) {
buffer = new byte[4 * 1024];
} else if (DeviceUtils.totalMemoryCapacity(context) < 5L * 1024 * 1024 * 1024) {
buffer = new byte[8 * 1024];
} else if (DeviceUtils.totalMemoryCapacity(context) < 7L * 1024 * 1024 * 1024) {
buffer = new byte[16 * 1024];
}
int bytesRead;
while (true) {
assert inputStream != null;
if ((bytesRead = inputStream.read(buffer)) == -1) break;
outputStream.write(buffer, 0, bytesRead);
}
outputStream.flush();
}
}
public static String getFileNameFromUri(Context context, Uri uri) {
String result = null;
Cursor cursor = context.getContentResolver().query(
uri,
null,
null,
null,
null
);
try {
if (cursor != null && cursor.moveToFirst()) {
int nameIndex = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
result = cursor.getString(nameIndex);
}
} finally {
if (cursor != null) {
cursor.close();
}
}
if (result == null) {
result = uri.getLastPathSegment();
}
return result;
}
public static void deleteDirectory(String _pathToDelete) {
File _dir = new File(_pathToDelete);
if (_dir.isDirectory()) {
@ -805,4 +863,21 @@ public class FileUtils {
return filePath;
}
public static boolean isValidFilePath(Activity activity, String filePath, boolean isShowDialog) {
if (filePath == null || filePath.isEmpty()) {
if (isShowDialog) {
DialogUtils.oneDialog(activity,
activity.getString(R.string.problem_has_been_detected),
activity.getString(R.string.invalid_file_path_content),
activity.getString(R.string.ok),
true,
R.drawable.folder_24px,
true,
null,
null);
}
return false;
}
return true;
}
}

View file

@ -0,0 +1,36 @@
package com.vectras.vm.utils;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.util.Log;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
public class ImageUtils {
public static final String TAG = "ImageUtils";
public static void convertToPng(Context context, Uri sourceUri, String outputFullPath) throws IOException {
File outputFile = new File(outputFullPath);
if (!outputFile.getParentFile().exists()) {
outputFile.getParentFile().mkdirs();
}
Bitmap bitmap = BitmapFactory.decodeStream(context.getContentResolver().openInputStream(sourceUri));
if (bitmap == null) {
Log.e(TAG, "Failed to decode bitmap from URI: " + sourceUri);
return;
}
FileOutputStream out = new FileOutputStream(outputFile);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
out.flush();
out.close();
}
}