takaiwa.net

Android、Java、Web系、Linux、マラソン等の備忘録

2013/09/28

JavaではてなAPIのOAuth

0 件のコメント

あらすじ

ここのドキュメントにあるお話をJavaでやってみようと
・Consumer key を取得して OAuth 開発をはじめよう - Hatena Developer Center
http://developer.hatena.ne.jp/ja/documents/auth/apis/oauth/consumer
サンプルコードもあるんですけど、Perl版とRuby版しかなくてどっちもあまりやったことないので一筋縄にいきませんでした。

OAuthのJavaライブラリ

OAuthのライブラリは、oauth-signpostを使いました。
・oauth-signpost - Simple OAuth message signing for Java - Google Project Hosting
http://code.google.com/p/oauth-signpost/
アクセストークン取得までは、GitHubにあるTwitterのサンプルですが、これを参考にサクッと取得ができました。
・signpost-examples/OAuthTwitterExample/src/TwitterMain.java at master · mttkay/signpost-examples · GitHub
https://github.com/mttkay/signpost-examples/blob/master/OAuthTwitterExample/src/TwitterMain.java

2013/09/27

Android JUnit testかJUnit testかでログの出力先を切り替える

0 件のコメント
テスト駆動開発でコーディング、テスト、リファクタリングというサイクルを素早く回す必要があるのですが、Eclipse上のAndroidでやる場合Android JUnit testは端末へのインストール処理を挟むためどうしても起動が遅いです。

起動で一呼吸している間にモチベーションや集中がどっかへ行ってしまいます。そのため、極力ロジック部分を切り離して(Androidを含まない)JUnit testとして起動した方が光の速さで起動するので良いと思います。それに伴って、特に意識せずにAndroidとロジック部分の結合度も下がるというメリットもあります
※「特に意識せず」というのはAndroidのクラス利用しようとしてたらコンパイラが指摘するから

ただ問題なのがログですね。テスト対象のクラスに埋め込むandroid.util.LogのLog.v("tag", "message")という感じで使うLogcatに表示してくれるメソッドは、JUnit testで起動するとエラーが出ます。使えるようにする方法もあるのかもしれませんが、以下のようなやり方を思いついたので掲載しておきます。

Log.vの箇所に下記のようなクラスを利用します。システムプロパティの文字を判定して、Log.vかSystem.out.printlnかをif文で分岐させてるだけです。

import android.util.Log;

public class MyLog {

    private static String runtime =
        System.getProperty("java.runtime.name");

    public static void v(String tag, String msg) {

        if(0 <= runtime.indexOf("Android")) {
            Log.v(tag, msg);
        }
        else {
            System.out.println(tag + ":" + msg);
        }
    }
}

ちなみに、System.getProperty("java.runtime.name")の戻り値は、
  • Android JUnit test実行時 : Android Runtime
  • JUnit test実行時 : Java(TM) SE Runtime Environment
という文字列を返します。
まあ、でも結合テストや運用のログには中で分岐させてるのは好ましくないかもしれませんね。テスト駆動開発用ということで。

代替案として、Eclipseへ新たにJavaプロジェクトを追加して、そこでロジック部分をテスト駆動で実装する。テストが終わったら本プロジェクトにコピーしてやる。ログの部分は同じようにMyLogクラスを設け、双方同じ名前のパッケージ内入れてLog.v (本プロジェクト側)やSystem.out.println (新たに追加したプロジェクト側)で出力してやれば、テスト済みのクラスを本プロジェクトへコピーするだけでいけます。

追記:2013/12/27

>代替案として、Eclipseへ新たにJavaプロジェクトを追加して、そこでロジック部分をテスト駆動で実装
と書いてますが、代替案としてもやらない方がいいですね。Javaプロジェクトで動くものが、Androidで同じように動くとは限らないので。ライブラリとか使ってる場合とか。当たり前ですね.....

2013/09/26

Android API Level 16でアクションバーの色が変らないメモ

0 件のコメント
values-11やそれ以前からコピぺしたきたstyles.xmlを使ってると、どこがダメなんだよ!と小一時間考えてしまったのでメモしておきます。


values-14のstyle.xmlは以下の通り。基本的には、「android:」で開始されるitem名にしないと適用されないという結論です。

<style name="AppTheme" parent="Theme.Sherlock.Light.DarkActionBar">
    <item name="android:actionBarStyle">@style/Widget.MyTheme.ActionRed</item>
</style>

<style name="Widget.MyTheme.ActionBar.TitleTextStyle"
    parent="TextAppearance.Sherlock.Widget.ActionBar.Title">
    <item name="android:textColor">#ffffff</item>

</style>

<style name="Widget.MyTheme.ActionRed" parent="Widget.Sherlock.ActionBar">
    <item name="android:background">#FF2222</item>
    <item name="android:icon">@drawable/action_log</item>
    <item name="android:titleTextStyle">@style/Widget.MyTheme.ActionBar.TitleTextStyle</item>
</style>

※ActionBarSherlockを使っています。
※直接色の値を記述してたり、どこかの定義を参照してたり、混ざってますがサンプルということで気にしないでください。

API Level毎のActionbarの色の確認は、Eclipseの下図プルダウンのレベルを変更することで行えますが、


たぶん、マニフェストに定義している全体のテーマが反映されてて、

<application
    android:label="hoge"
    android:theme="@style/AppTheme" >

Activity個別にテーマを設定している場合はやっぱりアプリを起動するしかないのかと思っているところです。

PR
Smashing Android UI レスポンシブUIとデザインパターン

2013/09/25

JumblrでPhotoSetとEclipse実行とコマンドプロンプト実行で挙動が異なるなど

0 件のコメント
Tumblr APIのJavaライブラリJumblrが公開されていて、それを使っていろいろとやってみているところです。なかなか一筋縄にいかないです。

PhotoSetの投稿

まずPhotoSetですが、1つの投稿に複数の写真を入れるやつです。GitHubのmasterに公開されているものには実装されていません。photo_postブランチの方に実装されています。
・tumblr/jumblr · GitHub
https://github.com/tumblr/jumblr/tree/photo_post
注意しないといけないのが、ブランチの方はmaster側に実装されているものが入ってなかったりするので、Photo.java、PhotoPost.java、PhotosetPost.javaをとってくるなどしてmasterに良い感じにマージしてやる必要があります。

また、このPhotosetPost.javaはレイアウトの指定ができないので、下記のようなレイアウトが自由に選べません。投稿すると勝手なレイアウトが割り当てられます。


Photo Setのレイアウトは、
・Photo set のレイアウトの指定 - p’s diary
http://d.hatena.ne.jp/poochin/20120329/1332994978
こちらで書かれているように、数字の羅列を一緒に送ってやれば良いそうです。なのでPhotoPost.javaを開いて、以下のdetailメソッドのようにphotoset_layoutを追加してやれば、レイアウトも指定できます。

/**
 * Get the detail for this post (and the base detail)
 * @return the details
 */
@Override
public Map<String, Object> detail() {
    Map<String, Object> details = super.detail();
    details.put("type", "photo");
    details.put("link", link);
    details.put("photoset_layout", photoset_layout);
    details.put("caption", caption);

    if (pendingPhotos != null) {
        for (int i = 0; i < pendingPhotos.size(); i++) {
            PhotoType type = pendingPhotos.get(0).getType();
            if (type != null) {
                details.put(type.getPrefix() + "[" + i + "]", pendingPhotos.get(i).getDetail());
            }
        }
    }

    return details;
}

ちなみに、ネットの情報によれば写真は1日75枚までという制限があるようです。ドキュメントには容量制限以外は特に書かれてないのですが。

2013/09/21

Evernoet連携のAndroidアプリ「Note Linker」バージョン0.1をリリースしました

0 件のコメント

Note LinkerはEvernoteのノートリンクを集めた目次(ノート)を作成する無料アプリです。

Windows クライアントでのイメージ

ノートを目次としてまとめる事で、ノートを探す手間を減らすことができます。

アプリのホーム画面

アプリの目次閲覧画面

このアプリの特徴的な部分は、目次の元となるノートにバックリンクを挿入することができる点です。ブログのような感覚でリンクを辿ることで、スムーズにノートを閲覧できます。

Evernoteに旅行の写真とか入れてる方は旅行アルバムの目次として、アイデアをとりあえず突っ込んでる方はアイデア集の目次として作成すれば、あのノートどこへやったっけ?という手間の軽減にお役に立てると思います。


Note Linker ヘルプページ

ご意見・ご感想・不具合のご報告などお気軽のお問い合わせください。お問い合わせ方法は、

また、Google Playでの評価をお待ちしておりますm(_ _)m

2013/09/19

Android 現状の見てる状態の画面回転をロック

0 件のコメント
Android端末でごちゃごちゃ処理している時に画面を回転させると、onDestroyが呼ばれActivityが再生成されて面倒なわけですが、ちょっとした処理を待たせるような時はActivity再生成の対策を考えるよりは画面を固定してしまった方が面倒なことも少ない。というわけで、ググってみるとあまりコレだ!という感じのがなかなか出てこないのでメモしておきます。

まあ、(たぶん)昔の端末は画面の回転は縦か横かだったのが、最近のは画面の向きに即して4パターン変る仕様になったのと & ユーザ側で画面をロックしたいなどのアプリ利用でのノウハウもあってすぐに出てこないと言った感じでしょうか。

こちらに、ありがたいメソッドがあるのですが、
・Androidで回転を固定にしたり解除したりする方法について : 新・開発者の戯言
http://blog2.kojin.biz/2010/04/23/androidで回転を固定にしたり解除したりする方法につ/
 これは、縦か横かの固定なので、Android 2.1と2.3とかの端末だとうまく行くのですが、Nexus 7とかを逆の縦(逆の横)に向けておいて、このメソッドを走らせると画面がくるんと回って固定されてしまうわけです。そして解除するとくるんと元に戻る。

そういうのもひっくるめていいやり方がありました。
・How to Lock screen orientation when displaying reverse landscape in android? - Stack Overflow
http://stackoverflow.com/questions/6410237/how-to-lock-screen-orientation-when-displaying-reverse-landscape-in-android
autremoiさんの回答でlockScreenOrientation()のメソッド。4パターン判定して固定しています。Surface.ROTATION_180とSurface.ROTATION_270に直接値が入ってますが、これはSCREEN_ORIENTATION_REVERSE_PORTRAITとSCREEN_ORIENTATION_REVERSE_LANDSCAPEがAPI Level 9以上であることから、それ以前用に向けてのことです。
・ActivityInfo | Android Developers
http://developer.android.com/reference/android/content/pm/ActivityInfo.html#SCREEN_ORIENTATION_REVERSE_LANDSCAPE
まあ、そもそもSurface.ROTATION_180にSurface.ROTATION_270入らないので大丈夫のような気がしなくもないですが。

上記2つのメソッドから使い回しできるようstaticメソッドに書き換えたのを載せておきます。

    /**
     * 画面の回転を固定・解除する関数
     * @param flg 真なら回転固定 偽なら回転可能
     */
    public static void lockScreenOrientation(Activity activity, Boolean flg){
        if(flg){
            switch (((WindowManager) activity.getSystemService(Activity.WINDOW_SERVICE))
                    .getDefaultDisplay().getRotation()) {
            case Surface.ROTATION_90:
                activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
                break;
            case Surface.ROTATION_180:
                activity.setRequestedOrientation(9/* reversePortait */);
                break;
            case Surface.ROTATION_270:
                activity.setRequestedOrientation(8/* reverseLandscape */);
                break;
            default :
                activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
            }
        }else{
            activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
        }
    }

PR
Androidプログラミングレシピ増補改訂版 アーキテクチャ/UI/ネットワーク編

2013/09/17

AsyncTaskの実行中にProgressDialog表示させ画面回転させるとIllegalArgumentException

0 件のコメント
よくやるやつ。

Activity上でAsyncTaskを継承したクラスのインスタンスを生成。このクラスのコンストラクタでProgressDialogのインスタンスを生成してダイアログを表示。onPostExecuteでダイアログをdismiss()する。このdismissするまでに画面を回転させると、

java.lang.IllegalArgumentException: View not attached to window manager

という例外が発生します。対策の一つとして、そもそも画面を回転させないというのもあり、過去のアプリにもやりましたが、それ以外のとりあえずの対応として、ProgressDialogの処理をActivityにやらせることにしました。

AsyncTaskのインスタンスを生成する前にActivity上にProgressDialogのインスタンスを生成して、AsyncTaskの処理終りにdismiss()。あと、ActivityのonDestroyが走った時に、ダイアログが開いてればdismiss()というやり方でとりあえず手持ちの端末では例外は発生しないようです。

どうやってActivity側からAsyncTaskの処理終りを捕まえるかについてなど処理のイメージは以下のソースで。※手持ちのソースから抜粋したので、コンパイラは通してません。

public class HogeActivity extends Activity {

    private ProgressDialog mDialog = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_hoge);

        mDialog = new ProgressDialog(this,
                R.string.msg_loading);
        mDialog.show();

        LoaderTask task = new LoaderTask(){

            @Override
            protected void onPostExecute(Void result) {
                super.onPostExecute(result)
                // 処理終りでダイアログを閉じる
                closeDialog();
            }
        };
        task.execute();
    }

    private static class LoaderTask 
        extends AsyncTask<Void, Void, Void> {

        @Override
        protected Void doInBackground(Void... params) {
            // なんか処理
            return null;
        }
    }

    private void closeDialog() {
        if(null != mDialog) {
            mDialog.dismiss();
            mDialog = null;
        }
    }

    @Override
    protected void onDestroy() {
        this.closeDialog();
    }
}


参考
mokkouyouの開発日記 ProgressDialogとAsyncTaskの(おそらく)正しい使い方
Android/View_not_attached_to_window_manager - tech.cm55.com

PR
AndroidエンジニアのためのモダンJava

2013/09/14

署名付きのapkファイルを書き出すとadmobが表示されない(凡ミス)

0 件のコメント
凡ミスを小一時間悩んだのでのメモしておきます。

Google Playに登録すべくEclipseから署名付きのapkファイルを出力して、Dropbox経由でAndroid端末にインストールしてみると、admobが表示されなくなりました。デバッグ段階では表示されていたのに。

Logcatを見ると、「Cannot find adapter class 'com.google.ads.mediation.admob.AdMobAdapter'. Did you link the ad network's mediation adapter? Skipping ad network.」だの「java.lang.ClassNotFoundException: com.google.ads.mediation.admob.AdMobAdapter」表示されています。ビルドのやり方に問題があるかと思ってましたが、違いました。

admobを表示させるxmlファイルのads:adUnitIdの値が違う値でした。admobのサイトにログインしてそこに記述されているパブリッシャー IDにしてやると、うまく表示されました。

こんなミスをする思い当たる節がありませんが、何かしたのでしょう。解決のヒントは以下のリンクよりいただきました。
・android - What is the class GADMAdapterCustomEvents - Stack Overflow
http://stackoverflow.com/questions/12284188/what-is-the-class-gadmadaptercustomevents
ちなみに、 ビルドに問題がある場合は、こちら↓のお話が参考になるかもしれません。
・Yet Another Diary: Androidで外部JarがAPKファイルに取り込まれなくなった時の対処法
http://yasu-2.blogspot.jp/2012/04/androidjarapk.html

それにしても、Admobのサイトに依頼数がカウントされているので、何をキーにそのアプリが依頼したんだと疑問も残りますが...

[PR]
Smartphone Ads iPhone・Androidアプリへの広告の実装と管理テクニック