пятница, 29 июля 2011 г.

Прогноз погоды через XML


  • gismeteo.ru - дает прогноз на сутки
  • foreca.com - дает яндексу
  • у гугла мутный секретный API - хуже чем у GisMeteo
  • суммируя до кучи всех прочих - нет нихрена в открытом доступе


сейчас как наиболее реальный вариант рассматриваю возможность выдрать необходимую информацию из XHTML странички для мобильников, которую дает Яндекс. Не есть хорошо с любой точки зрения, но за неимением лучшего варианта...

На маркете из бесплатных пожалуй лучший вариант от Яндекса. Росгидрометцентр платный, Gismeteo ограничен суточным прогнозом и зря народ просит большего. Автор явно забил на свое творение (потому как развивать в общем-то некуда) и просто имеет какой-то трафик на свой сайт.

При таком раскладе свое приложение можно сделать исключительно в учебных целях

WebView - вот это номер!

Решил написать свое первое приложение, которое выполнят хоть что-то полезное, а именно выводит прогноз погоды. Сделать это можно по разному, в том числе не просто, а очень просто:


  1. Берем на GisMeteo код HTML информера
  2. Ложим в файлик, файлик кладем в assets
  3. Загружаем файлик в WebView. Не забываем про setSciptEnabled("true")
  4. Вуаля, все здорово


А вот и хрен. WebView говорит - страница недоступна. После непродолжительного траха выясняем, что удаление из файлика содержимого тега <style> лечит эту проблему и наступает счастье. Однако это не есть хорошо, потому как непонятно - а в чем собственно проблема заключалась? Проблем-то, собственно быть не должно изначально. Заметим также, что в браузере (который как бы идентичен WebView данный информер открывается нормально).

Ищем... ага, вот, не я один наступил на эти грабли

В конце концов выясняем. Символы типа % воспринимаются методом WebView.loadData(...) как специальные и он изгаляется над ними с особой жестокостью.

Поэтому передаваемую строку нужно как-то закодировать Как именно, вернее чем, документация этот вопрос скромно умалчивает. Могли бы и ссылочку дать на пример. Решение оказывается простым до безобразия

вместо
mWebView.loadData(data,"text/html" ,"utf-8");
используем
mWebView.loadDataWithBaseURL(null,data,"text/html" ,"utf-8",null);

и ничего, никуда перекодировать не надо. И работает!... один раз. Но тут выясняется что упал Gismeteo.ru. Неужели это я?!!! Да не, навряд ли.

Проверяем:
It's not just you! http://informer.gismeteo.ru looks down from here.

Ну и хрен с ним. На сегодня найдутся другие дела, а более сложный вариант получения погоды рассмотрим завтра

четверг, 28 июля 2011 г.

Крестики-нолики

Поскольку я редкостная язва, то даже пытаться пролезть на хабрахабр довольно бессмысленная затея. Что не мешает мне его читать. Вот довольно таки полезная статья по созданию приложения уровнем посложнее чем набивший оскомину Hello, World.

В целом полезная. Но с точки зрения реализации некоторых алгоритмов... я содрогнулся. Элементарная задача решается путем таких жутких умственных вывертов, что я не верю никаким оправданиям автора, что ему было лень думать, или он хотел показать как эта задача может быть решена в более сложном случае.

Начнем с того, что тупо проверять все мыслимые варианты, в то время как тебе точно известно где поставлена последняя метка - граничит с идиотизмом. Достаточно проверить одну вертикальную линию, одну горизонтальную и две диагонали. 4 линии вместо 14. Это в наихудшем случае. Если метка не попадает на диагональ, то логично не проверять эту диагональ вовсе.

Замечу также что известна последняя метка - стало быть если это крестик, то сложно ожидать что вдруг выиграли нолики. И наоборот. Что еще сильнее упрощает проверку.

среда, 27 июля 2011 г.

Получение отладочного ключа для Maps API

Первым делом нужно снять отпечатки пальчиков и зарегистрировать в местном отделении полиции (почти шутка - пока ненужно, но скоро придется)

Пока вы занимаетесь разработкой, ваше приложение автоматически подписывается отладочным сертификатом. Чтобы MapView нормально отображал карты, нужно получить временный ключ Maps API, зарегистрированный на этот сертификат. Чтобы это сделать нужно получить MD5 отпечаток вашего сертификата. Когда вы будете выкладывать законченную версию вашего шедевра, вам придется повторить операцию уже сертификатом релиза, получить новый ключ и внести изменения в элемент MapView вашего приложения.

Чтобы сгенерировать отпечаток MD5 отладочного сертификата, нужно найти отладочное хранилище ключей (debug.keystore). По умолчанию он хранится в директории AVD, которая в свою очередь находится:

Windows Vista: C:\Users\\.android\debug.keystore
Windows XP: C:\Documents and Settings\\.android\debug.keystore
OS X and Linux: ~/.android/debug.keystore

Если вы пользуете Eclipse/ADT и слабо ориентируетесь, где она хранит ключи, можете посмотреть под кроватью (Windows > Prefs > Android > Build) чтобы выяснить точное место.

Когда найдете, используйте keytool чтобы получить требуемое:

$ keytool -list -alias androiddebugkey \
-keystore <путь к файлу>debug.keystore \
-storepass android -keypass android

В ответ получите что-то вроде этого: Certificate fingerprint (MD5): 94:1E:43:49:87:73:BB:E6:A6:88:D7:20:F1:8E:B5:98

Вот эти вот цифирки и буковки, разделенные двоеточиями, вы предъявите гуглу от тут. Невредно перед этим войти в свой гугловский аккаунт, а за неимением оного - заиметь. Потому как незарегистрированным юзерам гугл ничего не выдаст.

В результате у вас появится набор тарабарщины, который вы вставите себе в MapView
<com.google.android.maps.MapView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/mapview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:clickable="true"
android:apiKey="364Fgjbdqwbduqwu82385285285"
/>

Как-то вот так

Hello, Gallery! Наступаем на те же грабли

Как я уже писал про GridView,
если вы возьмете для изучения набор свой картинок (у меня под рукой
оказалась неплохая подборка девчонок разной степени раздетости), то
выяснится, что туториал умалчивает об очень важном нюансе. Прежде чем
заталкивать картинки в GridView/Gallery их необходимо уменьшить.

Переписываем ImageAdapter следующим образом:

public View getView(int position, View convertView, ViewGroup parent) {

    ImageView imageView;
    if (convertView==null){
        Bitmap orig=BitmapFactory.decodeResource(mContext.getResources(), mImageIds[position]);
        int width=orig.getWidth();
        int height=orig.getHeight();
        int nw=150; int nh=150;       

        float scalew=((float)nw)/width;
        float scaleh=((float)nh)/height;
        Matrix matrix = new Matrix();
        matrix.postScale(scalew, scaleh);
        Bitmap nbmp=Bitmap.createBitmap(orig, 0, 0, width, height,matrix,true);

        imageView= new ImageView(mContext);
        //imageView.setImageResource(mImageIds[position]); раньше брали картинку прямо из ресурсов
        imageView.setImageBitmap(nbmp);
        imageView.setLayoutParams(new Gallery.LayoutParams(150,150));
        imageView.setScaleType(ImageView.ScaleType.FIT_XY);

        imageView.setBackgroundResource(mGalleryItemBackground);
        } else {
            imageView=(ImageView) convertView;
        }
    return imageView;
}



Решение взято отсюда, и убраны лишние детали. Нужна ли конструкция
    if (convertView==null) { ...  }
      else {
            imageView=(ImageView) convertView;
        }

для меня пока под вопросом. Для GridView в туториале сделано так, для Gallery нет, хотя в остальном реализация идентичная.

вторник, 26 июля 2011 г.

Livejournal опять лежит

когда эти хреновы умники наконец поймут, что тупо наращивать мощность оборудования - бессмысленно? Система имеющая центр в одной точке всегда будет проигрывать распределенной по устойчивости к атакам.

unable start ComponentInfo

Типичная ошибка новичков, вызывающая данную ошибку - забыть прописать Activity в манифесте. Нужно запомнить раз и навсегда - все activity должны быть прописаны в манифесте.