четверг, 1 ноября 2012 г.

Про разработку

Про Windows Phone 8

Microsoft преследуют постоянные PR и маркетинговые фейлы, связанные с Windows Phone 8. Словно над этой ОС висит какой-то злой рок. Вот взять например, новую инициативу $8 for 8 (зарегистрируйся с 30 октября по 7 ноября как разработчик всего за $8 вместо $99). Классно? На первый взгляд - да. Но не все так просто. При внимательном прочтении условий оказывается, что Microsoft берет у вас беспроцентный кредит в размере $91 на срок от 30 до 60 дней. Т.е. с вашей карты снимут $99, а через месяц-другой вернут $91. Видимо, решение этой задачи поручили не специалисту по PR, а математику, который кипятит чайник, выливая воду и сводя задачу к предыдущей.

Про баг в ECM-Journal

Запустив приложение ECM-Journal в эмуляторе Android 4.1, я увидел, что оно падает сразу при запуске. Причина этого оказалась банальна: вызов requestWindowFeature(Window.FEATURE_NO_TITLE); оставшийся еще с тех времен, когда я не использовал ActionBarSherlock.

Обновление 2.1.3, исправляющее этот баг, уже в маркете. Качайте, обновляйтесь.


PS.  Дополнение про Windows Phone 8. Оказывается, $99 - это не цена входа в программу, а размер ежегодного платежа. Ну, молодцы, что еще тут скажешь... И эти люди запрещают мне ковыряться в носу хотят соперничать с Android? Совсем озверел Черный Абдулла связь с реальностью потеряли.

суббота, 20 октября 2012 г.

Новый NAS

Намучившись со старым сетевым хранилищем, я сказал себе: "Хватит терпеть этот беспредел!" и пошел покупать новое.

Чтение форумов и прайсов ввергло меня в уныние. Дешевые d-link'и все ругали, а хваленые Qnap и Synology стоили совсем уж бешеных денег. Поэтому я решил выбрать компромиссное решение: Iomega ix2-dl. Единственное, что взял бездисковый вариант и отдельно взял WD Green, поскольку Seagate Barracuda, поставляющиеся с Iomega, тоже ругали.

Что я получил:
  • DLNA-сервер с поддержкой протоколов даже для техники Apple, хотя мне это и без надобности. Проверить успел только на видео 720p - играет отлично.
  • Torrent-клиент, который был ужасен более, чем полностью, но с возможностью замены его на Transmission вот по этой замечательной инструкции (клиент для управления брать здесь).
  • Принт-сервер. Пока не проверял в реальной работе, но вещь вообще полезная, с учетом того, что дома у меня только ноутбуки).
В общем, пока я вполне доволен.

воскресенье, 5 августа 2012 г.

Android: WebView vs. YouTube

Как известно, WebView не показывает ролики YouTube. Т.е. Показывает, конечно, но только через Flash. Т.е. Работает далеко не на всех устройствах. Самое смешное, что встроенный браузер Android эти же самые ролики отлично показывает.

Впрочем, если не принципиально смотреть ролик на самой странице, то выход есть. Что для этого нужно:
  1. Перед показом страницы распарсить ее, найти ролики YouTube. Как правило, надо искать тег <objsafeect>, внутри которого есть источник src="http://www.youtube.com/v/ролик-ИД".
  2. Вместо этого тега надо вписать свою cсылку. Если в ней хочется показать название видео, то для этого надо сходить на YouTube и запросить его. Вместо описания просто приведу пример:
    private String getYouTubeVideoTitle(String videoUrl)
    {
        try
        {
            final String videoInfoUrl = ("http://www.youtube.com/oembed?url=" + 
                URLEncoder.encode(videoUrl, "UTF-8")).replace("%2Fv%2F", "%2Fwatch%3Fv%3D") + 
                "&format=xml";
            URL url = new URL(videoInfoUrl);
            URLConnection urlConn = url.openConnection();
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = dbf.newDocumentBuilder();
            Document doc = db.parse(urlConn.getInputStream());
            String title = doc.getElementsByTagName("title").item(0).getTextContent();
            return title;
        }
        catch (Exception ex)
        {
            // Если не получилось - ничего не делаем, возвращаем null.
        }
        return null;
    }
  3. При клике на эту ссылку надо запустить встроенное приложение YouTube. Для этого вызываем у WebView метод setWebViewClient и передаем в него объект с переопределенным методом shouldOverrideUrlLoading, в котром проверяем url  и при необходимости запускаем Intent.ACTION_VIEW с Youtube url.


PS. ECM-Journal 2.1.2 с такой фишкой - уже в Google Play Store.

PPS. Если вам нравится приложение, не забывайте голосовать или даже писать комменты :-)

четверг, 7 июня 2012 г.

ECM-Journal 2.1.1 - bugfix release

Выпустил новую версию приложения ECM-Journal - 2.1.1. По сути это багфикс-релиз. Исправлен один явный баг и сделаны две фичи, отсутствие которых выглядело как баги:
  1. Возвращена подсветка искомых ключевых слов в результатах поиска (только на странице материала, а не в списке). Эта штука была уже давно, но отвалилась где-то в 2.x.
  2. Сделано кеширование обложки. Теперь при старте приложения всегда открывается обложка, сохраненная при предыдущем запуске. Только после этого происходит проверка обновления, но даже, если обнаружена новая обложка, то в этом сеансе она только сохранится, а не переоткроется. Решение спорное, но я решил, что скорость и удобство работы важнее оперативности прочтения новой обложки.
  3. Большие изображения теперь вписываются в экран, а не приводят к горизонтальной прокрутке. Естественно, что при смене ориентации экрана они автоматически увеличиваются/уменьшаются (ширина экрана ведь изменяется). Любопытно, что это сделано всего одной строчкой в css, хотя я уже начинал писать монструозные скрипты для изменения размера изображений :-)

QR-код:

Ссылка для компьютера.

понедельник, 28 мая 2012 г.

ECM-Journal v2.1

Обновил приложение ECM-Journal до версии 2.1. Несмотря на изменения только в второй цифре, под капотом обновлений довольно много. Связано это с переходом на ActionBarSherlock и более точное соблюдение Google guidelines по дизайну Android-приложений.

С точки зрения конечного пользователя изменений всего два:
  1. В Android 4.0 приложение выглядит (ну или должно выглядеть, по крайней мере) менее чужеродно, за счет использования родного ActionBar.
  2. Отключено постоянное принудительное обновление списков. Новые материалы обновляются автоматически, только если устарели более, чем на 4 часа, список авторов и блоги - не чаще, чем раз в 24 часа. Разумеется, есть возможность ручного обновления.
В данной версии возможны мелкие баги, которые будут исправлены в 2.1.1.
QR-код:

Ссылка для компьютера.

среда, 18 апреля 2012 г.

Android: используем ActionBarSherlock

Поехали

Продолжаем серию "Android для начинающих". Как же использовать ActionBarSherlock после его установки?
  1. Для начала надо зайти в опции компилятора для проекта и поставить там использование Java 1.6.
  2. Далее меняем предка для активности - с Activity на SherlockActivity.
  3. Потом в манифесте добавляем атрибут для этой активности (или для всего приложения, что более логично):
android:theme="@style/Theme.Sherlock"

После это запускаем приложение и видим ActionBar в теме Holo dark со значком и наименованием приложения.

Если нужна светлая тема Holo light то, сооветственно вместо Theme.Sherlock пишем Theme.Sherlock.Light.

Навигация

Навигация через выпадающее меню

Для навигации через выпадающим список (Spinner) скопируем в OnCreate активности код из примера, поставляемого с ActionBarSherlock:

        mLocations = getResources().getStringArray(R.array.locations);

        Context context = getSupportActionBar().getThemedContext();
        ArrayAdapter list = ArrayAdapter.createFromResource(
            context, R.array.locations, R.layout.sherlock_spinner_item);
        list.setDropDownViewResource(
            R.layout.sherlock_spinner_dropdown_item);

        getSupportActionBar().setNavigationMode(
            ActionBar.NAVIGATION_MODE_LIST);
        getSupportActionBar().setListNavigationCallbacks(list, this);

R.array.locations - это набор элементов выпадающего списка (т.е. по сути набор страниц/экранов приложения, по которым досупна навигация). R.layout.sherlock_spinner_dropdown_item разрешается автоматически, делать чего-то в своем layout не надо.

Для обработки выбора элемента списка (и реализации навигации) нужно будет реализовать в активности интерфейс OnNavigationListener (ну или передать другую реализацию интерфейса в вызов setListNavigationCallbacks).

Навигация через табы

Для реализации навигации через табы тоже можно скопировать код из примера:

        getSupportActionBar().setNavigationMode(
            ActionBar.NAVIGATION_MODE_TABS);
        for (int i = 1; i <= 3; i++) {
            ActionBar.Tab tab = getSupportActionBar().newTab();
            tab.setText("Tab " + i);
            tab.setTabListener(this);
            getSupportActionBar().addTab(tab);
        }

Здесь уже активности нужно будет реализовать интерфейс TabListener.

На устройствах с HVGA-экраном набор ActionBar+табы может занимать непозволительно много места, поэтому можно скрыть ActionBar, оставив одни табы:

        getSupportActionBar().setDisplayShowHomeEnabled(false);
        getSupportActionBar().setDisplayShowTitleEnabled(false);

Действия

Создание

ActionBar на то и ActionBar, чтобы показывать пользователю не только навигацию, но и действия. Добавление действий описано в демо-примере так:

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        //Used to put dark icons on light action bar
        boolean isLight = SampleList.THEME == R.style.Theme_Sherlock_Light;

        menu.add("Save")
            .setIcon(isLight ? 
                R.drawable.ic_compose_inverse : 
                R.drawable.ic_compose)
            .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);

        menu.add("Search")
            .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM | 
                MenuItem.SHOW_AS_ACTION_WITH_TEXT);

        menu.add("Refresh")
            .setIcon(isLight ? R.drawable.ic_refresh_inverse : 
                R.drawable.ic_refresh)
            .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM | 
                MenuItem.SHOW_AS_ACTION_WITH_TEXT);

        return true;
    }

Обработка

Для обработки действий есть две альтернативы:
  1. Реализовать метод onOptionsItemSelected, в который будут приходить события на каждое действие.
  2. Действиям задать индивидуальные обработчики при помощи метода setOnMenuItemClickListener()

Выводы

По факту ActionBar оказался довольно простой в использовании компонентой, по крайней мере там, где дело касается самых основ.

понедельник, 9 апреля 2012 г.

Про scriptogr.am

Scriptogr.am - это очень гиковский сервис блогов, построенный вокруг dropbox.

Для того, чтобы начать работать с обычным сервисом блогов, надо придумать себе имя и пароль. А в srcriptogr.am вместо этого надо авторизовать приложение в dropbox.

Дальше - больше. Посты - это файлы в формате markdown, лежащие в специальной папке в dropbox. Нужен новый пост - пишем файлик и в сервисе жмем кнопку синхронизации. Voila!

Комментарии к постам прикручиваются через редактирование HTML-шаблона. Я поставил себе disqus, но как-то он немного криво выглядит (народ в интернетах тоже жалуется на это).

Зачем все это? Just for fun! Я завел линкблог. Как пойдет дело дальше - пока не знаю, посмотрим.

воскресенье, 18 марта 2012 г.

Android: устанавливаем ActionBarSherlock

ActionBarSherlock - это враппер, позволяющий делать модные ActionBar-ы в любой версии Android. В ICS он использует системный ActionBar, а в более ранних версиях (2.х) - рисует свой.

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

Итак, как же его установить "с нуля". Рассмотрим на примере Eclipse (хотя бы потому, что IDEA и прочие альтернативы я не пробовал):

  1. Скачиваем архив с официального сайта и распаковываем за пределами Workspace (это важно!)
  2. Создаем новый проект из существующих исходников, указывая подпапку library. Контролируем, что target sdk стоит в 15 (Android 4.0.3), а minimal sdk - в ту версию, которая вам нужна (у меня это 7 - Android 2.1).
  3. Проверяем, что в свойствах проекта на закладке Android стоит флажок Library.
  4. В Eclipse запускаем Android SDK Manager, у него в самом конце списка находим Extras и устанавливаем Android support package.
  5. В контекстном меню проекта выбираем Android Tools - Add Compatibility Library...
  6. Все, теперь можно собирать проект и подключать к своему как Library.

воскресенье, 26 февраля 2012 г.

ECM-Journal 2.0

Допилил все-таки версию 2.0.

Основные изменения:
  • Новый дизайн (почти по гайдлайнам Google);
  • Цветовая схема теперь соответствует последней версии сайта;
  • Появилась обложка с материалом главного редактора.

Ссылка на маркет та же. QR-код тоже не изменился:

пятница, 17 февраля 2012 г.

Android: делаем свой шрифт WebView

Некоторое время назад я начал переделывать интерфейс приложения ECM-Journal под новые гайдлайны Google. Одна из рекомендаций этих гайдлайнов состоит в использовании шрифта Roboto. Шрифт стандартный в ICS, но в Android 2.x его надо добавлять и настраивать вручную. Для простых элементов управления или даже списков шрифт настраивается достаточно легко (разве что со Spinner приходится писать несколько "необязательный" код. А вот как быть с WebView?

В принципе, решение находится примерно секунд за 10, но оно не окончательное, ведь в "браузере" может использоваться не только Regular-шрифт, но и другие начертания. Для того, чтобы их использовать, достаточно положить себе полный набор шрифтов Roboto и слегка подкрутить CSS:
<style type="text/css">
<!--
@font-face {
font-family: roboto;
font-style: normal;
font-weight: normal;
src: url("file:///android_asset/Roboto-Regular.ttf") }
@font-face {
font-family: roboto;
font-style: italic;
font-weight: normal
  src: url("file:///android_asset/Roboto-Italic.ttf") }
@font-face {
font-family: roboto;
font-style: normal;
font-weight: bold;
src: url("file:///android_asset/Roboto-Bold.ttf")
}
@font-face {
font-family: roboto;
font-style: italic;
font-weight: bold;
src: url("file:///android_asset/Roboto-BoldItalic.ttf") }
body {
font-family: roboto;
}
--> </style>
Вот такой tip&trick.