Pull to refresh

Открытый клон Chameleon Launcher

Reading time5 min
Views17K
Года два­-три назад я случайно узнал о интересном лаунчере для android ­ chameleon launcher. Купил и какое­-то время даже успешно использовал, пока создатель не потерял к нему интерес.

Привлекло меня в этом лаунчере то, что он позволял превратить домашний экран планшета в информационное табло — тут и rss­ленты, и twitter, и погода и т. д. Всё смотрится красиво и удобно, а место на экране не расходуется зря (а его на экране всегда мало). Кроме того, он позволял писать свои собственные виджеты на js.

Но создатель потерял интерес к своему творению (в своё время он собирал на него деньги через kickstarter) и сначала виджеты перестали работать (они используют сервер для работы), появились баги, которые не фиксились. В итоге недавно приложение и вовсе было удалено из Play Market.

Постепенно у меня начало появляться желание написать аналогичный лаунчер — приценивался к технологиям, но не хотел связываться с Java. Но в эти выходные я решил попробовать свои силы в написании клона этого лаунчера. В этой заметке я расскажу о текущем состоянии дел. Возможно, кто­-то ещё заинтересуется проектом и присоединится к нему.

Основной экран:
image


Cписок приложений:
image

Целью было сделать что­-то более­-менее похожее за минимальное время: для начала без всяких фенечек — анимации, drag&drop и т. п., чтобы потом постепенно довести функционал до нужного состояния. Также я практически не заморачивался кроссдевайсовой вёрсткой и не имею понятия, насколько хорошо будет отображаться это на девайсах, отличных от семидюймовых планшетов (1024x600) в горизонтальном положении. Минимум значит минимум, иначе можно застрять надолго. Я хотел сделать хоть какой­-то прототип для развития, и вообще — пощупать технологии.

Также я сделал одно важное для меня изменение в концепции архитектуры виджетов. Теперь не нужно их хостить на сервере, чтобы делать кроссдоменные запросы. Их можно делать без использования скриптов на сервере.

Начало пути


Прежде чем начать разработку, я в очередной раз проверил, не начал ли писать кто-то клон до меня (я периодически это мониторил) и убедившись, что всё ещё нет, я начал искать проекты лаунчера на html. Cразу нашёл github.com/Aricwithana/DOMLauncher2. Но базис показался не слишком подходящим, много лишнего, а удаление кода (почти всего) это потеря времени. По этому я решил начать с чистого листа. Решил не использовать PhoneGap, т.к. мне показалось, что лаунчер вещь не простая и вдруг чего-то не хватит мне в нём и придётся начинать заново на чистом Android SDK.

После установки Android SDK, я сгенерировал дефолтный проект следующей командой:
android create project -n Launcher -t 'android-16' -p . -k com.longerdev.launcher -a LauncherActivity

примечание
Сразу сделаю отступление, тут я указал версию API 16, думая о телефоне, на котором у меня сейчас android 4.1, я тогда ещё не знал, что из-за этого я потеряю минут 20 пытаясь понять, почему проект не собирается с JavaScriptInterface (о том, что это будет далее).

Сбилдил проект и установил приложение:
ant debug && ant installd

Первое, что я хотел сделать — избавиться это от заголовка окна. После поисков и различных эксперементов, я пришёл к выводу, что лучший способ это сделать прописать для приложения. Для этого нужно создать файл res/values/styles.xml и немного отредактировать AndroidManifest.xml:
<application
    ... 
    ...
    android:theme="@style/AppTheme">

    <resources>
        <style name="AppTheme" parent="android:Theme.Holo.Wallpaper">
            <item name="android:windowActionBar">false</item>
            <item name="android:windowNoTitle">true</item>
        </style>
    </resources>

В название темы Wallpaper не случайно, если его убрать, то фон приложения будет чёрный. Но т.к. он есть, то приложение подтягивает обои из системных настроек (а это избавляет от написание большого колличества кода).

Превращение в лаунчер


Любое приложения можно легко превратить в «лаунчер». Для этого нужно добавить 2 строки в AnroidManifest.xml и приложение будет доступно по кнопке home:
<application
    ...
    <activity
        ...
        <intent-filter>
            ...
            <category android:name="android.intent.category.HOME" />
            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>

примечание

Теперь после сборки и установки приложение будет доступно по клавише home.

Создание и оживление WebView


В android, чтобы была возможность использовать html и js, нужно добавить элемент WebView в приложение. Для этого нужно отредактировать основной layout (res/layout/main.xml):
<?xml version="1.0" encoding="utf-8"?>
<WebView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/webview"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    />

После этого я создал assets/www/index.html с каким-то небольшим текстом и подключил его отображение в LauncherActivity.java:
public void onCreate(Bundle savedInstanceState){
    ...
    WebView mainWebView = (WebView) findViewById(R.id.webview);
    mainWebView.loadUrl("file:///android_asset/www/index.html");

Теперь если запустить приложение, можно увидеть содержимое файла, но если попробовать написать какой-нибудь js код, то он не будет работать. Его нужно включать отдельно:
WebSettings webSettings = mainWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setAllowFileAccessFromFileURLs(true);
webSettings.setAllowUniversalAccessFromFileURLs(true);

Последние 2 строки разрешают делать кроссдоменные запросы из js, являющегося частью приложения.

Пробрасывание в js функций из java


Со временем, возникла необходимость к обращению к android api. В ходе поисков как это сделать, я узнал, что можно создать класс, методы которогу будут доступны из js почти как родные (приходится использовать JSON.parse при передачи объектов).

Весь код класса описывать не буду, опишу лишь ключевые моменты.

Если в классе создать функцию и написать перед ней @JavascriptInterface она будет доступна в js. Функция запуска приложения:
@JavascriptInterface
public String echo(String name) throws Exception{
    return name;
}

На самом деле нужно ещё подключить этот класс к WebView:
MyJavaScriptInterface myInterface = new MyJavaScriptInterface(mainWebView, LauncherActivity.this);
mainWebView.addJavascriptInterface(myInterface, "AndroidAPI");

Теперь из js можно достучаться до кода так:
AndroidAPI.echo();


Заключение


Я описал наиболее интересные/сложные этапы разработки. Всё расписывать не стал, т.к. статья вышла бы слишком длинной. Да и не факт, что интересной. Лучше спрашивайте, я отвечу.

Что уже есть:
— один экран домашний (пока несколько нельзя, но это один из следующих этапов, попутно буду прибираться в коде)
— виджеты — rss (поддерживает только rss 2.0), погода
— простой список приложений без постраничного листания
— настраиваемая панель быстрых ярлыков (там же есть, временная кнопка refresh для удобства дебага)

Ближайшие планы:
— как-то вынести настройки в конфиг (вот с этим мне нужна в первую очередь помощь, т.к. это моё первое приложение под android и пока не совсем понял экосистему. Небольшой эксперимент провёл по этому вопросу, но пока в коде отключил его)
— несколько домашних экранов
— более удобное API для виджетов
— переписать виджеты rss и погоды
— написать виджет для twitter, часы (с функцией будильника),
— кроссдевайсовая вёрстка (если будут девайсы для тестирования)

В первую очередь я хочу реализовать версию для планшета и лишь потом, возможно, возьмусь за телефон. Поддержка стандартных виджетов android не планируется. Минимально необходимая версия android 4.2 (API 17).

Буду благодарен комментариям, советам и желающим поучаствовать в проекте.
Исходники — github.com/Longer/ClawLauncher (билд).
Tags:
Hubs:
+14
Comments10

Articles