среда, августа 01, 2012

Нет сети в эмуляторе Android

Бывает странный глюк в эмуляторе android. Допустим в моей домашней сети в эмуляторе нет интернета ни в приложении ни в браузере. Для решения этой проблемы попробуйте явно указать dns сервер.
./emulator.exe -avd android-emulator-name -dns-server 192.168.0.1
Все же если у вас есть интернет в браузере эмулятора, но нет в приложении. То проверьте permission в AndroidManifest.xml.
Еще более полная статья (на англ.) 

Изменения в политике Google Play для разработчиков

Все мы знаем насколько лояльно Google относится к приложениям в своём магазине. Идеальный алгоритм модерации, который устраивал и пользователей и разработчиков, ещё не придумал никто. Но Google движется в этом направлении.
Сегодня (01.08.2012) прислал письмо разработчикам о новой политике, вот краткий список нововведений:

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

Ссылка на полный текст новой политики (на англ.).

вторник, февраля 07, 2012

Ошибки Eclipse и Android SDK

Я разрабатываю под ubuntu (на момент публикации 11.04).
Eclipse SDK Version: 3.7.1 Build id: M20110909-1335
$ java -version
java version "1.6.0_26"
Java(TM) SE Runtime Environment (build 1.6.0_26-b03)
Java HotSpot(TM) Server VM (build 20.1-b02, mixed mode)

При очередном старте проекта наткнулся на ошибку
parsesdkcontent failed android

проекты собирались, т.к. sdk не был загружен. Я попытался переустановить все с начала - не помогло. Попробовал обновить sdk через файл ./sdk/tools/android (Android SDK Manager), стали появляться следующие ошибки:
Failed to fetch URL http://dl-ssl.google.com/android/repository/addons_list-1.xml, reason: Failure initializing default SSL context
но файл по адресу открывается. Покопавшись в интернетах обнаружил вот это обсуждение.
Там сказано, что следует удалить gcj, позже я вспомнил, что недавно устанавливал этот пакет.
sudo apt-get remove gcj-*
Далее при попытке сборки в консоли эклипса появляется следующее
Android requires compiler compliance level 5.0 or 6.0. Found '1.4' instead. Please use Android Tools > Fix Project Properties.
Должно лечиться этими инструкциями, а именно Project properties -> Android Tools -> Fix Project Properties
Мне не помогло. Я попробовал перейти на openjdk.

sudo apt-get remove sun-java6-*
ubuntu сразу предложил поставить пакеты на замену

ca-certificates-java default-jre default-jre-headless icedtea-6-jre-cacao icedtea-6-jre-jamvm icedtea-netx libaccess-bridge-java libaccess-bridge-java-jni openjdk-6-jre openjdk-6-jre-headless openjdk-6-jre-lib tzdata-java

добавил путь /usr/lib/jvm/java-6-openjdk/jre/bin/ в bash_profile чтобы запускался eclipse

$ vim ~/.bash_profile
PATH=$PATH:/usr/lib/jvm/java-6-openjdk/jre/bin
export PATH

После этого все заработало, ура.

среда, января 25, 2012

Простой алгоритм случайной выборки с учетом веса

Часто необходимо обращаться к одной и той же задаче:
"случайная выборка с учетом веса".

Чтобы не забыть вот кратное описание взятое отсюда:

Простой алгоритм случайной выборки с учетом веса


В общем виде этот алгоритм можно описать так:

  1. Выбрать случайное число между еденицей и суммой “весов” всех элементов
  2. Спускаться по списку элементов добавляя к счетчику вес текущего элемента
  3. Проверить, если счетчик (шаг №2) больше или равен случайному числу (шаг №1), то закончить
  4. цикл и вернуть текущий элемент. В противном случае перейдите к шагу №2.
/**
 * Выборка случайного элемента с учетом веса
 *
 * @param array $values индексный массив элементов
 * @param array $weights индексный массив соответствующих весов
 * @return mixed выбранный элемент
 */
function weighted_random_simple ( $values, $weights )
{
    $total = array_sum( $weights );
    $n = 0;
 
    $num = mt_rand( 1, $total );
 
    foreach ( $values as $i => $value )
    {
        $n += $weights[$i];
 
        if ( $n >= $num )
        {
            return $values[$i];
        }
    }
}

$values = array('A', 'B', 'C');
$weights = array(3, 7, 10);
echo weighted_random_simple($values, $weights);

Алгоритм случайной выборки из тысяч элементов

Алгоритм может быть расширен, чтобы сделать его значительно быстрее. Вместо вычисления общего веса (шаг №1) и счетчика (шаг №2) каждый раз, можно сделать это один раз и сохранить значения счетчиков в массиве. Тогда мы сможем использовать бинарный поиск, чтобы быстро выбрать правильный элемент. Ниже приведен модифицированный вариант скрипта:
/**
 * Случайно выбирает один из элементов на основе их веса. 
 * Оптимизирован для большого числа элементов.
 *
 * @param array $values индексный массив элементов
 * @param array $weights индексный массив соответствующих весов
 * @param array $lookup отсортированный массив для поиска
 * @param int $total_weight сумма всех весов
 * @return mixed выбранный элемент
 */
function weighted_random($values, $weights, $lookup = null, $total_weight = null)
{
    if ($lookup == null OR $total_weight == null) 
    {
        list($lookup, $total_weight) = calc_lookups($values, $weights);
    }
 
    $r = mt_rand(1, $total_weight);
         
    return $values[binary_search($r, $lookup)];
}
 
/**
 * Создание массива используемого в бинарном поиске
 *
 * @param array $values 
 * @param array $weights
 * @return array
 */
function calc_lookups($values, $weights)
{
    $lookup = array();
    $total_weight = 0;
         
    for ($i=0; $i < count($weights); $i++)
    {
        $total_weight += $weights[$i];
        $lookup[$i] = $total_weight;
    }
     
    return array($lookup, $total_weight);
}
 
/**
 * Ищет в массиве элемент по номеру и возвращает элемент если он найден.
 * В противном случае возвращает позицию, где он должен быть вставлен, 
 * или count($haystack)-1, если $needle больше чем любой элемент в массиве.
 *
 * @param int $needle
 * @param array $haystack
 * @return int
 */
function binary_search($needle, $haystack)
{
    $high = count($haystack) - 1;
    $low = 0;
 
    while ( $low < $high )
    {
        $probe = (int)(($high + $low) / 2);
 
        if ($haystack[$probe] < $needle)
        {
            $low = $probe + 1;
        } 
        elseif ($haystack[$probe] > $needle) 
        {
            $high = $probe - 1;
        } 
        else
        {
            return $probe;
        }
    }
 
    if ( $low != $high )
    {
        return $probe;
    } 
    else
    {
        return ($haystack[$low] >= $needle) ? $low : $low + 1;
    }
}

// Рассчет массивов (1 раз)
list($lookup, $total_weight) = calc_lookups($values, $weights);
//....
// Каждый раз когда вам необходимо выбрать случайный элемент:
$val = weighted_random($values, $weights, $lookup, $total_weight);