Статьи

Создание живых обоев на Android

Android имеет ряд функций персонализации, которые помогают пользователям настраивать многие аспекты работы с устройством. Одной из таких особенностей являются живые обои. Живые обои не остаются статичными фоновыми изображениями, а имеют интерактивные функции. Узнайте, как создать живые обои в этом уроке!

Живые обои на Android обычно используются в качестве фона на домашнем экране, который каким-то образом анимируется или изменяется со временем. Если у вас есть устройство Android, вы, вероятно, видели пару встроенных живых обоев, например, те, где листья падают в рябь воды.

Как разработчик, вы можете создавать и публиковать живые обои. Процесс не особо сложный. Однако создание живых обоев, которые увлекательны и желательны, но при этом не разряжают батарею устройства пользователя, являются чем-то вроде проблемы. В этом уроке мы познакомим вас с процессом создания живых обоев, которые ведут себя хорошо. 🙂


Недавно мы показали вам, как использовать RenderScript . Конечным результатом этого урока был простой эффект снегопада. Давайте превратим этот эффект в живые обои.

Открытый исходный код этого руководства доступен для скачивания . Мы рекомендуем использовать его, чтобы следовать. Списки кода в этом руководстве не включают в себя все содержимое каждого файла и не охватывают настройку проекта или код, описанный в предыдущих руководствах.


Можно сказать, что живые обои — это просто услуга. В конце концов, чтобы создать живые обои, вы просто выходите из класса WallpaperService и реализуете один метод, часто всего с одной строкой кода, а затем добавляете определение службы в файл манифеста.

Давайте посмотрим, как это выглядит. Вот обои для рабочего стола:

И вы сделали! Ладно не совсем Основная часть работы с живыми обоями происходит в реализации WallpaperService.Engine. Здесь вы можете ответить на обратные вызовы, такие как onSurfaceChanged () и onSurfaceCreated (). Звучит знакомо? Они очень похожи на обратные вызовы, которые вы могли видеть при реализации View или другого объекта Surface.

И теперь реальность живых обоев раскрывается: при реализации WallpaperService.Engine все, что вы делаете, это рисуете на предоставленную поверхность (через SurfaceHolder). Это почти так просто. Прежде чем мы перейдем к реализации WallpaperService.Engine, давайте рассмотрим некоторые другие аспекты конфигурации.


Поскольку живые обои — это сервис, вы должны зарегистрировать сервис в файле манифеста. Регистрация службы может выглядеть примерно так:

01
02
03
04
05
06
07
08
09
10
11
<service
    android:name=»com.mamlambo.fallingsnow.FallingSnowWallpaperService»
    android:label=»@string/app_name»
    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/fallingsnow_wp» />
</service>

Здесь есть пара вещей, на которые стоит обратить внимание. Во-первых, для использования этой службы требуется разрешение BIND_WALLPAPER (т.е. другому приложению, использующему эти обои, потребуется разрешение BIND_WALLPAPER в качестве записи разрешения использования в их манифесте). Во-вторых, фильтр намерений — это строка, похожая на базовый класс. Наконец, метаданные указывают на файл XML. Этот XML-файл, определенный разработчиком, предоставляет некоторые дополнительные настройки обоев. Вот наш XML-файл для настроек живых обоев, который называется fallingsnow_wp:

1
2
3
4
<?xml version=»1.0″ encoding=»utf-8″?>
<wallpaper xmlns:android=»http://schemas.android.com/apk/res/android»
    android:thumbnail=»@drawable/ic_launcher»
    android:description=»@string/fallingsnow_wp_desc» />

Здесь мы просто используем обычный значок запуска в качестве эскиза и указываем на строку, которая будет отображаться в качестве описания в списке обоев. Если ваши живые обои нуждаются в настройке, вы должны указать на них с помощью свойства android: settingsActivity.

Android SDK - Настройки живых обоев

Наконец, вернувшись в свой файл манифеста, не забудьте установить функцию для использования для android.software.live_wallpaper:

1
<uses-feature android:name=»android.software.live_wallpaper» />

Теперь, когда скучные, но критически важные вещи не нужны, давайте вернемся к реальной работе: созданию класса WallpaperService.Engine. Поскольку у нас уже есть файл RenderScript для анимации, все, что нам нужно сделать, это связать рендеринг с новой поверхностью. Метод onSurfaceCreated () в Engine является отличным местом для создания объекта RenderScriptGL, который нам понадобится:

01
02
03
04
05
06
07
08
09
10
@Override
public void onSurfaceCreated(SurfaceHolder holder) {
    super.onSurfaceCreated(holder);
     
    RenderScriptGL.SurfaceConfig surfaceConfig = new RenderScriptGL.SurfaceConfig();
    mRenderScriptGL = new RenderScriptGL(FallingSnowWallpaperService.this, surfaceConfig);
     
    // use low for wallpapers
    mRenderScriptGL.setPriority(RenderScript.Priority.LOW);
}

Мы также установили низкий приоритет рендеринга — это живые обои, а не критическая игра или движок рендеринга пользовательского интерфейса. Это не должно замедлять что-либо еще в системе.

Очистите это в методе onSurfaceDestroyed ():

01
02
03
04
05
06
07
08
09
10
11
12
@Override
public void onSurfaceDestroyed(SurfaceHolder holder) {
    super.onSurfaceDestroyed(holder);
    if (mSnowRS != null) {
        mSnowRS.stop();
        mSnowRS = null;
    }
    if (mRenderScriptGL != null) {
        mRenderScriptGL.destroy();
        mRenderScriptGL = null;
    }
}

Метод onSurfaceChanged () является отличным местом для инициализации класса RenderScript. Это первое место, где вы узнаете детали того, что вы будете рендерить, такие как ширина и высота. Здесь мы также устанавливаем поверхность для класса RenderScriptGL.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
@Override
public void onSurfaceChanged(SurfaceHolder holder, int format,
        int width, int height) {
    super.onSurfaceChanged(holder, format, width, height);
     
     
    if (mRenderScriptGL != null) {
        mRenderScriptGL.setSurface(holder, width, height);
    }
    if (mSnowRS == null) {
        mSnowRS = new SnowRS(width, height);
        mSnowRS.init(mRenderScriptGL, getResources(), isPreview());
        mSnowRS.start();
    }
}

Это хорошая идея, чтобы остановить обои, когда они не видны.

01
02
03
04
05
06
07
08
09
10
@Override
public void onVisibilityChanged(boolean visible) {
    super.onVisibilityChanged(visible);
    if (mSnowRS == null) {
        if (visible) {
            mSnowRS.start();
        } else {
            mSnowRS.stop();
        }
    }

Вот и все. Живые обои катятся. Или оживляет. Или делает все, что вы хотите, чтобы это было сделано.

Хотите отвечать на постукивания? Переопределите метод onCommand () класса WallpaperService.Engine.

Хотите изменить положение, когда пользователь перемещается между страницами домашнего экрана? Переопределите метод onOffsetsChanged () класса WallpaperService.Engine.

Хотите знать, просматривает ли пользователь предварительный просмотр перед установкой обоев? Вызовите метод isPreview () класса WallpaperService.Engine и проверьте результаты.

Полная реализация нашего класса WallpaperService.Engine может быть найдена в FallSnowWallpaperService.java проекта с открытым исходным кодом.

Давайте посмотрим на живые обои:

Android SDK - Live Wallpaper Preview

Это должно выглядеть знакомо; это то же самое, что мы видели в действии RenderScript.


Живые обои — отличное место для создания высокоэффективных и великолепных графических эффектов. Но вы должны сделать это, осознавая, что пользователь не обязательно сидит и смотрит демо (вы знаете, как на scene.org ). Это означает, что вам может понадобиться уменьшить частоту кадров, уменьшить количество пикселей, количество полигонов или детали текстур, чтобы обои были интересными, но не вызывали нагрузки на процессор, графический процессор и батарею. Если пользователи обнаружат, что ваши живые обои разряжают их батарею, это делает ваше приложение плохо выглядящим, а их устройство кажется слабым с низким временем автономной работы. Неудачный опыт работы с устройством Android приводит к тому, что все разработчики терпят неудачу


Демонстрация и активность (из предыдущего урока) по-прежнему доступны при запуске приложения. Вместо того, чтобы удалить его, почему бы просто не добавить обработчик, чтобы, когда пользователь щелкает по нему, настройки живых обоев появлялись, чтобы пользователь мог выбирать живые обои?

1
2
3
4
public void onWallpaperSettings(View view) {
    Intent wallpaperSettings = new Intent(Intent.ACTION_SET_WALLPAPER);
    startActivity(wallpaperSettings);
}

Почему бы и нет! Это было легко. В любом интерактивном представлении просто добавьте свойство android: onClick = «onWallpaperSettings», и все готово.

Вот неподвижное изображение:

Android SDK - Live Wallpaper Preview

Живые обои — это удобный способ расширить ваше приложение за пределы его типичных границ. Есть ролевая игра? Сделайте аккуратные живые обои с участием главных героев. Просто убедитесь, что вы используете здравый смысл при рендеринге на экран, чтобы пользовательский опыт работы со своим устройством не пострадал.

Дайте нам знать, какие крутые живые обои вы создаете в комментариях!

Разработчики мобильных приложений Лорен Дарси и Шейн Кондер являются соавторами нескольких книг по разработке Android: углубленная книга по программированию под названием « Разработка беспроводных приложений для Android» и « Самс научи себя разрабатывать приложения для Android за 24 часа» . Когда они не пишут, они тратят свое время на разработку мобильного программного обеспечения в своей компании и оказание консультационных услуг. С ними можно связаться по электронной почте [email protected] , через их блог на androidbook.blogspot.com и в Twitter @androidwireless .

Купить Android-разработку беспроводных приложений, 2-е издание Купить Sam's Teach Yourself для Android-разработки приложений в течение 24 часов Код Мамламбо в Код-Каньоне