Androidで音を再生してみる
今回はSoundPoolクラスを使って音を再生してみたいと思います。再生する音楽ファイルはogg形式でassetsフォルダ配下に格納されているものを使用するので、前回、投稿のAssetManagerも使用します。
やりたいこと
実装の要点を下記にまとめます
1. 音量ボタンが音楽のStreamを制御するように紐付ける
setVolumeControlStream(AudioManager.STREAM_MUSIC);
2. SoundPoolオブジェクトを取得
private static final int SOUND_NUM = 10; private SoundPool mSp; mSp = new SoundPool(SOUND_NUM, AudioManager.STREAM_MUSIC, 0);
3. AssetManagerを取得し、AssetFileDescriptorを取得
private static final String AUDIO = "metal.ogg"; AssetManager am = getAssets(); try { AssetFileDescriptor fd = am.openFd(AUDIO); } catch (IOException e) { e.printStackTrace(); }
4. FileDescripterを使って、使用するサウンドをloadしIDを取得する
private int mId = -1; mId = mSp.load(fd, 1);
5. サウンドのIDを指定して再生
mSp.play(mId, 1, 1, 0, 0, 1);
6. 使わなくなったサウンドをunloadして、SoundPoolはreleaseする
mSp.unload(mId); mSp.release();
では実装です
軽くAssetManager
連日の投稿です。今回はassetsフォルダにあるテキストファイルを読み込んで、TextViewに表示してみようと思います。
やりたいこと
- AssetManagerを取得する
- assetsフォルダのテキストファイルを読み込む
- 読み込んだファイルをTextViewに表示する
実装の要点を下記にまとめます
1. Context#getAssets()メソッドでAssetManagerを取得
AssetManager assets = getAssets();
2. 読み込みたいファイルのassetsフォルダからの相対パス名を引数として渡しInputStreamを取得する
private static final String TEXT_NAME = "lorem.txt"; InputStream is = null; try { is = assets.open(TEXT_NAME); } catch (IOException e) { e.printStackTrace(); }
3. InputStreamをByteArrayOutputStreamに読みこんで、それからStringを作成する
private String getText(InputStream is) throws IOException{ ByteArrayOutputStream bs = new ByteArrayOutputStream(); byte[] bytes = new byte[4096]; int len = 0; while((len = is.read(bytes)) > 0){ Log.d(TAG, "len = " + len); bs.write(bytes, 0, len); } //テキストファイルがUTF8でエンコードされているので第2引数に指定 return new String(bs.toByteArray(), "UTF8"); }
では実装です
久しぶりに軽くAndroidでSensorManager
久しぶりのBlogを更新。今まで何をやっていたかというと、業務が開発と離れていたためサボっていました...。ということで、久しぶりに地道に頑張ってBlog更新して行こうかと思います。ということで、今回は軽めにSensorManagerから加速度センサーを取得し、各軸の加速度をTextViewに表示してみたいと思います。
実装の要点を下記にまとめます
1. SensorMangerを取得
SensorManager manager = (SensorManager)getSystemService(Context.SENSOR_SERVICE);
2. 加速度センサーを取得
Sensor ac = manager.getSensorList(Sensor.TYPE_ACCELEROMETER).get(0);
3. 加速度センサーにSensorEventListerを登録
manager.registerListener(this, ac, SensorManager.SENSOR_DELAY_GAME)
4. SensorEventListener#onSensorChanged()内で加速度を取得
@Override public void onSensorChanged(SensorEvent event) { mBuilder.setLength(0); mBuilder.append("x: "); //values[0]にはx軸の加速度 mBuilder.append(event.values[0]); mBuilder.append(", y: "); //values[1]にはy軸の加速度 mBuilder.append(event.values[1]); mBuilder.append(", z: "); //values[2]にはz軸の加速度 mBuilder.append(event.values[2]); mTextView.setText(mBuilder.toString()); }
では実装です
Fragmentを勉強する - part2
今回も前回の続きでFragmentに関しての覚え書きです。今回はここから
Managing Fragment
Fragmentを管理するにはFragmentManagerを使用する。Activity#getFragmentManager()でFragmentManagerを取得する
FragmentManagerで出来る事の例
-
- FragmentManager#findFragmentById()やFragmentManager#findFragmentByTag()でFragmentを取得する
- FragmentManager#popbackStack()でback stackからFragmentを取得する(Back keyで戻る行為と同じ)
- FragmentManager#addOnBackStackChangedListener()でback stackのlistenerを登録する
Performing Fragment Transactions
-
- 1回のcommitでやりとりされる変更をtransactionと呼ぶ
- 1つのtransactionにFragmentに対する変更をFragmentTransaction#add(), FragmentTransaction#remove(), FragmentTransaction#replace()といったmethodでまとめる事が出来る
- UserがBack keyで以前の状態に戻るにはFragmentTransaction#commit()をする前にFragmentTransaction#addToBackStack()を呼ぶ
//FragmentとFragmentTransactionを生成する Fragment newFragment = new ExampleFragment(); FragmentTransaction transaction = getFragmentManager().beginTransaction(); //fragment_container viewにあるFragmentを生成したFragmentで入れ替えて //このreplace transactionをback stackに追加する transaction.replace(R.id.fragment_container, newFragment); transaction.addToBackStack(null); // transactionをcommitする transaction.commit();
-
- いくつかの変更を追加したtransactionをcommitする前にback stackに追加するとBack keyで加えられた変更が一気に巻き戻される
- Transactionに変更を加える順番は影響しない。ただし、ひとつの親viewに複数のFragmentが付加される場合はaddされた順番でview hierarchyに現れる
- Fragmentをremoveするtransactionをcommitする前にback stackに登録しなければ、そのtransactionがcommitされると、そのFragmentはdestroyされる。一方、登録されたFragmentはstopされる
- Transaction毎にFragmentTransaction#setTransition()でFragmentのAnimationをすることが出来る
- Transactionは即座には実行されず、UI threadが実行可能になった際に実行される。即座に実行したい場合はFragmentManager#executePendingTransactions()を呼ぶ
- commitはActivityがonSaveInstanceState()が呼ばれる前に実行されなければいけない。状態を残さずにcommitしても良い場合はFragmentTransaction#commitAllowingStateLoss()で実行する
Communicating with the Activity
FragmentはActivityから独立しているがActivityと直接のつながりがある
//現在つながりのあるActivityを取得するにはFragment#getActivity()を呼ぶ
View listView = getActivity().findViewById(R.id.list);
//逆にActivityからFragmentを取得するには
ExampleFragment fragment = (ExampleFragment) getFragmentManager().findFragmentById(R.id.example_fragment);
Creating event callbacks to the activity
Activityとeventを共有したい場合はcallback interfaceを定義しActivityに実装させる
1. Interfaceを宣言する
public static class FragmentA extends ListFragment { ... // Activityがこのinterfaceを実装する public interface OnArticleSelectedListener { public void onArticleSelected(Uri articleUri); } ... }
2. Fragment#onAttach()で渡されるActivityをListener登録する
public static class FragmentA extends ListFragment { OnArticleSelectedListener mListener; ... @Override public void onAttach(Activity activity) { super.onAttach(activity); try { mListener = (OnArticleSelectedListener) activity; } catch (ClassCastException e) { throw new ClassCastException(activity.toString() + " must implement OnArticleSelectedListener"); } } ... }
3. Eventを取得したらListener登録されたActivityに通知する
public static class FragmentA extends ListFragment { OnArticleSelectedListener mListener; ... @Override public void onListItemClick(ListView l, View v, int position, long id) { Uri noteUri = ContentUris.withAppendedId(ArticleColumns.CONTENT_URI, id); //EventをListener登録されたActivityに通知 mListener.onArticleSelected(noteUri); } ... }
Adding items to the Action Bar
FragmentはOptionMenu(結果的にはAction Bar)にMenu itemを追加する事が出来る
-
- Fragment#onCreate()でFragment#setHasOptionsMenu()を呼び、設定を行う
- Fragment#onCreateOptionsMenu()で実装を行う
Fragment内のViewに対してFragment#registerForContextMenu()でContext menuを提供する様出来る
*ただし、Menu itemに対するcallbackはActivityが始めに受け取り、Activityで処理を完結しなかった時のみFragmentに通知される
Handling the Fragment Lifecycle
Fragmentのlife cycleはActivityのlife cycleと似ている
-
- Resumed
Fragmentが実行中のActivity内で表示される時
-
- Paused
他のActivityが全面に出ているが、FragmentをhostするActivityが見えている状態になった時
-
- Stopped
HostのActivityがstopしたか、FragmentがActivityからback stackに登録されremoveされた時
また、Activityと同様にFragment#onSavedInstanceState()で状態をBundle objectに保存することが出来る
Coordinating with the activity lifecycle
基本的にはActivityのcallbackが呼ばれた際にはFragmentの同じ様なcallbackが呼ばれる。ただし、Fragmentには追加で下記のcallbackが用意されている
-
- onAttach()
FragmentがActivityと結び付けられた時
-
- onCreateView()
FragmentのView hierarchyを作る時
-
- onActivityCreated()
Activity#onCreate()が終了した時
-
- onDestroyView()
FragmentのView hierarchyが取り除かれる時
-
- onDetach()
FragmentがActivityとの結び付けを解除された時
Fragmentに関連したcodeはここ
HashTag #Android, #Java, #Fragment, #FragmentManager, #FragmentTransaction
Fragmentを勉強する - part1
今回はAndroid 3.0で追加されたFragmentに関してです。
2回位に分けてここの要点をまとめたいと思います。
Fragment
-
- 複数のFragmentを一つのActivity内で表示する事が出来る
- 複数のActivityでFragmentを共有する事が出来る
- FragmentのLifecycleはActivityのLifecycleに影響される
- FragmentのTransactionはStackに保存されBack keyで戻ることが出来る
- FragmentはActivityで使用されるViewGroupに組み込まれる
- xmlで定義する際は
要素として定義する - fragmentをUI上に表示する必要はない(Backgroundで作業をさせる)
Fragment Design Philosophy
複数のScreen sizeでそれぞれ適したUIを
Creating a Fragment
-
- Activityと同じようなLife cycle。少なくとも下記のcallback methodを実装する必要がある
- onCreate()
- onCreateView()
- 初めてUIをdrawする際に呼ばれる。fragmentのrootとなるViewを返す必要がある。UIを持たない場合はViewを返す必要がない
- onPause
- Fragmentのsub class
- DiaglogFragment
- ListFragment
- PreferenceFragment
- Activityと同じようなLife cycle。少なくとも下記のcallback methodを実装する必要がある
Adding a user interface
UIにFragmentを追加するにはonCreateView()でActivityのlayout(ViewGroup)に追加されるViewを返す
public static class ExampleFragment extends Fragment { //第2引数のViewGroupにreturnするViewが追加される @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // 第3引数のbooleanは"container"にreturnするViewを追加するかどうか //trueにすると最終的なlayoutに再度、同じView groupが表示されてしまうのでfalseでOKらしい return inflater.inflate(R.layout.example_fragment, container, false); } }
Adding a fragment to an Activity
ActivityにFragmentを追加する
1. Activityのlayout xmlに定義
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="match_parent"> <fragment android:name="com.example.news.ArticleListFragment" android:id="@+id/list" android:layout_weight="1" android:layout_width="0dp" android:layout_height="match_parent" /> <fragment android:name="com.example.news.ArticleReaderFragment" android:id="@+id/viewer" android:layout_weight="2" android:layout_width="0dp" android:layout_height="match_parent" /> </LinearLayout>
FragmentにはSystemやProgrammerが識別する為のidもしくはtagが必要である
2. Source内で追加
FragmentTransaction objectを取得
FragmentManager fragmentManager = getFragmentManager() FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
FragmentTransaction#add()でfragmentをActivityのViewGroupに追加
//Fragmentをinstance化 ExampleFragment fragment = new ExampleFragment(); //FragmentTransaction#add()で第1引数のlayoutにfragmentを追加 fragmentTransaction.add(R.id.fragment_container, fragment); //変更をcommit fragmentTransaction.commit();
Adding a Fragment without a UI
-
- FragmentTransaction#add(Fragment, String)でFragmentを追加
- UIを持たないのでonCreateView()を実装する必要がない
- FragmentManager#findFragmentByTag()でFragmentを取得する(tagを定義しないとUIを持たないFragmentを取得する方法がなくなる)
1回目はまずはここまで。
HashTag #Android, #Fragment, #FragmentManager, #FragmentTransaction, #Activity
MatrixとCanvas
久々のpostです。MatrixとCanvasの動作に関してです。ちょっとチンプンカンプンなところがあったので動作を確認しながらまとめてみました
今回やりたいこと
- Matrix(とHandler)を使用してIconを縦方向に落下するAnimationをさせる
- Canvasを操作し文字列とIconを縦方向に描画する
Matrixを操作しIconを回転させ、画面に沿って落下させるの図
Canvasを操作し文字列、Iconを縦に回転させるの図
MatrixとCanvasで気付いたこと
1. Matrix
-
- Matrixにはpre-concat系、post-concat系、set系のMatrix操作系methodがある
- 引数に指定するx、yは画面に対してのx、yなのでmatrixを90度回転してもx軸、y軸は変わらない
2. Canvas
その他気付いたこと
-
- Viewを入れ替える際はView.INVISIBLEでは駄目でView.GONEを指定する必要がある
- Matrixを使用する際にはscaleType属性にmatrixを指定する必要あり
- Canvas#drawText()で指定する座標位置はtextのbaselineの座標位置
それでは実装です
HTMLの基礎覚え書き - form
HTML基礎覚え書き最後にしたいと思います。今回はformに関してです。またまた、ここのサイトを参考にさせて頂いてます
form要素
-
- formはcontrolのまとまり
- 「なにを」「どこに」「どうやって」の「どこに」「どうやって」を指定してあげる
- 「どこに」はaction属性で指定
- action属性にはprogramの名前を
- action属性にはURIを指定することも出来る(ex. mailto:)
- 「どうやって」はmethod属性で指定
- method属性には"post", "get"のmethodの指定を
- 「なにを」はcontrolが担当
- 「どこに」はaction属性で指定
input要素(controlの一種)
-
- name属性を指定することにより、dataを受信したプログラムが入力dataの項目を判別することが出来る
- readonly属性を使用し、readonly="readonly"と指定することにより、読み取り専用のcontrolとなる
- type属性を指定することにより、様々な入力形式に変化する
1. textタイプ
-
- 文字の入力
- size属性でtext boxの長さを指定することが出来る
- value属性でhint textを表示することが出来る
<p>URL: <input type="text" name="url" value="http://" size="60" />
2. submitタイプ
-
- submit buttonの表示
- value属性でbuttonに表示する文字列を指定することが出来る
<input type=”submit" value="送信">
3. radioタイプ
-
- radio buttonの表示
- あらかじめchecked属性、checked="checked"を指定することにより初期選択ができる
- 選択されたbuttonを判別するためにvalue属性が必要
<li><input type="radio" name="sex" value=”male” checked="checked" /> Male</li> <li><input type="radio" name="sex" value=”female” /> Female</li>
4. checkboxタイプ
-
- checkboxの表示
- radioタイプと同様checked属性が指定できる
<li><input type="checkbox" name="hobby" value="Running" checked="checked" /> Running</li> <li><input type="checkbox" name="hobby" value="Swimming" /> Swimming</li>
5. hiddenタイプ
-
- HTML文書作成者が設定したdataを送るUserに知られることなく送れる
<!-- infoという名前とsecretというvalueを持ったdataが送られる --> <input type="hidden" name="info" value="secret" />
6. fileタイプ
-
- 選択されたfileがformのdataとして送信することが出来る
- form要素のenctype属性をmultipart/form-data指定するとMIMEのマルチパートデータとしてファイルやその他の項目の内容を送信する
select要素(controlの一種)
-
- option要素を入れ子にすることによって、それらをアイテムとしたメニューリストを表示
- option要素を初期選択状態にするにはselected属性を使用し、selected="selected"を指定する
- size属性を指定することにより、そのリストアイテムの数を表示したスクロールフィールドを表示する
<select name="favourite_fruit"> <option selected="selected">りんご</option> <option>みかん</option> </select>
textarea要素
-
- input要素textタイプでは一行dataしか入力出来ないので複数行に渡るdataを入力したい時に使用
- readonly属性を使用し、readonly="readonly"と指定することにより、読み取り専用のcontrolとなる
- 入力エリアの行数、列数を指定するにはrows属性、cols属性を指定する
- input要素textタイプと異なり、文字をmarkupするとtext areaにあらかじめtextを表示する(Input要素textタイプではvalue属性に定義していた)
<textarea name="free_ans" rows="2" cols="40">答えを入力</textarea>
URLエンコード
label要素
-
- controlと表示文字列を紐づける
- ここを参照