Second commit

- VPN bugs fixed
- custom background update
- map bug fixed
This commit is contained in:
2025-03-26 22:47:09 +08:00
parent fb6ebb9031
commit 5aeedfd973
9 changed files with 397 additions and 128 deletions

View File

@@ -22,6 +22,30 @@
<uses-permission android:name="android.permission.CHANGE_CONFIGURATION" tools:ignore="ProtectedPermissions"/>
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.WRITE_SETTINGS" tools:ignore="ProtectedPermissions"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
<!-- 允许获取精确位置,精准定位必选 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<!-- 后台获取位置信息,若需后台定位则必选 -->
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<!-- 用于申请调用A-GPS模块,卫星定位加速 -->
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="35"
tools:ignore="ScopedStorage"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="35"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_CONFIGURATION" tools:ignore="ProtectedPermissions"/>
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.WRITE_SETTINGS" tools:ignore="ProtectedPermissions"/>
<application
android:allowBackup="true"
android:fullBackupContent="@xml/backup_rules"
@@ -36,6 +60,15 @@
android:networkSecurityConfig="@xml/network_security_config"
android:enableOnBackInvokedCallback="true"
android:theme="@style/Theme.FindMaimaiUltra">
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
<meta-data
android:name="com.baidu.lbsapi.API_KEY"
@@ -76,7 +109,29 @@
android:launchMode="singleTask"
android:exported="true">
</activity>
<activity
android:name="com.yalantis.ucrop.UCropActivity"
android:screenOrientation="fullSensor"
android:theme="@style/Theme.AppCompat.Light.NoActionBar"
tools:ignore="MissingClass" />
<service
android:hardwareAccelerated="true"
android:name="org.astral.findmaimaiultra.utill.updater.vpn.core.LocalVpnService"
android:permission="android.permission.BIND_VPN_SERVICE"
android:exported="true">
<intent-filter>
<action android:name="android.net.VpnService" />
</intent-filter>
</service>
<service android:name="org.astral.findmaimaiultra.utill.updater.server.HttpServerService"
android:exported="true" />
<service android:name="org.astral.findmaimaiultra.utill.updater.notification.NotificationUtil"
android:enabled="true"
android:foregroundServiceType="dataSync"
android:exported="false">
</service>
</application>
</manifest>

View File

@@ -0,0 +1,6 @@
// ImagePickerListener.java
package org.astral.findmaimaiultra.ui;
public interface ImagePickerListener {
void openFileChooser();
}

View File

@@ -1,7 +1,17 @@
package org.astral.findmaimaiultra.ui;
import android.content.Intent;
import android.Manifest;
import android.annotation.SuppressLint;
import android.content.*;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.Menu;
import android.widget.Toast;
@@ -14,13 +24,20 @@ import androidx.navigation.ui.AppBarConfiguration;
import androidx.navigation.ui.NavigationUI;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.appcompat.app.AppCompatActivity;
import com.yalantis.ucrop.UCrop;
import org.astral.findmaimaiultra.R;
import org.astral.findmaimaiultra.databinding.ActivityMainBinding;
public class MainActivity extends AppCompatActivity {
import java.io.File;
import java.io.FileOutputStream;
import static android.app.Activity.RESULT_OK;
public class MainActivity extends AppCompatActivity implements ImagePickerListener {
private AppBarConfiguration mAppBarConfiguration;
private ActivityMainBinding binding;
private SharedPreferences settingProperties;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -28,6 +45,7 @@ public class MainActivity extends AppCompatActivity {
binding = ActivityMainBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
settingProperties = getSharedPreferences("setting", Context.MODE_PRIVATE);
setSupportActionBar(binding.appBarMain.toolbar);
DrawerLayout drawer = binding.drawerLayout;
@@ -35,7 +53,7 @@ public class MainActivity extends AppCompatActivity {
// Passing each menu ID as a set of Ids because each
// menu should be considered as top level destinations.
mAppBarConfiguration = new AppBarConfiguration.Builder(
R.id.nav_home, R.id.nav_gallery, R.id.nav_music,R.id.nav_slideshow)
R.id.nav_home, R.id.nav_gallery, R.id.nav_music, R.id.nav_slideshow)
.setOpenableLayout(drawer)
.build();
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment_content_main);
@@ -60,18 +78,122 @@ public class MainActivity extends AppCompatActivity {
});
menu.findItem(R.id.action_update).setOnMenuItemClickListener(item -> {
Intent update = new Intent(this, UpdateActivity.class);
Toast.makeText(this, "敬请期待", Toast.LENGTH_SHORT).show();
//startActivity(update);
startActivity(update);
return true;
});
return false;
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Log.d("SettingActivity", "onActivityResult called with requestCode: " + requestCode + ", resultCode: " + resultCode);
if (requestCode == 1 && resultCode == RESULT_OK && data != null && data.getData() != null) {
Uri uri = data.getData();
startCropActivity(uri);
} else if (requestCode == UCrop.REQUEST_CROP && resultCode == RESULT_OK) {
handleCroppedImage(data);
} else if (requestCode == UCrop.REQUEST_CROP && resultCode == UCrop.RESULT_ERROR) {
final Throwable cropError = UCrop.getError(data);
Log.e("SettingActivity", "Cropping failed: ", cropError);
Toast.makeText(this, "裁剪失败: " + cropError.getMessage(), Toast.LENGTH_SHORT).show();
} else {
Log.w("SettingActivity", "Unexpected result from image picker or cropper");
Toast.makeText(this, "裁剪操作未成功", Toast.LENGTH_SHORT).show();
}
}
private void startCropActivity(Uri uri) {
Uri destinationUri = Uri.fromFile(new File(this.getCacheDir(), "cropped_image.jpg"));
UCrop.Options options = new UCrop.Options();
options.setCompressionQuality(90);
options.setCompressionFormat(Bitmap.CompressFormat.JPEG);
// 计算屏幕宽高比
float[] aspectRatio = getScreenAspectRatio();
UCrop uCrop = UCrop.of(uri, destinationUri)
.withAspectRatio(aspectRatio[0], aspectRatio[1]) // 设置裁剪比例为屏幕比例
.withMaxResultSize(getScreenWidth(), getScreenHeight()) // 设置最大结果尺寸
.withOptions(options);
// 启动 UCrop 并使用 cropImageLauncher 处理结果
uCrop.start(this);
}
private void show(String text) {
if (this != null) {
this.runOnUiThread(() -> Toast.makeText(this, text, Toast.LENGTH_SHORT).show());
}
}
private void handleCroppedImage(Intent data) {
Uri croppedUri = UCrop.getOutput(data);
if (croppedUri != null) {
try {
Bitmap photo = MediaStore.Images.Media.getBitmap(this.getContentResolver(), croppedUri);
if (photo != null) {
File croppedFile = new File(this.getExternalFilesDir(null), "cropped_image.jpg");
try (FileOutputStream out = new FileOutputStream(croppedFile)) {
photo.compress(Bitmap.CompressFormat.JPEG, 90, out);
SharedPreferences.Editor editor = settingProperties.edit();
editor.putString("image_uri", croppedUri.toString());
editor.apply();
show("成功");
Log.d("SettingActivity", "图片已保存到: " + croppedFile.getAbsolutePath());
} catch (Exception e) {
e.printStackTrace();
show("失败");
Log.e("SettingActivity", "保存图片失败: ", e);
}
} else {
show("无法获取裁剪后的图片");
Log.w("SettingActivity", "无法获取裁剪后的图片");
}
} catch (Exception e) {
e.printStackTrace();
show("无法获取裁剪后的图片");
Log.e("SettingActivity", "无法获取裁剪后的图片: ", e);
}
} else {
show("无法找到裁剪后的图片");
Log.w("SettingActivity", "无法找到裁剪后的图片");
}
}
private int getScreenWidth() {
DisplayMetrics displayMetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
return displayMetrics.widthPixels;
}
private int getScreenHeight() {
DisplayMetrics displayMetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
return displayMetrics.heightPixels;
}
private float[] getScreenAspectRatio() {
DisplayMetrics displayMetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
float width = displayMetrics.widthPixels;
float height = displayMetrics.heightPixels;
return new float[]{width, height};
}
@Override
public boolean onSupportNavigateUp() {
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment_content_main);
return NavigationUI.navigateUp(navController, mAppBarConfiguration)
|| super.onSupportNavigateUp();
}
}
@Override
public void openFileChooser() {
Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
intent.setType("image/*");
startActivityForResult(intent, 1);
}
}

View File

@@ -41,8 +41,15 @@ public class GalleryFragment extends Fragment {
binding = FragmentGalleryBinding.inflate(inflater, container, false);
View root = binding.getRoot();
sharedViewModel = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);
double x = Double.parseDouble(Objects.requireNonNull(sharedViewModel.getSharedMap().getValue().get("x")));
double y = Double.parseDouble(Objects.requireNonNull(sharedViewModel.getSharedMap().getValue().get("y")));
double x = 116.3912757;
double y = 39.906217;
try {
x = Double.parseDouble(Objects.requireNonNull(sharedViewModel.getSharedMap().getValue().get("x")));
y = Double.parseDouble(Objects.requireNonNull(sharedViewModel.getSharedMap().getValue().get("y")));
}catch (Exception e) {
Toast.makeText(getContext(), "经纬度获取失败", Toast.LENGTH_SHORT).show();
}
mapView = binding.bmapView;
mapView.onCreate(getContext(),savedInstanceState);

View File

@@ -7,7 +7,8 @@ import android.app.AlertDialog;
import android.content.*;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.graphics.*;
import android.graphics.drawable.BitmapDrawable;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
@@ -21,6 +22,7 @@ import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
@@ -80,6 +82,8 @@ public class HomeFragment extends Fragment {
private boolean isFlag = true;
private SharedPreferences shoucang;
private SharedPreferences settingProperties;
private SharedPreferences settingProperties2;
private FragmentHomeBinding binding;
private SharedViewModel sharedViewModel;
@Override
@@ -90,6 +94,8 @@ public class HomeFragment extends Fragment {
if (context != null) {
shoucang = context.getSharedPreferences("shoucang_prefs", Context.MODE_PRIVATE);
settingProperties = context.getSharedPreferences("setting_prefs", Context.MODE_PRIVATE);
settingProperties2 = context.getSharedPreferences("setting", Context.MODE_PRIVATE);
}
sharedViewModel = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);
}
@@ -118,6 +124,124 @@ public class HomeFragment extends Fragment {
// 使用 savedData
}
if (settingProperties2.getString("image_uri", null) != null ) {
Uri uri = Uri.parse(settingProperties2.getString("image_uri", null));
try {
Bitmap bitmap = BitmapFactory.decodeStream(getContext().getContentResolver().openInputStream(uri));
if (bitmap != null) {
// 获取RecyclerView的尺寸
int recyclerViewWidth = 0;
int recyclerViewHeight = 0;
recyclerViewWidth = recyclerView.getWidth();
recyclerViewHeight = recyclerView.getHeight();
if (recyclerViewWidth > 0 && recyclerViewHeight > 0) {
// 计算缩放比例
float scaleWidth = ((float) recyclerViewWidth) / bitmap.getWidth();
float scaleHeight = ((float) recyclerViewHeight) / bitmap.getHeight();
// 选择较大的缩放比例以保持图片的原始比例
float scaleFactor = Math.max(scaleWidth, scaleHeight);
// 计算新的宽度和高度
int newWidth = (int) (bitmap.getWidth() * scaleFactor);
int newHeight = (int) (bitmap.getHeight() * scaleFactor);
// 缩放图片
Bitmap scaledBitmap = Bitmap.createScaledBitmap(bitmap, newWidth, newHeight, true);
// 计算裁剪区域
int x = (scaledBitmap.getWidth() - recyclerViewWidth) / 2;
int y = (scaledBitmap.getHeight() - recyclerViewHeight) / 2;
// 处理x和y为负数的情况
x = Math.max(x, 0);
y = Math.max(y, 0);
// 裁剪图片
Bitmap croppedBitmap = Bitmap.createBitmap(scaledBitmap, x, y, recyclerViewWidth, recyclerViewHeight);
// 创建一个新的 Bitmap与裁剪后的 Bitmap 大小相同
Bitmap transparentBitmap = Bitmap.createBitmap(croppedBitmap.getWidth(), croppedBitmap.getHeight(), croppedBitmap.getConfig());
// 创建一个 Canvas 对象,用于在新的 Bitmap 上绘制
Canvas canvas = new Canvas(transparentBitmap);
// 创建一个 Paint 对象,并设置透明度
Paint paint = new Paint();
paint.setAlpha(128); // 设置透明度为 50% (255 * 0.5 = 128)
// 将裁剪后的 Bitmap 绘制到新的 Bitmap 上,并应用透明度
canvas.drawBitmap(croppedBitmap, 0, 0, paint);
// 创建BitmapDrawable并设置其边界为RecyclerView的尺寸
BitmapDrawable bitmapDrawable = new BitmapDrawable(getResources(), transparentBitmap);
// 设置recyclerView的背景
recyclerView.setBackground(bitmapDrawable);
} else {
// 如果RecyclerView的尺寸未确定可以使用ViewTreeObserver来监听尺寸变化
recyclerView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
recyclerView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
int recyclerViewWidth = 0;
int recyclerViewHeight = 0;
recyclerViewWidth = recyclerView.getWidth();
recyclerViewHeight = recyclerView.getHeight();
// 计算缩放比例
float scaleWidth = ((float) recyclerViewWidth) / bitmap.getWidth();
float scaleHeight = ((float) recyclerViewHeight) / bitmap.getHeight();
// 选择较大的缩放比例以保持图片的原始比例
float scaleFactor = Math.max(scaleWidth, scaleHeight);
// 计算新的宽度和高度
int newWidth = (int) (bitmap.getWidth() * scaleFactor);
int newHeight = (int) (bitmap.getHeight() * scaleFactor);
// 缩放图片
Bitmap scaledBitmap = Bitmap.createScaledBitmap(bitmap, newWidth, newHeight, true);
// 计算裁剪区域
int x = (scaledBitmap.getWidth() - recyclerViewWidth) / 2;
int y = (scaledBitmap.getHeight() - recyclerViewHeight) / 2;
// 处理x和y为负数的情况
x = Math.max(x, 0);
y = Math.max(y, 0);
// 裁剪图片
Bitmap croppedBitmap = Bitmap.createBitmap(scaledBitmap, x, y, recyclerViewWidth, recyclerViewHeight);
// 创建一个新的 Bitmap与裁剪后的 Bitmap 大小相同
Bitmap transparentBitmap = Bitmap.createBitmap(croppedBitmap.getWidth(), croppedBitmap.getHeight(), croppedBitmap.getConfig());
// 创建一个 Canvas 对象,用于在新的 Bitmap 上绘制
Canvas canvas = new Canvas(transparentBitmap);
// 创建一个 Paint 对象,并设置透明度
Paint paint = new Paint();
paint.setAlpha(128); // 设置透明度为 50% (255 * 0.5 = 128)
// 将裁剪后的 Bitmap 绘制到新的 Bitmap 上,并应用透明度
canvas.drawBitmap(croppedBitmap, 0, 0, paint);
// 创建BitmapDrawable并设置其边界为RecyclerView的尺寸
BitmapDrawable bitmapDrawable = new BitmapDrawable(getResources(), transparentBitmap);
recyclerView.setBackground(bitmapDrawable);
}
});
}
}
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(requireContext(), "图片加载失败,权限出错!", Toast.LENGTH_SHORT).show();
}
}
return root;
}
@@ -296,6 +420,7 @@ public class HomeFragment extends Fragment {
// 调用高德地图 API 进行逆地理编码
reverseGeocode(lastKnownLocation.getLatitude(), lastKnownLocation.getLongitude());
} else {
Toast.makeText(requireActivity().getApplicationContext(), "无法获取最新定位信息", Toast.LENGTH_SHORT).show();
Log.d("Location", "无法获取最新定位信息");
setDefaultLocation(); // 设置默认位置
}
@@ -418,6 +543,9 @@ public class HomeFragment extends Fragment {
private void setDefaultLocation() {
x = String.valueOf(116.3912757);
y = String.valueOf(39.906217);
tot = "北京";
city = "北京市";
extracted();
}
//手动刷新定位

View File

@@ -165,7 +165,9 @@ public class MusicFragment extends Fragment {
ImageView musicTypeImageView = dialogView.findViewById(R.id.dialog_music_type);
ImageView musicComboStatusTextView = dialogView.findViewById(R.id.dialog_music_combo_status);
TextView musicPlayCountTextView = dialogView.findViewById(R.id.dialog_music_play_count);
if (musicRating.getMusicName().equals("空-请去导入成绩")) {
return;
}
// 设置图像曲绘
int id = musicRating.getMusicId();
if (id > 10000) {

View File

@@ -1,16 +1,12 @@
package org.astral.findmaimaiultra.ui.slideshow;
import android.Manifest;
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.content.*;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.provider.Settings;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
@@ -19,32 +15,33 @@ import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.TextView;
import android.widget.Toast;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
import com.google.android.material.button.MaterialButton;
import com.google.android.material.radiobutton.MaterialRadioButton;
import com.google.android.material.switchmaterial.SwitchMaterial;
import com.google.android.material.textfield.TextInputEditText;
import com.yalantis.ucrop.UCrop;
import org.astral.findmaimaiultra.been.Release;
import org.astral.findmaimaiultra.databinding.FragmentSlideshowBinding;
import org.astral.findmaimaiultra.service.GitHubApiService;
import org.astral.findmaimaiultra.ui.ImagePickerListener;
import org.astral.findmaimaiultra.ui.LinkQQBot;
import org.astral.findmaimaiultra.utill.GitHubApiClient;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import java.io.File;
import java.io.FileOutputStream;
import java.util.Objects;
import static android.app.Activity.RESULT_OK;
public class SlideshowFragment extends Fragment {
private SharedPreferences settingProperties;
private static final int PICK_IMAGE_REQUEST = 1;
private static final int REQUEST_CODE_PERMISSIONS = 1001;
private TextInputEditText shuiyuEditText;
private TextInputEditText luoxueEditText;
@@ -52,16 +49,59 @@ public class SlideshowFragment extends Fragment {
private String x;
private String y;
private FragmentSlideshowBinding binding;
private ImagePickerListener imagePickerListener;
private static final String[] REQUIRED_PERMISSIONS = {
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
};
@Override
public void onAttach(@NonNull Context context) {
super.onAttach(context);
if (context instanceof ImagePickerListener) {
imagePickerListener = (ImagePickerListener) context;
} else {
throw new RuntimeException(context.toString() + " must implement ImagePickerListener");
}
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
settingProperties = requireActivity().getSharedPreferences("setting", Context.MODE_PRIVATE);
if (allPermissionsGranted()) {
// 初始化代码
} else {
requestPermissions();
}
}
private void show(String text) {
if (getActivity() != null) {
getActivity().runOnUiThread(() -> Toast.makeText(getActivity(), text, Toast.LENGTH_SHORT).show());
}
}
private boolean allPermissionsGranted() {
for (String permission : REQUIRED_PERMISSIONS) {
if (ContextCompat.checkSelfPermission(requireContext(), permission) != PackageManager.PERMISSION_GRANTED) {
return false;
}
}
return true;
}
private void requestPermissions() {
ActivityCompat.requestPermissions(
requireActivity(),
REQUIRED_PERMISSIONS,
REQUEST_CODE_PERMISSIONS
);
}
@Override
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
SlideshowViewModel slideshowViewModel =
@@ -74,7 +114,7 @@ public class SlideshowFragment extends Fragment {
switchMaterial.setOnCheckedChangeListener((buttonView, isChecked) -> {
SharedPreferences.Editor editor = settingProperties.edit();
if (isChecked) {
show( "已开启实验性功能,可能并不起作用");
show("已开启实验性功能,可能并不起作用");
editor.putBoolean("setting_autobeta1", true);
} else {
editor.putBoolean("setting_autobeta1", false);
@@ -102,7 +142,7 @@ public class SlideshowFragment extends Fragment {
saveSettings(switchMaterial.isChecked(), shuiyuEditText.getText().toString(), luoxueEditText.getText().toString(), userId.getText().toString());
});
MaterialButton changeButton = binding.changePhoto;
changeButton.setOnClickListener(v -> openFileChooser());
changeButton.setOnClickListener(v -> imagePickerListener.openFileChooser());
TextView uuid = binding.uuid;
@SuppressLint("HardwareIds") String androidId = Settings.Secure.getString(getContext().getContentResolver(), Settings.Secure.ANDROID_ID);
uuid.setText("Android ID:" + androidId);
@@ -133,13 +173,6 @@ public class SlideshowFragment extends Fragment {
webView.loadUrl(url); // 加载网页
return root;
}
private void openFileChooser() {
Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
intent.setType("image/*");
if (intent.resolveActivity(getContext().getPackageManager()) != null) {
startActivityForResult(intent, PICK_IMAGE_REQUEST);
}
}
private String getAppVersionName() {
try {
@@ -151,75 +184,6 @@ public class SlideshowFragment extends Fragment {
}
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Log.d("SettingActivity", "onActivityResult called with requestCode: " + requestCode + ", resultCode: " + resultCode);
if (requestCode == PICK_IMAGE_REQUEST && resultCode == RESULT_OK && data != null && data.getData() != null) {
Uri uri = data.getData();
startCropActivity(uri);
} else if (requestCode == UCrop.REQUEST_CROP && resultCode == RESULT_OK) {
handleCroppedImage(data);
} else if (requestCode == UCrop.REQUEST_CROP && resultCode == UCrop.RESULT_ERROR) {
final Throwable cropError = UCrop.getError(data);
Log.e("SettingActivity", "Cropping failed: ", cropError);
} else {
Log.w("SettingActivity", "Unexpected result from image picker or cropper");
}
}
private void startCropActivity(Uri uri) {
Uri destinationUri = Uri.fromFile(new File(requireActivity().getCacheDir(), "cropped_image.jpg"));
UCrop.Options options = new UCrop.Options();
options.setCompressionQuality(90);
options.setCompressionFormat(Bitmap.CompressFormat.JPEG);
// 计算屏幕宽高比
float[] aspectRatio = getScreenAspectRatio();
UCrop.of(uri, destinationUri)
.withAspectRatio(aspectRatio[0], aspectRatio[1]) // 设置裁剪比例为屏幕比例
.withMaxResultSize(getScreenWidth(), getScreenHeight()) // 设置最大结果尺寸
.withOptions(options)
.start(getActivity());
}
private void handleCroppedImage(Intent data) {
Uri croppedUri = UCrop.getOutput(data);
if (croppedUri != null) {
try {
Bitmap photo = MediaStore.Images.Media.getBitmap(getContext().getContentResolver(), croppedUri);
if (photo != null) {
File croppedFile = new File(getContext().getExternalFilesDir(null), "cropped_image.jpg");
try (FileOutputStream out = new FileOutputStream(croppedFile)) {
photo.compress(Bitmap.CompressFormat.JPEG, 90, out);
SharedPreferences.Editor editor = settingProperties.edit();
editor.putString("image_uri", croppedUri.toString());
editor.apply();
show("成功");
Log.d("SettingActivity", "图片已保存到: " + croppedFile.getAbsolutePath());
} catch (Exception e) {
e.printStackTrace();
show("失败");
Log.e("SettingActivity", "保存图片失败: ", e);
}
} else {
show("无法获取裁剪后的图片");
Log.w("SettingActivity", "无法获取裁剪后的图片");
}
} catch (Exception e) {
e.printStackTrace();
show("无法获取裁剪后的图片");
Log.e("SettingActivity", "无法获取裁剪后的图片: ", e);
}
} else {
show("无法找到裁剪后的图片");
Log.w("SettingActivity", "无法找到裁剪后的图片");
}
}
private void saveSettings(boolean betaEnabled, String shuiyuUsername, String luoxueUsername, String userId) {
SharedPreferences.Editor editor = settingProperties.edit();
MaterialRadioButton materialRadioButton = binding.radioButton1;
@@ -278,6 +242,7 @@ public class SlideshowFragment extends Fragment {
}
}
}
private void getLatestRelease() {
GitHubApiService service = GitHubApiClient.getClient();
Call<Release> call = service.getLatestRelease("Spaso1", "FindMaimaiDX_Phone"); // 替换为你的仓库信息
@@ -289,16 +254,18 @@ public class SlideshowFragment extends Fragment {
if (response.isSuccessful()) {
Release release = response.body();
if (release != null) {
String tagName = release.getTagName();
String name = release.getName();
String body = release.getBody();
String htmlUrl = release.getHtmlUrl();
TextView textView = binding.vits;
textView.setText(textView.getText() + tagName + "\n" + name + "\n" + body);
//Toast.makeText(SettingActivity.this, "Latest Release:\nTag Name: " + tagName + "\nName: " + name + "\nBody: " + body + "\nHTML URL: " + htmlUrl, Toast.LENGTH_SHORT).show();
} else {
try {
String tagName = release.getTagName();
String name = release.getName();
String body = release.getBody();
String htmlUrl = release.getHtmlUrl();
TextView textView = binding.vits;
textView.setText(textView.getText() + tagName + "\n" + name + "\n" + body);
//Toast.makeText(SettingActivity.this, "Latest Release:\nTag Name: " + tagName + "\nName: " + name + "\nBody: " + body + "\nHTML URL: " + htmlUrl, Toast.LENGTH_SHORT).show();
} catch (Exception e) {
Log.d("SettingActivity", "获取最新版本失败: ", e);
}
}
} else {
}
}
@@ -308,28 +275,9 @@ public class SlideshowFragment extends Fragment {
});
}
private int getScreenWidth() {
DisplayMetrics displayMetrics = new DisplayMetrics();
requireActivity().getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
return displayMetrics.widthPixels;
}
private int getScreenHeight() {
DisplayMetrics displayMetrics = new DisplayMetrics();
requireActivity().getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
return displayMetrics.heightPixels;
}
private float[] getScreenAspectRatio() {
DisplayMetrics displayMetrics = new DisplayMetrics();
getActivity().getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
float width = displayMetrics.widthPixels;
float height = displayMetrics.heightPixels;
return new float[]{width, height};
}
@Override
public void onDestroyView() {
super.onDestroyView();
binding = null;
}
}
}

View File

@@ -34,6 +34,7 @@
android:id="@+id/radioGroup"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
android:orientation="vertical">
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content"
android:textColor="@color/textcolorPrimary"