2013年5月26日日曜日

[Android]アプリケーションのActivityを全て終了してアプリを終了する

ある Activityからアプリケーションを終了しようとした場合、別の Activityが起動してあったりするとうまくいかなかったりします。

この場合、BroadcastRecieverを使えば、自分のアプリの Activityだけを終了させることができます。

ただ、BroadcastRecieverは外部アプリケーションからの Broadcastも受信できてしまうので、今回のケースのようなアプリケーション内で完結するような Broadcastの場合は LocalBroadcastManagerを使用したほうがよいです。

LocalBroadcastManager | Android Developers

LocalBroadcastManagerを使うことで、アプリケーション内で完結する Broadcastを送信したり、アプリケーション内でのみ動作する BroadcatRecieverを登録することができます。

で、アプリケーション終了の方法でが、全ての Activityに Reciverを登録しておき、終了処理を行う Activityから登録した IntentFiterの Broadcast を送信します。
Reciverの中では onReciveで Activity の finish()の呼び出しと Recieverの解除を行うだけです。

以下、サンプルコードです。
・MainActivity
package jp.inara.appfinishsample;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.support.v4.content.LocalBroadcastManager;
import android.view.View;
import android.view.View.OnClickListener;

public class MainActivity extends Activity {

    BroadcastReceiver mReceiver;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        findViewById(R.id.button1).setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(MainActivity.this, SecondActivity.class);
                startActivity(intent);
            }
        });
        
        // BroadcastRecieverを LocalBroadcastManagerを使って登録
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction("jp.inara.appFinishSample.APP_FINISH");
        mReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                LocalBroadcastManager.getInstance(getApplicationContext()).unregisterReceiver(mReceiver);
                finish();
            }
        };
        LocalBroadcastManager.getInstance(getApplicationContext()).registerReceiver(mReceiver, intentFilter);
    }
}

・SecondActivity
package jp.inara.appfinishsample;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.content.LocalBroadcastManager;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class SecondActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
        Button finishButton = (Button) findViewById(R.id.finish_button);
        finishButton.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                // LocalBroadcastManagerを使ってBroadcastを送信
                Intent appFinishIntent = new Intent();
                appFinishIntent.setAction("jp.inara.appFinishSample.APP_FINISH");
                LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(appFinishIntent);
                finish();
            }
        });
    }
}

ただ、BroadcastManagerはそもそも Serviceから Activityを呼び出したりする時に使ったりするものなので、この使い方が間違っている可能性大です。。。

2013年5月3日金曜日

[android][ListView]FooterViewのハマりどころ

ListViewのFooterの設定をした際に色々ハマったのでメモ。

addFooterView と removeFooterView に指定するインスタンス


addFooterView と removeFooterView に指定するインスタンスは同一のインスタンスである必要があるみたいです。
xml リソースから View を生成している場合、View を使うタイミングで findViewById で View を取得したりすると思いますが、この場合はインスタンス自体は別になってしまうので addFooterView で追加した Footer を removeFooterView で削除することはできません。
addFooter する View はメンバ変数などで保持していく必要があるみたいです。

Footerに指定するViewをXMLから生成する場合


Footerに指定するViewをXMLから生成する場合、root の View に layout_margin を設定してもうまく設定されないようです。 marginの設定をしたい場合は rootView の配下の View に対して設定する必要があります。つまり、

LinearLayout ー Button 

のような Layout を Footer に設定する場合、root の LinearLayoutに margin を設定してもうまく設定されません。
もし LinearLayout に margin を 設定した場合は、

LinearLayout ー LinearLayout  ー Button 

のような Layout にし、子の LinearLayout に margin を設定するとうまく設定されるみたいです。
# ただしこの方法だと Lint から怒られます。もっと良い方法が本当はあるのかも。

こういうのは Reference 見るとちゃんと書いてあったりするのかなー??

2013年4月28日日曜日

[Android]onAnimationEndの呼ばれるとき

アニメーションの終了時に何か処理をしたい場合はAnimation.AnimationListenerのonAnimationEndを使うと思いますが、onAnimationEnd()はアニメーションの終了時以外でも以下のタイミングで呼ばれるみたいです。

Animation.cancel()が呼ばれたとき

Animation.cancel()が呼ばれるとAnimationListenerに通知が飛び、onAnimationEnd()が呼ばれます。

View.clearAnimation()が呼ばれたとき

リファレンスにはclearAnimationを呼ぶとAnimationがキャンセルされるという事だけ書いてありますが、おそらくそのキャンセルの中で上記のAnimation.cancelが呼ばれているのか、ここでもonAnimationEndが呼ばれるようです。

上記のタイミングでonAnimationEndが呼ばれたくないのであれば、事前にAnimationListenerを解除しておく必要がありそうです。


2013年4月26日金曜日

[Java]Arrays.asListを使ってListを作るとadd/clear/removeする時にUnsupportedOperationExceptionが発生するよ

ハマったのでメモ。

なぜかUnsupportedOperationExceptionが発生して困っていたのですが、原因はタイトルの通りでした。

Arrays.asList()使うと固定長のListが返ってくるそうな。
リファレンスに書いてありますね。

Arrays (Java Platform SE 6)

Returns a fixed-size list backed by the specified array
解決法はCollection インタフェースを実装したクラスを生成すれば良いと。

String[] str = new String[] {"aaa", "bbb", "ccc"};
List<string> list = new ArrayList<string>(Arrays.asList(str));

Java やってる人なら当たり前って感じなんでしょうか。

参考:
http://stackoverflow.com/questions/2965747/why-i-get-unsupportedoperationexception-when-trying-to-remove-from-the-list

2013年4月2日火曜日

[Android]SearchViewを使うために工夫したあれこれ

最近オレ得アプリを公開しました。

風来のシレン4 攻略支援ツール〜アイテム識別管理、値段識別〜

このアプリ内でSearchViewを使っているのですが、使うにあたって色々と設定をするのに苦労したので忘れないように記録を残しておこうと思います。

詳しくは以下。


2013年3月25日月曜日

[Skyrim]PS3版スカイリムでDLC導入後に攻撃できなくなる不具合への対処法

PS3にもDLCがいよいよやってきましたね。

早速導入してみたのですが、ゲームを起動するとなぜか右手攻撃、シャウトができなくなっていました。

その時の対処法です。


  1. PS3のメニューからゲームデータ管理を選択し、「skyrim update」を削除。
  2. Skyrimを起動し、最新パッチ(現時点では1.8)を当てる。
  3. PSStoreから再度DLCをダウンロードし、インストールする。


これで無事に不具合が治りました。

参考:
スカイリム(ps3)のdlcを購入してアップデートをして、セーブデータをロー... - Yahoo!知恵袋

2013年3月18日月曜日

[Android]ABC 2013 Springに参加してきました

イベント概要は以下リンクから。
ABC 2013 Spring | Android Bazaar and Conference 2013 Spring

自分は土曜日の2日目に朝から参加しました。
ABCはずっと行きたいと思っていながらなかなか参加できなかったので今回が初めての参加になります。
しかし明星大学、遠かったです…。

以下、自分が聞いたカンファレンスの感想になります。


2013年2月23日土曜日

[Android]ActionBarSherlockを使うまでの設定

いつも忘れてしまうのでメモ。

ActionBarSherlockを使えるようにする

  1. http://actionbarsherlock.com/index.htmlからライブラリをダウンロード
  2. プロジェクトの新規作成から「Android Project from Existing Code」を選択
  3. ダウンロードしたActionBarSherlockのlibraryフォルダを選択
  4. 名前がlibraryのプロジェクトが作成される。適当な名前に変更

プロジェクトからActionBarSherlockを使う

  1. プロジェクトのプロパティからAndroidの項目を選択
  2. LibraryからAddを選択するとさっき作ったActionBarSherlockのプロジェクトが表示されるので選択してOK
  3. Consoleに「Jar mismatch」のエラーがでることがあるが、プロジェクトのandroid-support-v4.jarとActionBarSherlockのプロジェクトのandroid-support-v4.jarのバージョンが違うのが原因。だいたいプロジェクトのほうが新しいと思うのでプロジェクト/libs/android-support-v4.jarをActionBarSherlockのlibs/にコピーする。
  4. res/values/style.xml、res/values-v11/style.xml、res/values-v14/style.xmlのAppBaseThemeのparentをActionBarSherlockのテーマに変更する。
  • Theme.Sherlock
  • Theme.Sherlock.Light
  • Theme.Sherlock.Light.DarkActionBar

ひとまずこれでビルドが通ってActionBarのついたアプリが起動します。
Themeの設定あたりをどうしても忘れちゃうんですよねー。

2013年1月31日木曜日

日本Androidの会 横浜支部に参加してきました

先週末に参加してきました。


日本Androidの会 横浜支部 第16回定例会 : ATND
http://atnd.org/events/35126


横浜支部は2回目の参加になります。
以下、所感。


2013年1月1日火曜日

2013年の目標

あけましておめでとうございます。
今年もよろしくお願いいたします。 

さてさて2013年になったので今年の目標を高らかに宣言したいと思います。

2013年目標


Webサービスを作る

今年の大きな目標はこれですね。ネタはもう決まっています。何番煎じになるかわわかりませんが…。

新しい言語を覚える

昨年はRubyを覚えました。今年は関数型言語に触ってみたいなーと思っています。Scalaあたりはどうなんでしょうか。

ブログを更新する

正直これが難しい?できれば月に2件は更新していきたいなーと。


勉強会で2件発表する

どこかの勉強会で発表したいなーと思っています。LTやってみたいです。



というわけで今年はブログ更新がんばりますのでよろしくお願いいたします。