安卓视频作为动态壁纸

7
我正在尝试将视频作为动态壁纸。 我正在使用媒体播放器实现。我可以获取SurfaceHolder并将其传递给媒体播放器。 但是它对我不起作用,它给我以下异常信息:
LogCat异常详细信息
ERROR/AndroidRuntime(302): java.lang.UnsupportedOperationException: Wallpapers do not support keep screen on

如果我不给媒体播放器提供持有者,它可以工作,但是我只能听到音频。我看到一个名为VideoLiveWallpaper的应用程序,它将视频设置为动态壁纸,所以这是可能的,也许我漏掉了什么。我粘贴了代码,对此的任何帮助都将不胜感激。

代码片段

public void surfaceCreated(SurfaceHolder holder) {
  // TODO Auto-generated method stub

 holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
  mp=MediaPlayer.create(getApplicationContext(), R.raw.sample);
  mp.setDisplay(holder);
  mp.start();
 }

@user593443 你解决了吗?我正在苦苦挣扎,已经开了悬赏。LISA https://dev59.com/N2025IYBdhLWcg3wPzbL - Lisa Anne
4个回答

5

与其使用**mediaPlayer.setDisplay(surfaceHolder)**,您可以使用**mediaPlayer.setSurface(surfaceHolder.getSurface())**

它不会与属性KeepScreenOn发生任何冲突。

NJOY.. :)


这应该是答案。它能够工作,虽然我不确定为什么,因为setSurface也会通过首先在MediaPlayer中调用updateSurfaceScreenOn来调用SurfaceHolder中的setKeepScreenOn。 - Flyview
想了想,setKeepScreenOn从未被调用,因为setSurface将mSurfaceHolder设置为null。 - Flyview

3
这是由于MediaPlayer调用了你传递给它的SurfaceHolder的setKeepScreenOn方法所致。你可以通过创建一个自定义的实现类来绕过这个问题,并覆盖setKeepScreenOn方法,如下所示:
package com.justinbuser.videolivewallpapers;

import android.graphics.Canvas;
import android.graphics.Rect;
import android.view.Surface;
import android.view.SurfaceHolder;

public class VideoSurfaceHolder implements SurfaceHolder {

    private SurfaceHolder surfaceHolder;

    public VideoSurfaceHolder(SurfaceHolder holder) {
        surfaceHolder = holder;
    }

    @Override
    public void addCallback(Callback callback) {
        surfaceHolder.addCallback(callback);
    }

    @Override
    public Surface getSurface() {
        return surfaceHolder.getSurface();
    }

    @Override
    public Rect getSurfaceFrame() {
        return surfaceHolder.getSurfaceFrame();
    }

    @Override
    public boolean isCreating() {
        return surfaceHolder.isCreating();
    }

    @Override
    public Canvas lockCanvas() {
        return surfaceHolder.lockCanvas();
    }

    @Override
    public Canvas lockCanvas(Rect dirty) {
        return surfaceHolder.lockCanvas(dirty);
    }

    @Override
    public void removeCallback(Callback callback) {
        surfaceHolder.removeCallback(callback);
    }

    @Override
    public void setFixedSize(int width, int height) {
        surfaceHolder.getSurface().setSize(width, height);
        surfaceHolder.setSizeFromLayout();
    }

    @Override
    public void setFormat(int format) {
        surfaceHolder.setFormat(format);
    }

    @Override
    public void setSizeFromLayout() {
        surfaceHolder.setSizeFromLayout();
    }

    @Override
    public void setType(int type) {
        surfaceHolder.setType(SURFACE_TYPE_PUSH_BUFFERS);
    }

    @Override
    public void setKeepScreenOn(boolean bool){
        //do nothing
    }

    @Override
    public void unlockCanvasAndPost(Canvas canvas) {
        surfaceHolder.unlockCanvasAndPost(canvas);
    }
}

那么当你只需要对上面发布的代码进行微小修改时,即:

mp.setDisplay(new VideoSurfaceHolder(holder));

你接下来可能会遇到的问题是,视频可以播放,但你只能听到音频。在经过数小时的煎熬、抓狂等之后,你会意识到由于某种原因 setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS)无法正常工作。如果你在 onCreate 中调用它,那么它将起作用,但 surfaceCreated 等永远不会被调用;如果你在 onSurfaceCreated 中调用它,那么就太晚了。我自己还没有解决这个问题,但我会随时向你汇报。


你能解决这个问题吗?我正在苦苦挣扎,我已经开了一个悬赏 https://dev59.com/N2025IYBdhLWcg3wPzbL - Lisa Anne

3
我的猜测是目前流通的视频动态壁纸正在使用完全不同的方法:手动解码媒体并逐帧绘制。我认为你的简单方法无法解决这个问题——否则更多的人已经做到了。我假设你有这个参考,但以防万一:http://forum.xda-developers.com/showthread.php?t=804720明确提到不同的视频格式,这让我相信开发者正在进行自己的解码...祝好运,George

0
错误听起来像是你设置了KeepScreenOn属性的某个地方。它可能在你的清单文件中、定义布局的xml文件中或者主要代码的某个地方。跟随logcat输出找到它并尝试将其移除。

我相信在使用MediaPlayer时,KeepScreenOn是隐含的,并且可以通过使用mp.setScreenOnWhilePlaying(false);或videoHolder.setKeepScreenOn(false);来移除。然而,这两种方法在使用动态壁纸时会导致“壁纸不支持保持屏幕常亮”错误。 - stealthcopter

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接