menu

 

 

Недавно столкнулся с проблемой — нужно было на удаленном сервере генерировать apk файл для загрузки, причем в зависимости от передаваемого адреса сервера программа должна была по умолчанию при установке соединяться с различными серверами. 

Итак задача — дать пользователю возможность загрузить из интернета динамически генерируемое Андроид приложение которые буду вести себя по разному в зависимости от переданных параметров (в данном случае разные сервера загрузки данных). 

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

Сначала настраиваете Java и Ant, Android SDK на вашем удаленном сервере. Убедитесь, что прописаны пути к ним или вводите полный путь при запуске приложений из этих пакетов. Скопируйте исходники проекта на сервер.

 

 

Порядок выполнения команд


Я привожу данный пример для Ubuntu. Для Windows сервера нужно будет заменить только команду создания файла в командной строке.

Создаете пакетный файл который будет генерировать apk файл с переменными адресами сервера. Естественно вы можете его использовать и для других переменных.

Сначала создаете файл ваших данных указал в качестве пути к данным папку /assets в вашем проекте…

cat<<ЕОF>путь_к_данным/файл_данных.txt
здесь любые ваши данные, в моем случае просто адрес сервера
ЕОF


Сгенерируйте файла build.xml в корне проекта, причем название проекта <project_name> вы можете указывать любое, это будет названием apk файла. Если вам нужно делать различные релизы, то вы можете указывать к примеру project_name_release_number_version_number и т.д.

android update project --name <project_name> --path <path_to_your_project>

Затем из корня проекта запускаете команду

ant release

в результате вы получите готовую apk в каталоге /bin. В данном случае вы получите файл с суффиксом -unsigned.apk, поскольку вы не подписали ваше приложение. Чтобы подписать ваше приложение нужно убедиться что в файлеlocal.properties прописаны пути к вашему хранилищу сертификатов. Как создать сертификат для подписи вашего приложения описано здесь. Это выходит за рамки этой заметки.

key.store=/Path/to/my/keystore/MyKeystore.ks
key.alias=myalias


Для уверенности мы можем вставить код генерации этого файла.

cat<<ЕОF >каталог_проекта/local.properties
# This file is automatically generated by Android Tools.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must *NOT* be checked in Version Control Systems,
# as it contains information specific to your local configuration.
# location of the SDK. This is only used by Ant
# For customization when using a Version Control System, please read the
# header note.
sdk.dir=/путь_к_sdk/Android-sdk
key.store=/Path/to/my/keystore/MyKeystore.ks
key.alias=myalias
ЕОF



В вашем Java коде достаете нужные для работы данные из сгенерированного файла в /assets. Используйте их как вам необходимо. В моем случае просто читаю адрес сервера с которого нужно производить загрузку.
Пользователю для загрузки даете ссылку на готовую apk.

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

ВНИМАНИЕ! В тексте заметки везде EOF написано при помощи русских букв Е и О — иначе некорректно отображалось.

cat<<ЕОF >путь_к_данным/файл_данных.txt
здесь любые ваши данные, в моем случае просто адрес сервера
ЕОF
android update project --name <project_name> --path <path_to_your_project>
cat<<ЕОF>каталог_проекта/local.properties
# This file is automatically generated by Android Tools.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must *NOT* be checked in Version Control Systems,
# as it contains information specific to your local configuration.
# location of the SDK. This is only used by Ant
# For customization when using a Version Control System, please read the
# header note.
sdk.dir=/путь_к_sdk/Android-sdk
key.store=/Path/to/my/keystore/MyKeystore.ks
key.alias=myalias
ЕОF
ant release

 
об этом и многом другом так же можно прочитать в официальной документации developer.android.com/guide/developing/building/building-cmdline.html
Category: Android | Views: 27055 | Added by: tsvetkov | Date: 29.06.2011

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

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

вашаАктивити.runOnUiThread(new Runnable() {

@Override
public void run() {
// Изменение видимой части
}
});

или для View:

вашеВию.post(new Runnable() {

@Override
public void run() {
// Изменение видимой части
}
});


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

Некоторые готовые функции уже запускаются в этом потоке. К таким функциям и относятся вызовы диалогов.
Не используйте создание диалогов напрямую. Для этого есть специальный механизм:

1. Назначьте каждому диалогу свой номер, например private static final int DIALOG_KEY = 1.
2. Создайте диалоги и назначьте их свойства в перезаписываемом методе onCreateDialog(int id).
3. Вызовите диалог на экран при помощи showDialog(DIALOG_KEY) по его номеру.
4. Удалить ставшим ненужным диалог при помощи dismissDialog(DIALOG_KEY).

Вариант 1. Вызов диалога в Activity и прекращение работы диалог при помощи handler.


В приведенном примере вызывается обычный ListView, ему назначается адаптер. При выборе элемента списка появляется диалог загрузки и после окончания загрузки диалог удаляется. Загрузка производится в отдельном потоке для того чтобы ваша activity не зависала на время исполнения загрузки! После окончания загрузки вызывается перехватчик handler для того, чтобы отреагировать и удалить ставшим ненужным диалог загрузки.

public class AlphabetView extends Activity {

private static final int DIALOG_LOAD_KEY = 1;
private Activity context;
private Alphabet alphabet;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.alphabet);
context = this;
alphabet = Main.getAlphabet();
ListView lv = (ListView) findViewById(R.id.ListViewMain);
lv.setAdapter(new ArrayAdapter<String>(this, R.layout.item, alphabet.getNames()));

                // Назначаем обработчик нажатий на элементе списка

lv.setOnItemClickListener(new OnItemClickListener() {

public void onItemClick(AdapterView parent, View view, int position, long id) {
final int i = position;
showDialog(DIALOG_LOAD_KEY); // Показываем диалог
                                // Запускаем в отдельном потоке загрузку ваших данных
new Thread(new Runnable() {

public void run() {
Main.loadData(i); // Вызов вашей функции загрузки
handler.sendEmptyMessage(0); // посылаем уведомление об окончании загрузки
}
}).start();
}
});
}

        // Это ваш обработчик удаления диалога и к примеру запуск новой Activity

private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
dismissDialog(DIALOG_LOAD_KEY); // удаляем диалог
Intent intent = new Intent(context, AuthorsView.class);
startActivity(intent);
}
};

@Override // Здесь вы создаете все диалоги
protected Dialog onCreateDialog(int id) {
switch (id) {
case DIALOG_LOAD_KEY: {
ProgressDialog dialog = new ProgressDialog(this);
dialog.setMessage("Загрузка, подождите пожалуйста...");
dialog.setCancelable(true);
return dialog;
}
}
return super.onCreateDialog(id);
}

}

Вариант 2. Вызов диалога в Activity и прекращение работы диалог без handler.


В данном варианте мы не используем handler. Вместо него мы после создания диалога запускаем в отдельном потоке загрузку, а после окончания загрузки удаляем диалог при помощи вышеописанной runOnUiThread.

public class AlphabetView extends Activity {

private static final int DIALOG_LOAD_KEY = 1;
private Activity context;
private Alphabet alphabet;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.alphabet);
context = this;
alphabet = Main.getAlphabet();
ListView lv = (ListView) findViewById(R.id.ListViewMain);
lv.setAdapter(new ArrayAdapter<String>(this, R.layout.item, alphabet.getNames()));

                // Назначаем обработчик нажатий на элементе списка

lv.setOnItemClickListener(new OnItemClickListener() {

public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
final int i = position;
showDialog(DIALOG_LOAD_KEY); // Показываем диалог
  }
});
}

@Override // Здесь вы создаете все диалоги
protected Dialog onCreateDialog(int id) {
switch (id) {
case DIALOG_LOAD_KEY: {
final ProgressDialog dialog = new ProgressDialog(this);
dialog.setMessage("Загрузка, подождите пожалуйста...");
dialog.setCancelable(true);
new Thread(new Runnable() {

@Override
public void run() {

Main.loadData(); // Вызов вашей функции загрузки
                                                // Удаление диалога после загрузки
runOnUiThread(new Runnable() {

@Override
public void run() {
dismissDialog(DIALOG_LOAD_DATA);
}

});

}

}).start();
return progressDialog;
}
}
return super.onCreateDialog(id);
}

}

Возможны также комбинации этих двух вариантов. К примеру в первом варианте возможно вместо hadler также использовать  приведенный во втором варианте код:

                                                Main.loadData(); // Вызов вашей функции загрузки
                                                // Удаление диалога после загрузки
runOnUiThread(new Runnable() {

@Override
public void run() {
dismissDialog(DIALOG_LOAD_DATA);
}

});


Вариант 3. Вызов диалога в Activity при помощи AsyncTask.

Иногда удобнее использовать асинхронную задачу AsyncTask. Подробно это описано на http://developer.android.com/resources/articles/painless-threading.html.

К примеру вы по нажатию вызываете новую асинхронную задачу для загрузки вашего файла:

public void onClick(View v) {
  new DownloadImageTask().execute("http://example.com/image.png");
}

DownloadImageTask расширяет класс AsyncTask в котором есть все методы для нормального отображения диалога. Для инициализации диалога используем функцию onCreateDialog приведенную в примере 1.

>private class DownloadImageTask extends AsyncTask<string, void,="" bitmap=""> {

     protected Bitmap doInBackground(String... urls) {
         return loadImageFromNetwork(urls[0]); // ваша функция загрузки
     }

     protected void onPreExecute() {
         showDialog(DIALOG_LOAD_KEY); // Показываем диалог
     }

     protected void onProgressUpdate() {
          // Здесь мы можем обрабатывать ход прогресса загрузки.
     } 

     protected void onPostExecute(Bitmap result) {
         dismissDialog(DIALOG_LOAD_DATA); // удаляем диалог
     }

 }


Если кто-то предложит еще интересные варианты, буду рад.

Category: Android | Views: 17119 | Added by: tsvetkov | Date: 11.01.2011 | Comments (17)

Общие впечатления

Побывал на конференции для разработчиков Google, привез впечатления :).



Кстати опубликовали фотографии с конференции -http://picasaweb.google.com/selanne2007/GDDMoscow2010?feat=flashslideshow#5540925326155696642

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

Иванов Петр
Украина, Киев
Android: 2D Game Developer, Office programs Developer.

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

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

По результатам этой поездки меня попросили подготовить заметки для помощи начинающим программистам под Android. Результат перед вами. Прошу прощения за нечеткие фотографии. Не всегда получались.

1. Пользовательский интерфейс и юзабилити

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

Помните, что первое впечатление полученное от загруженной программы самое важное и в течении считанных секунд будет решаться участь вашей программе — снесут ли ее немедленно. К сожалению вы не всегда можете контролировать первое впечатление о вашей программе. Тут может вмешаться сторонний человек рекомендующий или не рекомендующий вашу программу, может повлиять впечатление полученное от предыдущих ваших программ, текущий рейтинг программы. Но вы можете постараться свести к минимуму отрицательные последствия этих и других факторов. Для этого нужно придерживаться простых правил.

Установка и запуск вашей программы

Минимизируйте время для запуска программы. Уберите или упростите до минимума процесс регистрации пользователя, пользователь не любит печатать на мобильных устройствах. Синхронизируйте данные пользователя с его контекстом по максимуму - без его рукотворного участия. Подключайтесь автоматически к аккаунтам Google, Facebook или другим.

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

Главная активити

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

Не используйте большое количество пунктов основного меню, это затрудняет действия пользователя и приводит его в замешательство. Дизайн иконок должен быть лаконичным и понятным. Желательно использовать стандартные элементы дизайна — уже известные для пользователя.

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

      

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

Элементы пользовательского интерфейса

Ясность интерфейса порождает легкость его использования. Как этого добиться?

Сконструируйте раскладку вашей информационной иерархической модели и модели данных. Выберите основной паттерн пользовательского интерфейса. Сделайте наброски прототипов вашего интерфейса.

Что НЕ рекомендуется:


Использование 5-ти и более вкладок, или вкладок внизу экрана.


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


Кнопка «Назад» сделанная в виде отдельного графического элемента «а-ля» Ай-Фон.

Что Рекомендуется:


Используйте Dashboard + Action bar


Причем используйте различные варианты Action bar в разных рабочих кранах.

Ограничьте количество закладок 4-мя,


Используйте сдвигающиеся закладки при ОДНОРОДНОМ их содержимом.


При разработке интерфейса рекомендуют использовать один из трех вариантов:


  1. Ручка и карандаш.

  2. Pensil for Firefox - http://pencil.evolus.vn/

  3. Adobe Fireworks.


Pensil for Firefox я уже ранее использовал для других проектов и остался доволен. Рекомендую. Не забудьте только скачать плагины для андроида. На основном сайте программы их нет, скачайте по адресу

http://code.google.com/p/android-ui-utils/downloads/detail?name=android-pencil-stencil-basic_0.1.zip

http://code.google.com/p/android-ui-utils/downloads/detail?name=android-pencil-stencil-frame_0.1.zip

Есть отзывы, что версия Pensil 1.2 не у всех запускается. Если у вас такой случай — попробуйте версию 1.1, она запускалась у всех.


Сейчас очень часто разработчиков просят разработать приложение под андроид и одновременно под айфон и блекберри.

НЕ КОПИРУЙТЕ бездумно все элементы дизайна разработанного для других платформ.

НЕ ПЕРЕРИСОВЫВАЙТЕ без крайней необходимости элементы диалогов или индикатовров активности (progress бары и т.д.)

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

НЕ ИСПОЛЬЗУЙТЕ маленький шрифт, он не удобен для чтения.

При разработке дизайна используйте относительный лэйаут и dp для указания размеров вместо px (sp для текста). Это поможет правильно отображать ваш дизайн при различных разрешениях экрана.

ИСПОЛЬЗУЙТЕ большие области для навигационных элементов интерфейса. Не заставляйте пользователей играть в игру «попади пальчиком» в маленькие элементы интерфейса. Не у всех такой миниатюрный палец как у вас.

ИСПОЛЬЗУЙТЕ навигацию при помощи трекбола. Возможно на вашем его устройстве и нет, но у многих он есть, и такие пользователи будут разочарованы отсутствием его поддержки.

КОРРЕКТНО используйте стек ваших активити. Помните, что при нажатии кнопки «back» пользователь ожидает возврат на предыдущую активность, а не на придуманную вами. Не изощряйтесь в навигации, делайте проще.

ПРАВИЛЬНО отрабатывайте повороты устройства. Это успокаивает пользователя.

Для облегчения работы разработчики платформы не зря потрудились и продумали структуру ресурсов.


Обязательно подготавливайте в ваших приложениях графику для различных разрешений. Это сильно улучшит внешний вид вашего приложения. Не сбрасывайте все на автоматический ресайзинг графики. Он не всегда корректно работает.

К сожалению далеко не каждый разработчик знает и тем более использует утилиту 9-patches, а она очень полезна для использования при различных разрешениях одного и того же изображения. Использование данной утилиты выходит за рамки данной статьи, при необходимости опишу ее использование отдельно.

Для дизайнеров разработчики системы андроид создали большое количество материалов. Если вы таки наняли дизайнера для своего проекта, и не желаете выбросить деньги на ветер, то ваш дизайнер просто обязан ознакомится с этими материалами. Вы их сможете найти здесь:

Дизайн иконок всех видов:

http://developer.android.com/guide/practices/ui_guidelines/icon_design.html

Дизайн виджетов:

http://developer.android.com/guide/practices/ui_guidelines/widget_design.html

Дизайн экранов (активити):

http://developer.android.com/guide/practices/ui_guidelines/activity_task_design.html

Дизайн меню:

http://developer.android.com/guide/practices/ui_guidelines/menu_design.html

Кроме того рекомендую Asset Studio – онлайн инструмент, при помощи которого вы можете даже без помощи дизайнера быстро создать наборы иконок для различных типов меню, уведомлений и т.д. http://j.mp/androidassetstudio Очень удобный инструмент, давно им пользуюсь.


Category: Android | Views: 2713 | Added by: tsvetkov | Date: 16.11.2010 | Comments (0)

- Добавлена перемотка экрана звуковыми кнопками
- Добавлено сохранение позиции чтения книги при листаннии
- Добавлена рубрикация загруженного по авторам
- Добавлена вертикальная фиксация читаемого текста
- Снижено время ожидания для проверки наличия интернета до 1 сек.
- Исправлена ошибка загрузки рейтинга некоторых авторов
Category: Android | Views: 1568 | Added by: tsvetkov | Date: 16.10.2010 | Comments (1)

Исправлены ошибки по вылету программы на некоторых моделях телефонов.
К сожалению имею возможность тестировать только на эмуляторе и Nexus One.
Многие ошибки не могу повторить. 
Если у Вас произошел сбой, напишите мне конкретно - жанр, автора, книгу.
Обновил программу на маркете и на сайте.
Поиск будет прикручен на выходных, вечером на это мало времени :)
Скачать можно с маркета или с сайта http://www.samizdat.moy.su/
Category: Android | Views: 1324 | Added by: tsvetkov | Date: 11.10.2010 | Comments (0)

Выпускаю в свет первую некоммерческую программ :) Не кидайте тапками сильно :)

Крупнейшая библиотека, свыше полумиллиона произведений - фантастика, приключения, детективы...
Читайте новейшие произвдения современных авторов без доступа в интернет в любом месте - в дороге и на природе.
Загрузка произведений с последующим чтением без доступа в интернет. 
Удобный рубрикатор. Сохранение в избранных. Закладки в книге.
Замечания и предложения оставляйте на сайте http://samizdat.moy.su либо на этом сайте на форуме.

Рекомендую загружать через маркет, поскольку там присутствует авто обновление. А планов по улучшению программы у меня еще много :)

Наберите на маркете в поиске "Самиздат" или воспользуйтесь данной ссылкой для перехода на маркет:


 

Список произвдений:
При долгом клике на произведении появляется меню управления.

Просмотр текста:
Быстрое нажатие вверху или внизу текста - прокрутка на страницу.
Быстрое нажатие посередне - управление размером шрифта и быстрая прокрутка.

 




Category: Android | Views: 50490 | Added by: tsvetkov | Date: 08.10.2010 | Comments (5)

CyanogenModЕсли у вас есть один Nexus то вы возможно вполне захотите его хакнуть :). Возможно вы уже слышали о проекте Cyan. CyanogenMod является бесплатной, свободно распространяемой версией Android 2,2 созданной энтузиастами, которая значительно расширяет возможности вашего телефона. Можете познакомиться с новой версией этой системы.

Как всегда, мы рекомендуем резервное копирование всех ваших приложений и данных, на всякий случай. Загрузить можно по ссылке [CyanogenMod]

Category: Android | Views: 1146 | Added by: tsvetkov | Date: 16.08.2010 | Comments (0)

Google introduces Voice Actions for Android 2.2

Сканировать для скачивания.

 Google  объявили новую услугу вызова Voice Actions , который позволяет вам совершать различные действия вызывая их голосом. Google также обновил свой голосовой поиск, он поддерживать все новейшие функции.

Пользователи могут голосовыми командами к отправить текстовое сообщение, прослушать песни, управлять электронной почтой, или писать заметки.

Voice Actions требует Android 2,2.

Примерные команды включают:
  • отправить текст на [контакт] [сообщение]
  • слушать [художника / песню / альбом]
  • вызов [бизнес]
  • вызов [контакты]
  • Отправить письмо на [контакт] [сообщение]
  • Перейти на веб-сайте []
  • Примечание для себя [отмечаем]
  • перейти на [место / коммерческое название]
  • направления [место / коммерческое название]
  • карта [место]
Category: Android | Views: 1115 | Added by: tsvetkov | Date: 13.08.2010 | Comments (0)

HTC Glacier benchmarks part 2

HTC Glacier показал в новые данные в GLBenchmark.com , на этот раз представила свой GPU.  Займемся математикой и в итоге вы получите цифры, которые соответствуют Qualcomm QSD8672 Snapdragon. Это третье поколение со следующими характеристками:

  • Двойной процессора до 1,5 ГГц
  • 45-нм технологии с низки энергопотреблением и лучшей производительностью
  • WSXGA (1440x900) разрешение экрана
  • 1080p записи/воспроизведения
  • HSPA + (именно 28Mbps) и CDMA Rev 0/A/B поддержка
  • 80 миллионов треугольников-за секунду 3D-графики
Category: Android | Views: 736 | Added by: tsvetkov | Date: 10.08.2010 | Comments (0)

Вышла новая версия программы дающей рутовые права на вашем Android телефоне. Скачать ее можно по этой ссылке.
Поддерживаемые модели:

Google Nexus One (2.2)
HTC Hero (2.1)
HTC Magic (1.5)
Dell Streak (2.1)
Motorola Milestone (2.1)
Motorola XT701
Motorola XT800 (2.1)
Motorola ME511
Sony Ericsson X10 (1.6)
Sony Ericsson X10 Mini Pro (1.6)
Acer Liquid (2.1)
Vibo A688 (1.6)

Не поддерживаются:
Samsung i9000 (Galaxy S)
Samsung i6500U
HuaWei U8220
HTC Desire / Legend / Wildfire
Category: Android | Views: 817 | Added by: tsvetkov | Date: 10.08.2010 | Comments (0)

1 2 »