Androidの権限

Androidの権限

INTERNET
インターネット接続に必要

CALL_PHONE
電話をかけるのに必要
ないと電話をかける画面はでるけどかけることはできない

READ_CONTACTS
Android標準の電話帳からのデータ取得に必要
この権限がないと、電話帳の更新ができない

READ_PHONE_STATE
端末の製造番号や電話番号を取得
この権限がないと、アプリからこれらの情報へアクセスできない

Androidでのマルチタスク

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アプリの構成

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 4.0から
Android Beamサポート
Wi-Fi Directのサポート 
が追加

Android 4.1から
画面描画のトリプルバッファリング
通知の追加スタイルサポート
flashは廃止
となった

Android 4.2以降では
360°パノラマ撮影機能
タブレットでのマルチユーザー機能
Quick Setting機能
ワイヤレスディスプレイ機能
スクリーンセイバー機能
が追加された

端末情報については
http://www.android.com/phones-and-tablets/
でみることができる

録音アプリ作成

録音アプリ作成

今回できたのは
audio

音声を記録するには
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のエラーコードメモ

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 へ変換

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
に掲載されている画面の大きさなどにありそう

このあたりの変換も今後調べる予定