Flutter开发Android应用:如何调用WallpaperManager设置壁纸?
Absolutely! Since you’re okay with dropping iOS support, you’ve got two great options to implement Android wallpaper setting in Flutter—either using a pre-built plugin (the fastest path) or creating a custom platform channel to call Android’s native WallpaperManager directly. Let’s walk through both:
This is the simplest approach, as someone else has already wrapped the Android WallpaperManager logic into a Flutter-friendly package. Here’s how to use one of the most popular options:
Step 1: Add the Plugin Dependency
Add this to your pubspec.yaml file (check for the latest version first):
dependencies: wallpaper_manager: ^2.0.0
Run flutter pub get to install it.
Step 2: Configure Android Permissions
Open android/app/src/main/AndroidManifest.xml and add these permissions inside the <manifest> tag (before the <application> tag):
<uses-permission android:name="android.permission.SET_WALLPAPER" /> <!-- For Android 10-12, needed to access local images --> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" />
Step 3: Implement the Wallpaper Logic
Here’s a sample function to pick an image from the gallery and set it as the home screen wallpaper:
import 'package:wallpaper_manager/wallpaper_manager.dart'; import 'package:image_picker/image_picker.dart'; import 'package:permission_handler/permission_handler.dart'; Future<void> setHomeScreenWallpaper() async { // Request necessary permissions first final storageStatus = await Permission.storage.status; if (!storageStatus.isGranted) { await Permission.storage.request(); } // Pick an image from the gallery final pickedImage = await ImagePicker().pickImage(source: ImageSource.gallery); if (pickedImage == null) return; // Set the wallpaper (use LOCK_SCREEN for lock screen, or BOTH_SCREENS for both) try { await WallpaperManager.setWallpaperFromFile( pickedImage.path, WallpaperManager.HOME_SCREEN, ); print("Wallpaper set successfully!"); } catch (e) { print("Failed to set wallpaper: $e"); } }
If you need full control over the native logic, you can create a direct bridge between Flutter and Android’s WallpaperManager:
Step 1: Flutter Side - Define the Method Channel
Create a service class to handle communication with Android:
import 'package:flutter/services.dart'; class AndroidWallpaperService { static const _methodChannel = MethodChannel('com.yourapp.wallpaper_service'); static Future<void> setWallpaper(String imagePath) async { try { await _methodChannel.invokeMethod('set_wallpaper', {'image_path': imagePath}); } on PlatformException catch (e) { throw Exception("Error setting wallpaper: ${e.message}"); } } }
Step 2: Android Side - Implement the Native Logic
Open android/app/src/main/kotlin/com/yourapp/MainActivity.kt (or Java equivalent) and add the channel handler:
import android.app.WallpaperManager import android.graphics.BitmapFactory import android.os.Bundle import io.flutter.embedding.android.FlutterActivity import io.flutter.embedding.engine.FlutterEngine import io.flutter.plugin.common.MethodChannel import java.io.IOException class MainActivity : FlutterActivity() { private val CHANNEL = "com.yourapp.wallpaper_service" override fun configureFlutterEngine(flutterEngine: FlutterEngine) { super.configureFlutterEngine(flutterEngine) MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result -> if (call.method == "set_wallpaper") { val imagePath = call.argument<String>("image_path") try { val wallpaperManager = WallpaperManager.getInstance(applicationContext) val bitmap = BitmapFactory.decodeFile(imagePath) wallpaperManager.setBitmap(bitmap) result.success(null) } catch (e: IOException) { result.error("SET_FAILED", e.message, null) } } else { result.notImplemented() } } } }
Don’t forget to add the same permissions to AndroidManifest.xml as in Option 1.
Step 3: Use the Service in Flutter
Call the service after picking an image (same permission and image picker logic as before):
final pickedImage = await ImagePicker().pickImage(source: ImageSource.gallery); if (pickedImage != null) { await AndroidWallpaperService.setWallpaper(pickedImage.path); }
Both approaches work perfectly for Android-only apps. The plugin route is faster for most cases, while the custom channel gives you full control if you need to tweak the native behavior.
内容的提问来源于stack exchange,提问作者Robbert

