You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Flutter中设置动态/视频壁纸(无需第三方应用)

Flutter 无需第三方应用/Activity 设置视频动态壁纸方案

由于async_live_wallpaper依赖系统或第三方应用完成设置,要实现无跳转的视频动态壁纸,核心思路是在Android端自定义LiveWallpaper Service,通过Flutter与原生的MethodChannel通信直接触发设置。iOS平台受系统限制,无法实现无跳转设置,以下仅针对Android方案说明。

实现步骤

1. 编写Android原生LiveWallpaper Service

创建VideoLiveWallpaperService.kt文件,继承WallpaperService并实现视频播放逻辑:

import android.service.wallpaper.WallpaperService
import android.view.SurfaceHolder
import android.media.MediaPlayer
import android.net.Uri

class VideoLiveWallpaperService : WallpaperService() {
    override fun onCreateEngine(): Engine = VideoWallpaperEngine()

    inner class VideoWallpaperEngine : Engine() {
        private var mediaPlayer: MediaPlayer? = null

        override fun onSurfaceCreated(holder: SurfaceHolder) {
            super.onSurfaceCreated(holder)
            mediaPlayer = MediaPlayer().apply {
                // 替换为你的视频路径:这里示例用res/raw下的video.mp4
                setDataSource(applicationContext, Uri.parse("android.resource://${packageName}/raw/video"))
                setSurface(holder.surface)
                isLooping = true
                prepareAsync()
                setOnPreparedListener { start() }
            }
        }

        override fun onVisibilityChanged(visible: Boolean) {
            super.onVisibilityChanged(visible)
            if (visible) mediaPlayer?.start() else mediaPlayer?.pause()
        }

        override fun onSurfaceDestroyed(holder: SurfaceHolder) {
            super.onSurfaceDestroyed(holder)
            mediaPlayer?.release()
            mediaPlayer = null
        }
    }
}

2. 配置AndroidManifest与资源文件

  • 在AndroidManifest.xml中添加权限与Service注册:
<uses-permission android:name="android.permission.SET_WALLPAPER" />
<!-- Android 13+ 使用READ_MEDIA_VIDEO替代下面的权限 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" />

<service
    android:name=".VideoLiveWallpaperService"
    android:label="Video Live Wallpaper"
    android:permission="android.permission.BIND_WALLPAPER">
    <intent-filter>
        <action android:name="android.service.wallpaper.WallpaperService" />
    </intent-filter>
    <meta-data
        android:name="android.service.wallpaper"
        android:resource="@xml/wallpaper" />
</service>
  • 在res/xml目录下创建wallpaper.xml:
<?xml version="1.0" encoding="utf-8"?>
<wallpaper xmlns:android="http://schemas.android.com/apk/res/android" />
  • 将video.mp4放入res/raw目录(注意文件名小写,无特殊字符)。

3. Flutter端通过MethodChannel调用原生方法

在Flutter中创建通道,调用原生代码完成壁纸设置:

import 'package:flutter/services.dart';

class VideoWallpaperManager {
  static const MethodChannel _channel = MethodChannel('video_wallpaper');

  static Future<void> setVideoWallpaper() async {
    try {
      await _channel.invokeMethod('setVideoWallpaper');
    } on PlatformException catch (e) {
      print('设置动态壁纸失败: ${e.message}');
    }
  }
}

// 调用示例:比如在按钮点击事件中触发
// ElevatedButton(
//   onPressed: () => VideoWallpaperManager.setVideoWallpaper(),
//   child: const Text('设置视频壁纸'),
// )

4. 原生端注册MethodChannel

在MainActivity.kt中处理Flutter的调用请求:

import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel
import android.app.WallpaperManager

class MainActivity : FlutterActivity() {
    private val CHANNEL = "video_wallpaper"

    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)
        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result ->
            if (call.method == "setVideoWallpaper") {
                val wallpaperManager = WallpaperManager.getInstance(this)
                try {
                    wallpaperManager.setWallpaperComponent(componentName = componentName, cls = VideoLiveWallpaperService::class.java)
                    result.success(null)
                } catch (e: Exception) {
                    result.error("SET_FAILED", e.message, null)
                }
            } else {
                result.notImplemented()
            }
        }
    }
}

注意事项

  • Android 13及以上版本,需动态申请READ_MEDIA_VIDEO权限才能读取外部存储的视频文件。
  • 若视频位于外部存储,需修改setDataSource的Uri为对应文件路径(如Uri.fromFile(File("/storage/emulated/0/DCIM/video.mp4")))。
  • iOS平台:苹果系统限制第三方应用直接设置动态壁纸,仅能引导用户手动前往设置界面完成操作,无无跳转方案。

内容的提问来源于stack exchange,提问作者Muhammad Tayyab

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 17:59:55