kinjouj.github.io

TabLayoutでaddTabした直後にselectしてもスクロールされない件

2015-08-23T04:27:36+09:00 Java Android

Android Design Support Libraryで?追加されているTabLayoutを使った場合に、addTabをした直後にselectメソッドを呼んだりaddTabの第2引数でtrue(selected)にしてもそのタブにフォーカスは当たるけど自動アニメーションスクロールによる処理が行われない為に自分でそのタブが出てる所までスライドしないといけない問題が出てるのですが...

なんとか解決出来たっぽいのでメモ

twitter4j+mockwebserver

2015-08-17T13:54:43+09:00 Java Android

例えばtwitter4jを使う所をテストしたい場合にやたらとAPIリクエスト投げられても困るなっていう事案が発生した場合に、twitter4jが投げるリクエストをローカルサーバーとかにぶん投げるようにしてテストしたいみたいなケースの場合の検証をしてみた

※環境はAndroid(Robolectric)

HttpsURLConnection TrustManagerでPublic Key Pinning

2015-07-07T09:55:21+09:00 Java

参考1: 不正なSSL証明書を見破るPublic Key Pinningを試す

参考2: https://developer.mozilla.org/ja/docs/Web/Security/Public_Key_Pinning

関連エントリー: HttpsURLConnection TrustManager

要はHTTPS通信をする際にサーバーから送られてくる証明書が正当な物であるかをどう検証するべきかっていう所が色々あるのですが、それを検証する手法としてあるのがPublic Key Pinningっていう事っぽい(あってるかは微妙)

とりあえず色々検証してみた

※あくまでセキュリティ対策を前提としたネタではない

※個人的なメモなので上記参考を読むべき

Google Cloud Endpoints(Java)を使ってみた

2015-06-24T17:03:46+09:00 Java Google App Engine JavaScript

公式ドキュメント: https://cloud.google.com/appengine/docs/java/endpoints

今までGoogle App Engineを使ってWeb API的なのを定義する際、Slim3を使ってOAuthServiceで認証情報を取得してJSONでレスポンス返す的な事を一から実装してたりとかしてたけど、今時そんな事しなくてもGoogle Cloud Endpointsを使う事で同等な事をさらっと出来るようになってるらしい

っていう事でドキュメントを読みつつやってみた

MockWebServerRule

2015-06-18T00:00:00+09:00 Java

okhttp+mockwebserverとかでもmockwebserverをテストで使うっていうネタ書いたけど、MockWebServerのインスタンス作ってグダグダしなくてもMockWebServerRuleを使えば良いらしい

※以前に検証したretrofitプロジェクトを利用して検証

retrofit

2015-06-15T17:45:49+09:00 Java RxJava Ruby Rails

公式: http://square.github.io/retrofit/

以前に

っていうように単純なデータのやりとりだけなのであればそういうのがあれば良いんじゃねって思ってたんですが、ソースとかを生成したりはしない(はずだ)けど、retrofitっていうのがあるみたいで使ってみた

RxAndroidをざっくり使ってみた

2015-06-11T16:49:40+09:00 Java Android RxJava

参考1: 【翻訳】AsyncTask と AsyncTaskLoader を rx.Observable に置き換える - RxJava Android Patterns

参考2: http://stablekernel.com/blog/replace-asynctask-asynctaskloader-rx-observable-rxjava-android-patterns (参考1の元)

参考3: 俺が RxAndroid について知っているいくつかのまとめ

大分前から色々話題になってるRxAndroidをちょっとざっくりと使ってみた

※あくまで個人的なメモなので詳しく知りたいなら上記の参考を読んだ方が良い

※0.24以降になるとAndroidScheduler以外は無くなるそうなので以下のAppObservableを使うには0.24より上のバージョンでは使えなくなるらしい

Google AppEngine(+OAuth2)にAndroid AccountManagerを介してリクエストする

2015-06-01T16:58:53+09:00 Java Android Google App Engine

chrome.identity APIを使ってGoogle App Engine OAuth2を使うの続き

前回ではJavaScript(Chrome Extension)側からchrome.identityのAPIを利用してアクセスしてレスポンスを取るみたいな事しましたが、AndroidでAccountManagerを使って端末に紐付けしてあるGoogleアカウントを使ってリクエストする場合どうなるのって事でやってみた

Google AppEngineでGoogle Analytics Core Reporting API

2015-05-15T00:00:00+09:00 Java Google App Engine

Google AppEngineにはAppIdentityっていうAPIがあってこれを使ってGoogleのサービスをAppEngine側から利用できる(※あくまでクライアント依存ではなくサーバーを利用しているユーザー依存かと)

っていう事で、このAppIdentity APIを使って自分が登録しているGoogle Analyticsのレポートデータを簡単に取得できるようにしてみた

doma2を使ってみた (2) - DI Containerを使う場合 -

2015-03-14T00:00:00+09:00 Java doma

公式ドキュメント: http://doma.readthedocs.org/ja/latest/config/#id21

参考: http://qiita.com/nyasba/items/1e22c2401f3849f9071d

前回にも記述した通り前回ではdomaで使うConfig実装なAppConfig上でDataSource等の設定をそのまま埋め込んでる。でそういう所をDI Containerに設定されているDataSource等を依存性注入して使うような形の場合には設定がいろいろ異なるっていうことでやってみた(使うDI ContainerはSpring Framework)

chrome.gcm

2014-10-24T00:00:00+00:00 Chrome Extension JavaScript Java

参考1: https://developer.chrome.com/apps/cloudMessaging

参考2: http://docs.monaca.mobi/3.5/ja/manual/backend/push_config/gcm/ (※主に設定の有効の仕方等)

ちょっと前にはchrome.pushMessagingっていうAPIが公開(って言っても一年以上前)されてたはずなのですが、現在これがどうもlegacy扱いになっている模様で現在はchrome.gcmを使うのが良いっぽそう。確かpushMessagingの方はwebstoreを経由してインストールしたアプリで無いと使えないのかどうかまでは覚えてないが、gcmはcrxパッケージングした拡張であれば使う事が可能らしい

っていう事でやってみた

※おそらくはChrome Sync(ChromeでのGoogleアカウントのログイン機能)をやっておかないと出来ないのかも知れない

JAX-RSをやってみる (20) - SecurityEntityFiltering -

2014-10-23T00:00:00+00:00 Java JAX-RS

参考: https://jersey.java.net/documentation/latest/entity-filtering.html#ef.security.annotations

Entity Filtering機能を使えば出力されるエンティティのデータ等?をフィルタリングできるらしい。一番わかりやすいパターンとして言えば、ログインしているユーザーが持つ権限に応じて出力されては困るデータ等をフィルタリングすることにより出力させないようにする事が可能になる感じ(他にも@EntityFilteringアノテーションを使ってフィルタリングする事自体も可能)

という事でやってみた

JAX-RSをやってみる (19) - OAuth1Providerを実装する -

2014-10-19T00:00:00+00:00 Java JAX-RS Ruby

以前やった「JAX-RSをやってみる (18) – OAuth1Provider -」のだと、jersey-oauthに含まれているDefaultOAuth1Providerを使ってるので、アクセストークンなどはインスタンス上で管理されるはずなのでサーバーダウンしたりするとアクセストークンなどが失効するのではないかと思われる。まぁ要はDefaultOAuth1Providerのようなのをつくればいいだけなので、OAuth1Providerを実装することでできるのでやってみた

※前回の「gradle jettyでJDBCRealm」の設定が別途で必要になるのでそれも前提となる

JAX-RSをやってみる (18) - OAuth1Provider -

2014-10-08T00:00:00+00:00 Java JAX-RS Ruby

公式ドキュメント: https://jersey.java.net/documentation/latest/security.html#d0e11010

参考: https://github.com/jersey/jersey/blob/master/tests/e2e/src/test/java/org/glassfish/jersey/tests/e2e/oauth/OAuthClientServerTest.java

※暫定なので大幅修正する可能性あり

org.glassfish.jersey.securityのoaut1-serverパッケージを使えばOAuth1Providerが使えるようになる模様。っていう事でやってみた

arquillian-managed

2014-09-15T00:00:00+00:00 Java JAX-RS

今回で3回のarquillianネタとして、今までをまとめると

  • arquillian-embeddedで組み込みのサーバーを使ってテスト
  • arquillian-remoteで外部のサーバーを利用してテスト

っていう感じなのでだけど、ローカルにあるサーバーとかを使ってテスト出来る仕組み的なのがarquillian-managedに相当するのではないかと。という事でやってみた

arquillian-remote

2014-09-10T00:00:00+00:00 Java

arquillian-remoteなパッケージを使えば、既存するサーバーに動的にデプロイしてテストしたり出来る模様。基本的には前回の「JAX-RS+CDIをArquillianでテスト」をそのまま使って、arquillian-remoteなパッケージを使ってテスト出来るようにする

JAX-RSをやってみる (15) - ForcedAutoDiscoverable -

2014-07-16T00:00:00+00:00 Java JAX-RS

以前にJAX-RSをやってみる (3) – AutoDiscoverable -っていうので

AutoDiscoverableっていうのを使う事で外部ライブラリで定義されたクラスをコンポーネント的な形として登録して利用

と説明した。でこれ前提がCommonProperties.FEATURE_AUTO_DISCOVERY_DISABLEが設定されているようなケースであるような場合だと処理されない模様。でそれの処理を設定されていようが強制するのがForcedAutoDiscoverableな模様

っていう事でやってみた

※AutoDiscoverableなのとForcedAutoDiscoverableな両方をアプリケーションにデプロイする。但し前者はこっちでは書かないので

JAX-RSをやってみる (13) - Refの依存性注入に関して -

2014-06-27T00:00:00+00:00 Java JAX-RS

前回も記述したけど、JspTemplateProcessorでは

final class JspTemplateProcessor extends AbstractTemplateProcessor<String> {

    @Inject
    private Provider<Ref<HttpServletRequest>> requestProviderRef;
    @Inject
    private Provider<Ref<HttpServletResponse>> responseProviderRef;

みたいになっとる訳で、テストで使用する際にあたってそういうところの依存性の注入の解決がうまくいかないのがあったので普通に@Contextで注入する的な事をしてましたけど、なんとか出来たっぽいので

JAX-RSをやってみる (12) - MVC -

2014-06-25T00:00:00+00:00 Java JAX-RS

公式ドキュメント: https://jersey.java.net/documentation/latest/user-guide.html#mvc

参考: http://qiita.com/opengl-8080/items/f4c25ad671e8a6dac743

jersey-mvcなAPIを使えばViewableをぶん投げたりする事によりテンプレートエンジンによりレスポンスを出したりする事も出来る。※現時点で公式でサポートされているテンプレートエンジンがfreemarkerとmustacheとjsp

っていう事でやってみる

JAX-RSをやってみる (9) - Container Filters -

2014-06-16T00:00:00+00:00 Java JAX-RS

公式ドキュメント: https://jersey.java.net/documentation/latest/user-guide.html#d0e8119

単純にリクエストなりレスポンスをフィルターする仕組みなAPIな模様。でリクエストからレスポンスまでのライフサイクルについては9.4. Filter and interceptor execution orderにかかれているのだけど、@PreMatchingを使う事によりリクエストからマッチするリソースが特定される前に実行される物なのだろうかと

JAX-RSをやってみる (7) - Reader & Writer interceptor -

2014-06-14T00:00:00+00:00 Java JAX-RS

公式ドキュメント先: https://jersey.java.net/documentation/latest/user-guide.html#filters-and-interceptors

リクエストなりレスポンスなりで処理される前後になんらかの処理をしたい場合にInterceptorが使える模様。それとInterceptorは普通に定義しちゃうとグローバルに作業してしまう件に関しては@NameBindingを使ったアノテーションを定義する事で、そのアノテーションがついている場合にのみ作動するような仕組みを利用する事も可能

JAX-RSをやってみる (4) - MessageBodyReader -

2014-06-11T00:00:00+00:00 Java JAX-RS

前回の「JAX-RSをやってみる (3) – AutoDiscoverable -」とかだと

package sample.controller;

import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;

import sample.bean.SampleBean;
import static javax.ws.rs.core.MediaType.*;

@Path("/sample")
public class Home {

    @Path("save")
    @POST
    @Consumes(APPLICATION_JSON)
    @Produces(APPLICATION_JSON)
    public SampleBean save(SampleBean bean) {
        return bean;
    }
}

なんていうので

package sample.controller;

import javax.ws.rs.client.Entity;
import javax.ws.rs.core.Application;

import org.glassfish.jersey.test.JerseyTest;
import org.junit.Test;

import sample.SampleApplication;
import sample.bean.SampleBean;

import static javax.ws.rs.core.MediaType.*;
import static org.junit.Assert.*;
import static org.hamcrest.Matchers.*;

public class HomeTest extends JerseyTest {

    @Override
    protected Application configure() {
        return new SampleApplication();
    }

    @Test
    public void test_save() {
        Entity<SampleBean> entity = Entity.entity(
            new SampleBean("hoge"),
            APPLICATION_JSON
        );

        SampleBean response = target("/sample/save").request().post(entity, SampleBean.class);
        assertThat(response, notNullValue());
    }
}

なんていうテストをやってみると「not found MessageBodyReader」なんていうエラーになるわけで。もちろん前回のはMessageBodyWriterは実装してあるけど、MessageBodyReaderが実装されてないので。っていう事でMessageBodyReaderを実装してみた

JAX-RSをやってみる (3) - AutoDiscoverable -

2014-06-10T00:00:00+00:00 Java JAX-RS

JAX-RSで返される値の型に対してレスポンスを変換するような仕組みはMessageBodyWriter(MessageBodyReaderっていうのもある)で利用する事が出来る。@Providerアノテーションを使う事でJAX-RSアプリケーションプロジェクト内にクラスを定義すれば良いだけなのだけど、例えばそういう仕組みな所を外部のライブラリにした場合でアノテーションが処理されるパッケージフィルターに該当しないような場合にどうやってその仕組みをロードするのか調べてみるとAutoDiscoverableっていうのを使う事で外部ライブラリで定義されたクラスをコンポーネント的な形として登録して利用できる模様。

という事でやってみた

JAX-RSをやってみる (2) - glassfish deployment -

2014-06-08T00:00:00+00:00 Java JAX-RS

参考: https://jersey.java.net/documentation/latest/deployment.html#deployment.servlet.3

JAX-RSに準拠しているアプリケーションサーバー(glassfish等)ではデプロイ時の設定が若干異なる模様。またJAX-RSに準拠しているアプリケーションサーバーであれば特にデプロイメントデスクリプタ(web.xml)を定義しなくても@ApplicationPathを使う事で引数に指定したパスを<servlet-mapping>のベースとして利用できるようになるっぽい。微妙にややこしいけど

※記述している内容が正しいかは微妙なのであくまで個人的なメモとして

JAX-RSをやってみる (1)

2014-06-05T00:00:00+00:00 Java JAX-RS

Jerseyドキュメント: https://jersey.java.net/documentation/latest/index.html

参考: http://backpaper0.github.io/2013/05/02/jaxrs.html

JavaでRESTfulなWebアプリケーションを作るっていう場合とかだとJAX-RSを使えば何かと便利っぽそうなのでいろいろ勉強してみたのでちょっとだけまとめる

※JAX-RSのバージョンは2.x系をターゲットにしてます。又、以下で書くのはあくまでサーバーを起動して利用する前提ではなくテストを書いて実行しているだけなのでサーバー関係に伴ってくる部分に関しては今後に書く予定

gradle-android-test-plugin+robolectric+espresso

2014-04-28T00:00:00+00:00 Android Java robolectric

https://groups.google.com/forum/#!topic/robolectric/xsOpEwtdTi4 にあるように元はJake Wharton氏が開発されていてdeprecatedになっていたgradle-android-test-pluginをrobolectric開発チームによってメンテされるようになった模様

てな訳でgradle-android-test-pluginを使いつつの、robolectricでの単体テスト及びespressoによるUIテストをやってみる

SwipeRefreshLayout

2014-03-30T00:00:00+00:00 Android Java

参考: [Android] Support Library に追加された SwipeRefreshLayout - @adakoda

上記参考によるとAndorid Support v4 packageにSwipeRefreshLayoutっていうのが追加された模様。んまぁ見る限りだとAndroid PullToRefreshとActionBar PullToRefreshを組み合わせたのっぽいような感じもするんですが

という事で使ってみた。ちなみに/path/to/android_sdk/extras/android/support/samples/Support4Demosにサンプルが入ってる

LoadMoreListView

2014-02-26T00:00:00+00:00 Android Java

まぁ要はListViewの末尾に達したら新しいデータをロードする等の仕組みを提供する機能的なやつ。Android PullToRefreshにはそういう機能があったけど、何回かふれているけどActionBar PullToRefreshを使うべきという形になっているので、それっぽい機能をどうするかって所なんですが

調べた所によると、LoadMoreListViewっていうのを利用する事で出来るっぽい。という事で使ってみた

gradle-android-toolkit+robolectric-plugin

2014-02-18T00:00:00+00:00 Android Java robolectric

っていう事でrobolectric-pluginっていうのがあるっては知ってはいたんですが、どうも上手く行かなずな感じで。まぁ一回は挫折したんですが再チャレンジでようやくテストの実行が出来たのでメモっておく

ActionBar-PullToRefreshをメニューボタン等で連動させる

2014-02-13T00:00:00+00:00 Android Java

っていうActionBar-PullToRefreshを使っている場合において、メニューでリフレッシュボタンとかでActionBar-PullToRefreshを発生させるような要件を実現したい場合にはどうすれば良いのか。簡単に言えば上記画像中の右上にあるリフレッシュボタンをクリックする事でonRefreshStartedメソッドを発生させたいっていう所

っていうのをやってみた

ActionBar-PullToRefresh

2014-02-12T00:00:00+00:00 Android Java

※ActionBar-PullToRefreshも「PLEASE NOTE, THIS PROJECT IS NO LONGER BEING MAINTAINED」になってますので現時点で使う場合注意

Android PullToRefreshにも追記しましたが、Android-PullToRefresh は既にdeprecated(正確にはNO LONGER BEING MAINTAINED)らしいので、ActionBar-PullToRefreshを使えとのこと。つーことでListFragmentを使う場合のドキュメントを見つつやってみた

※但し、Android PullToRefreshとActionBar PullToRefreshはスタンスは異なるかと思われますので

gradle-android-toolkitでライブラリプロジェクト

2014-02-11T00:00:00+00:00 Android gradle Java

例えば、アプリプロジェクト・ライブラリプロジェクトの両方を持ちつつActionBarSherlock等のような外部のライブラリプロジェクトを利用する場合のgradle-android-toolkitでのビルドってどうなってるかとか辺りをまだやってなかったのでやってみた (※Android Studioに関してはノータッチで)

※以下のバージョンのgradle-android-toolkitはGradleのバージョンが1.10くらい辺りからじゃないと動かないので(ry

Android4.4(Kitkat)のデフォルトSMSアプリに関して

2014-01-29T00:00:00+00:00 Android Java

参考1: Getting Your SMS Apps Ready for KitKat

参考2: Android KITKAT: デフォルトSMSアプリを作る - ブライテクノBlog

※非常に内容がざっくりとしてますので上記参考を(ry

Android 4.4(Kitkat)からデフォルトなSMSのアプリを作って利用する事が出来るらしいとの事は知っていたのだけど検証的な辺りとかしてなかったので色々やってみた

ottoとActivityRecognition

2014-01-27T00:00:00+00:00 Android Java

ottoな勉強をするにあたってそういう要件が必要にならないと例にならない気がしたので、ActivityRecognitionを使って行動認識をActivityへottoを使って通知する仕組み的な事やってみた

AndroidSlidingUpPanel

2014-01-21T00:00:00+00:00 Android Java

Android Library Rankingで1位になっているAndroid SlidingUpPanelっていうのが気になったので使ってみた。んまぁAuthor見れば分かるがUmanoっていうアプリで使われてるそうで

でどういうライブラリなのかざっくり画像で見せると

っていう感じになってて下側にあるsliding contentsっていう部分をひっぱることが出来る

まぁ今時は使われてないけど、似たようなのにAndroid公式でサポートされているSlidingDrawerっていうのがある。まぁようはそれっぽい動作をする物みたいな感じ

Spring WebMVCのformとFormatterの件

2014-01-10T00:00:00+00:00 Java Spring Framework

※おそらくは書いてる内容は自分以外は理解しにくいと思いますので興味ないならCTRL+Wしてください(笑)

Spring WebMVCをやってみる (18) – AnnotationFormatterFactory -でも書いてるけど

「getPrinter実装してもどういう作用で発生するのかが謎」。普通にFormatterを使う場合とかだと等で作用されるっていうはあるのだけど、このAnnotationFormatterFactoryの事象だけはgetPrinterメソッドが作用する事が無い

っていう件に関して。結論から言うと「やり方が悪い」っていうだけだった模様

mock-javamail

2014-01-07T00:00:00+00:00 Java

「JavaMailを使ってgmailでメールを送る件」なコードをそのまま使う

前回のをそのまま実行すると普通にメール送れるのは良いんですが、それをテストする方法としてまぁちょっと古いけれどもmock-javamailっていうのがある模様。どうやらjavamailで使用するメールトランサポートをモックする事で送ったメールをMailboxクラスで参照できる的な所かと

MahoutのLocalitySensitiveHashSearch

2014-01-06T00:00:00+00:00 Java Mahout

通称で言うとLSH。んまぁmixiさんの「LSH (Locality Sensitive Hashing) を用いた類似インスタンスペアの抽出」辺りが有名?ですかね

http://hillbig.cocolog-nifty.com/do/2009/02/lsh-spectral-ha.html にはLSHとはなんぞやと以下の本とかでも触れられているらしい(ていうか筆者かと)

でMahoutでそのLSHサポートがあるっぽいのでちょっと使ってみたのでメモ

Spring WebMVCをやってみる (17) - Formatter -

2014-01-03T00:00:00+00:00 Java Spring Framework

前回のConverter同様に型を変換したりする仕組みな模様。@DateTimeFormatのようにアノテーションによって型変換を行うのも可能(後日書く)。んまぁ違い的な所としては非常に曖昧で微妙なのだけど、Formatterはインターフェースによりパースする所と出力サポートを行うメソッドを実装する必要がある。んまぁ詳しい違いとかわかり次第補足なりする予定

とりあえず使ってみる。題材的なのとしてEnumを変換する仕組み的なのを作ってみる

Spring WebMVCをやってみる (15) - TypeMismatch -

2013-12-25T00:00:00+00:00 Java Spring Framework

前回の「Spring WebMVCをやってみる (14) – @Valid+BindingResult+RedirectAttributes -」で書いたのをそのまま利用

前回だとSampleFormのnameプロパティだけをフォームで入力させて利用するっていうパターンだけやったのですが、SampleFormにはidプロパティもあるのでそれをフォームで入力させる際にあたって、数値(int)型では無い値を入れた場合のエラーメッセージはTypeMismatchを利用する事で出来る模様

Spring WebMVCをやってみる (14) - @Valid+BindingResult+RedirectAttributes -

2013-12-24T00:00:00+00:00 Java Spring Framework

前回で出した問題点として、「エラー表示はビューをレンダリングしているのでリロードするとPOSTなリクエストになる」って件。まぁ良くあるパターンなのかは微妙な所なんですが、対策として

  • ビューをレンダリングしないでフォームを出す所にリダイレクトする
  • リダイレクトする際にFlashスコープでエラーを突っ込んでおく
  • リダイレクト先で上記で突っ込んだエラーがあるのならば、それをビューで表示できるように構成する (BindingResult.MODEL_KEY_PREFIX + ModelAttributeな文字列をキーとする)

っていう感じじゃねーかと。んまぁ今回修正案として出すのはコントローラーだけ(それとテストも)

Spring WebMVCをやってみる (12) - RedirectAttributes -

2013-12-20T00:00:00+00:00 Java Spring Framework

んまぁSpring WebMVCでアクションからリダイレクトを利用したい場合等にはredirect:なプレフィックスを利用する事で出来るんだけれども

  • リダイレクト先にパラメーターを設置したい (リダイレクト先で@RequestParam)
  • フラッシュスコープを利用してリダイレクトしたい

っていう要件を検証してみた

Spring WebMVCをやってみる (11) - @RequestMappingのparams -

2013-12-18T00:00:00+00:00 Java Spring Framework

例えば

<form action="/swmvc/sample/index.action" method="post">
    <input type="submit" name="say1" value="say1" />
    <input type="submit" name="say2" value="say2" />
</form>

っていうようにターゲットとなるアクションは1つでサブミットによって処理されるアクションを切り分けたい場合には@RequestMappingアノテーションにparams属性で<input type="submit">で指定されてるname属性の値を指定すれば良いらしいとの事

java.util.ServiceLoader

2013-12-16T00:00:00+00:00 Java

まぁJavaやってるとたまーにみるMETA-INF/servicesっていうディレクトリにファイルがあってその中身が実装クラスのFQDNが書いてるっていうケース。こういう仕組みを作るにはどうするのかっていうのをやってみた

Spring WebMVCをやってみる (10) - gsonを使う -

2013-12-15T00:00:00+00:00 Java Spring Framework JavaScript

例えば

  • @ResponseBodyアノテーションがついてるメソッドでStringじゃなくてオブジェクトだとかをぶん投げたりとか
  • @RequestBodyアノテーションがついてるメソッドの引数でStringじゃなくてオブジェクトだとかを指定したりとか

っていうケースな場合にJSONで投げられる事を前提とするのであれば、MessageConverterな方式を利用する事でサポート出来るらしいのでやってみた

Spring WebMVCをやってみる (4) - AbstractViewを利用した独自Viewを利用する -

2013-12-08T00:00:00+00:00 Java Spring Framework

前回のSpring WebMVCをやってみる (3) – 返せるレスポンスタイプに関して -でも書いたように、レスポンスを返す型としてView型を返す事も出来る。又、ModelAndViewにsetViewNameを利用する事でも独自のViewを使ってレスポンスを返却させる事が出来る。という事で使ってみた

Spring WebMVCをやってみる (3) - 返せるレスポンスタイプに関して -

2013-12-06T00:00:00+00:00 Java Spring Framework

大まかにSpring WebMVCでコントローラーアクション(@RequestMappingで処理されるメソッド)で返せる値の形式は

  • String (redirect/forward等のプレフィックスも含む)
  • ModelAndView
  • Map<String, Object>
  • String、又はbyte[]等で@ResponseBodyなアノテーションを付与
  • ResponseEntityを使用
  • org.springframework.web.servlet.Viewを使用

っていうような感じで値を返す事が出来る。もちろん値を返さないvoidでも引数にHttpServletResponseを利用してレスポンスを出す事も可能

ModelAndViewはSpring WebMVCをやってみる (2) – アノテーションを使わないコントローラー -で既に検証済みなので省略する。又、最後のViewに関しては後日別途で記事を書く予定になっているので今回は省略する。という事でコントローラー書いてテスト書いて検証してみる

DialogFragmentのsetShowsDialog

2013-11-25T00:00:00+00:00 Android Java

※ソースを完全に読んだ訳じゃないので若干微妙なのであくまでネタとして

例えば、DialogFragmentを継承したクラスを作りsetArgumentsでandroid.os.Bundleを指定してパラメーターを渡す。そこまでは良いのだけど、そのパラメーターに値が入ってないとかgetSerializableなりはできるけどnullが返ってきてるような場合でそのままonCreateDialogを実行されてしまうとNPEなりの問題が発生してくる訳。そこら辺の制御とか辺りどうするのかって所なんですが

slf4j

2013-11-16T00:00:00+00:00 Java

前にから気になってたロガーのslf4jを使ってみる

Android+JsonPullParser

2013-11-14T12:00:00+00:00 Android Java

AndroidでJsonPullParserを使うっていうネタ。まぁ公式にもサンプルあるしそれ参考にすれば良いんじゃねって所なんで

※@JsonModel等は前回のをそのまま利用

InputMethodServiceを使ってIMを作るメモ

2013-11-06T00:00:00+00:00 Android Java Python

ネタ帳からの大体そのままな引用(要は雑って事)。以前、Androidのソフトウェアキーボードを作って、PC側とbluetoothを経由してスマフォ上のテキスト入力をPCから入力させるとかっていうのをやってた。とりあえず書いておこうかと

SpeechRecognizerを使って音声テキスト及び音声データを取得する方法

2013-11-05T00:00:00+00:00 Android Java

昔書いたネタをそのまま書く。

※リソース開放方式まで考慮してないので、そこら辺は活用する場合にはそれなりに要修正必須

※onBufferReceivedが機種依存により呼ばれないのもあるそうです

android.speech.SpeechRecognizerを使って音声からテキストを起こすAPIがあるけど、この際に音声データ自体も保管しておくっていう事をする。

SherlockNavigationDrawerを使ってみた

2013-10-23T00:00:00+00:00 Android Java

んまぁSlidingMenuだったりだとか色々あるのですけど、Googleが公開したNavigationDrawer方式をベースに使えるようにした物がSherlockNavigationDrawerらしい、正しいかは微妙だけど。ちなみにデモアプリもあるのでちょっとどんな感じかってのを見たければそれ入れて確認してみるってのも可能

という事で使ってみた (ただ公式なサンプルを見て自分で書いてやってみただけなので、ほとんど同じ)

Robolectric+powermockito

2013-10-11T00:00:00+00:00 Android Java robolectric

参考: http://addie9000.blogspot.jp/2012/12/robolectricpowermockandroidunit-test.html

Robolectricを使ってJUnit4ベースでテストしたいけど、PowerMockitoを使ってstaticメソッドをテストしたいって思ってもRobolectric自体が@RunWith(RobolectricTestRunner.class)を使うので、PowerMockitoのPowerMockRunner.class指定出来ないよねっていう事で上記の参考にRobolectricでのPowerMockitoの動かし方参考にしつつやってみた。ただ気になる事の検証的な目的かなと

※但し、上記の参考のRobolectricバージョン(1.1)とこの記事のバージョン(2.2)は違う

Android NativeMethods Pattern

2013-10-10T00:00:00+00:00 Android C++ Java

Androidっていうか単純にJNIに関する事だと思うので(ry

おそらくは通常だと

JNIEXPORT JNICALL jstring Java_パッケージ_say(JNIEnv* env, jobject thiz) {
}

的な感じでパッケージ名とメソッド名をconcatしたような名前の関数を定義する方式が一般的に知られていると思われるのですが、Androidのコアパッケージのソースとか色々見ているとNativeMethodsパターンな方式を採用しているのが多い。つまり上記のように定義しないっていうのがAndroidでは一般的なのかなと。んまぁNDKというかこういう辺りな事をやる事自体まったく無いんだけれどもやってみた

Struts2をやってみる (16) - ModelDriven -

2013-10-04T00:00:00+00:00 Java Struts2

今までだとフォームだとかで送信されるデータをActionクラスにセッターメソッドを用意して利用するっていう方式ですけど、従来のStrutsの方式であるActionFormのような方式をModelDrivenを使う事で可能らしい。という事でやってみた

Struts2をやってみる (13) -validationインターセプターを抑制する -

2013-09-27T00:00:00+00:00 Java Struts2

validateメソッドによる入力検証だったり、XML定義による入力検証っていうような方式がある。でこういう処理はフレームワークレベルで判断される訳だけど、これを抑制して自動で処理せずに自分でコントロールしたい場合とかの方法も用意されているようで

ちなみにStruts2のバリデーションインターセプターの実体はcom.opensymphony.xwork2.validator.ValidationInterceptorとなっている模様。でこちらで色々オプションなパラメーターがある模様

HBaseのTableMapper

2013-09-18T00:00:00+00:00 Hadoop HBase Java

前回の逆というか、TableMapperを使ってHBase上のテーブルからデータとってそれを普通のReducerで処理する

という事なので前回のと今回のを合わせれば、「HBaseで取ってHBaseに出力」なんていう事も出来る。というかベースはそれでなっててそれを分割しているにしかすぎないのが今回の件

Struts2をやってみる (3) - <result>のtypeに関して

2013-09-16T00:00:00+00:00 Java Struts2

struts.xmlにて

<action name="..." class="...">
    <result name="success">/WEB-INF/jsp/index.jsp</result>
</action>

っていうような記述を行う訳ですが、そこのtypeに指定する値でレスポンス方式を変えたり出来る模様。んまぁまだアノテーション利用な部分まで進んでないので(ry

で結構たくさんある模様なのだけど

  • redirect
  • redirectAction
  • plainText
  • stream

等を利用してみる

Struts2をやってみる (1)

2013-09-15T00:00:00+00:00 Java Struts2

まぁStruts1.xがEOLっていう事で代わりとなりえるだろうフレームワークを調査中で。でまぁStruts2とかもあるんじゃないかっていう事で色々勉強をしてみる事に

Android Live Wallpaper

2013-09-10T00:00:00+00:00 Android Java

いわゆるライブ壁紙っていう機能。SurfaceView的な感じで壁紙に動的にレンダリングしたりとか出来る

まぁ自宅のメモ用ブログには書いてたけどこっちに書いてなかったので、美人時計サービスを利用して1分毎に動的に壁紙をレンダリングするっていうのをやってみる。ただ、結構雑に作ってあるので(ry

※あくまでLive Wallpaperってどんな感じで作るのかっていう

LocalBroadcastManager

2013-07-19T00:00:00+00:00 Android Java

※ローカルのネタ帳からのほぼコピペ

一言で言えばアプリ内ローカルでのみ利用可能なブロードキャスト的な感じかなと。一般的には

ViewPager(FragmentPagerAdapter)のテスト

2013-07-04T00:00:00+00:00 Android Java

ViewPager(+FragmentPagerAdapter)を使っている際に、Activityのテスト(ActivityInstrumentalTestCase2)でViewPagerで利用されているFragmentPagerAdapterを取って、そのFragmentを取得してごにょごにょテストする方法

Mockitoでfinalクラスをモック化

2013-06-28T00:00:00+00:00 Java

※解釈が正しいかは微妙なのであしからず

通常Mockitoではfinalクラス等はモック化出来ない。やってもエラーになるのだけど、それを無茶ぶりでやっちゃう方法がある模様

BaseAdapterでgetFilter

2013-05-29T00:00:00+00:00 Android Java

BaseAdapterを用いる際にはgetFilterなんてメソッドが存在しないのでどうすんの的な感じなんだけど、Android FrameworkソースのArrayAdapterは

ActionBarSherlockでSearchView

2013-05-27T00:00:00+00:00 Android Java

android.widget.SearchViewなメニューのActionView自体が多分Android3.xくらいからサポートされたんだと思うんだけど、ActionBarSherlockにそれと同等な感じのWidgetが存在する模様。という事でAndroidAnnotations+ActionBarSherlockな構成でやってみた

DialogFragmentのテスト

2013-05-21T00:00:00+00:00 Android Java

例えば、なんかの登録処理をAlertDialogで表示させてsetViewでフォーム的なのをビューとして利用、そのAlertDialog自体はDialogFragmentで生成される。でそれのテストをどうやるのかって所なんですが、DialogFragmentはレイアウトにIDとか含まれず

AddFormDialogFragment fragment = new AddFormDialogFragment();
fragment.show(getSupportFragmentManager(), "add_form_fragment");

的な感じで使ってる場合にそのUIの振る舞いな処理をテストするにはって所なんですが

HDFSにデータをコピるケース

2013-05-17T00:00:00+00:00 Hadoop Java

例えばシステム側で処理したデータをHadoopで処理するためにはデータをうpしないといけなかったりする(InputFormatによる)

でhadoop fs putとか使わずにそれをやるには

Androidでテストカバレッジレポートを出力

2013-05-13T00:00:00+00:00 Android Java

http://blog.kawamura-lab.com/?p=68

を参考にしました。まぁ普通に「android update (test-)project」的な事をやったら生成されるbuild.xmlのantタスクでemmaタスクでサポート出来る模様。でこっちでハマったのがライブラリプロジェクトの扱い、ライブラリプロジェクトにもbuild.xmlとかそういう辺りが必要な模様(フィルターすれば必要ないのかは不明)

Universal Image Loader for Androidを使ってみた

2013-05-10T00:00:00+00:00 Android Java

参考: http://qiita.com/chuross/items/e3ca79065d9b67716ace

https://github.com/nostra13/Android-Universal-Image-Loader

ちょうど、AndroidAnnotations+Twitter4jで作ってたデモアプリ的なのがあったので、そいつでプロフィール画像をロードする仕組みな所をこのUniversal Image Loaderを使ってプロフィール画像を読み込むっていうのを処理してみた

Android PullToRefresh

2013-04-16T00:00:00+00:00 Android Java

※以下のAndroid-PullToRefreshは現時点でも既にdeprecatedになっており、 https://github.com/chrisbanes/ActionBar-PullToRefresh を使うべきだそうです。既に補足済み

シリーズネタになるかどうかは現状微妙ですが...

PullToRefreshっていう引っ張ってリロードしたりだとか、画面中でデータが末尾に達した場合に次のページなデータを読み込むかだとか、んまぁそういうのを実現したい時に便利なのが https://github.com/chrisbanes/Android-PullToRefresh っていうのがある訳なんですが、まだ使ってみたりとかした事が無いし、ちょっと要件としてそういうのが出てきたので使ってみた

ActionBarCompat

2013-04-14T00:00:00+00:00 Android Java

一般的にAndroid3.x以下のバージョンにおいてはActionBarそのものがサポートされてない。でAndroidのサンプル集にActionBarCompatっていうのがあって、それを利用する事でAndroid3.x以下のバージョンでもActionBar同様なUIを実現する事は出来る模様(但し、ActionBarクラス自体が存在する訳じゃないのでそれは使えない。あくまでUI的な所かと)

UbuntuとAndroidをbluetooth RFCOMMで通信する

2013-01-21T00:00:00+00:00 Android Java Python

まぁAndroid公式にBluetoothChatっていうのはありますけど。一応Android側はそれのソース読んでやってみたって話。ただこれはAndroidとPC(Ubuntu)をbluetooth RFCOMMを使って通信するというところになる

一応前持って行っておきますが、以下のソースはクソですので... (Threadの扱いとかダメ)。あくまでAndroidとRFCOMMにおける通信方法の手段にしかすぎないかと

でソースですけど、AndroidManifest.xmlとかはBLUETOOTH/BLUETOOTH_ADMINのpermissionが必要なくらいなので端折る。という事でActivityだけ書く

package net.kinjouj.test;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.UUID;

import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.Process;
import android.content.Intent;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.Toast;

public class SampleActivity extends Activity {

    public static final String TAG = "SampleActivity";

    private static final int REQUEST_ENABLE_BT = 2;
    private static final int MESSAGE_CLIENT_ACCEPT = 1;
    private static final int MESSAGE_RECEIVE = 2;

    private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");

    private BluetoothAdapter adapter;
    private BluetoothSocket socket;
    private ArrayAdapter<String> arrays;
    private AcceptThread mAcceptThread;
    private ConnectThread mConnectThread;

    private final Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MESSAGE_CLIENT_ACCEPT:
                    if (msg.obj != null && msg.obj instanceof BluetoothSocket) {
                        if (mConnectThread != null) {
                            mConnectThread.cancel();
                            mConnectThread = null;
                        }

                        LinearLayout layout = (LinearLayout)findViewById(R.id.layout);

                        if (layout.getVisibility() == View.INVISIBLE) {
                            layout.setVisibility(View.VISIBLE);
                        }

                        BluetoothSocket socket = (BluetoothSocket)msg.obj;

                        mConnectThread = new ConnectThread(socket);
                        mConnectThread.start();
                    }

                    break;

                case MESSAGE_RECEIVE:
                    if (msg.obj != null) {
                        String text = (String)msg.obj;

                        if (!TextUtils.isEmpty(text)) {
                            arrays.add(text);
                        }
                    }

                    break;
            }
        }
    };

    @Override
    public void onCreate(Bundle bundle) {
        super.onCreate(bundle);
        setContentView(R.layout.main);

        ((Button)findViewById(R.id.btn)).setOnClickListener(new View.OnClickListener() {
            public void onClick(View view) {
                String text = ((EditText)findViewById(R.id.text)).getText().toString();

                if (TextUtils.isEmpty(text)) {
                    return;
                }

                try {
                    if (socket == null) {
                        Set<BluetoothDevice> devices = adapter.getBondedDevices();

                        if (devices.size() <= 0) {
                            return;
                        }

                        BluetoothDevice device = devices.iterator().next();
                        socket = device.createRfcommSocketToServiceRecord(MY_UUID);
                        socket.connect();
                    }

                    socket.getOutputStream().write(text.getBytes());
                } catch (IOException e) {
                    e.printStackTrace();

                    Toast.makeText(
                        SampleActivity.this,
                        String.format("connect unavailable: %s", socket.getRemoteDevice().getName()),
                        Toast.LENGTH_LONG
                    ).show();
                } finally {
                    if (socket != null) {
                        try {
                            socket.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        });

        arrays = new ArrayAdapter<String>(this, R.layout.messages);

        ((ListView)findViewById(R.id.listView)).setAdapter(arrays);
    }

    @Override
    public void onStart() {
        super.onStart();

        adapter = BluetoothAdapter.getDefaultAdapter();

        if (adapter == null) {
            finish();

            return;
        }

        if (!adapter.isEnabled()) {
            Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(intent, REQUEST_ENABLE_BT);
        } else {
            onBonding();
        }
    }

    @Override
    public void onStop() {
        super.onStop();

        if (socket != null) {
            try {
                socket.close();
                socket = null;
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        if (mConnectThread != null) {
            mConnectThread.cancel();
            mConnectThread = null;
        }

        if (mAcceptThread != null) {
            mAcceptThread.cancel();
            mAcceptThread = null;
        }

        Process.killProcess(Process.myPid());
    }

    @Override
    protected void onActivityResult(int request, int result, Intent intent) {
        if (request == REQUEST_ENABLE_BT && result == RESULT_OK) {
            onBonding();
        }
    }

    private void onBonding() {
        Set<BluetoothDevice> devices = adapter.getBondedDevices();

        if (devices.size() <= 0) {
            return;
        }

        if (mAcceptThread != null) {
            mAcceptThread.cancel();
            mAcceptThread = null;
        }

        mAcceptThread = new AcceptThread(adapter);
        mAcceptThread.start();
    }

    private class AcceptThread extends Thread {

        private BluetoothServerSocket server;

        public AcceptThread(BluetoothAdapter adapter) {
            super("accept");

            try {
                server = adapter.listenUsingRfcommWithServiceRecord("RFCOMM Service", SampleActivity.MY_UUID);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void run() {
            boolean isRunnable = true;

            while (isRunnable) {
                try {
                    BluetoothSocket socket = server.accept();

                    if (socket != null) {
                        managedConnection(socket);
                    }
                } catch (IOException e) {
                    Log.v(TAG, "disconnect", e);

                    isRunnable = false;

                    cancel();
                }
            }
        }

        private void managedConnection(final BluetoothSocket socket) {
            handler.post(new Thread() {
                @Override
                public void run() {
                    BluetoothDevice device = socket.getRemoteDevice();

                    Toast.makeText(
                        SampleActivity.this,
                        String.format("Connect: %s:%s" ,device.getName(), device.getAddress()),
                        Toast.LENGTH_LONG
                    ).show();
                }
            });

            handler.obtainMessage(SampleActivity.MESSAGE_CLIENT_ACCEPT, socket).sendToTarget();
        }

        public void cancel() {
            try {
                server.close();
                server = null;
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    private class ConnectThread extends Thread {

        private BluetoothSocket socket;

        public ConnectThread(BluetoothSocket socket) {
            super("connect");

            this.socket = socket;
        }

        @Override
        public void run() {
            InputStream is = null;

            try {
                is = socket.getInputStream();

                try {
                    BufferedReader br = new BufferedReader(new InputStreamReader(is));
                    String str = null;

                    while ((str = br.readLine()) != null) {
                        handler.obtainMessage(SampleActivity.MESSAGE_RECEIVE, str).sendToTarget();
                    }
                } catch (IOException  e) {
                    Log.v(TAG, "disconnect", e);

                    cancel();
                } finally {
                    if (is != null) {
                        try {
                            is.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if(is != null) {
                    try {
                        is.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }

        public void cancel() {
            if(socket != null) {
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

簡単に言うと起動するとAcceptThreadが走って、そこでBluetooth RFCOMMをリッスンする。でPC側のクライアントを使って接続するとConnectedThreadが走って、クライアントから受け取ったデータを取得してそれをListViewのアダプターにバインドする。まぁそんな感じ

でPCからデータを送るクライアントは以前書いたネタにも書いてあるけど、python-bluezを使う

from bluetooth import find_service,RFCOMM,BluetoothSocket,BluetoothError

host = None
port = 0

for service in find_service():
    if service["protocol"] == "RFCOMM" and service["name"] == "RFCOMM Service":
        host = service["host"]
        port = service["port"]

if host is not None:
    sock = BluetoothSocket(RFCOMM)
    sock.connect((host, port))

    print "Connected: %s:%d" % (host, port)

    while True:
        data = raw_input("message: ")

        if data is not None:
            try:
                sock.send("%sn" % data)
            except:
                break;

まぁこれを実行してデータを送ったりするとスマフォ側にデータが表示される。でその動画を撮影しました

{% youtube 9FjwF3B0rqo %}

というような感じ。で問題はここからで逆にスマフォ側からPC側にデータをどうやって送るのかって話なんですが。上記のJavaソース上だとcreateRfcommSocketToServiceRecordのメソッドを使ってPC側デバイスのRFCOMMと接続してごにょごにょしているのですが、そもそもPC側のbluetoothにRFCOMMがバインドされてるかって所なんですが、基本的にはRFCOMMは自分でやらないとバインドされないはずなので

sudo sdptool browse local

をやったあとに。Serial Port通信なRFCOMMがあるかどうかを確認しなきゃならん。多分、デフォルトでは無いはずなので

sudo sdptool add --channel=15 SP

で登録しておく。でもっかい見ると

Service Name: Serial Port
Service Description: COM Port
Service Provider: BlueZ
Service RecHandle: 0x10009
Service Class ID List:
  "Serial Port" (0x1101)
Protocol Descriptor List:
  "L2CAP" (0x0100)
  "RFCOMM" (0x0003)
    Channel: 15

な感じで出てるかと。あとはこっちもサーバープログラムを作って、スマフォから送られてきたデータを取得して表示したりするなりだけ。だが、上記のJavaソースだと一度PC側からクライアント接続しないと送信なフォームが出ないようになってるので、それと事前にPC側のRFCOMMレシーバーなプログラムを起動しておかないとスマフォ側からデータ送信出来ない。理由としてスマフォからPC側のサーバーへのコネクションは一度処理した一回のみだけ接続処理を行うので

でそのRFCOMMサーバープログラムも書く。ここもPython

from bluetooth import BluetoothSocket,RFCOMM
import notify2

port = 15

server = BluetoothSocket(RFCOMM)
server.bind(("", port))
server.listen(1)
conn, addr = server.accept()

notify2.init("bluetooth notify")

while True:
    data = conn.recv(4096)

    n = notify2.Notification("Bluetooth Message", data)
    n.show()

っていう感じ。今回のだと

  • PC側のRFCOMMサーバーを起動する (その前にPC側でRFCOMMなSerial Portあるか確認)
  • スマフォアプリ側を起動
  • PC側クライアントからスマフォのRFCOMMへ接続するプログラムを実行 (ここで双方的なコネクションが立つ)
  • PC側からデータを送る (スマフォアプリ側の画面に出る)
  • スマフォ側からデータを送る (PC側にinoitfyなポップアップが出る)

Android AccountManagerで使えるカスタムアカウントを開発する方法

2013-01-19T00:00:00+00:00 Android Java

んまぁAndroid端末使ってる人とかだと見た事あるし、触った事もある人もいるだろう

まぁWebサービスとかのアカウントを端末内に保管して、認証要求だとかをAccountManagerな機能を通じて行えたり出来るAPIが存在する訳ですが、これの独自のを作る方法。まぁ結構書く量が多いので

AppWidgetでListView

2013-01-18T00:00:00+00:00 Android Java

検証したのいつかは覚えてないんですが、ネタとして書いておく

Android API Level 11(Android3.x)くらいから(RemoteViews.setRemoteAdapter辺りがAPI Level14が必要なのでAndroid4.0以降)だと思うんですが、AppWidgetにListViewが使えるようになってる。それを検証したという件

Mockito

2013-01-03T00:00:00+00:00 Java

どうもモック伊藤です。っていう鉄板ジョークはおいといて、Mockitoを使ってみた。でstaticメソッドのmockはPowerMockitoってのを使えば出来る模様なので

Linuxでのjava.util.prefs.Preferences

2013-01-02T00:00:00+00:00 Java Linux

Windowsでいうレジストリ的な事するの場合にはjava.util.prefs.Preferencesを使えば出来た気がするのですが、これLinuxだとどこでデータが保管されているのか知らない(っていうかやった事が無い)のでやってみた

jsonicを使ってみる

2012-12-23T00:00:00+00:00 Java

ちょいと事情によりorg.jsonじゃなくてjsonicを使う事案が出てきて勉強している。まだまだ勉強途中だけどとりあえずまとめてみた。

s2jdbc-genでtinyblobになる件

2012-12-18T00:00:00+00:00 Java

何やらs2jdbc-genでgen-ddlをした際のSQLでLob型のやつがデータベース上ではtinyblob(MySQL)になってるのを確認。これmediumblobとかにする場合には

joda-timeとhamcrest

2012-12-05T00:00:00+00:00 Java

以前からやろうと思ってた物シリーズ的な感じ。日付処理系でjoda-time、んで単体テストのマッチャにhamcrestを使ってみた

Eclipse BIRTを使ってみる (5) - Excelで出力 -

2012-11-22T00:00:00+00:00 Eclipse BIRT Java

EXCELRenderOptionっていうのがあるので、これを使えばExcelを出力可能。だけど、これを使うとチャートがレンダリングされないっていうのがあったので、NativeXlsっていうエミッターを使う事で対処可能らしい(正確にはOpenDocument Spreadsheetで出さない物っぽい)

とりあえずrtpdesignに関しては適当にデータベースに接続して、集計の結果をチャートで出すっていう感じで作っておく

Mavenでs2jdbc-gen

2012-11-17T00:00:00+00:00 Java

まぁググれば色々情報あるのでそれ参考にすれば良いと思います

今までは、普通にデータベースにテーブル作ってエンティティクラス書いてみたいな事してましたが、s2jdbc-genを使ってデータベースからテーブル構成のSQLをダンプできたり、厚生からエンティティクラスを生成したり、データをロード・マイグレーション出来る模様

PagerTitle(Tab)Stripを使ってみる

2012-10-15T00:00:00+00:00 Android Java

最近、サーバー関係なタスクが多くてAndroidな音沙汰がまったくしなかったのでリハビリ的な感じでちょいと調べ物をしてました。それがだいぶ前からGoogle Play等であったように

の上部に表示される「おすすめ」や「カテゴリ」といったようなヘッダーラベルのような物。これどうやってやるのかって調べたらPagerTitleStrip、PagerTabStrip等を用いる事で簡単に出来る模様。なのでやってみた(実行環境はAndroid2.2)

(AndroidManifest.xmlはアクティビティ定義だけなのでパス)

android.accessibilityservice.AccessibilityServiceを使用してNotificationを取得する

2012-10-14T00:00:00+00:00 Android Java

ちょっと前にDeskNotifierっていうスマフォの通知をPCにプッシュするというアプリがあったのを見て思ったのですけど、(Android)スマフォのNotificationって監視して取得したり出来る物なのかっていう所が不明だったので色々と調査

で調査結果としてAccessibilityServiceを使う事で可能な模様、という事でやってみた。まぁ詳しい事は公式ドキュメントに書いてあるんですけど

ConnectivityManager.isActiveNetworkMeteredな件

2012-10-08T00:00:00+00:00 Android Java

なんかどっかで見た気がするのですが、例えばでかいファイルをダウンロードする必要性がある場合に3GではなくWi-Fiを使ってダウンロードさせたい。っていうか正しいのかは曖昧なんですが、「通信制限が存在するネットワークでダウンロード処理を継続しない」っていう処理をする場合等に使える模様。

android.support.v13.dreams.BasicDream

2012-10-07T00:00:00+00:00 Android Java

android-support-v13.jarの中身を見てたらそういうのがあるっていうのを発見。で色々調べてみたら、なにやらスクリーンセーバーのような物を作れるAPIな模様。という事でやってみた

Hectorを使ってみる (4) - 単体テスト -

2012-09-24T00:00:00+00:00 Cassandra Java

hector-testっていうパッケージがあるのですがこれ特になんちゃらTestCaseとかがある訳じゃなくて、あくまでCassandraのサーバーインスタンスを起動できるヘルパークラスがあって、それを使う事でCassandraを使う事ができるみたいな感じな模様

CassandraのJMX

2012-09-18T00:00:00+00:00 Cassandra Java

何やら「CassandraのJMXに接続すればノードとかキースペースとかの情報は取れるよ」っていうのを言われたのでやってみた。Cassandraを起動している状態だと、デフォルトでは7199(cassandra-env.shで変更可能)でJMXポートが開放されている。jconsoleで見ると

という風になっているので、このStorageServiceMBeanなのを取得すれば云々出来る模様

Slim3でrespond_toもどき

2012-08-19T00:00:00+00:00 Java JavaScript

IndexController.java

package server_director.controller.profile;

import org.slim3.controller.Navigation;

import server_director.controller.ServerDirectorController;
import server_director.model.Profile;
import server_director.service.ProfileService;

import com.google.appengine.api.users.User;

public class IndexController extends ServerDirectorController {

    ProfileService service = new ProfileService();

    @Override
    protected Navigation run() throws Exception {
        User user = service.getUser();

        if (!service.isLogin() || user == null) {
            return redirect(service.createLoginURL("/profile"));
        }

        Profile profile = service.getProfile();

        requestScope("profile", profile);

        return forward("/WEB-INF/jsp/index.jsp");
    }
}

まぁてな感じで継承しているクラス以外は普通のSlim3コントローラークラス。もちろんコントローラー側でJSONに変換したりっていう処理は含まれない(あるがJSONに変換する処理自体はModelに。それは以下参照)

modelToJsonでInverseModelListRefを扱う

2012-08-18T00:00:00+00:00 Java

package server_director.model;

import java.io.Serializable;

import org.slim3.datastore.Attribute;
import org.slim3.datastore.InverseModelListRef;
import org.slim3.datastore.Model;

import server_director.meta.ServerMeta;

import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.users.User;

@Model
public class Profile implements Serializable {

    private static final long serialVersionUID = 1L;

    @Attribute(primaryKey = true)
    private Key key;

    @Attribute(persistent = true)
    private User user;

    @Attribute(persistent = false)
    private InverseModelListRef<Server, Profile> servers = new InverseModelListRef<Server, Profile>(
        Server.class,
        ServerMeta.get().profileRef.getName(),
        this
    );

    public Key getKey() {
        return key;
    }

    public void setKey(Key key) {
        this.key = key;
    }

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    public InverseModelListRef<Server, Profile> getServers() {
        return servers;
    }
}

みたいなのがあって、これをmodelToJsonを使ってJSON化するとInverseModelListRefなのはエンコードしたJSONに含まれない(ModelRefの場合はKeyが出るらしい)

でこれをやる方法がちゃんとあるみたいで以下のようにJsonアノテーションを設定する

Hadoop+Cassandra (3) - Mapper & ReducerでCassandra -

2012-04-08T00:00:00+09:00 Cassandra Hadoop Java

HadoopでCassandraを使ってみるネタシリーズはこれで終わり。1回目と2回目をくっつけて、Cassandraから読み込みCassandraにプッシュしてみる。で、MapperとReducerは1回目で書いたSampleCassandraMapperと2回目で書いたSampleCassandraReducerをそのまま使います。なのでHadoopジョブを投げる側だけを作れば良い

android.widget.ArrayAdapterでのフィルタリングの拡張

2012-02-28T00:00:00+00:00 Android Java

Quick Search Box関係を調べていて勉強しているとふと思ったのが、クエリーによる検索をするのは良いけど例えばフィルターをする実際の処理を自分で実装した場合とかどうするのって思った。というかどうやらデフォルトのAdapterのフィルターだと検索キーワードをトークンで分割してフィルタしてくれない模様なんだけど。という事でフィルタ処理を自分で処理する方法を調べた所だと、Adapterとそれが使用するFilterオブジェクトを拡張してやれば良いらしい

android.content.BroadcastReceiver Using Android ICS of android.test.AndroidTestCase

2012-01-07T00:00:00+00:00 Android Java

Android4.0以前だとonReceiveメソッドをそのままインスタンスメソッドとしてAndroidTestCaseを使ってテスト出来たんですけど、Android4.0からだとエラーになる。そのエラーになるケースがsetResultExtrasを使った場合になるんですが[APIドキュメント][1]によると

Change the current result extras of this broadcast; only works with broadcasts sent through Context.sendOrderedBroadcast. This is a Bundle holding arbitrary data, whose interpretation is up to the broadcaster. Can be set to null. Calling this method completely replaces the current map (if any). This method does not work with non-ordered broadcasts such as those sent with Context.sendBroadcast

って書いちゃってんすよね。英語読める訳じゃないけど、要するにsetResultExtrasを使う場合はonReceiveをそのまま実行してもsendBroadcastでやっても出来ないらしいっぽい事を書いてる気がする。じゃあどないすんねんと。まぁ書いてあるとおりにsendBroadcastではなく、sendOrderedBroadcastを使えとの事らしいので

android.content.Loader Test Case Using android.test.LoaderTestCase

2011-12-19T00:00:00+00:00 Android Java

例えば

SampleLoader.java

package sample.test;

import android.content.Context;
import android.content.CursorLoader;
import android.database.Cursor;
import android.database.MatrixCursor;

public class SampleLoader extends CursorLoader {

    public SampleLoader(Context context) {
        super(context);
    }

    @Override
    public Cursor loadInBackground() {
        Cursor csr  = null;

        try {
            MatrixCursor mc = new MatrixCursor(new String[]{ "_id", "NAME" });
            mc.addRow(new Object[] { 1, "hoge" });
            mc.addRow(new Object[] { 2, "fuga" });
            mc.addRow(new Object[] { 3, "foobar" });

            csr = mc;
        } catch(Exception e) {
            e.printStackTrace();
        }

        return csr;
    }
}

的な感じで作っといて、これをテストする方法ですが。普通にLoaderTestCaseっていうのがあるので