适配android 6
This commit is contained in:
parent
59d4e1e73d
commit
f271d47c86
@ -101,4 +101,7 @@ flutter {
|
||||
source '../..'
|
||||
}
|
||||
|
||||
dependencies {}
|
||||
dependencies {
|
||||
implementation 'androidx.work:work-runtime-ktx:2.9.0'
|
||||
implementation 'com.github.bumptech.glide:glide:4.16.0'
|
||||
}
|
||||
|
||||
@ -0,0 +1,95 @@
|
||||
package com.hello.wallpaper
|
||||
|
||||
import android.app.Activity
|
||||
import android.app.WallpaperManager
|
||||
import android.content.Context
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.os.Build
|
||||
import android.util.Size
|
||||
import androidx.window.layout.WindowMetricsCalculator
|
||||
import androidx.work.*
|
||||
import com.bumptech.glide.Glide
|
||||
import com.bumptech.glide.request.RequestOptions
|
||||
import com.bumptech.glide.request.target.CustomTarget
|
||||
import com.bumptech.glide.request.transition.Transition
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
|
||||
class GlideWallpaperWorker(
|
||||
context: Context,
|
||||
params: WorkerParameters
|
||||
) : Worker(context, params) {
|
||||
|
||||
override fun doWork(): Result {
|
||||
val imagePath = inputData.getString("imagePath") ?: return Result.failure()
|
||||
val wallpaperType = inputData.getInt("wallpaperType", 0)
|
||||
val desiredWidth = inputData.getInt("desiredWidth", 0)
|
||||
val desiredHeight = inputData.getInt("desiredHeight", 0)
|
||||
|
||||
return try {
|
||||
Glide.with(applicationContext)
|
||||
.asBitmap()
|
||||
.load(File(imagePath))
|
||||
.apply(RequestOptions().override(desiredWidth, desiredHeight))
|
||||
.into(object : CustomTarget<Bitmap>() {
|
||||
override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap>?) {
|
||||
val wallpaperManager = WallpaperManager.getInstance(applicationContext)
|
||||
try {
|
||||
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.M) {
|
||||
wallpaperManager.setBitmap(resource)
|
||||
} else {
|
||||
when (wallpaperType) {
|
||||
0 -> wallpaperManager.setBitmap(resource, null, true, WallpaperManager.FLAG_SYSTEM)
|
||||
1 -> wallpaperManager.setBitmap(resource, null, true, WallpaperManager.FLAG_LOCK)
|
||||
2 -> {
|
||||
wallpaperManager.setBitmap(resource, null, true, WallpaperManager.FLAG_SYSTEM)
|
||||
wallpaperManager.setBitmap(resource, null, true, WallpaperManager.FLAG_LOCK)
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e: IOException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onLoadCleared(placeholder: Drawable?) {
|
||||
// Handle cleanup if needed
|
||||
}
|
||||
})
|
||||
Result.success()
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
Result.retry()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Trigger the WorkManager task
|
||||
fun setWallpaperWithGlide(context: Context, activity: Activity, imagePath: String, wallpaperType: Int) {
|
||||
val screenSize: Size = getScreenDimensions(activity)
|
||||
val desiredWidth = screenSize.width * 2 // 适应横向滚动
|
||||
val desiredHeight = screenSize.height
|
||||
|
||||
val inputData = Data.Builder()
|
||||
.putString("imagePath", imagePath)
|
||||
.putInt("wallpaperType", wallpaperType)
|
||||
.putInt("desiredWidth", desiredWidth)
|
||||
.putInt("desiredHeight", desiredHeight)
|
||||
.build()
|
||||
|
||||
val setWallpaperRequest = OneTimeWorkRequest.Builder(GlideWallpaperWorker::class.java)
|
||||
.setInputData(inputData)
|
||||
.build()
|
||||
|
||||
WorkManager.getInstance(context).enqueue(setWallpaperRequest)
|
||||
}
|
||||
|
||||
// Modern method to get screen dimensions
|
||||
private fun getScreenDimensions(activity: Activity): Size {
|
||||
val windowMetrics = WindowMetricsCalculator.getOrCreate().computeCurrentWindowMetrics(activity)
|
||||
val bounds = windowMetrics.bounds
|
||||
val width = bounds.width()
|
||||
val height = bounds.height()
|
||||
return Size(width, height)
|
||||
}
|
||||
@ -1,22 +1,27 @@
|
||||
package com.hello.wallpaper
|
||||
|
||||
import android.app.Activity
|
||||
import android.app.WallpaperManager
|
||||
import android.content.Context
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.BitmapFactory
|
||||
import android.os.Build
|
||||
import androidx.annotation.RequiresApi
|
||||
import android.util.Size
|
||||
import androidx.window.layout.WindowMetricsCalculator
|
||||
import io.flutter.embedding.engine.plugins.FlutterPlugin
|
||||
import io.flutter.embedding.engine.plugins.activity.ActivityAware
|
||||
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding
|
||||
import io.flutter.plugin.common.MethodCall
|
||||
import io.flutter.plugin.common.MethodChannel
|
||||
import kotlinx.coroutines.DelicateCoroutinesApi
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
class SetWallpaperPlugin : FlutterPlugin, MethodChannel.MethodCallHandler {
|
||||
class SetWallpaperPlugin : FlutterPlugin, ActivityAware, MethodChannel.MethodCallHandler {
|
||||
private lateinit var context: Context
|
||||
private lateinit var channel: MethodChannel
|
||||
private lateinit var activity: Activity
|
||||
|
||||
override fun onAttachedToEngine(flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
|
||||
channel = MethodChannel(flutterPluginBinding.binaryMessenger, "set_wallpaper")
|
||||
@ -24,31 +29,13 @@ class SetWallpaperPlugin : FlutterPlugin, MethodChannel.MethodCallHandler {
|
||||
channel.setMethodCallHandler(this)
|
||||
}
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.N)
|
||||
@OptIn(DelicateCoroutinesApi::class)
|
||||
override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) {
|
||||
if (call.method == "setWallpaper") {
|
||||
val path = call.argument<String>("path")
|
||||
val wallpaperType = call.argument<Int>("wallpaperType") // 0 for home screen, 1 for lock screen, 2 for both
|
||||
|
||||
GlobalScope.launch(Dispatchers.IO) {
|
||||
val bitmap = BitmapFactory.decodeFile(path)
|
||||
withContext(Dispatchers.Main) {
|
||||
try {
|
||||
val wallpaperManager = WallpaperManager.getInstance(context)
|
||||
when (wallpaperType) {
|
||||
0 -> wallpaperManager.setBitmap(bitmap, null, true, WallpaperManager.FLAG_SYSTEM)
|
||||
1 -> wallpaperManager.setBitmap(bitmap, null, true, WallpaperManager.FLAG_LOCK)
|
||||
2 -> {
|
||||
wallpaperManager.setBitmap(bitmap, null, true, WallpaperManager.FLAG_SYSTEM)
|
||||
wallpaperManager.setBitmap(bitmap, null, true, WallpaperManager.FLAG_LOCK)
|
||||
}
|
||||
}
|
||||
result.success("Wallpaper applied successfully")
|
||||
} catch (e: Exception) {
|
||||
result.error("ERROR", "Failed to set wallpaper: ${e.message}", null)
|
||||
}
|
||||
}
|
||||
if (path != null && wallpaperType != null) {
|
||||
setWallpaper(path, wallpaperType, result)
|
||||
}
|
||||
} else {
|
||||
result.notImplemented()
|
||||
@ -58,4 +45,59 @@ class SetWallpaperPlugin : FlutterPlugin, MethodChannel.MethodCallHandler {
|
||||
override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) {
|
||||
channel.setMethodCallHandler(null)
|
||||
}
|
||||
|
||||
override fun onAttachedToActivity(binding: ActivityPluginBinding) {
|
||||
activity = binding.activity
|
||||
}
|
||||
|
||||
override fun onDetachedFromActivityForConfigChanges() {
|
||||
}
|
||||
|
||||
override fun onReattachedToActivityForConfigChanges(binding: ActivityPluginBinding) {
|
||||
activity = binding.activity
|
||||
}
|
||||
|
||||
override fun onDetachedFromActivity() {
|
||||
}
|
||||
|
||||
@OptIn(DelicateCoroutinesApi::class)
|
||||
fun setWallpaper(path: String, wallpaperType: Int, result: MethodChannel.Result) {
|
||||
val screenSize: Size = getScreenDimensions()
|
||||
val desiredWidth = screenSize.width * 2 // 适应横向滚动
|
||||
val desiredHeight = screenSize.height
|
||||
|
||||
GlobalScope.launch(Dispatchers.IO) {
|
||||
val wallpaperManager = WallpaperManager.getInstance(context)
|
||||
try {
|
||||
val largeBitmap = BitmapFactory.decodeFile(path)
|
||||
val scaledBitmap = Bitmap.createScaledBitmap(largeBitmap, desiredWidth, desiredHeight, true)
|
||||
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.M) {
|
||||
wallpaperManager.setBitmap(scaledBitmap)
|
||||
} else {
|
||||
when (wallpaperType) {
|
||||
0 -> wallpaperManager.setBitmap(largeBitmap, null, true, WallpaperManager.FLAG_SYSTEM)
|
||||
1 -> wallpaperManager.setBitmap(largeBitmap, null, true, WallpaperManager.FLAG_LOCK)
|
||||
2 -> {
|
||||
wallpaperManager.setBitmap(largeBitmap, null, true, WallpaperManager.FLAG_SYSTEM)
|
||||
wallpaperManager.setBitmap(largeBitmap, null, true, WallpaperManager.FLAG_LOCK)
|
||||
}
|
||||
}
|
||||
}
|
||||
largeBitmap.recycle()
|
||||
scaledBitmap.recycle()
|
||||
result.success("Wallpaper applied successfully")
|
||||
} catch (e: Exception) {
|
||||
result.error("ERROR", "Failed to set wallpaper: ${e.message}", null)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Modern method to get screen dimensions
|
||||
private fun getScreenDimensions(): Size {
|
||||
val windowMetrics = WindowMetricsCalculator.getOrCreate().computeCurrentWindowMetrics(activity)
|
||||
val bounds = windowMetrics.bounds
|
||||
val width = bounds.width()
|
||||
val height = bounds.height()
|
||||
return Size(width, height)
|
||||
}
|
||||
}
|
||||
@ -21,7 +21,9 @@ class TitleBarWidget extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SizedBox(
|
||||
return Padding(
|
||||
padding: EdgeInsets.only(top: MediaQuery.of(context).padding.top),
|
||||
child: SizedBox(
|
||||
height: titleBarHeight,
|
||||
child: Row(
|
||||
children: [
|
||||
@ -57,6 +59,7 @@ class TitleBarWidget extends StatelessWidget {
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -51,7 +51,6 @@ class CatalogController extends GetxController {
|
||||
Get.toNamed(AppPages.wallpaperDet, arguments: {
|
||||
'position': index,
|
||||
'wallpaperList': wallpaperList,
|
||||
'heroTag': 'Catalog-$clsName-$index',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -107,8 +107,6 @@ class CatalogView extends GetView<CatalogController> {
|
||||
Widget _buildWallpaperItem(String clsName, List<WallpaperData> wallpaperList, WallpaperData item, int index) {
|
||||
return GestureDetector(
|
||||
onTap: () => controller.onTapItem(clsName, wallpaperList, index),
|
||||
child: Hero(
|
||||
tag: 'Catalog-$clsName-$index',
|
||||
child: KeepAliveWrapper(
|
||||
child: ImageNetworkWidget(
|
||||
url: item.previewThumb,
|
||||
@ -117,7 +115,6 @@ class CatalogView extends GetView<CatalogController> {
|
||||
radius: 8.r,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -19,7 +19,6 @@ class ClsDetController extends GetxController {
|
||||
Get.toNamed(AppPages.wallpaperDet, arguments: {
|
||||
'position': index,
|
||||
'wallpaperList': wallpaperDataList,
|
||||
'heroTag': 'ClsDet-$index',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -35,13 +35,10 @@ class ClsDetView extends StatelessWidget {
|
||||
Widget _buildDiscoverItem(WallpaperData item, int index) {
|
||||
return GestureDetector(
|
||||
onTap: () => controller.onTapItem(index),
|
||||
child: Hero(
|
||||
tag: 'ClsDet-$index',
|
||||
child: ImageNetworkWidget(
|
||||
url: item.previewThumb,
|
||||
radius: 8.r,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -80,7 +80,6 @@ class DiscoverController extends GetxController {
|
||||
Get.toNamed(AppPages.wallpaperDet, arguments: {
|
||||
'position': index,
|
||||
'wallpaperList': wallpaperDataList,
|
||||
'heroTag': 'Discover-$index',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -18,7 +18,6 @@ class DiscoverView extends GetView<DiscoverController> {
|
||||
builder: (controller) {
|
||||
return Column(
|
||||
children: [
|
||||
SizedBox(height: 7.h),
|
||||
if (controller.todayNewestList.isNotEmpty) ...[
|
||||
_buildTodayNewest(),
|
||||
SizedBox(height: 7.h),
|
||||
@ -56,13 +55,10 @@ class DiscoverView extends GetView<DiscoverController> {
|
||||
Widget _buildDiscoverItem(WallpaperData item, int index) {
|
||||
return GestureDetector(
|
||||
onTap: () => controller.onTapItem(index),
|
||||
child: Hero(
|
||||
tag: 'Discover-$index',
|
||||
child: ImageNetworkWidget(
|
||||
url: item.previewThumb,
|
||||
radius: 8.r,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -54,7 +54,6 @@ class FavoriteController extends GetxController {
|
||||
Get.toNamed(AppPages.wallpaperDet, arguments: {
|
||||
'position': index,
|
||||
'wallpaperList': isFavorite ? favoriteList : todayHottestList,
|
||||
'heroTag': '${isFavorite ? 'Favorite' : 'TodayHottest'}-$index',
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -55,13 +55,10 @@ class FavoriteView extends GetView<FavoriteController> {
|
||||
return GestureDetector(
|
||||
onTap: () => controller.onTapItem(index, true),
|
||||
onLongPress: () => controller.onLongPress(index),
|
||||
child: Hero(
|
||||
tag: 'Favorite-$index',
|
||||
child: ImageNetworkWidget(
|
||||
url: item.previewThumb,
|
||||
radius: 8.r,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@ -87,8 +84,6 @@ class FavoriteView extends GetView<FavoriteController> {
|
||||
padding: const EdgeInsets.symmetric(horizontal: 3.5).w,
|
||||
child: GestureDetector(
|
||||
onTap: () => controller.onTapItem(e.key, false),
|
||||
child: Hero(
|
||||
tag: 'TodayHottest-${e.key}',
|
||||
child: ImageNetworkWidget(
|
||||
url: e.value.previewThumb,
|
||||
height: 183.h,
|
||||
@ -96,7 +91,6 @@ class FavoriteView extends GetView<FavoriteController> {
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
|
||||
@ -15,13 +15,13 @@ class HomeView extends StatelessWidget {
|
||||
return Scaffold(
|
||||
body: Column(
|
||||
children: [
|
||||
SizedBox(height: ScreenUtil().statusBarHeight),
|
||||
Obx(() {
|
||||
return TitleBarWidget(
|
||||
controller.pages[controller.currentIndex.value].label,
|
||||
settingsOnTap: controller.onTapSettings,
|
||||
);
|
||||
}),
|
||||
SizedBox(height: 7.h),
|
||||
Expanded(
|
||||
child: PageView(
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
|
||||
@ -23,7 +23,6 @@ class WallpaperDetController extends GetxController {
|
||||
late final List<GlobalKey> globalKey;
|
||||
late final List<WallpaperData> wallpaperList;
|
||||
late final PageController pageController;
|
||||
late final String heroTag;
|
||||
var blurs = <bool>[].obs;
|
||||
var position = 0;
|
||||
var filePath = '';
|
||||
@ -34,7 +33,6 @@ class WallpaperDetController extends GetxController {
|
||||
Map<String, dynamic> arguments = Get.arguments ?? {};
|
||||
position = arguments['position'] ?? 0;
|
||||
wallpaperList = arguments['wallpaperList'] ?? <WallpaperData>[];
|
||||
heroTag = arguments['heroTag'] ?? '';
|
||||
globalKey = List.generate(wallpaperList.length, (index) => GlobalKey());
|
||||
blurs.value = List.generate(wallpaperList.length, (index) => false);
|
||||
pageController = PageController(initialPage: position);
|
||||
|
||||
@ -87,7 +87,6 @@ class WallpaperDetView extends StatelessWidget {
|
||||
maxScale: PhotoViewComputedScale.covered * 3,
|
||||
loadingBuilder: (context, event) => loadingView(),
|
||||
errorBuilder: (BuildContext context, Object error, StackTrace? stackTrace) => errorView,
|
||||
heroAttributes: PhotoViewHeroAttributes(tag: controller.heroTag),
|
||||
),
|
||||
);
|
||||
}),
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
import 'package:get/get.dart';
|
||||
|
||||
/// 标题栏高度
|
||||
double titleBarHeight = 45.h;
|
||||
@ -13,9 +14,9 @@ double todayNewestHeight = 64.h;
|
||||
|
||||
/// discover列表高度
|
||||
double discoverListHeight = 1.sh -
|
||||
ScreenUtil().statusBarHeight -
|
||||
MediaQuery.of(Get.context!).padding.top -
|
||||
titleBarHeight -
|
||||
todayNewestHeight -
|
||||
7.h -
|
||||
14.h -
|
||||
kBottomNavigationBarHeight -
|
||||
ScreenUtil().bottomBarHeight;
|
||||
MediaQuery.of(Get.context!).padding.bottom;
|
||||
|
||||
@ -16,7 +16,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||
# In Windows, build-name is used as the major, minor, and patch parts
|
||||
# of the product and file versions while build-number is used as the build suffix.
|
||||
version: 1.0.1+2
|
||||
version: 1.0.2+3
|
||||
|
||||
environment:
|
||||
sdk: '>=3.3.4 <4.0.0'
|
||||
|
||||
Loading…
Reference in New Issue
Block a user