пятница, декабря 06, 2013

ListView, не вызывается OnItemClickListener

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

Проблема заключается в том, что Button по умолчанию является focusable.
Решилось просто: берём Button и говорим ему:

        android:focusable="false"
        android:focusableInTouchMode="false"


вторник, ноября 26, 2013

Eclipse Kepler ADT, не запускается после падения, лечение / Eclipse Kepler does not start after crash

После (очередного) падения Eclipse по причине нехватки памяти он отказался запускаться

Выглядит это так:
1. кликаем на ярлык
2. наблюдаем секунду-две начальный экран
3. всё завершается.

В логе наблюдается следующая симптоматика:
!ENTRY org.eclipse.osgi 4 0 2013-11-26 11:48:30.590
!MESSAGE An error occurred while automatically activating bundle com.android.ide.eclipse.adt (414).
!STACK 0
org.osgi.framework.BundleException: Exception in com.android.ide.eclipse.adt.AdtPlugin.start() of bundle com.android.ide.eclipse.adt.

Запуск с параметром -clean не помог.

Вылечилось гуглом и следующим действием (отсюда):
delete .metadata\.plugins\org.eclipse.e4.workbench file




вторник, сентября 03, 2013

EditText - запрет подсказок при вводе

По идее, для того, чтобы запретить предлагать варианты в процессе ввода символов в EditText, достаточно указать флаг
android:inputType="textNoSuggestions"

Не знаю отчего, но на моём HTC One с клавиатурой от Swype наличие этого параметра не предотвращает от появления подсказок.

Помогло добавление ещё одного флага:
android:inputType="textVisiblePassword|textNoSuggestions"

среда, августа 21, 2013

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

В Android – Using TouchDelegates увидел исключительно простой способ что-то сделать после того, как процесс раскладки компонентов завершён и известны их реальные размеры.


@Override
protected void onCreate(Bundle savedInstanceState) {
...

View content = findViewById(android.R.id.content);
content.post(r);
}

Runnable r = new Runnable() {

@Override
public void run() {
Log.d("TestApp", "width is:" + myView.getWidth());
}
};

понедельник, июня 24, 2013

Использование HierarchyViewer на нерутованных устройствах

В помощь: https://github.com/romainguy/ViewServer

Подключается так:

public class MyActivity extends Activity {
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // Set content view, etc.
        ViewServer.get(this).addWindow(this);
    }
      
    public void onDestroy() {
        super.onDestroy();
        ViewServer.get(this).removeWindow(this);
    }
  
    public void onResume() {
        super.onResume();
        ViewServer.get(this).setFocusedWindow(this);
    }
}

Я просто скопировал ViewServer.java в свой проект - чтобы не создавать зависимости между проектами, работает. 

среда, мая 29, 2013

Прототипирование UI и Pencil

Обнаружил приложение для рисования графических интерфейсов (и не только).
Называется Pencil. Ставится как обычное приложение, т. е. не онлайновое. Особо не разбирался но вроде стоящая вещь.

Содержит элементы GUI для веба, для Windows, для Android (ICS) и для iOS. Есть элементы в рукописном стиле.

Вот так оно выглядит:
Или, например, вот так:

пятница, мая 24, 2013

Spinner, setSelection - не изменяется отображаемое значение

У меня есть Spinner, в нём содержится несколько элементов.
В то время когда spinner свёрнут, мне нужно задать в качестве выбранного какой-то из этих элементов, к примеру - второй (если считать с нуля - то первый):

spinner.setSelection(1);

К удивлённому сожалению, в результате наблюдается следующий эффект:
1. в качестве отображаемого в свёрнутом состоянии значения так и осталось значение, соответствующему самому первому элементу
2. если спиннер развернуть - то увидим, что выбран как раз тот элемент, который просили - а именно, второй.

Чтобы привести в соответствие ожидание и реальность, достаточно добавить второй аргумент - параметр animate, равный true. В таком случае всё работает как ожидалось:

spinner.setSelection(1, true);






пятница, апреля 26, 2013

Поместить в TextView текст в формате html и сделать ссылку нажимаемой

Понадобилось:
1. поместить в TextView получаемый с сервера текст, отформатировнный под html
2. сделать так, чтобы при нажатии на ссылку, содержащуюся в этом тексте, открывался бы браузер - и показывал бы содержимое, нажатой ссылке соответствующее.

Очевидное решение использовать

                android:autoLink="web"
                android:linksClickable="true"
привело только к тому, что ссылки выделялись красивым синим цветом, но при нажатии на них ничего не происходило.

Гуглопоиск выдал ссылку с таким работающим решением:
1. не использовать очевидное решение, оставить TextView в самом простом виде (без android:autoLink и android:linksClickable):

            <TextView

                android:id="@+id/txtView"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content" />

2. сделать следующее:
textView.setMovementMethod(LinkMovementMethod.getInstance());

3. после чего можно спокойно присваивать текст:
textView.setText(Html.fromHtml(text))

Упаковал всё это в утилити-метод

public static void showHtml(TextView textView, String text) {
textView.setText(Html.fromHtml(text));
textView.setMovementMethod(LinkMovementMethod.getInstance());
}

и красота.

суббота, апреля 13, 2013

Evernote и код ошибки 2732

При обновлении Evernote получил сообщение об ошибке с кодом 2732. Аналогичное сообщение получил при попытке просто удалить приложение.

Вылечилось запуском Evernote.msi из C:\User\userName\AppData\Local\Temp

суббота, марта 16, 2013

android:listSelector

Столкнулся с тем, что селектор для ListView, заданный при помощи android:listSelector, обрабатывается по-разному в android 2.2 и в 4.x

Селектор был объявлен так:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@color/green_background_light" android:state_selected="true"/>
    <item android:drawable="@color/green_background_light" android:state_pressed="true"/>
    <item android:drawable="@color/background_default"/>
</selector>

Есть стиль:

    <style name="ListView" parent="@android:style/Widget.ListView">
        <item name="android:cacheColorHint">#00000000</item>
        <item name="android:listSelector">@drawable/background_selector_normal</item>
        ...   ...    ...
    </style>


Этот стиль уже применяется к ListView.
При запуске на устройствах с андроидом 4.х элементы списка ведут себя ожидаемым образом - при нажатии и до отпускания элементы меняют цвет фона на заданный в селекторе.
При запуске на 2.2 увидел, что цвет фона меняется для всего listView целиком - более того, после отпускания элемента сам список так и остаётся гламурно-зеленоватым, а элемент, для которого было выполнено нажатие, меняет цвет фона на заданный по-умолчанию.

Чтобы достичь желаемого поведение и на старых устройствах, нужно в селекторе вместо объявления цвета использовать "честные" drawable:


<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_selected="true">
        <shape android:shape="rectangle">
            <solid android:color="@color/green_background_light" />
        </shape>
    </item>
    <item android:state_pressed="true">
        <shape android:shape="rectangle">
            <solid android:color="@color/green_background_light" />
        </shape>    
    </item>
    <item>
        <shape android:shape="rectangle">
            <solid android:color="@color/background_default" />
        </shape>      
    </item>
</selector>

четверг, февраля 21, 2013

Выделить фоном нажатия элементов ListView

Чтобы нажатый элемент ListView выделялся бы нужным фоном, нужно:

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


    <color name="background_default">...</color>
    <color name="background_selected">...</color>

2. создать селектор для выбора цвета фона в зависимости от состояния элемента
drawable/item_background.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@color/background_selected" android:state_pressed="false" android:state_selected="true"/>
    <item android:drawable="@color/background_selected" android:state_pressed="true"/>
    <item android:drawable="@color/background_default"/>
</selector>

3. указать свежесозданный селектор в качестве фона для элемента, отображаемого в списке
layout/listview_item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:background="@drawable/listitem_background_selector" ... ... ...>
   ... ... ...

</LinearLayout>

вместо п. 3 можно сделать проще и указать свойство ListView:
android:listSelector="@drawable/background_selected"

Готово.

воскресенье, февраля 17, 2013

Как показать в WebView страницу целиком

С настройками по-умолчанию WebView не даёт возможности уменьшить отображаемую страницу так, чтобы она показалась бы целиком - пусть и мелко.

Добавить такую возможность легко:

webView = (WebView) findViewById(R.id.webview);
WebSettings settings = webView.getSettings();


settings.setLoadWithOverviewMode(true);
settings.setUseWideViewPort(true);

Определить размер элементов в runtime

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

Проблема заключается в том, что во время выполнения onResume, а тем более - onCreate, размеры элементов ещё не известны. При этом какого-либо специального метода жизненного цикла Activity, вызываемого после окончания построения layout, нет.

Есть несколько способов решить такую проблему:
1. упаковать нужный набор компонентов в какой-нибудь потомок View, переопределить для полученного потомка метод onLayout, в котором вначале вызвать super-метод, а потом уже взять готовые размеры элементов и сделать то, что требуется.
Проблема - ну не хочется на каждый набор элементов создавать отдельный класс, так и утонуть в них недолго.

2. есть решение, использующее ViewTreeObserver - создать слушатель на OnGlobalLayoutListener(), в котором реализовать метод onGlobalLayout. Такое решение можно посмотреть в этом топике. Это уже лучше, но работать с этим не очень удобно, так как нужно поразбираться в isAlive(), не забыть вызвать removeGlobalOnLayoutListener, то есть работать нужно аккуратно.

Мне больше понравилось следующее решение, которое сейчас представляется наиболее и универсальным, и наиболее простым:

1. Создаём интерфейс

public interface OnLayoutCompletedListener {
void layoutCompleted(ViewGroup layout);
}


2. Делаем производный класс от одного из "базовых" layout - например, MyLinearLayout, в котором переопределяем метод onLayout - и в переопределённом методе вызываем layoutCompleted.


public class MyLinearLayout extends LinearLayout {
private OnLayoutCompletedListener layoutCompletedListener;

@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
if (layoutCompletedListener != null) {
layoutCompletedListener.layoutCompleted(this);
}
}

public void setOnLayoutCompletedListener(OnLayoutCompletedListener layoutCompletedListener) {
this.layoutCompletedListener = layoutCompletedListener;
}
}

3. В раскладке Activity (пусть activity_main.xml) заменяем "корневой" LineаrLayout на свежесозданный MyLinearLayout, при этом не забыть установить для него идентификатор:


<my.components.MyLinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    ... тут обычный набор ...

</my.components.MyLinearLayout>


4. Допиливаем Activity (у меня используются AndroidAnnotations):

@EActivity(R.layout.activity_main)
public class MyActivity extends Activity implements OnLayoutCompletedListener {

@ViewById
MyLinearLayout layout;

@AfterViews
protected void initViews() {
layout.setOnLayoutCompletedListener(this);
...
}

@Override
public void layoutCompleted(ViewGroup layout) {
updateArrowsPosition();
}
}

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


1. изменить раскладку для этой активити:
1.1. изменить класс для root-layout
1.2. добавить идентификатор
2. реализовать в активити интерфейс OnLayoutCompletedListener

2.1. добавить интерфейс в implements
2.2. получить экземпляр раскладки - в общем случае через findViewById
2.3. установить для экземпляра раскладки слушатель события
2.4. реализовать обработку события, генерируемого после завершения раскладки.

Вроде вполне несложно.






четверг, февраля 14, 2013

WebView, SSL, сайт с неверным сертификатом и Fatal signal 11 (SIGSEGV) at 0x00000010 (code=1)

Понадобилось отобразить в WebView страницу с сайта с некорректным сертификатом. Для того, чтобы игнорировать ошибку сертификата, создал экземпляр WebViewClient и переопределил в нём метод onReceivedSslError:


webView = (WebView) findViewById(R.id.webview);

WebViewClient viewClient = new WebViewClient() {
@Override
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
super.onReceivedSslError(view, handler, error); 
handler.proceed();
}
};

webView.setWebViewClient(viewClient);


Вызов handler.proceed() указывает на необходимость продолжать обработку, игнорируя ошибку сертификата.

После этого при запуске приложения на Android 4.0.4, Android 4.1.2 (проверял на устройствах, которые есть под рукой) стала возникать такая ошибка:
02-13 18:08:53.017: A/libc(1594): Fatal signal 11 (SIGSEGV) at 0x00000010 (code=1), thread 1622 (WebViewCoreThre)
(полный дамп приведён ниже, чтобы не мешать).

При этом приложение закрывается без каких либо сообщений и запускается снова.

На Android 2.2.2 такой ошибки не возникает.

Проблема решилась исключением вызова родительского метода onReceivedSslError:

public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
// super.onReceivedSslError(view, handler, error); REMOVE THIS LINE!
handler.proceed();
}
};


Заглянув в исходный код WebViewClient, увидел следующую реализацию:
public class WebViewClient {
   ...

   public void onReceivedSslError(WebView view, SslErrorHandler   handler, SslError error) {
        handler.cancel();
   }
   ...
}


Таким образом, вызвав унаследованный метод, я фактически получил
handler.cancel();
handler.proceed();

Как видно, такое сочетание Андроиду не понравилось.

А вот дамп:


02-13 18:08:53.017: A/libc(1594): Fatal signal 11 (SIGSEGV) at 0x00000010 (code=1), thread 1622 (WebViewCoreThre)
02-13 18:08:53.117: I/DEBUG(924): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
02-13 18:08:53.117: I/DEBUG(924): Build fingerprint: 'generic/google_sdk/generic:4.1.2/MASTER/495790:eng/test-keys'
02-13 18:08:53.117: I/DEBUG(924): pid: 1594, tid: 1622, name: UNKNOWN  >>> skipped by me <<<
02-13 18:08:53.117: I/DEBUG(924): signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000010
02-13 18:08:53.327: I/DEBUG(924):     r0 45947a90  r1 c4760772  r2 46249169  r3 00000000
02-13 18:08:53.327: I/DEBUG(924):     r4 00000000  r5 40076a4c  r6 40076a4c  r7 49040eb4
02-13 18:08:53.327: I/DEBUG(924):     r8 00000000  r9 00000000  sl 40076a4c  fp 00000001
02-13 18:08:53.327: I/DEBUG(924):     ip 467346ac  sp 49040998  lr 462461bd  pc 458a6f24  cpsr 80000030
02-13 18:08:53.327: I/DEBUG(924):     d0  bfcc400000002710  d1  40c3880000000005
02-13 18:08:53.327: I/DEBUG(924):     d2  3ff0000000000000  d3  bf95c966c155d531
02-13 18:08:53.327: I/DEBUG(924):     d4  4000000000000000  d5  3fc8adc3e03ae00c
02-13 18:08:53.327: I/DEBUG(924):     d6  7e37e43c8800759c  d7  40c3880000000000
02-13 18:08:53.327: I/DEBUG(924):     d8  000000003dcccccd  d9  43a0000042880000
02-13 18:08:53.327: I/DEBUG(924):     d10 0000000043450000  d11 0000000000000000
02-13 18:08:53.327: I/DEBUG(924):     d12 0000000000000000  d13 0000000000000000
02-13 18:08:53.327: I/DEBUG(924):     d14 0000000000000000  d15 0000000000000000
02-13 18:08:53.337: I/DEBUG(924):     scr 20000012
02-13 18:08:53.337: I/DEBUG(924): backtrace:
02-13 18:08:53.337: I/DEBUG(924):     #00  pc 00101f24  /system/lib/libchromium_net.so (net::URLRequest::ContinueDespiteLastError()+71)
02-13 18:08:53.337: I/DEBUG(924):     #01  pc 002311bb  /system/lib/libwebcore.so
02-13 18:08:53.337: I/DEBUG(924):     #02  pc 000565d9  /system/lib/libchromium_net.so (MessageLoop::RunTask(Task*)+180)
02-13 18:08:53.337: I/DEBUG(924):     #03  pc 0005773b  /system/lib/libchromium_net.so (MessageLoop::DeferOrRunPendingTask(MessageLoop::PendingTask const&)+18)
02-13 18:08:53.347: I/DEBUG(924):     #04  pc 000577ab  /system/lib/libchromium_net.so (MessageLoop::DoWork()+94)
02-13 18:08:53.347: I/DEBUG(924):     #05  pc 000584eb  /system/lib/libchromium_net.so
02-13 18:08:53.347: I/DEBUG(924):     #06  pc 00056c9b  /system/lib/libchromium_net.so (MessageLoop::RunInternal()+114)
02-13 18:08:53.347: I/DEBUG(924):     #07  pc 00056cf9  /system/lib/libchromium_net.so (MessageLoop::Run()+16)
02-13 18:08:53.347: I/DEBUG(924):     #08  pc 000773a9  /system/lib/libchromium_net.so (base::Thread::ThreadMain()+188)
02-13 18:08:53.347: I/DEBUG(924):     #09  pc 00076e33  /system/lib/libchromium_net.so
02-13 18:08:53.347: I/DEBUG(924):     #10  pc 00012db0  /system/lib/libc.so (__thread_entry+48)
02-13 18:08:53.347: I/DEBUG(924):     #11  pc 00012514  /system/lib/libc.so (pthread_create+172)
02-13 18:08:53.347: I/DEBUG(924):     #12  pc 000fedd4  
02-13 18:08:53.347: I/DEBUG(924): stack:
02-13 18:08:53.347: I/DEBUG(924):          49040958  2a2d1cfc  [heap]
02-13 18:08:53.347: I/DEBUG(924):          4904095c  2a131dd0  [heap]
02-13 18:08:53.347: I/DEBUG(924):          49040960  2a2d1d0c  [heap]
02-13 18:08:53.347: I/DEBUG(924):          49040964  2a294ff8  [heap]
02-13 18:08:53.347: I/DEBUG(924):          49040968  2a131dd0  [heap]
02-13 18:08:53.347: I/DEBUG(924):          4904096c  c4760772  
02-13 18:08:53.357: I/DEBUG(924):          49040970  00000000  
02-13 18:08:53.357: I/DEBUG(924):          49040974  2a2d1cfc  [heap]
02-13 18:08:53.357: I/DEBUG(924):          49040978  2a131dd0  [heap]
02-13 18:08:53.357: I/DEBUG(924):          4904097c  00000000  
02-13 18:08:53.357: I/DEBUG(924):          49040980  40076a4c  
02-13 18:08:53.357: I/DEBUG(924):          49040984  45852bc7  /system/lib/libchromium_net.so
02-13 18:08:53.357: I/DEBUG(924):          49040988  00000000  
02-13 18:08:53.357: I/DEBUG(924):          4904098c  2a2bcbe4  [heap]
02-13 18:08:53.357: I/DEBUG(924):          49040990  df0027ad  
02-13 18:08:53.357: I/DEBUG(924):          49040994  00000000  
02-13 18:08:53.357: I/DEBUG(924):     #00  49040998  2a247720  [heap]
02-13 18:08:53.357: I/DEBUG(924):          4904099c  40076a4c  
02-13 18:08:53.357: I/DEBUG(924):          490409a0  40076a4c  
02-13 18:08:53.357: I/DEBUG(924):          490409a4  49040dd8  
02-13 18:08:53.357: I/DEBUG(924):          490409a8  40076a4c  
02-13 18:08:53.357: I/DEBUG(924):          490409ac  4581b1af  /system/lib/libchromium_net.so (base::internal::LockImpl::Unlock()+18)
02-13 18:08:53.357: I/DEBUG(924):          490409b0  00001000  
02-13 18:08:53.367: I/DEBUG(924):          490409b4  2a2d2828  [heap]
02-13 18:08:53.367: I/DEBUG(924):          490409b8  00000000  
02-13 18:08:53.367: I/DEBUG(924):          490409bc  2a2ebee0  [heap]
02-13 18:08:53.367: I/DEBUG(924):          490409c0  00000000  
02-13 18:08:53.367: I/DEBUG(924):          490409c4  4003b769  /system/lib/libc.so (dlfree+56)
02-13 18:08:53.367: I/DEBUG(924):          490409c8  46247d6b  /system/lib/libwebcore.so
02-13 18:08:53.367: I/DEBUG(924):          490409cc  00000000  
02-13 18:08:53.367: I/DEBUG(924):          490409d0  00001000  
02-13 18:08:53.367: I/DEBUG(924):          490409d4  2a13b210  [heap]
02-13 18:08:53.367: I/DEBUG(924):          ........  ........
02-13 18:08:53.367: I/DEBUG(924):     #01  49040a50  46249169  /system/lib/libwebcore.so
02-13 18:08:53.367: I/DEBUG(924):          49040a54  00000000  
02-13 18:08:53.367: I/DEBUG(924):          49040a58  46246193  /system/lib/libwebcore.so
02-13 18:08:53.367: I/DEBUG(924):          49040a5c  457fb5db  /system/lib/libchromium_net.so (MessageLoop::RunTask(Task*)+182)
02-13 18:08:53.367: I/DEBUG(924):     #02  49040a60  49040eb4  
02-13 18:08:53.367: I/DEBUG(924):          49040a64  00000000  
02-13 18:08:53.367: I/DEBUG(924):          49040a68  ffffffff  
02-13 18:08:53.378: I/DEBUG(924):          49040a6c  49040ea8  
02-13 18:08:53.378: I/DEBUG(924):          49040a70  40076a4c  
02-13 18:08:53.378: I/DEBUG(924):          49040a74  457fb505  /system/lib/libchromium_net.so (MessageLoop::ReloadWorkQueue()+164)
02-13 18:08:53.378: I/DEBUG(924):          49040a78  00000002  
02-13 18:08:53.378: I/DEBUG(924):          49040a7c  2a2d6718  [heap]
02-13 18:08:53.378: I/DEBUG(924):          49040a80  00000001  
02-13 18:08:53.378: I/DEBUG(924):          49040a84  2a2d6718  [heap]
02-13 18:08:53.378: I/DEBUG(924):          49040a88  00000000  
02-13 18:08:53.378: I/DEBUG(924):          49040a8c  457fbabf  /system/lib/libchromium_net.so
02-13 18:08:53.378: I/DEBUG(924):          49040a90  49040ad4  
02-13 18:08:53.378: I/DEBUG(924):          49040a94  2a2d6718  [heap]
02-13 18:08:53.378: I/DEBUG(924):          49040a98  49040b68  
02-13 18:08:53.378: I/DEBUG(924):          49040a9c  457fd125  /system/lib/libchromium_net.so
02-13 18:08:53.378: I/DEBUG(924):          ........  ........
02-13 18:08:53.397: I/DEBUG(924): memory near r0:
02-13 18:08:53.397: I/DEBUG(924):     45947a70 00000000 00000000 00000000 00000000  ................
02-13 18:08:53.397: I/DEBUG(924):     45947a80 00000000 00000000 00000000 00000000  ................
02-13 18:08:53.397: I/DEBUG(924):     45947a90 00000000 00000000 463906e9 00000000  ..........9F....
02-13 18:08:53.397: I/DEBUG(924):     45947aa0 00000000 00000000 00000000 00000002  ................
02-13 18:08:53.397: I/DEBUG(924):     45947ab0 0000000f 45947ab0 ffffffff 00000000  .....z.E........
02-13 18:08:53.397: I/DEBUG(924): memory near r2:
02-13 18:08:53.397: I/DEBUG(924):     46249148 4a062006 447a4479 ef48f6b8 e8bd68e0  . .JyDzD..H..h..
02-13 18:08:53.397: I/DEBUG(924):     46249158 f2b04010 bf00b859 0034639c 003464ea  .@..Y....c4..d4.
02-13 18:08:53.397: I/DEBUG(924):     46249168 f2b068c0 68c0b859 b85ef2b0 4605b57f  .h..Y..h..^....F
02-13 18:08:53.397: I/DEBUG(924):     46249178 b1eb6843 0108f100 c903aa04 0003e902  Ch..............
02-13 18:08:53.397: I/DEBUG(924):     46249188 9c029803 0f01f010 0660ea4f bf186928  ........O.`.(i..
02-13 18:08:53.397: I/DEBUG(924): memory near r5:
02-13 18:08:53.397: I/DEBUG(924):     40076a2c 00000000 00000000 00000000 00000000  ................
02-13 18:08:53.407: I/DEBUG(924):     40076a3c 00000000 00000000 00000000 00000000  ................
02-13 18:08:53.407: I/DEBUG(924):     40076a4c c4760772 00000000 00000000 00000000  r.v.............
02-13 18:08:53.417: I/DEBUG(924):     40076a5c 00000000 00000000 00000000 00000000  ................
02-13 18:08:53.417: I/DEBUG(924):     40076a6c 00000000 00000000 00000000 00000000  ................
02-13 18:08:53.417: I/DEBUG(924): memory near r6:
02-13 18:08:53.417: I/DEBUG(924):     40076a2c 00000000 00000000 00000000 00000000  ................
02-13 18:08:53.417: I/DEBUG(924):     40076a3c 00000000 00000000 00000000 00000000  ................
02-13 18:08:53.417: I/DEBUG(924):     40076a4c c4760772 00000000 00000000 00000000  r.v.............
02-13 18:08:53.417: I/DEBUG(924):     40076a5c 00000000 00000000 00000000 00000000  ................
02-13 18:08:53.417: I/DEBUG(924):     40076a6c 00000000 00000000 00000000 00000000  ................
02-13 18:08:53.417: I/DEBUG(924): memory near r7:
02-13 18:08:53.417: I/DEBUG(924):     49040e94 2a247720 2a247798 2a12d710 2a12d6f8   w$*.w$*...*...*
02-13 18:08:53.417: I/DEBUG(924):     49040ea4 00000008 00000000 49040d14 00000005  ...........I....
02-13 18:08:53.417: I/DEBUG(924):     49040eb4 00000000 00000000 00000000 00000000  ................
02-13 18:08:53.428: I/DEBUG(924):     49040ec4 00000000 4581be25 c4760772 2a2ba7e8  ....%..Er.v...+*
02-13 18:08:53.428: I/DEBUG(924):     49040ed4 4581be25 2a2bb778 00000078 4581be25  %..Ex.+*x...%..E
02-13 18:08:53.428: I/DEBUG(924): memory near sl:
02-13 18:08:53.428: I/DEBUG(924):     40076a2c 00000000 00000000 00000000 00000000  ................
02-13 18:08:53.428: I/DEBUG(924):     40076a3c 00000000 00000000 00000000 00000000  ................
02-13 18:08:53.428: I/DEBUG(924):     40076a4c c4760772 00000000 00000000 00000000  r.v.............
02-13 18:08:53.428: I/DEBUG(924):     40076a5c 00000000 00000000 00000000 00000000  ................
02-13 18:08:53.428: I/DEBUG(924):     40076a6c 00000000 00000000 00000000 00000000  ................
02-13 18:08:53.428: I/DEBUG(924): memory near ip:
02-13 18:08:53.428: I/DEBUG(924):     4673468c 45814d41 45814d8f 458a7b99 458a7c45  AM.E.M.E.{.EE|.E
02-13 18:08:53.428: I/DEBUG(924):     4673469c 458a6d8f 458a7081 458a6fc9 458a7145  .m.E.p.E.o.EEq.E
02-13 18:08:53.428: I/DEBUG(924):     467346ac 458a6edd 458a73e1 45830ba1 458a723d  .n.E.s.E...E=r.E
02-13 18:08:53.428: I/DEBUG(924):     467346bc 45814d4b 45814d9b 457fb2ad 45820c79  KM.E.M.E...Ey..E
02-13 18:08:53.428: I/DEBUG(924):     467346cc 45839615 458a6f4d 4087323d 45836865  ...EMo.E=2.@eh.E
02-13 18:08:53.437: I/DEBUG(924): memory near sp:
02-13 18:08:53.437: I/DEBUG(924):     49040978 2a131dd0 00000000 40076a4c 45852bc7  ...*....Lj.@.+.E
02-13 18:08:53.437: I/DEBUG(924):     49040988 00000000 2a2bcbe4 df0027ad 00000000  ......+*.'......
02-13 18:08:53.437: I/DEBUG(924):     49040998 2a247720 40076a4c 40076a4c 49040dd8   w$*Lj.@Lj.@...I
02-13 18:08:53.437: I/DEBUG(924):     490409a8 40076a4c 4581b1af 00001000 2a2d2828  Lj.@...E....((-*
02-13 18:08:53.437: I/DEBUG(924):     490409b8 00000000 2a2ebee0 00000000 4003b769  .......*....i..@
02-13 18:08:53.437: I/DEBUG(924): code around pc:
02-13 18:08:53.437: I/DEBUG(924):     458a6f04 f240490f 23032232 4479a801 ffa2f753  .I@.2".#..yDS...
02-13 18:08:53.437: I/DEBUG(924):     458a6f14 a802490c f7424479 a801f962 fd76f753  .I..yDB.b...S.v.
02-13 18:08:53.437: I/DEBUG(924):     458a6f24 68026920 47886c91 682b9829 d0014298   i.h.l.G).+h.B..
02-13 18:08:53.437: I/DEBUG(924):     458a6f34 eb92f740 bd30b02b 0009f86e 0009f866  @...+.0.n...f...
02-13 18:08:53.447: I/DEBUG(924):     458a6f44 000649bf 000649e6 4604b570 460e4817  .I...I..p..F.H.F
02-13 18:08:53.447: I/DEBUG(924): code around lr:
02-13 18:08:53.447: I/DEBUG(924):     4624619c c8030c08 0003e90c 9a009801 0f01f010  ................
02-13 18:08:53.447: I/DEBUG(924):     462461ac 0060ea4f 5819bf18 bf184418 4790588a  O.`....X.D...X.G
02-13 18:08:53.447: I/DEBUG(924):     462461bc 0000bd0e b5104b04 4604447b 60033308  .....K..{D.F.3.`
02-13 18:08:53.447: I/DEBUG(924):     462461cc ef1cf6bb bd104620 004c0248 4605b538  .... F..H.L.8..F
02-13 18:08:53.447: I/DEBUG(924):     462461dc b13c6804 f6bc1d20 b118ef82 68436820  .h<. ....... hCh
02-13 18:08:53.827: D/Zygote(36): Process 1594 terminated by signal (11)





понедельник, февраля 04, 2013

Android Query

Дали наводку на очень интересный проект - Android Query

Содержит разные вкусности вида

//fetch and set the image from internet, cache with file and memory 
aq.id(R.id.image1).image("http://www.vikispot.com/z/images/vikispot/android-w.png");

понедельник, января 14, 2013

Galaxy Note 2, usability и стилус

Забавный usability баг с Galaxy Note 2: при помощи стилуса можно выполнять почти все виды взаимодействия с экраном... за исключением нажатия на аппаратную кнопку "Назад" :)

А так как кнопка эта используется очень часто, то возникает некий дискомфорт - (1) нажимаешь, на автомате, стилусом на Back, (2) соображаешь, что эта кнопка нажатия стилуса не обрабатывает, (3) вынимаешь стилус из пальцев и нажимаешь на кнопку уже пальцем.

How to send a toast message from a thread or a service


Sometimes I need to show a toast message from some service or from a thread.
I make it so:

1. add private handler and public method into my Application class:
public class MyApplication extends Application {
    ...

private static Handler toastHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
String message = msg.getData().getString("message");
Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT).show();
}
};

public static void showToast(String messageText) {
Message message = Message.obtain();
Bundle data = new Bundle();
data.putString("message", messageText);
message.setData(data);

toastHandler.sendMessage(message);
}
}

2. call my method from anywhere
public class MyService extends IntentService {
...
private void doSomething() {
...
MyApplication.showToast("Something is done");
}
}

среда, января 09, 2013

Как установить произвольный формат даты-времени при использовани JAXB

Аннотируем пакет, в котором размещаются отображаемые классы: создаём package-info.java с таким содержимым:


@XmlJavaTypeAdapter(value=DateFormatterAdapter.class,type=Date.class)
package messagesendapp.domain;

import java.util.Date;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;

Создаём сам адаптер:


public class DateFormatterAdapter extends XmlAdapter {
    
    private SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yyyy HH:mm:ss Z");

    @Override
    public Date unmarshal(String v) throws Exception {
        return sdf.parse(v);
    }

    @Override
    public String marshal(Date v) throws Exception {
        return sdf.format(v);
    }    
}

Готово.