tag:blogger.com,1999:blog-713465304616455462024-02-21T02:28:46.189+09:00いならの住処Anonymoushttp://www.blogger.com/profile/16788004860100538219noreply@blogger.comBlogger33125tag:blogger.com,1999:blog-71346530461645546.post-88603084312118080592013-05-26T23:30:00.000+09:002013-05-26T23:30:31.819+09:00[Android]アプリケーションのActivityを全て終了してアプリを終了するある Activityからアプリケーションを終了しようとした場合、別の Activityが起動してあったりするとうまくいかなかったりします。<br />
<br />
この場合、BroadcastRecieverを使えば、自分のアプリの Activityだけを終了させることができます。<br />
<br />
ただ、BroadcastRecieverは外部アプリケーションからの Broadcastも受信できてしまうので、今回のケースのようなアプリケーション内で完結するような Broadcastの場合は LocalBroadcastManagerを使用したほうがよいです。<br />
<br />
<a href="http://developer.android.com/reference/android/support/v4/content/LocalBroadcastManager.html" target="_blank">LocalBroadcastManager | Android Developers</a><br />
<br />
LocalBroadcastManagerを使うことで、アプリケーション内で完結する Broadcastを送信したり、アプリケーション内でのみ動作する BroadcatRecieverを登録することができます。<br />
<br />
で、アプリケーション終了の方法でが、全ての Activityに Reciverを登録しておき、終了処理を行う Activityから登録した IntentFiterの Broadcast を送信します。<br />
Reciverの中では onReciveで Activity の finish()の呼び出しと Recieverの解除を行うだけです。<br />
<br />
以下、サンプルコードです。<br />
・MainActivity<br />
<pre class="brush:[java];">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);
}
}
</pre>
<br />
・SecondActivity<br />
<pre class="brush:[java];">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();
}
});
}
}
</pre>
<br />
ただ、BroadcastManagerはそもそも Serviceから Activityを呼び出したりする時に使ったりするものなので、この使い方が間違っている可能性大です。。。Anonymoushttp://www.blogger.com/profile/16788004860100538219noreply@blogger.com0tag:blogger.com,1999:blog-71346530461645546.post-10976508286514894352013-05-03T23:59:00.000+09:002013-05-03T23:59:10.873+09:00[android][ListView]FooterViewのハマりどころListViewのFooterの設定をした際に色々ハマったのでメモ。<br />
<br />
<h3>
addFooterView と removeFooterView に指定するインスタンス</h3>
<div>
<br /></div>
<div>
addFooterView と removeFooterView に指定するインスタンスは同一のインスタンスである必要があるみたいです。</div>
<div>
xml リソースから View を生成している場合、View を使うタイミングで findViewById で View を取得したりすると思いますが、この場合はインスタンス自体は別になってしまうので addFooterView で追加した Footer を removeFooterView で削除することはできません。</div>
<div>
addFooter する View はメンバ変数などで保持していく必要があるみたいです。</div>
<div>
<br /></div>
<h3>
Footerに指定するViewをXMLから生成する場合</h3>
<div>
<br /></div>
<div>
Footerに指定するViewをXMLから生成する場合、root の View に layout_margin を設定してもうまく設定されないようです。 marginの設定をしたい場合は rootView の配下の View に対して設定する必要があります。つまり、</div>
<div>
<br /></div>
<div>
LinearLayout ー Button </div>
<div>
<br /></div>
<div>
のような Layout を Footer に設定する場合、root の LinearLayoutに margin を設定してもうまく設定されません。</div>
<div>
もし LinearLayout に margin を 設定した場合は、</div>
<div>
<br /></div>
<div>
LinearLayout ー LinearLayout ー Button </div>
<div>
<br /></div>
<div>
のような Layout にし、子の LinearLayout に margin を設定するとうまく設定されるみたいです。</div>
<div>
# ただしこの方法だと Lint から怒られます。もっと良い方法が本当はあるのかも。</div>
<div>
<br /></div>
<div>
こういうのは Reference 見るとちゃんと書いてあったりするのかなー??</div>
Anonymoushttp://www.blogger.com/profile/16788004860100538219noreply@blogger.com0tag:blogger.com,1999:blog-71346530461645546.post-54988349768894079822013-04-28T00:01:00.001+09:002013-04-28T00:02:26.587+09:00[Android]onAnimationEndの呼ばれるときアニメーションの終了時に何か処理をしたい場合はAnimation.AnimationListenerのonAnimationEndを使うと思いますが、onAnimationEnd()はアニメーションの終了時以外でも以下のタイミングで呼ばれるみたいです。<br />
<br />
<h3>
Animation.cancel()が呼ばれたとき</h3>
<div>
Animation.cancel()が呼ばれるとAnimationListenerに通知が飛び、onAnimationEnd()が呼ばれます。</div>
<div>
<br /></div>
<h3>
View.clearAnimation()が呼ばれたとき</h3>
<div>
リファレンスにはclearAnimationを呼ぶとAnimationがキャンセルされるという事だけ書いてありますが、おそらくそのキャンセルの中で上記のAnimation.cancelが呼ばれているのか、ここでもonAnimationEndが呼ばれるようです。</div>
<div>
<br /></div>
<div>
上記のタイミングでonAnimationEndが呼ばれたくないのであれば、事前にAnimationListenerを解除しておく必要がありそうです。</div>
<div>
<br /></div>
<div>
<br /></div>
Anonymoushttp://www.blogger.com/profile/16788004860100538219noreply@blogger.com0tag:blogger.com,1999:blog-71346530461645546.post-91336719449545463252013-04-26T00:25:00.000+09:002013-04-26T00:25:21.729+09:00[Java]Arrays.asListを使ってListを作るとadd/clear/removeする時にUnsupportedOperationExceptionが発生するよハマったのでメモ。<br />
<br />
なぜかUnsupportedOperationExceptionが発生して困っていたのですが、原因はタイトルの通りでした。<br />
<br />
Arrays.asList()使うと固定長のListが返ってくるそうな。<br />
リファレンスに書いてありますね。<br />
<br />
<a href="http://docs.oracle.com/javase/6/docs/api/java/util/Arrays.html#asList(T...)" target="_blank">Arrays (Java Platform SE 6) </a><br />
<br />
<blockquote class="tr_bq">
<span style="background-color: white;">Returns a fixed-size list backed by the specified array</span></blockquote>
解決法はCollection インタフェースを実装したクラスを生成すれば良いと。<br />
<br />
<pre class="brush:[java];">String[] str = new String[] {"aaa", "bbb", "ccc"};
List<string> list = new ArrayList<string>(Arrays.asList(str));
</pre>
<br />
Java やってる人なら当たり前って感じなんでしょうか。<br />
<br />
参考:<br />
<a href="http://stackoverflow.com/questions/2965747/why-i-get-unsupportedoperationexception-when-trying-to-remove-from-the-list">http://stackoverflow.com/questions/2965747/why-i-get-unsupportedoperationexception-when-trying-to-remove-from-the-list</a>Anonymoushttp://www.blogger.com/profile/16788004860100538219noreply@blogger.com0tag:blogger.com,1999:blog-71346530461645546.post-91023650786173622672013-04-02T23:30:00.000+09:002013-04-02T23:33:37.179+09:00[Android]SearchViewを使うために工夫したあれこれ最近オレ得アプリを公開しました。<br />
<br />
<a href="https://play.google.com/store/apps/details?id=jp.inara.siren4support" target="_blank">風来のシレン4 攻略支援ツール〜アイテム識別管理、値段識別〜</a><br />
<br />
このアプリ内でSearchViewを使っているのですが、使うにあたって色々と設定をするのに苦労したので忘れないように記録を残しておこうと思います。<br />
<br />
詳しくは以下。<br />
<br />
<br />
<a name='more'></a><br />
<h3>
ソフトキーボードを閉じた時にSearchViewを閉じる</h3>
<div>
<br /></div>
<div>
通常SearchViewが開いている時にバックナビゲーションやアップナビゲーションをしてソフトキーボードを閉じてもSearchViewは開いたままになっています。</div>
<div>
そのためSearchViewを閉じるためにはもう一度バックナビゲーション、アップナビゲーションをしてあげる必要があります。</div>
<br />
自分で作ったアプリを触っていて思ったのですがこれは結構使い勝手が悪いです。<br />
なので、一度のナビゲーションでSearchViewが閉じるようにしました。<br />
<br />
やり方はSearchViewのsetOnQueryTextFocusChangeListenerの中でcollapseActionView()を呼び出すようにします。<br />
<br />
<pre class="brush:[java];"> searchView.setOnQueryTextFocusChangeListener(new OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
mSearchMenuItem.collapseActionView();
}
});
</pre>
<br />
<br />
<h3>
SearchViewを開いた状態でActivityを開く</h3>
<div>
<br /></div>
<div>
今回作ったアプリは検索クエリを入力するActivityと検索結果を表示するActivityを分けました。さらに再検索できるようにしたかったので、検索結果表示用ActivityにもSearchViewを配置しました。</div>
<div>
この場合、SearchViewは開いた状態で検索文字列が入っている状態にしたかったので以下のようにしました。</div>
<pre class="brush:[java];">
final MenuItem searchItem = menu.findItem(R.id.menu_search);
searchItem.expandActionView();
SearchView searchView = (SearchView) searchItem.getActionView();
String query = getActivity().getIntent().getStringExtra(SearchManager.QUERY);
searchView.setQuery(query, false);
</pre>
<div>
<br /></div>
<div>
<br /></div>
<h3>
SearchViewを閉じた時にActivityを終了する</h3>
<div>
<br /></div>
<div>
今回のアプリでは検索結果表示用のActivityから検索用のActivityに戻るときに、SearchViewを開いているため2回のナビゲーションが必要になっていました。(1.SearchView閉じる 2.Activity遷移)<br />
これも凄い煩わしかったので1回のナビゲーションで戻れるようにしました。<br />
具体的にはMenuItemのsetOnActionExpandListenerのonMenuItemActionCollapseでActivityをFnishしているだけです。<br />
<br />
<pre class="brush:[java];"> searchItem.setOnActionExpandListener(new OnActionExpandListener() {
@Override
public boolean onMenuItemActionExpand(MenuItem item) {
// 何もしないよ。
return false;
}
@Override
public boolean onMenuItemActionCollapse(MenuItem item) {
getActivity().finish();
return true;
}
});
</pre>
<br />
<br />
<h3>
Landscapeの時にSearchViewの入力モードがフルスクリーンにならないようにする</h3>
<div>
<br /></div>
<div>
なぜかLandscapeにするとフルスクリーンになって困っていました。これはsearchableの中でimeOptionsにflagNoExtractUiを設定すればいいみたいです。</div>
</div>
<pre class="brush:[xml];">
<searchable android:hint="@string/search_hint" android:imeoptions="actionSearch|flagNoExtractUi" android:label="@string/search_label" xmlns:android="http://schemas.android.com/apk/res/android">
</searchable></pre>
<br />
以上が今回のアプリでSearchViewを使うために工夫したあれこれです。<br />
あれこれやったのである程度は自分の意図する動きにすることができたんですけど、やり方がわからずに妥協した部分があったりします。<br />
<br />
<ul>
<li>検索結果用Activity表示時にSearchViewのフォーカスを外したい</li>
<li>検索結果用Activityから検索用Activityに戻ってきた時に検索用ActivityのSearchViewを閉じた状態にしたい</li>
</ul>
<br />
以上2点のやり方をご存知の方がいましたらぜひ教えて下さいー!<br />
<br />Anonymoushttp://www.blogger.com/profile/16788004860100538219noreply@blogger.com0tag:blogger.com,1999:blog-71346530461645546.post-72836040516721360112013-03-25T12:48:00.001+09:002013-03-25T12:49:33.363+09:00[Skyrim]PS3版スカイリムでDLC導入後に攻撃できなくなる不具合への対処法PS3にもDLCがいよいよやってきましたね。<br />
<br />
早速導入してみたのですが、ゲームを起動するとなぜか右手攻撃、シャウトができなくなっていました。<br />
<br />
その時の対処法です。<br />
<br />
<br />
<ol>
<li>PS3のメニューからゲームデータ管理を選択し、「skyrim update」を削除。</li>
<li>Skyrimを起動し、最新パッチ(現時点では1.8)を当てる。</li>
<li>PSStoreから再度DLCをダウンロードし、インストールする。</li>
</ol>
<br />
<br />
これで無事に不具合が治りました。<br />
<br />
参考:<br />
<a href="http://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q13104082063" target="_blank">スカイリム(ps3)のdlcを購入してアップデートをして、セーブデータをロー... - Yahoo!知恵袋 </a>Anonymoushttp://www.blogger.com/profile/16788004860100538219noreply@blogger.com0tag:blogger.com,1999:blog-71346530461645546.post-35894211705111186392013-03-18T13:47:00.000+09:002013-04-02T23:35:46.061+09:00[Android]ABC 2013 Springに参加してきましたイベント概要は以下リンクから。<br />
<a href="http://www.android-group.jp/conference/abc2013s/" target="_blank">ABC 2013 Spring | Android Bazaar and Conference 2013 Spring </a><br />
<br />
自分は土曜日の2日目に朝から参加しました。<br />
ABCはずっと行きたいと思っていながらなかなか参加できなかったので今回が初めての参加になります。<br />
しかし明星大学、遠かったです…。<br />
<br />
以下、自分が聞いたカンファレンスの感想になります。<br />
<br />
<br />
<a name='more'></a><br />
<h3>
アプリリリース後に公開しないための20のこと</h3>
<div>
<br /></div>
<div>
バザールをプラプラと見ていたので途中からお聞きしました。</div>
<div>
内容としてはGoogle Playで後悔するようなコメントがつかないようにするためにこれだけはやっときましょうというもの。こういったお話はとてもありがたいです。</div>
<div>
個人的にはアプリのバージョンアップ時に、上書きインストールの確認をやりましょうというのが印象に残っています。というか自分はやってなかったです…。</div>
<div>
<br /></div>
<div>
<br /></div>
<h3>
モバイルコンテンツ制作を効率化するツールを使いこなせ</h3>
<div>
<br /></div>
<div>
タイトル通りモバイルコンテンツを効率化するツールのお話。レスポンシブなWebサイトを作成するためのツールやCSSを効率よく編集するためのツール等の紹介でした。特にAndroid特化という話ではありませんでした。半分くらいAdobeの宣伝かな?と言った感じ。</div>
<div>
自分はWeb系のスキルがほとんど無いに等しいのでこういったツールが使えると楽ができるんだろうなぁと感じました。でも、やっぱりお高いんでしょう?</div>
<div>
<br />
<br /></div>
<h3>
</h3>
<h3>
マルチデバイス対応と最近のアプリの傾向</h3>
<div>
<br /></div>
<div>
今回のイベントで一番気になっていたセッション。午後イチのセッションという事もあり会場は満員に近いぐらい人が入ってました。</div>
<div>
<br /></div>
<h4>
最近のアプリの傾向</h4>
<div>
<br /></div>
<div>
やっぱりDrawer。Drawer流行ってるみたいですね。自分は機能がたくさんあるアプリを作ったことがないのでDrawerを実装する機会はなかったのですが、どんな感じで作るのかは一度実装して知っといたほうがいいのかもしれませんね。</div>
<div>
と言いつつも必要になったらadamrockerさんのsimple side drawer使っちゃいそうですけど。</div>
<div>
<a href="https://github.com/adamrocker/simple-side-drawer" target="_blank">adamrocker/simple-side-drawer ·GitHub</a></div>
<div>
<br /></div>
<h4>
マルチデバイス対応</h4>
<div>
<br /></div>
<div>
大事なことは拡縮領域を意識して作成することですかね。RelativeLayoutとかListViewとかをうまく使ってやる感じですかね。</div>
<div>
タブレットとスマホでレイアウト変えたい場合はどうしてもレイアウトファイルを2つ作るしかないようですけど、それでもincludeを使ってなるべくわけないようにしたほうがいいみたいです。修正発生すると大変ですしね。</div>
<div>
<br /></div>
<div>
<br /></div>
<h3>
マルチプラットフォーム時代を生き抜くためのたった一つの方法</h3>
<div>
<br /></div>
<div>
ネイティブアプリを作ろう、というお話だと思っていたらNDKのお話でした。そっちのネイティブか!</div>
<div>
要はWebアプリにしもて各プラットフォーム固有のアプリに関してもカオスで大変なので、ネイティブのレイヤでアプリを作りましょうということ。そうするとどのプラットフォームで動くよ。iOSでもWindowsでもLinuxでもAndroidでも1つのコードでOK、とのこと。</div>
<div>
確かにプラットフォームに合わせたアプリを作るの開発者としては大変ですよね。でも、ネイティブのレイヤのアプリを書くのは今の自分にはハードルが高いかも。</div>
<div>
といいつつもAndroidのOSのコードを見たりいじったりしようと思うと結局はいつかやらなきゃいけないんだろうと思うんですが。</div>
<div>
<br /></div>
<div>
<br /></div>
<h3>
LT</h3>
<div>
<br /></div>
<div>
次の時間帯はLT部屋に行きました。</div>
<div>
ちゃんとした?LTを見るのは実は初めてで、ドラ&ドラ娘も初めて見ました。</div>
<div>
個人的にはIntenTRANがどんなものか気になっていたのでお話が聞けてよかったです。</div>
<div>
IntenTRANは別端末にIntentを発行することができるアプリのようでした。</div>
<div>
端末間は独自プロトコルで通信をしているのかと思ったのですが、HTTPを使っているみたいでした。</div>
<div>
スマホで見ててタブレットのほうで見たい、ってケースは自分も結構あるので使ってみたいですね。</div>
<div>
<br /></div>
<div>
<br /></div>
<h3>
モバイルアプリのWebバックエンドをサクッと作れるGoogle Cloud Endpoints</h3>
<div>
<br /></div>
<div>
AppEngine上で動作するモバイルアプリのバックエンドが簡単に作成できるよ、というものでした。</div>
<div>
サーバー側に配置したコードをRPCで簡単に呼び出せるようで、サーバー側のコードもローカルのEclipse上で作成することができるようで、I/Fとかいちいち定義しなくてもその辺はよしなにしてくれるようです。</div>
<div>
サーバーからの戻り値は戻り値のクラスを作ってやればいいみたいですし良い感じです。</div>
<div>
ただ、サーバーサイドの実装はやっぱり必要で、DBに保存したければそのコードも必要とのこと。Googleの認証とかは簡単にできるぽいです。</div>
<div>
現在、もっと簡単に利用するためのサンプルコード(スニペット?)を作成中とのことで近日中には公開されるみたいです。</div>
<div>
<br /></div>
<div>
<br /></div>
<h3>
まとめ</h3>
<div>
<br /></div>
<div>
ABC、初参加でしたがとても楽しかったです。最近あまりAndroidの開発する時間がとれなくてモチベーション下がり気味だったんですが、だいぶモチベーションが回復した気がします。</div>
<div>
カンファレンス以外にも様々なバザールがあり色んな開発者の方とお話できて楽しかったです。</div>
<div>
<br /></div>
<div>
なぜか実機のFirefoxOSなんかも出展されていたりしました。Androidのイベントながらもブースはとても賑わってましたね。自分も触らせて貰いましたがつい戻るボタンを探してしまいますね。これはまぁ慣れの問題だとは思いますが。</div>
<div>
<br /></div>
<div>
という訳で次回も参加したいところですね。次回は自分も何か提供する側をやってみたいですねー。</div>
<div>
<br /></div>
<div>
<br /></div>
Anonymoushttp://www.blogger.com/profile/16788004860100538219noreply@blogger.com0tag:blogger.com,1999:blog-71346530461645546.post-27369021449449176162013-02-23T14:20:00.000+09:002013-02-23T14:20:28.536+09:00[Android]ActionBarSherlockを使うまでの設定いつも忘れてしまうのでメモ。<br />
<br />
<h3>
ActionBarSherlockを使えるようにする</h3>
<ol>
<li>http://actionbarsherlock.com/index.htmlからライブラリをダウンロード</li>
<li>プロジェクトの新規作成から「Android Project from Existing Code」を選択</li>
<li>ダウンロードしたActionBarSherlockのlibraryフォルダを選択</li>
<li>名前がlibraryのプロジェクトが作成される。適当な名前に変更</li>
</ol>
<h4>
プロジェクトからActionBarSherlockを使う</h4>
<div>
<ol>
<li>プロジェクトのプロパティからAndroidの項目を選択</li>
<li>LibraryからAddを選択するとさっき作ったActionBarSherlockのプロジェクトが表示されるので選択してOK</li>
<li>Consoleに「Jar mismatch」のエラーがでることがあるが、プロジェクトのandroid-support-v4.jarとActionBarSherlockのプロジェクトのandroid-support-v4.jarのバージョンが違うのが原因。だいたいプロジェクトのほうが新しいと思うのでプロジェクト/libs/android-support-v4.jarをActionBarSherlockのlibs/にコピーする。</li>
<li>res/values/style.xml、res/values-v11/style.xml、res/values-v14/style.xmlのAppBaseThemeのparentをActionBarSherlockのテーマに変更する。</li>
</ol>
<ul>
<li>Theme.Sherlock</li>
<li>Theme.Sherlock.Light</li>
<li>Theme.Sherlock.Light.DarkActionBar</li>
</ul>
<br />
<ol>
</ol>
</div>
<div>
ひとまずこれでビルドが通ってActionBarのついたアプリが起動します。</div>
<div>
Themeの設定あたりをどうしても忘れちゃうんですよねー。</div>
Anonymoushttp://www.blogger.com/profile/16788004860100538219noreply@blogger.com0tag:blogger.com,1999:blog-71346530461645546.post-85842052243923786372013-01-31T21:52:00.003+09:002013-01-31T21:52:59.259+09:00日本Androidの会 横浜支部に参加してきました先週末に参加してきました。<br />
<br />
<br />
日本Androidの会 横浜支部 第16回定例会 : ATND<br />
<a href="http://atnd.org/events/35126">http://atnd.org/events/35126</a><br />
<br />
<br />
横浜支部は2回目の参加になります。<br />
以下、所感。<br />
<br />
<br />
<h2>
<a name='more'></a></h2>
<h3>
オープンデータを使ってみよう</h3>
<br />
今回は横浜オープンデータハッカソンと同じ会場で開催されたので、<br />
まず<a href="http://twitter.com/ohwada" target="_blank">@ohwada</a>さんからオープンデータのお話がありました。<br />
<br />
個人的にオープンデータって何?な状態だったのでそんな動きがあるんだーと<br />
勉強になりました。<br />
SPARQLを覚える必要はありますけど、それさえやれば簡単に使えそうな印象です。<br />
せっかくなのでオープンデータ使って何か作ってみたいですね。<br />
とは言え優先順位は低そうですが。<br />
<br />
<h4>
12月のaMake Tokyo 出展</h4>
<a href="http://twitter.com/hrdakinori" target="_blank">@hrdakinori</a>さんのMake Faire Tokyoに出展した際のお話。<br />
<a href="http://twitter.com/leibun" target="_blank">@leibun</a>さんの自動変速自転車出展の1コマもありました。<br />
デバイスとAndroidの連携は面白そうです。<br />
ちなみに今週末には横浜支部ロボ部の定例会があるそうな。<br />
<br />
日本アンドロイドの会横浜支部ロボット部定例会 : ATND<br />
<a href="http://atnd.org/events/35285">http://atnd.org/events/35285</a><br />
<br />
<h4>
OpenCV4Androidで画像処理アプリのススメ</h4>
<div>
<a href="https://twitter.com/nekomeshi312" target="_blank">@nekomeshi312</a>さんのOpenCV4Androidを使ったAndroidアプリのお話。</div>
<div>
Galaxy Cameraを使ったデモを見せて頂きました。</div>
<div>
OpenCVはお仕事で少し触ったことがあったのですが、Cでしか使えないものだと思ってました。Javaで簡単に使えるなら個人的にもさわってみたいですね。</div>
<div>
なんとか時間を捻出したいところ・・・。</div>
<div>
<br /></div>
<h4>
LTやりませんか?</h4>
<div>
<a href="https://twitter.com/TakamiChie" target="_blank">@TakamiChie</a>さんのLTに関するお話。</div>
<div>
LTはやってみたいとは思っているのですがどうしてもあと一歩が踏み出せず…。</div>
<div>
次こそは…!といつもいってるのですがいい加減本当にやらないと、と思っています。</div>
<div>
<br /></div>
<h4>
初めてのGCM</h4>
<div>
<a href="http://twitter.com/ohwada" target="_blank">@ohwada</a>さんのGCMのハンズオン。</div>
<div>
個人的には1番楽しみにしていたセッションです。</div>
<div>
1つめのサンプルはなんとか動かすことができたのですが2つめのサンプルはうまく動かせず時間切れとなってしまいました。</div>
<div>
ただ、1つめのサンプルも実際はビルドしただけなので中身を理解できていない状態。</div>
<div>
時間を見つけてしっかり復習したいところですね。</div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
その後のLODハッカソンの結果発表があり、その後でLODハッカソンの方も交えて懇親会に突入。</div>
<div>
<br /></div>
<div>
自分が最近ミラーレス一眼を購入したこともあり、カメラの話に花が咲きました。</div>
<div>
Android界隈はカメラに詳しい方が多い気がしますね。</div>
<div>
<br /></div>
<div>
とりあえず自分も今週末は単焦点レンズの下見(というか購入?)にいきたいところ。</div>
<div>
レンズ沼にはまらないように気をつけないと…。(もう嵌ってるかも)</div>
<div>
<br /></div>
<div>
<br /></div>
<br />
<br />Anonymoushttp://www.blogger.com/profile/16788004860100538219noreply@blogger.com0tag:blogger.com,1999:blog-71346530461645546.post-17052989651216869872013-01-01T11:57:00.002+09:002013-01-01T11:57:42.841+09:002013年の目標あけましておめでとうございます。<br />
今年もよろしくお願いいたします。
<br />
<br />
さてさて2013年になったので今年の目標を高らかに宣言したいと思います。
<br />
<br />
<h3>
2013年目標</h3>
<div>
<br /></div>
<h4>
Webサービスを作る</h4>
<div>
今年の大きな目標はこれですね。ネタはもう決まっています。何番煎じになるかわわかりませんが…。</div>
<div>
<br /></div>
<h4>
新しい言語を覚える</h4>
<div>
昨年はRubyを覚えました。今年は関数型言語に触ってみたいなーと思っています。Scalaあたりはどうなんでしょうか。</div>
<div>
<br /></div>
<h4>
ブログを更新する</h4>
<div>
正直これが難しい?できれば月に2件は更新していきたいなーと。</div>
<h4>
<br /></h4>
<h4>
勉強会で2件発表する</h4>
<div>
どこかの勉強会で発表したいなーと思っています。LTやってみたいです。</div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
というわけで今年はブログ更新がんばりますのでよろしくお願いいたします。</div>
<div>
<br /></div>
Anonymoushttp://www.blogger.com/profile/16788004860100538219noreply@blogger.com0tag:blogger.com,1999:blog-71346530461645546.post-63831175552949072222012-11-22T07:44:00.000+09:002012-11-22T07:44:00.154+09:00[Android]コードからmarginの設定をするメモ。<br />
<br />
LayoutParamsのsetMarginで設定する。<br />
<br />
<br />
<pre class="brush:[java];">
LayoutParams params = new LayoutParams(0, LayoutParams.MATCH_PARENT, 1);
params.setMargins(5, 5, 5, 5);
</pre>
<br />
情報元<br />
<a href="http://stackoverflow.com/questions/3416087/how-to-set-margin-of-imageview-using-code-not-xml" target="_blank">How to set margin of ImageView using code, not xml</a>Anonymoushttp://www.blogger.com/profile/16788004860100538219noreply@blogger.com0tag:blogger.com,1999:blog-71346530461645546.post-19947291572023431202012-11-15T08:14:00.000+09:002012-11-15T08:14:35.116+09:00[Android]2.3以前でPreferenceScreenにテーマが適用されない不具合の対処ひょっとしたら今更感があるネタなのですが、ハマったのでメモ。<br />
<br />
2.3以前のOSだとPreferenceScreenを入れ子にしたPreferenceを生成するとテーマが正しく適用されないバグがあるみたいです。<br />
<br />
<a href="http://code.google.com/p/android/issues/detail?id=4611" target="_blank">Issue 4611: Background from PreferenceActivity is not applied to sub-PreferenceScreen</a><br />
<br />
つまり、下記のようなXMLをPrefereceActivityに読み込ませると子のPreferenceScreenにはテーマが正常に適用されません。<br />
<br />
<h4>
preference.xml</h4>
<br />
<pre class="brush:[xml];">
<preferencescreen xmlns:android="http://schemas.android.com/apk/res/android">
<preferencescreen android:title="メニュー2">
<checkboxpreference android:defaultvalue="true" android:icon="@android:drawable/ic_input_add" android:key="chk1" android:title="チェック1">
<checkboxpreference android:defaultvalue="true" android:icon="@android:drawable/ic_input_add" android:key="chk2" android:title="チェック2">
</checkboxpreference></checkboxpreference></preferencescreen>
</preferencescreen>
</pre>
<br />
最初のPreferenceはちゃんと表示されますが、<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjybP27WLgfy7r26CB9PZ9ZtqarPEHJQ7Lx7i69Nl8MU17ajw5ytJn1HRvbWh6bF8TglmyDQJcrfh24ycng7CehVZ2yF7kSOeDV-uqYsrF6gt1rcWJH1ofSJgu6LuAo5QviuO3vfZhKcQ8/s1600/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88+2012-11-15+7.44.24.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="299" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjybP27WLgfy7r26CB9PZ9ZtqarPEHJQ7Lx7i69Nl8MU17ajw5ytJn1HRvbWh6bF8TglmyDQJcrfh24ycng7CehVZ2yF7kSOeDV-uqYsrF6gt1rcWJH1ofSJgu6LuAo5QviuO3vfZhKcQ8/s320/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88+2012-11-15+7.44.24.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
メニュー2を表示させようとすると、こうなります。</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhwZqBHH1UMuJWNKDJ9Lug5RQ64iM6EbsI3B32rBkPawXQ-ExI8dom7Me67pI6Vj_duTmmdZztLF6Wh2p70zOCtIw5aeaHCkp4MJLSulNb3uLZl5Vsy8o469i5G1p2zMcPp0wpkCqU42oQ/s1600/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88+2012-11-15+7.45.12.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="299" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhwZqBHH1UMuJWNKDJ9Lug5RQ64iM6EbsI3B32rBkPawXQ-ExI8dom7Me67pI6Vj_duTmmdZztLF6Wh2p70zOCtIw5aeaHCkp4MJLSulNb3uLZl5Vsy8o469i5G1p2zMcPp0wpkCqU42oQ/s320/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88+2012-11-15+7.45.12.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
対策として上記リンクのコメント20に書かれていた対策を実施しました。</div>
<div class="separator" style="clear: both; text-align: left;">
具体的には子のPreferenceScreenはxmlを分けて、Intent呼び出しでもう1つPreferenceActivityを生成して表示するようにします。</div>
<div class="separator" style="clear: both; text-align: left;">
なのでPreferenceActivityではIntentの中身を見て読み込むxmlを切り替えます。</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<h4>
preference.xml</h4>
<div>
<br /></div>
<pre class="brush:[xml];">
<preferencescreen xmlns:android="http://schemas.android.com/apk/res/android">
<preferencescreen android:title="メニュー2">
<intent android:action="android.intent.action.VIEW" android:data="preferences://preference2" android:targetclass="jp.inara.sample.preferencebug.MyPreferenceActivity" android:targetpackage="jp.inara.sample.preferencebug">
</intent></preferencescreen>
</preferencescreen>
</pre>
<br />
<h4>
preference2.xml</h4>
<div>
<br /></div>
<pre class="brush:[xml];">
<preferencescreen xmlns:android="http://schemas.android.com/apk/res/android">
<checkboxpreference android:defaultvalue="true" android:icon="@android:drawable/ic_input_add" android:key="chk1" android:title="チェック1">
<checkboxpreference android:defaultvalue="true" android:icon="@android:drawable/ic_input_add" android:key="chk2" android:title="チェック2">
</checkboxpreference></checkboxpreference></preferencescreen>
</pre>
<br />
<h4>
MainActiviy.jara</h4>
<div>
<br /></div>
<pre class="brush:[java];">
package jp.inara.sample.preferencebug;
import android.net.Uri;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.Menu;
import android.view.MenuItem;
public class MainActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
Intent intent = new Intent(this, MyPreferenceActivity.class);
intent.setData(Uri.parse("preferences://preference1"));
startActivity(intent);
return true;
}
}
</pre>
<br />
<h4>
MypreferenceActivity.java</h4>
<div>
<br /></div>
<pre class="brush:[java];">
package jp.inara.sample.preferencebug;
import android.os.Bundle;
import android.preference.PreferenceActivity;
public class MyPreferenceActivity extends PreferenceActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getIntent().getData().toString().equals("preferences://preference2")) {
addPreferencesFromResource(R.xml.preference2);
} else {
addPreferencesFromResource(R.xml.preference);
}
}
}
</pre>
<br />
こんな感じにするとちゃんと子のPreferenceScreenが表示されるようになります。<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjpPn4AWiWLjvgPqEMR-Hji_TKDuSsT_FPUkvyYtXzoLqyfMVcVuzAURli04mnjxY2CJBWNXeC9bqsY8dSPojS_6HeYgF4uRH2WCXzaAYMUu9zFkSdE5oYAMgpCMvNrPUTeweNi0638lwQ/s1600/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88+2012-11-15+8.11.35.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="299" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjpPn4AWiWLjvgPqEMR-Hji_TKDuSsT_FPUkvyYtXzoLqyfMVcVuzAURli04mnjxY2CJBWNXeC9bqsY8dSPojS_6HeYgF4uRH2WCXzaAYMUu9zFkSdE5oYAMgpCMvNrPUTeweNi0638lwQ/s320/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88+2012-11-15+8.11.35.png" width="320" /></a></div>
気をつけなくちゃいけないのは、PreferenceActivityを呼び出すところでIntentにDataをセットし忘れないようにすることですかね。<br />
<div>
<br /></div>
Anonymoushttp://www.blogger.com/profile/16788004860100538219noreply@blogger.com0tag:blogger.com,1999:blog-71346530461645546.post-57344475253822735992012-10-31T07:59:00.000+09:002012-10-31T08:00:34.396+09:00[Android]ViewPagerに追加したFragmentのインスタンスを取得する調べたのでメモ。<br />
<br />
と言ってもここに書いてある事をやっただけ。<br />
<a href="http://stackoverflow.com/questions/7379165/update-data-in-listfragment-as-part-of-viewpager" target="_blank">Update data in ListFragment as part of ViewPager</a><br />
<br />
<span style="font-family: inherit;">ここの2番めのFragmentStatePagerAdapter#<span style="line-height: 18px;">instantiateItem</span><span style="line-height: 18px;">を使う方法でいけました。</span></span><br />
<br />
最も投票されているViewPagerが自動的に設定する、Tagを使ってFragmentを取ってくる回答はFragmentPagerAdapterを使っている場合は使えるけど、FragmentStatePagerAdapterを使っている場合はダメみたいです。<br />
<br />
まぁどのみちAPIが勝手に設定しているTagを利用するのはちょっと怖いですよね。いつ変わるか分からないし。<br />
<br />
ちなみに任意のページのFragmentではなくて、現在表示しているページのFragmentを取得したいのであればこんなふうにすればいけました。<br />
<br />
<br />
<pre class="brush:[java];"> ViewPager pager = (ViewPager) getActivity().findViewById(R.id.pager);
FragmentStatePagerAdapter sAdapter = (FragmentStatePagerAdapter) pager.getAdapter();
HistoryListFragment f2 =(HistoryListFragment) sAdapter.instantiateItem(pager, pager.getCurrentItem());
</pre>
ViewPager#getCurrentItemで現在表示しているページのpositionを取得しただけですが。
Anonymoushttp://www.blogger.com/profile/16788004860100538219noreply@blogger.com0tag:blogger.com,1999:blog-71346530461645546.post-38514044643463257262012-10-23T07:17:00.001+09:002012-11-09T07:15:57.547+09:00[Android]DialogFragmentにListFragmentを表示することはできない調べてみたのですが、現状だとできなそう。<br />
<br />
結局DialogFragment内のonCreateDialogでAlertDialogを作成して、AlertDialogのsetViewでListViewを設定する事にしました。<br />
<br />
せっかく作ったListFragmentが再利用できなくてがっかり・・・。<br />
ローディング中の表示とかデータが無いときのメッセージとかを1から作るのめんどくさいんですよね。<br />
<br />
もし何かいい方法があったら教えて下さいー。<br />
<br />Anonymoushttp://www.blogger.com/profile/16788004860100538219noreply@blogger.com0tag:blogger.com,1999:blog-71346530461645546.post-52333150883708171112012-10-05T22:07:00.002+09:002012-10-05T22:09:19.292+09:00[Android]育レコのバージョンアップをしました<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhI359PWLCKM4cKzSOnynzjKhfs_NJbDUjZjfvw6tlr7R_PqPBgjPe6bde66BtiORA_8NkT9q7PSVzfibmKy2IxekANgcfFXzSEsqa6dmDhrmQOBL-8trneX209HpiPDsun3AVM3wcX6bU/s1600/market_icon.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhI359PWLCKM4cKzSOnynzjKhfs_NJbDUjZjfvw6tlr7R_PqPBgjPe6bde66BtiORA_8NkT9q7PSVzfibmKy2IxekANgcfFXzSEsqa6dmDhrmQOBL-8trneX209HpiPDsun3AVM3wcX6bU/s200/market_icon.png" width="200" /></a></div>
<br />
ワンタッチで育児記録が行えるアプリ、育レコのバージョンアップをしました。<br />
<br />
<a href="https://play.google.com/store/apps/details?id=jp.inara.babyreco" target="_blank">育レコ - Google Play の Android アプリ</a><br />
<br />
今回のバージョンアップでは記録に対して簡単なメモを残せるようにしました。<br />
おっぱいを飲んだけどいつもの半分だったとか、お出かけした場所を記録したりとかができます。<br />
<br />
メモの付け方は記録をつけた後に数秒間表示されるメモボタンをクリックしてください。<br />
<br />
不具合等何かありましたら教えて下さい。<br />
<br />
ではではー。<br />
<br />Anonymoushttp://www.blogger.com/profile/16788004860100538219noreply@blogger.com0tag:blogger.com,1999:blog-71346530461645546.post-80186806626052819532012-09-24T07:42:00.000+09:002012-09-24T07:44:33.035+09:00[Android]MediaCodecAPIを使って動画の音声のみを再生以前、横浜AndroidPF部の勉強会に参加した時にMediaCodecAPIのお話をお聞きしました。<br />
詳しくはこちらのブログ→<a href="http://handyfox.blog.fc2.com/blog-entry-29.html" target="_blank">横浜Androidプラットフォーム部第23回勉強会 #yapf : 手ぎつねメモ</a><br />
<br />
MediaCodecAPIはAndroid 4.1(Jelly Bean)から追加され、動画周りの処理が簡単にできるようになったとの事でした。<br />
<br />
という訳で、動画処理とかやったことない自分でも動画処理ができるか試してみました。<br />
以前から動画の音声だけを再生したかったんですよね。<br />
<br />
<br />
<a name='more'></a><br />
参考にしたのは、リファレンスと勉強会で紹介して頂いたサンプルコード2つです。<br />
リファレンスはこの辺り。<br />
<a href="http://developer.android.com/reference/android/media/MediaCodec.html" target="_blank">MediaCodec | Android Developers</a><br />
<a href="http://developer.android.com/reference/android/media/MediaExtractor.html" target="_blank">MediaExtractor | Android Developers </a><br />
<a href="http://developer.android.com/reference/android/media/MediaFormat.html" target="_blank">MediaFormat | Android Developers</a><br />
<br />
サンプルコードは以下。<br />
<a href="https://dpsm.wordpress.com/2012/07/28/android-mediacodec-decoded/" target="_blank">Android MediaCodec “Decoded” « David Marques' Blog</a><br />
<a href="http://stackoverflow.com/questions/12037119/mediacodec-and-mediaextrator-code" target="_blank">android - mediacodec and mediaextrator code - Stack Overflow </a><br />
<br />
以下が実際に動画ファイルの音声のみを再生したサンプルコードです。<br />
<span style="color: red;"><b>サンプルと言うことでActivityで色々と処理をやってますが実際には音声の再生はUIスレッドとは別スレッドでやるべきです。このまま真似はしないでください。</b></span><br />
<span style="color: red;"><b><br /></b></span>
<br />
<pre class="brush:[java];">package jp.inara.mediacodecapisample;
import java.nio.ByteBuffer;
import android.app.Activity;
import android.content.res.AssetFileDescriptor;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioTrack;
import android.media.MediaCodec;
import android.media.MediaCodec.BufferInfo;
import android.media.MediaExtractor;
import android.media.MediaFormat;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
/**
* MediaCodecAPIを使って動画から音声のみを取り出すサンプルコード
*
* @author inara
*/
public class MainActivity extends Activity {
private static final String LOG_TAG = "MainActivity";
/** バッファを取り出す際のタイムアウト時間(マイクロ秒) */
private static final long TIMEOUT_US = 1;
/** 音声再生用のAudioTrack */
private AudioTrack mAudioTrack;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// assetsからメディアファイルを読み込む
AssetFileDescriptor descriptor = getResources().openRawResourceFd(
R.raw.sample);
// MediaExtractorでファイルからフォーマット情報を抽出。
MediaExtractor extractor = new MediaExtractor();
extractor.setDataSource(descriptor.getFileDescriptor(),
descriptor.getStartOffset(), descriptor.getLength());
// トラック数
// 動画の場合、トラック1が映像、トラック2が音声?
Log.d(LOG_TAG, String.format("TRACKS #: %d", extractor.getTrackCount()));
// 音声のMime Type
MediaFormat format = extractor.getTrackFormat(1);
String mime = format.getString(MediaFormat.KEY_MIME);
Log.d(LOG_TAG, String.format("Audio MIME TYPE: %s", mime));
// デコーターを作成する
MediaCodec codec;
codec = MediaCodec.createDecoderByType(mime);
codec.configure(format, null, null, 0);
codec.start();
// デコーダーからInputBuffer, OutputBufferを取得する
ByteBuffer[] codecInputBuffers;
ByteBuffer[] codecOutputBuffers;
codecInputBuffers = codec.getInputBuffers();
codecOutputBuffers = codec.getOutputBuffers();
// 読み込むトラック番号を指定する
// ここでは音声を指定
extractor.selectTrack(1);
// AudioTrac生成用にメディアから情報取得
// サンプリングレート
int sampleRate = format.getInteger(MediaFormat.KEY_SAMPLE_RATE);
// バッファの最大バイトサイズ
int maxSize = format.getInteger(MediaFormat.KEY_MAX_INPUT_SIZE);
// AudioTrackのインスタンス生成
mAudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, // 音楽再生用のオーディオストリーム
sampleRate, // サンプリングレート
AudioFormat.CHANNEL_OUT_MONO, // モノラル
AudioFormat.ENCODING_PCM_16BIT, // フォーマット
maxSize,// 合計バッファサイズ
AudioTrack.MODE_STREAM); // ストリームモード
// 再生開始
mAudioTrack.play();
// インプットバッファがEnd Of Streamかどうかを判定するフラグ
boolean sawInputEOS = false;
// 以下、バッファの処理。インプットバッファの数だけ繰り返す
for (;;) {
// TIMEOUT_USが 0 だと待ち時間なしで即結果を返す。
// 負の値で無限に応答を待つ
// 正の値だと 値 microseconds分だけ待つ
int inputBufIndex = codec.dequeueInputBuffer(TIMEOUT_US);
// Log.d(LOG_TAG, String.format("Input Buffer Index = %d",
// inputBufIndex));
if (inputBufIndex >= 0) {
// インプットバッファの配列から対象のバッファを取得
ByteBuffer dstBuf = codecInputBuffers[inputBufIndex];
// バッファサイズ
int bufferSize = extractor.readSampleData(dstBuf, 0);
long presentationTimeUs = 0;
if (bufferSize < 0) {
sawInputEOS = true;
bufferSize = 0;
} else {
presentationTimeUs = extractor.getSampleTime();
}
// デコード処理してアウトプットバッファに追加?
codec.queueInputBuffer(inputBufIndex, 0, bufferSize, presentationTimeUs,
sawInputEOS ? MediaCodec.BUFFER_FLAG_END_OF_STREAM : 0);
if (!sawInputEOS) {
extractor.advance();
} else {
break;
}
}
// 出力処理
MediaCodec.BufferInfo info = new BufferInfo();
int outputBufIndex = codec.dequeueOutputBuffer(info, TIMEOUT_US);
// Log.d(LOG_TAG, String.format("Output Buffer Index = %d",
// outputBufIndex));
if (outputBufIndex >= 0) {
// ここで出力処理をする
ByteBuffer buf = codecOutputBuffers[outputBufIndex];
// チャンクを作る
final byte[] chunk = new byte[info.size];
buf.get(chunk);
buf.clear();
// AudioTrackに書き込む
if (chunk.length > 0) {
mAudioTrack.write(chunk, 0, chunk.length);
}
codec.releaseOutputBuffer(outputBufIndex, false);
} else if (outputBufIndex == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
codecOutputBuffers = codec.getOutputBuffers();
} else if (outputBufIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
// Subsequent data will conform to new format.
format = codec.getOutputFormat();
mAudioTrack.setPlaybackRate(format.getInteger(MediaFormat.KEY_SAMPLE_RATE));
}
}
// 終了処理
mAudioTrack.stop();
extractor.release();
extractor = null;
codec.stop();
codec.release();
codec = null;
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
}</pre>
おおまかな流れは、<br />
<br />
<ol>
<li>MediaExtractorで動画ファイルからフォーマットやトラック数、サンプリングレート等を取得</li>
<li>取得した情報を基にMediaCodecのデコーダーを生成</li>
<li>再生用のオブジェクトを生成(サンプルではAudioTrack)</li>
<li>バッファ処理</li>
</ol>
といった感じです。<br />
こんな感じでとりあえずGalaxy Nexusで録画した動画の音声のみを再生することができました。<br />
<br />
動画ファイルのフォーマットを特に意識しなくても良いのでその辺はとても良い感じですね。<br />
<br />
正直、参考にしたサンプルコードとそんなに変わらないです。でもバッファ処理部分のループ処理がよく分からず結構悩みました。<br />
MediaCodecのリファレンスとMediaExtractorのリファレンスの両方にループ処理が書いてあって、どう絡ませるのかよく分からなかったんですよね。<br />
<br />
たぶん、色々と考慮してない部分やダメな部分が多々あると思いますので、ご指摘頂けたらなと思います。<br />
<br />
<br />
<br />
<br />Anonymoushttp://www.blogger.com/profile/16788004860100538219noreply@blogger.com0tag:blogger.com,1999:blog-71346530461645546.post-21344948352215367392012-09-03T19:57:00.001+09:002012-09-03T19:57:20.623+09:00[Ruby]Ruby技術者認定試験を受けてきました。<br />
<br />
受けてきました。<br />
<br />
結果は80/100点で合格でした。<br />
合格ラインが75点なので結構ギリギリですかね。<br />
<br />
特に今すぐどこかでRubyを使うという訳ではないのですが、<br />
スクリプト言語を1つ覚えたかったのと、サーバー側のアプリケーションを<br />
作成する時はきっとRuby On Railsを使うだろうなーということでRubyのお勉強を<br />
してました。<br />
<br />
で、せっかく勉強したので受けてみた、という感じです。<br />
<br />
ちなみにRubyのお勉強は定番ともいえる、「たのしいRuby」で行いました。<br />
<iframe frameborder="0" marginheight="0" marginwidth="0" scrolling="no" src="http://rcm-jp.amazon.co.jp/e/cm?t=homespacdipjp-22&o=9&p=8&l=as1&asins=4797357401&ref=tf_til&fc1=000000&IS2=1&lt1=_blank&m=amazon&lc1=0000FF&bc1=000000&bg1=FFFFFF&f=ifr" style="height: 240px; width: 120px;"></iframe>
<br />
<br />
<br />
サンプルコードも多く、StringやArrayといった主要な組込みライブラリの解説もあるためはじめてRubyを触るには最適ですね。<br />
実際にサンプルコードを動かしながら読み進めていくとより理解できると思います。(自分はそのように進めました)<br />
<br />
試験対策は公式ガイド本を使いました。<br />
<br />
<iframe frameborder="0" marginheight="0" marginwidth="0" scrolling="no" src="http://rcm-jp.amazon.co.jp/e/cm?t=homespacdipjp-22&o=9&p=8&l=as1&asins=4822234304&ref=tf_til&fc1=000000&IS2=1&lt1=_blank&m=amazon&lc1=0000FF&bc1=000000&bg1=FFFFFF&f=ifr" style="height: 240px; width: 120px;"></iframe>
<br />
教科書 + 問題集といった構成になっています。教科書の部分は正直たのしいRubyを読んでいればそれほど必要はないかもしれません。<br />
問題集部分は100問、試験2回分の問題が用意されているので、ここの問題をこなせば実際のテストでどんな問題が出題されるかだいたいつかむ事ができると思います。<br />
<br />
さて、せっかくRubyを覚えたのでこれから色々と面倒な作業はどんどんスクリプト化していきたいなぁと思っています。<br />
<br />
とはいっても目的はWebアプリケーションなのでRoRも早く勉強しないと・・・Anonymoushttp://www.blogger.com/profile/16788004860100538219noreply@blogger.com0tag:blogger.com,1999:blog-71346530461645546.post-19390600860251501492012-07-18T21:28:00.001+09:002012-07-18T21:28:38.038+09:00[fragment][android]FragmentにFragmentをXMLからinflateする事はできないはまりました。<br />
Fragment内でFragmentを定義したレイアウトXMLをinflateしようとしたのですが、下記のような例外が発生。<br />
<br />
<blockquote class="tr_bq">
java.lang.IllegalArgumentException: Binary XML file line #67: Duplicate id 0x7f050008, tag null, or parent id 0x0 with another fragment for HistoryListFragment</blockquote>
<br />
原因が良く分からなかったのでグーグル先生に聞いてみると以下のスレッドを発見。<br />
<br />
<br />
<a href="http://stackoverflow.com/questions/6847460/fragments-within-fragments" target="_blank">Fragments within Fragments</a><br />
<br />
<br />
どうやら去年の時点ではFragment内にFragmentを配置することはサポートされていないようです。そんな使い方は推奨しないということでしょうか。<br />
<br />
なんでそんな事をしたかというと、ViewPager内にFragmentPagerAdapterを使ってListFragmentを表示していたのですが、固定ヘッダが表示したくなったんですよね。<br />
<br />
元のListFragmentをいじりたくなかったので、固定ヘッダとListFragmentを持つFragmentを作って、そのFragmentをFragmentPagerAdapterに渡すようにしました。<br />
その結果、上記例外発生となりました。<br />
<br />
ListFragmentを普通のFragmentに置き換えるしかないんですかねー。面倒だ。Anonymoushttp://www.blogger.com/profile/16788004860100538219noreply@blogger.com0tag:blogger.com,1999:blog-71346530461645546.post-56599333011484285172012-07-05T20:10:00.000+09:002012-07-18T21:02:22.785+09:00[Android][Fragment][Loader][ArrayAdapter]ListFragmentにLoaderを使ってArrayAdapterからリストを表示するListFragmentにデータを表示する際、単純にリストのデータを表示したい場合は、ArrayAdapterを使って表示すると思いますが、データが大量にある場合にはやっぱりバックグラウンドでやるべきですよね。<br />
<br />
最近はバックグラウンドでの読み込みはLoaderを使ってやるのが良いみたいなのでLoaderを使ってみました。<br />
<br />
<br />
<a name='more'></a><br />
<br />
データをCursorから読み込み場合にはCursorLoaderというクラスがあって簡単に実装できるのですが、Listから読み込むにはAsyncTaskLoaderで独自のLoaderを作成する必要があります。<br />
<br />
とうわけでコードです。<br />
<br />
まずはLoader。<br />
<br />
<pre class="brush:[java];">import java.util.List;
import android.content.Context;
import android.support.v4.content.AsyncTaskLoader;
public class MyLoader extends AsyncTaskLoader<List<String>> {
private List<String> mStrings;
/**
* コンストラクタ
* @param context 親クラスのコンテキスト
*/
public MyLoader(Context context) {
super(context);
}
@Override
public List<String> loadInBackground() {
// ここでArrayAdapterに渡すためのデータを作って返す
List<String> strings;
return strings;
}
/**
* 提供する新しいデータがある場合に呼び出される
*/
@Override
public void deliverResult(List<String> strings) {
if(isReset()){
// リセット時
return;
}
mRecords = records;
if(isStarted()) {
// データの読込中
super.deliverResult(strings);
}
}
/**
* ローダーの開始
*/
@Override
protected void onStartLoading() {
if(mRecords != null){
// データが取得済みの場合それを返す
deliverResult(mStrings);
} else {
// 取得できていない場合読み込む
forceLoad();
}
}
/**
* ローダーの停止
*/
@Override
protected void onStopLoading() {
cancelLoad();
}
/**
* キャンセル処理
*/
@Override
public void onCanceled(List<String> strings) {
super.onCanceled(strings);
}
/**
* ローダーのリセット
*/
@Override
protected void onReset() {
super.onReset();
onStopLoading();
if (mStrings != null) {
mStrings = null;
}
}
}
</pre>
次に、Loaderを生成するListFragmentです。<br />
<pre class="brush:[java];">import java.util.List;
import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.ListFragment;
import android.support.v4.app.LoaderManager;
import android.support.v4.app.LoaderManager.LoaderCallbacks;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
public class LatestRecordFragment extends ListFragment implements LoaderCallbacks<List<String>> {
/** アダプター */
private MyArrayAdapter mAdapter;
/** ローダー */
private MyLoader mLoader;
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setEmptyText(getText(R.string.msg_no_record));
mAdapter = new MyArrayAdapter(getActivity());
setListAdapter(mAdapter);
setListShown(false);
LoaderManager manager = getLoaderManager();
manager.initLoader(0, null, this);
}
@Override
public Loader<List<String>> onCreateLoader(int id, Bundle args) {
mLoader = new MyLoader(getActivity());
return mLoader;
}
@Override
public void onLoadFinished(Loader<List<String>> loader, List<String> data) {
mAdapter.setData(data);
if (isResumed()) {
// リストを表示
setListShown(true);
} else {
// 一時停止時はアニメーションなしで表示
setListShownNoAnimation(true);
}
}
@Override
public void onLoaderReset(Loader<List<String>> arg0) {
mAdapter.setData(null);
}
/**
* ローダーを再読み込みするためのメソッド
*/
public void loderContentChanged() {
mLoader.onContentChanged();
}
}</pre>
ArrayAdapterの実装は大したことないので割愛します。
<br />
<br />
Loader使うと画面回転時にも自動でデータの再読み込みしてくれるみたいですし、ちょっと面倒でもLoaderを使うようにしたほうがよさそうですね。<br />
<br />
ちなみに参考にしたのは、<a href="http://www.amazon.co.jp/Android-Cookbook-ICS%EF%BC%88Ice-Cream-Sandwich%EF%BC%89%E3%82%A2%E3%83%97%E3%83%AA%E9%96%8B%E7%99%BA%E8%A1%93/dp/4844331744/">こちら</a>のAndroid UI Cookbook for 4.0 ICSです。<br />
FragmentやLoaderなどの2.3以降に追加された機能に関しての内容が盛り沢山でとても参考になります。
電子書籍版も発売されてますしオススメですよー。Anonymoushttp://www.blogger.com/profile/16788004860100538219noreply@blogger.com0tag:blogger.com,1999:blog-71346530461645546.post-40782237957321696652012-06-28T00:39:00.001+09:002012-06-28T00:48:15.355+09:00[Android][Eclipse]複数の開発マシンでデバッグキーを共有する忘れないようにメモ。<br />
<br />
同じデバイスに複数の開発マシンからデバッグビルドでアプリを上書きインストールすると、<br />
開発マシンごとに証明書が違うのでアプリのアップデートが出来ません。<br />
<br />
アップデートするには一度アプリのアンイストールが必要になります。<br />
<br />
これ面倒だったんですけど、今日タオ本読んでたら書いてありました。<br />
<br />
共有するデバッグ用の証明書を用意すれば、それをEclipseに設定してやれば良いみたいです。<br />
<br />
Eclipseのメニューから、<b>「Preference」→「Android」→「Build」</b>でビルドのメニューを開いて、<b>「Custom Debug keystore」</b>に共通のデバッグ用証明書を設定するだけ。<br />
<br />
なんとも簡単ですね。<br />
次の開発からはこれで少し幸せになれそうです。Anonymoushttp://www.blogger.com/profile/16788004860100538219noreply@blogger.com0tag:blogger.com,1999:blog-71346530461645546.post-661394063241995692012-06-14T22:26:00.001+09:002012-06-14T22:26:12.220+09:00ブログを移行しました<a href="http://dl.dropbox.com/u/964705/fluxflex/goodbye_fluxflex.md">fluxflexがサービス終了する</a>と言うことなので、ブログを移行しました。<br />
とりあえずドメインが使えそうなところという事でbloggerにしてみました。<br />
<br />
以前の記事はせっかくなのでインポートしてみました。<br />
Wordpressから記事をエクスポートして、<a href="http://wordpress2blogger.appspot.com/">ここ</a>でblogger用に変換してインポートしました。<br />
<br />
インポートはできたのですが、コードの部分が見づらいですね。<br />
syntaxhiliterのスクリプトは入れたのですが、インポートした記事にはうまく反映されてくれませんでした。<br />
というか、インポートした記事のHTML見るとすごいことになってます。
<br />
<br />
まぁ、前の記事はひとまず見れるだけよしとして、あのままにしておきますかね。<br />
あ、がんばって更新も再開していきたいです。Anonymoushttp://www.blogger.com/profile/16788004860100538219noreply@blogger.com0tag:blogger.com,1999:blog-71346530461645546.post-30835361057375190242012-03-05T00:50:00.000+09:002012-06-11T01:32:02.997+09:00Galaxy Nexusを購入しました<img alt="Glaxy Nexus" height="480" src="http://s2.i1.picplzthumbs.com/upload/img/57/51/40/5751401dbf8c68a2ae769f93e250e7e16549e37b_wmeg_00001.jpg" width="640" /><br />
<br />
なんだか最近Galaxy Nexusの値段が急落していたので、これを機に購入しました。<br />
<br />
地元の携帯ショップで9,400円で購入できました。<br />
<br />
<a name='more'></a><br />
<br />
これで1年半使ってきたSO-01Bはお役御免となりました。でも、開発機として使っていくので出番はありますが。<br />
<br />
昨日1日GNを触ってみたのですが、良い端末ですね。<br />
<br />
初めは端末のサイズが大きいなーと思っていたのですが、数時間触っていたら気にならなくなってしまいました。慣れって怖い。<br />
<br />
ただ、バックキーの位置がSO-01Bと反対側なのでちょいちょい押し間違えます。というかいい加減この辺は統一して欲しいですね。<br />
<br />
ちなみにまだroot化はしてません。特にROMを入れる予定もありませんし、しばらくはこのままで使うつもりです。<br />
<br />
記念にホーム画面のキャプチャでも。<br />
<a href="http://f.hatena.ne.jp/inara/20120304153331"><img alt="20120304153331" src="http://img.f.hatena.ne.jp/images/fotolife/i/inara/20120304/20120304153331.jpg" /></a><br />
<br />
端末単体でスクリーンショットが取れるのはやっぱり便利でいいですね。<br />
<br />
ホーム画面に置いているウィジェットは、<a href="https://market.android.com/details?id=com.uphyca.android.app.bandlauncher" target="_blank" title="Band Launcher">Band Launcher</a> と <a href="https://market.android.com/details?id=com.uphyca.android.app.bandoclock" target="_blank" title="Band O'Clock">Band O'Clock</a> です。<br />
<br />
ちなみに、自作アプリの<a href="https://market.android.com/details?id=jp.inara.whatstodaystask" target="_blank" title="What's Today's Task ?"> What's Today's Task ?</a> は、ICSでもちゃんと動いてくれました。良かった良かった。Anonymoushttp://www.blogger.com/profile/16788004860100538219noreply@blogger.com0tag:blogger.com,1999:blog-71346530461645546.post-28514732169579892792012-02-04T09:31:00.000+09:002012-06-11T01:32:12.332+09:00[Android]タスクアプリ「What's Today's Task ?」をバージョンアップしましたお久しぶりです。<br/><br/>長らくブログをサボっていました。<br/><br/>アプリ開発もサボっていました。<br/><br/>全部Skyrimのせいだということにしたい・・・。<br/><br/>と、本題ですが、タスクアプリ 「What's Today's Task ?」をバージョンアップしました。<br/><br/><a href="https://market.android.com/details?id=jp.inara.whatstodaystask" target="_blank">What's Today's Task ? - Android マーケットのアプリ</a><br/><br/>変更点は続きから。<br/><br/><a name='more'></a>変更点は以下の3点です。<br/><h1>文字色の変更</h1><br/>タスクの文字色が薄くて視認性が悪かったので、色を変更しました。というか、バグで自分が定義した色が設定されていませんでした。。。これで目に優しくなったと思います。<br/><h1>完了済みタスクを未完了タスクの下にソート</h1><br/>自分で使ってて不満だったのが、タスクをたくさん登録すると追加したタスクが画面外に追加されてしまう事。忘れないようにタスクを登録したのに、結局気づかずに忘れてしまうこともありました。<br/><br/>そのため、完了済みになったタスクは未完了タスクより下にソートするように変更しました。初期表示時、タスク追加時、タスクの完了/未完了変更時にソートがかかります。<br/><br/>タスクの完了/未完了時にソートさせるのは、いきなりタスクの位置が変わってしまうのでタスクを見失ってしまうかもしれませんが、ひとまず変更する方式にしてみました。使いづらいようでしたら元に戻すかもしれません。<br/><h1>日付変更時に指定した日付にタスクが表示されないバグを修正</h1><br/>なぜか今年に入ってからタスクの日付変更が正常に動作しなくなっていました。<br/><br/>原因は日付文字列のパディングの失敗でした。タスクの情報はSQLiteに登録しているのですが、SQLiteにはDate型がないため、日付は文字列として登録しています。DBから取り出した時にDate型に戻しやすいように、yyyyMMddのフォーマットで保持してました。<br/><br/>作っている時には日にちはパディングしなくちゃ桁が変わってしまうことに気付いたのですが、月も桁が変わることには気づきませんでした。Oh....。<br/><br/>なので、今年の1月になった時点で、日付を移動すると、yyyy1ddとDBに登録されてしまい、画面には表示されてませんでした。いやーこんなの普通作ってる時に気づきますよねー普通。。。<br/><br/>と、細かな修正ですがちょっとだけ以前より使いやすくなったと思いますので、よかったら使ってみてくださいー!Anonymoushttp://www.blogger.com/profile/16788004860100538219noreply@blogger.com0tag:blogger.com,1999:blog-71346530461645546.post-72444340265361955462011-12-20T08:36:00.000+09:002012-06-28T00:47:51.188+09:00[Skyrim][NVIDIA]NVIDIA製グラボでスカイリムがフリーズする現象を解決する今更ですが、とうとう日本語版のスカイリムが発売されましたね。<br />
<br />
スカイリムはオープンワールド系のRPGゲームです。詳しくは下記のリンクから。<br />
<br />
<a href="http://www.bethsoft.com/jpn/elderscrolls/" target="_blank">The Elder Scrolls Official Site</a><br />
<br />
前作のオブリビオン(Oblivion)が日本でも話題になり、そこそこヒットしました。自分もオブリビオンはかなりハマりました。もともとXBox360版を購入してプレイしていましたが、MOD目当てでPC版も購入してプレイしたほどです。<br />
<br />
さて、話をスカイリムに戻しますが、今回はPS3版を購入しました。しかし、PS3版は長時間プレイすると動作が重くなるという不具合が発生する、と先行して発売された海外では話題となっていました。<br />
<br />
オブリビオンやスカイリムは基本、長時間のプレイが想定されたゲームです。自分はオブリビオンは何百時間もプレイしました。そういったゲームで長時間のプレイで不具合がでるのは致命的・・・。<br />
<br />
いつ不具合が発生するかビクビクしながらプレイするのも精神衛生上よくないので・・・PC版を購入してしまいました!<br />
<br />
というわけで、早速PCにインストールしてプレイしてみようと思ったのですが・・・フリーズの連発でまともにプレイできない状態に・・・。<br />
<br />
はじめはPCのスペックが低くて無理なのかと絶望しましたが、いろいろ調べて試してみたところ、原因が判明。無事プレイできるようになりました!せっかくなので原因を残しておきます。<br />
<h1>
<a name='more'></a></h1>
<br />
<h1>
原因</h1>
<br />
結局のところ、フリーズの原因はグラフィックドライバでした。NVIDIAのドライバを最新版の 285.62 にしていたのですが、それがいけなかった模様。1つ前の 280.26に変更したところ、フリーズが発生しなくなりました。<br />
<br />
もし、NVIDIA制のグラボを使っていてフリーズが頻発している場合は、ドライバのバージョンを確認してみることをお勧めします。<br />
<br />
ドライバのバージョンはNVIDIAコントロールパネルから確認できます。(きっとタスクトレイに常駐してます)<br />
<br />
ちなみに、自分の環境では、最新ドライバだとNVIDIAコントロールパネルの異常終了が頻発していましが、これもドライバのバージョンを変更する事で回復しました。<br />
<h1>
参考:マシンスペック</h1>
<br />
参考までに自分のマシンスペックです。モノ自体は去年ドスパラで購入した、<a href="http://pc.watch.impress.co.jp/docs/news/20091116_329311.html" target="_blank">Galleria IW</a>というモデルになります。<br />
<br />
<table border="0"><tbody>
<tr><td>CPU</td><td>Core i 7 Q740 1.73GHz</td></tr>
<tr><td>チップセット</td><td>Inte PM55</td></tr>
<tr><td>メモリ</td><td>DDR3 4GB</td></tr>
<tr><td>GPU</td><td>GeForce GTS 250M</td></tr>
<tr><td>HDD</td><td>SSD 160GB</td></tr>
</tbody></table>
<br />
<h1>
おわりに</h1>
<br />
ドライバは最新版にすれば良いってわけではないんですね。勉強になりました。楽しみにしていたゲームだけに本当にプレイできてよかったです。<br />
<br />
ちなみに、PS3版はまだ手放さずに持っています。というか実はPS3版をメインでプレイしてます。<br />
<br />
というのも、不具合が本当なのかどうかよく分からないからです。なので、自分の目で確かめてみようかと思ってプレイしています。たとえ不具合が発生したとしても、PC版をプレイできる環境があるので安心です。<br />
<br />
もし、不具合が発生した時にはこのブログでも報告しようと思います。Anonymoushttp://www.blogger.com/profile/16788004860100538219noreply@blogger.com0tag:blogger.com,1999:blog-71346530461645546.post-45704743708217041312011-12-09T08:59:00.000+09:002012-06-11T01:32:12.385+09:00[Android]Androidアプリケーション「What's Today's Task ?」を公開しました<a href="http://f.hatena.ne.jp/inara/20111208235316"><img src="http://img.f.hatena.ne.jp/images/fotolife/i/inara/20111208/20111208235316.png" alt="20111208235316" /></a><br/>What's Today's Task ?はシンプルなToDoアプリケーションになります。<br/><br/><a href="https://market.android.com/details?id=jp.inara.whatstodaystask">Android Marketからどうぞ。</a><br/><br/>手帳についてる、ToDo欄の代わりになるようなものが欲しいなぁ、と考えて作ってみました。できるだけ少ない操作でタスクを登録・管理ができるように作りました。<br/><br/><a name='more'></a><br/><br/>初めて自分で作ったアプリを世に出しました。アプリ作るの楽しいですね。<br/><br/>今後もできるだけバージョンアップして機能追加していく方針です。乞うご期待。<br/><br/>ちなみに一番大変だったのは、実装はなく、アイコンの作成でした。もともと絵心もなく、何をどうやって作ればよいのかも分からなかったので。苦労して作ったのでこの記事のトップにも貼っておきましたw<br/><br/>ちなみにアイコンは<a href="http://inkscape.org/index.php?lang=ja">Inkscape</a>というツールを使いました。デザイン音痴の自分でも使いやすかったので、きっとおススメです。Anonymoushttp://www.blogger.com/profile/16788004860100538219noreply@blogger.com0