Androidの権限
INTERNET
インターネット接続に必要
CALL_PHONE
電話をかけるのに必要
ないと電話をかける画面はでるけどかけることはできない
READ_CONTACTS
Android標準の電話帳からのデータ取得に必要
この権限がないと、電話帳の更新ができない
READ_PHONE_STATE
端末の製造番号や電話番号を取得
この権限がないと、アプリからこれらの情報へアクセスできない
Just another WordPress site
Androidの権限
INTERNET
インターネット接続に必要
CALL_PHONE
電話をかけるのに必要
ないと電話をかける画面はでるけどかけることはできない
READ_CONTACTS
Android標準の電話帳からのデータ取得に必要
この権限がないと、電話帳の更新ができない
READ_PHONE_STATE
端末の製造番号や電話番号を取得
この権限がないと、アプリからこれらの情報へアクセスできない
Androidでのマルチタスク
Androidでのマルチタスクは、パソコンとは異なる
どちらかと言うと、Webブラウザのタブ
1つのタスクは、
バックスタックというスタックを持ち
その中へ今まで
タブで表示したActivityがスタックされる
このタスクを必要に応じて切り替えることでAndroidはマルチタスクを実現している
また、Activityは起動するごとに
現在アクティブなタスクのバックスタックへスタックされていく
このとき、Activityがどのアプリなのかは重要ではなく
他のアプリのActivityでも、Activityの呼び出し方によっては同じバックスタックへスタックしていく
こうしてスタックされたActivityは、
端末のバックボタンを押すことで
取り出すことができる
そのときに表示されていたActivityは破棄される
次に、タスクの切り替え
タスクの切り替えは、Homeボタンや
マルチタスクボタンを押したとき
ホーム画面からアプリアイコンをタップしたときに行われる
このとき表示していたActivityが属するタスクは休眠状態になり
新たに表示されるActivityの属するタスクが活動状態になる
このように、ユーザーの操作で必要になったときにタスクが切り替えられる
そして、休眠状態のタスクは
時間が経過すると
保持する必要がないとOSが判断して
終了させられる
タスクは、Activityが属するアプリに関係なく動作する
このため、1つのアプリに属するActivityが複数のタスクに存在することもある
このとき、タスクを越えて
1つのアプリでデータや処理を共有したり
タスクにとらわれない処理を実現する手段として、Serviceがある
Serviceは、タスクに属さずアプリに属する形になり
異なるタスク間に属するActivityのデータや処理の共有ができる
暗黙的インテントとインテントフィルター
Activityがどのようなインテントに対応できるかはインテントフィルターにより表される
インテントフィルターは
AndroidManifest.xmlへ設定したり
実行コード内からのメソッド呼び出しで定義できる
インテントフィルターは、以下の要素で構成される
action
インテントが対応できるアクションを文字列で指定
この要素は必須で、1つ以上のかアクションを指定する
category
インテントが対応できるアクションのカテゴリーを文字列て指定
この要素も必須
カテゴリーに指定するのがないときには
CATEGORY_DEFAULT(android.intent.category.DEFAULT)
を指定する
カテゴリー指定をしないと
CATEGORY_DEFAULTにされるので注意
data
インテントのデータに含まれているURI
そのURIが示すMIMEタイプを指定する
例えば
httpスキームが指定されている暗黙的インテントに反応するとか
特定のサイトのURLが含まれている暗黙的インテントに反応するインテントフィルターを定義するときに使う
暗黙的インテントの種類
暗黙的インテントは、目的の動作をアクション名で表す
インテントに格納できるのは、
一つのアクションや
起動するコンポーネントを、絞り込むためのカテゴリ指定
ちなみに、カテゴリ指定は複数指定が可能
もしくは、任意のデータURI
となる
もし、Googleのサイトを表示したいのなら
値はACTION
データは
ACTION_VIEW(android.intent.action.VIEW)
もしくは
値がDATA
データが
http://www.google.com/
となる
この暗黙的インテントは
どちらも
DATAプロパティの値、つまり上でかいたデータの
http://www.google.com
を表示するものを起動する
という意味になり
http://www.google.com
を表示できるアプリ一覧が表示される
つまり
Firefox とかchromeなど
ブラウザー関連が候補で表示される
基本的な暗黙的インテントの例としては
アクションが ACTION_VIEW
データが http://www.google.com/
なら
Googleのサイトを表示
応用で指定のサイトを表示できる
アクションが ACTION_CALL
データが tel:119
なら
電話番号119 入力状態で電話画面を開く
応用で指定の番号へ電話をかける
アクションが ACTION_SENDTO
データが mailto:
なら
メールを送信する
送信先とか送信内容については
EXTRAと呼ばれる付加情報領域へ指定する
これは指定の相手へメール送信するのに使う
アクションは、インテントを要求する動作を示す文字列で
一般的にはJavaクラスのFQCN(完全修飾名)のような . で区切った文字列になる
でも、ほとんどの場合は
ACTION_VIEWとかみたいに
android.content.Intentクラスの定数として定義されたものを使う
インテントについて
Androidでは、インテントにより
コンポーネント間、アプリ間のデータのやりとりをする
アプリのコンポーネントは
常にインテントにより呼び出されるようになっていて
アプリはシステムが必要と判断したときに
システムにより起動される
インテントは
Androidフレームワークに用意されている
オブジェクトの一つで
ActivityやServiceを起動するための重要要素となっている
また
インテントには、
明示的インテントと暗黙的インテントがある
明示的インテントの場合
アプリのパッケージ名と
起動するコンポーネント名
つまりActivityとかServiceなど
を指定するタイプのインテントになる
ここから起動するActivityは常に一意
つまりかぶらない
例えば、アプリをホーム画面で選択して
起動するときに、アプリ内部で
他のアプリを表示するときなどに使用するインテントが明示的インテント
これに対して、暗黙的インテントは
コンポーネント名を指定せず
目的の動作に、対応ができるコンポーネントを呼び出す
一般的にはActivityになる
例えば、ギャラリーやブラウザなどのアプリ、メモ帳などで共有機能で
共有先を指定するダイアログを表示する機能がこれになる
よくあるアプリ一覧がでて選択するのが
暗黙的インテント
アプリ開発の書籍だとインテントは
ほとんど暗黙的インテントで書かれている
暗黙的インテントの場合
目的の動作をアクションで指定する
Androidアプリの構成
Androidアプリは、PC向けとは異なり
4つのコンポーネントで構成される
Activity
これは、アプリの画面を表すクラス
画面の表示、
画面から非表示になったときの各種イベントへ対応可能
Service
これは、画面には表示されず
バックグラウンドで行われるデータ処理
サーバーに近い感覚
天気予報やRSSなどのインターネット上のデータ受信などで使われる
ContentProvider
アプリのデータを外部公開するとき
窓口になるクラス
例えば、電話帳のデータ公開には
このContentProviderを使う
BroadcastReceiver
システムやその他のアプリから
すべてのアプリに向けて送出されるブロードキャストメッセージを受け取る
Receiverクラス
電池の消耗
日付
時刻更新などのタイミングをアプリに通知するときに
このブロードキャストメッセージが使われる
アプリは、これらのコンポーネントを1つ以上実装する必要がある
どれか一つ以上なので
Activityだけとか、Serviceだけのアプリも存在する
そして、これら4種類のコンポーネントは
AndroidManifest.xmlで定義することで
機能として呼び出し可能になる
Androidアプリのパッケージは
.apkファイルになる
このapkファイルは
Claase.dexにまとめられた
実行バイナリ
リソース
AndroidManifest.xml
をzip圧縮したものになる
Claase.dexは
Android SDK でコンパイル済みのJavaクラスファイルをまとめたもの
Androidでは、このファイルを実行バイナリとして
仮想マシンで実行している
Androidアプリ実行の仕組みは
携帯のような少ないメモリ環境のために最適化されたDalvikと呼ばれる仮想マシンで動作する
apkファイルに格納された .dexファイルは
Dalvik VM による実行時に
apkファイルより検出され
Dalvik VMで動作する
仮想マシンで動かすので
初期の非力なハードウェアでは動きが遅かった
Android 4.0以降で追加された機能
Android 4.0から
Android Beamサポート
Wi-Fi Directのサポート
が追加
Android 4.1から
画面描画のトリプルバッファリング
通知の追加スタイルサポート
flashは廃止
となった
Android 4.2以降では
360°パノラマ撮影機能
タブレットでのマルチユーザー機能
Quick Setting機能
ワイヤレスディスプレイ機能
スクリーンセイバー機能
が追加された
端末情報については
http://www.android.com/phones-and-tablets/
でみることができる
録音アプリ作成
音声を記録するには
android.media.MeiaRecorder クラスの
setAudioSource() を使う
MediaRecorder は録画にも使うけど
ソースとして音声のみを指定すれば録音に使える
ソース
記録フォーマット
コーデック
に指定する定数は
MediaRecorder.AudioSource
MediaRecorder.OutputFormat
MediaRecorder.AudioEncoder
となる
なお、録音を使うには
権限として
RECORD_AUDIO
と
WRITE_EXTERNAL_STORAGE
が必要になる
まずは実践
新しくプロジェクトを
RecordAudio で作成
対象は Android 4.0.3
プロジェクトができたら
新しくレイアウトファイルをつくるので
file > new > other > Android XML Layout File
で
record.xml
を作成
RootElement には
LinearLayout を選択
これで作成されるので
次にテキストで録音中と表示し
停止するボタンも設置する
<TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="録音中"/> <Button android:id="@+id/stop" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="録音停止"/>
を追加する
次に
AndroidManifest.xml へ権限を追加する
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.RECORD_AUDIO"/>
を追記する
ここまでできたら
MainActivity で処理を書く
Android アプリでは基本的に
HTMLのような画面をXMLで作成
Javascript の処理のようなものを
java で書く
まず
extends ActionBarActivity
を
extends Activity
にして
Ctrl + shift + o で import を補完
使用する画面を変更したので
setContentView(R.layout.record);
にする
if (savedInstanceState == null) { getSupportFragmentManager().beginTransaction() .add(R.id.container, new PlaceholderFragment()).commit(); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); } /** * A placeholder fragment containing a simple view. */ public static class PlaceholderFragment extends Fragment { public PlaceholderFragment() { } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.fragment_main, container, false); return rootView; } }
はいらないので削除
そして使うものを宣言しておく
private Button executeBtn; private MediaRecorder mRecorder;
ここからの処理は onCreate() の中へ書く
まず MediaRecorder インスタンス作成
mRecorder = new MediaRecorder();
次に入力ソースをマイクに設定する
mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
そして記録するときのフォーマットを3GPP にするので
mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
次に音声コーデックをAMR-N8 にする
mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
次に出力ファイルのパスを設定する
このときにSDカードに書き込むので権限がほしい
mRecorder.setOutputFile("/sdcard/audio.3gp");
今回はテストだけど
実際にこれをやると以前のものが上書きされるので注意
次にレコーダを準備
例外対策のため
try catch で書く
try { //レコーダを準備 mRecorder.prepare(); }catch(IllegalStateException e){ e.printStackTrace(); } catch (IOException e) { // TODO: handle exception e.printStackTrace(); }
次に録音開始
mRecorder.start();
次に、終了ボタンをタップしたときの処理を追加
this.executeBtn =(Button)findViewById(R.id.stop);
これでボタンを判別
挙動は
setOnClickListener で設定する
途中でエラーがでるので
マウスオーバーして指示にしたがい補完する
もしくは
Ctrl + shift + o で候補を出して補完する
最初に
import android.view.View.OnClickListener;
を書いてもいいけど
なれない内は補完したほうがいい
挙動は例外対策を考えて
try catch で書いていく
ソースは
try { //録音停止 mRecorder.stop(); //再使用に備えレコーダ状態のリセット } catch (IllegalStateException e) { // TODO: handle exception e.printStackTrace(); }
あと、メモリ管理みたいに使ったら開放をわすれずに行うので
@Override protected void onDestroy() { // TODO Auto-generated method stub super.onDestroy(); //使わなくなったらレコードリソースを開放 mRecorder.release(); }
を追加する
これで実行すればできあがり
録音している画面は変化しないので
なにかエフェクトをつけるとおもしろいかもしれない
PhoneGap 1.7.0のエラーコードメモ
CAPTURE_INTERNAL_ERROR
コード0
内部エラー
CAPTURE_APPLICATION_BUSY
コード1
アプリ動作中
CAPTURE_INVALID_ARGUMENT
コード2
引数の誤り
CAPTURE_NO_MEDIA_FILES
コード3
メディアファイルがない
CAPTURE_NOT_SUPPORTED
コード20
未サポート
COMPASS_INTERNAL_ERROR
コード0
内部エラー
COMPASS_NOT_SUPPORT
コード20
未サポート
UNKNOWN_ERROR
コード0
不明なエラー
INVALID_ARGUMENT_ERROR
コード1
引数の誤り
TIMEOUT_ERROR
コード2
タイムアウト
PENDING_OPERATION_ERROR
コード3
操作中エラー
I/O_ERROR
コード4
I/Oエラー
NOT_SUPPORTEd_ERROR
コード5
未サポート
PERMISSION_DENIED_ERROR
コード20
アクセス権限がない
NOT_FOUND_ERR
コード1
ファイルが見つからない
SECURITY_ERR
コード2
セキュリティーエラー
ABORT_ERR
コード3
中断された
NOT_READABLE_ERR
コード4
読み込めない
ENCODING_ERR
コード5
エンコーディングエラー
NO_MODIFICATION_ALLOWED_ERR
コード6
編集が許可されてない
INVALID_STATE_ERR
コード7
不正な状態
SYNTAX_ERR
コード8
文法エラー
INVALID_MODIFICATION_ERR
コード9
不正なID
QUOTA_EXCEED_ERR
コード10
ストレージ容量が足りない
TYPE_MISMATCH_ERR
コード11
タイプミス
PATH_EXISTS_ERR
コード12
パスがすでに存在する
FILE_NOT_FOUND_ERR
コード1
ファイルが見つからない
INVALID_URL_ERR
コード2
不正なURL
CONNECTION_ERR
コード3
接続エラー
PERMISSION_DENIED_ERROR
コード1
アクセス権がない
POSITION_UNAVAILABLE
コード2
接続エラー
TIMEOUT
コード3
タイムアウト
MEDIA_ERR_NONE_ACTIVE
コード0
再生中でない
MEDIA_ERR_ABORTED
コード1
中断された
MEDIA_ERR_NETWORK
コード2
ネットワークエラー
MEDIA_ERR_DECODE
コード3
デコードできない
MEDIA_ERRNONE_SUPPOSED
コード4
サポートされない
ubuntu で .ovg から mp4 へ変換
android アプリで動画を再生させようとしたけど
エラーでできなかった
もしかしたら .ovg なのが原因かもしれないので
変換
変換には
mencoder を使うので
sudo apt-get install mencoder
でインストール
オプションがわからないので
mencoder オプションで検索し
http://haraita9283.blog98.fc2.com/blog-entry-186.html
を参考にまずはオプションをメモ
-oac
音声のコーデック。そのままコピーする場合は
-oac copy
-ovc
映像のコーデック。そのままコピーする場合は
-ovc copy
-o
出力先ファイル名
-ss
処理開始時間を指定。秒または hh:mm:ss
-endpos
処理対象時間(長さ)を指定。秒または hh:mm:ss
-list-options
利用できるオプションをリストアップする
これを元に
ubuntu上でogvやaviをmp4に変換する
の内容を自分なりに解釈
mencoder input.ogv -oac mp3lame -ovc lavc -lavcopts vcodec=mpeg4 -o output.mp4
しかしこれだけだと途中でわからないもの
mp3lame
がでてきたので
【HowTo】MEncoderの基本的な使い方とちょっとしたTips
も参考に考えてみる
こっちには
mencoder hoge.mpeg -oac mp3lame -ovc lavc -o hoge.avi
とりあえず書式としては
mencoder 変換元のファイル -oac mp3lame -ovc lavc -lavcopts vcodec=mpeg4 -o 変換後のファイル
という解釈で良さげ
mencoder out.ogv -oac mp3lame -ovc lavc -lavcopts vcodec=mpeg4 -o out.mp4
を実行すると
out.ogv から
out.mp4 が作成できた
しかし、これをandroid で再生しようとすると
この動画を再生できません
と表示されてしまう
原因を検索すると
http://qiita.com/tetsuya/items/6e287aa7b2ca17bb17c5
に
http://developer.android.com/guide/appendix/media-formats.html
にある規格に含まれていないとこうなってしまうらしい
Core Media Formats
にはmp4 が載っているので
おそらく原因は
Video Encoding Recommendations
に掲載されている画面の大きさなどにありそう
このあたりの変換も今後調べる予定