Second commit
- VPN bugs fixed - custom background update - map bug fixed
This commit is contained in:
@@ -8,7 +8,7 @@ android {
|
||||
|
||||
defaultConfig {
|
||||
applicationId "org.astral.findmaimaiultra"
|
||||
minSdk 30
|
||||
minSdk 29
|
||||
targetSdk 34
|
||||
versionCode 1
|
||||
versionName "1.6.0 Ultra"
|
||||
|
||||
@@ -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>
|
||||
@@ -0,0 +1,6 @@
|
||||
// ImagePickerListener.java
|
||||
package org.astral.findmaimaiultra.ui;
|
||||
|
||||
public interface ImagePickerListener {
|
||||
void openFileChooser();
|
||||
}
|
||||
@@ -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;
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
//手动刷新定位
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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 =
|
||||
@@ -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,6 +254,7 @@ public class SlideshowFragment extends Fragment {
|
||||
if (response.isSuccessful()) {
|
||||
Release release = response.body();
|
||||
if (release != null) {
|
||||
try {
|
||||
String tagName = release.getTagName();
|
||||
String name = release.getName();
|
||||
String body = release.getBody();
|
||||
@@ -296,9 +262,10 @@ public class SlideshowFragment extends Fragment {
|
||||
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 {
|
||||
} catch (Exception e) {
|
||||
Log.d("SettingActivity", "获取最新版本失败: ", e);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -308,25 +275,6 @@ 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();
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user