AppNext Press 

アンドロイドアプリ開発をしているAppNextによるAndroidアプリ開発・リリース情報をお届けします。 ツイッターもやっています。ぜひフォローしてください♪ 【@AppNextJP】

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

PageTop

Serviceの自動起動

今回はServiceの自動起動についてのポイントです。


端末を起動した時にServiceを自動起動させるように実装させるにはBroadcastRecieverを使ってBOOT_COMPLETEDを受けてServiceを起動させればよいだけなので簡単に実装できます。

参考サイト:「kino's blog」


ですが! 

実際に実機で試してみたところ、全く動作してくれませんでした・・・


なぜか?

原因は意外(?)なところにありました。
それはアプリのインストール先でした。

どうやらアプリをSDカードなど外部メモリに保存すると動作しないようです。
試しにアプリをスマホ本体に保存したところ正しく動作してくれました。

参考サイト:「team-hiroq」


すべての機種やandroid OSのヴァージョンにおいてそうなのかは確認していませんが、この実装をする場合にはどうやらアプリのインストール先を本体にした方が良さそうですね。


ただSDカードへの保存ってすごくユーザーのニーズが高いんですよね。。。
使い勝手の良さを取るか、SDカードへの保存を取るかは結局のところユーザーに任せるしかないということになりそうです。


ちなみに今回紹介した実装は、『スマートバッテリー』ver3.5でアップデートしました。
参考までに!




スポンサーサイト

PageTop

Serviceとprocess

自分用にちょっとだけメモっておきます。

Serviceを使って常駐アプリを作るときの注意点。


Serviceにはローカルとリモートがある。
ローカルは単一のプロセスで、リモートは複数のプロセスに分離する。


例えば、アクティビティとサービスで構成されたアプリを作るとする。


ローカルサービスだとアクティビティとサービス両方の処理を同じ1つのプロセスで処理する。結果として当然のことながらそのプロセスにかかる負担は重くなってしまう。


それに対してリモートサービスだとアクティビティはアクティビティとしてのプロセス、サービスはサービスとしてのプロセスとして分離して処理する。そのためそれぞれのプロセスにかかる負担は分離されて軽くなる。



リモートでなはく、ローカルサービスとして実装した場合どんなことが起こるか?
「実行中のサービス」一覧でそれが確認できる。
該当するサービスのメモリ容量を見ると、かなり大きくなってしまう。『スマートバッテリー』では10MB前後あった。
さらに悪いことには、サービスを起動し直したり、またアクティビティを起動したりすると、みるみるメモリ容量は膨らんでいく。その数値は20MB以上になることも確認できた。
なおかつ、画面消灯するとサービスが進行していないという不思議な(?)現象も起きるようだ。


以上の問題はリモートサービスとして実装し直すことで解決できた。
やり方としてはマニフェストのサービスタグに「android:process=":remote"」を付けるだけ。もしかしたらまだ詳細なやり方があるかもしれないが現在のところはこれで意図したとおりの動作になったのでよしとしよう。
ちなみにリモートにすると、「実行中のサービス」の「プロセス」名の右端に「:remote」と表示される。


「android:process」属性はサービスだけではなく、ブロードキャストレシーバなど他の基本コンポーネントでも使用できる。

以上、参考までに。


※追記

リモートサービスを使うとプロセスは分離される。サービスのプロセスだけを生かして別のプロセスは不要だという場合はさらに別途処理が必要なようだ。

というのも、例えばアクティビティとサービスとで構成されるアプリの場合、アクティビティのプロセスが無駄にメモリや電池を消費しているからだ。
プロセスの終了は基本的にアンドロイドOSが自動でkillしてくれるらしいのだが、なかなかkillしてくれないので、意図的に実装する必要がある。

やり方はプロセスをkillしたい箇所で「android.os.Process.killProcess(android.os.Process.myPid());」を呼び出すだけだ。


参考サイト:「KamoLand」


PageTop

祝『スマートバッテリー』公開♪ & Timerに泣かされる事件

最新アプリ『スマートバッテリー』を無事公開することができました!

前作『バッテリーサポート』に続いてのスマホ節電アプリとなりますが、今回は主に通信の制御に焦点を絞った節電アプリとなります。非常にシンプルでわかりやすいアプリとなっていますのでぜひダウンロードしてお試しください♪


ここでちょっとした開発裏話。
今回のアプリ開発で一番苦労したことはTimerの扱いについてでした。

通信を定期的に復旧させたり停止させたりする処理にこのTimerを使ったのですが、IllegalStateExceptionが発生してしまい、Timerのタスクがキャンセルされ、アプリが正しく動作してくれなかったのでした。


はじめてお目にかかったこのIllegalStateExceptionなるものの対処法を調べていたら解決法が見つかりました。

参考サイト 『Javaトラブルシューティング』


このサイトの<Q11-4>にその解決法が載っていました。それによると、

① runメソッド内の例外処理対策をする

② schedule()を呼び出す箇所でIllegalStateExceptionをキャッチし、Timerを再生成するようにする

とのことでした。


自分の書いたコードを見てみると①に関してはしっかりやっているので問題なし。そして②をコードに追加してみたところバッチリ上手くいきました。実際のコードは以下のとおりです。






try {

mTimer.schedule(tt, firstTime.getTime(), 1); // ほぼ0秒間隔でタスクを実行する

} catch (IllegalStateException e) {
// TODO: handle exception

mTimer = new Timer(); // Timerを再生成する

mRegularTask.start(mTimespan); // TimerTaskを再スタートする

}




Timerはなにかと便利なのでぜひぜひマスターしておきたいですね♪


※追記

TimerのIllegalStateExceptionについてより正確なことがわかったので補足します。

上記のコーディングで上手く動作はします。ですがLogで確認したところ、IllegalStateExceptionそのものの発生を抑えているわけではないようです。
最初にscheduleメソッドを設定したTimerはやはりキャンセルされてしまいますが、catch部分で再生成したTimerがしっかりスケジュールをこなしてくれて上手くいく! みたいなことのようです。参考までに。


Twitterボタン
Twitterブログパーツ

PageTop

OpenGLでのアルファ・ブレンディングについて

 またもや開発メモ。今回のテーマは「Open GLのアルファ・ブレンディングについて」です。

絶対爆発させんなよ?~爆弾で運試し~』(通常版はこちら!/ソーシャル版はコチラ!)を制作していたときのこと。

このゲームアプリは『OpenGLで作るAndroid SDKゲームプログラミング』を参考にして作りました。


OpenGLで作る Android SDKゲームプログラミングOpenGLで作る Android SDKゲームプログラミング
(2011/04/07)
中島 安彦、横江 宗太 他

商品詳細を見る



 で、いざ画面描画をプログラミングしていたときのこと。この本では画像の背景色を消すには「加算合成」(glBlendFunc(GL_SRC_ALPHA,GL_ONE);)でイケると書いてあるのですがなぜかダメでした(上手くブレンドされず背景色が消えるどころか、背景色が別の色で表示されてしまう)。そこでいろいろなアルファ・ブレンディングの組み合わせを試してみること小一時間(といっても5~6時間くらいやっていた気が・・・w)。ようやく原因がわかったんです。

上記の本で使用されているテクスチャ(ハエたたきゲームのハエの画像)の背景色は黒。で、自分が使用していた画像(爆弾のテクスチャやテキストのテクスチャですね、はい)には背景色がついていなかったんです←おいおいw

つまりは単なる凡ミスだったわけですねw

そこで再度、背景色をつけたテクスチャを作成するのは面倒だったので、なんとか背景色なしのテクスチャをうまくアルファ・ブレンディングして描画できないかと試行錯誤していたわけです。

上記の本以外にも、オライリーから出ている『初めてのOPENGL ES』で調べたりネットで調べたりしてたんですが、上手くいかない・・・。←すっごい焦ってましたよ、当時はw


初めてのOpenGL ES初めてのOpenGL ES
(2011/07/21)
山下 武志

商品詳細を見る


で、ようやく上手くいったアルファ・ブレンディングの組み合わせがこれ↓


glBlendFunc(GL_SRC_ALPHA, GL_MINUS_SRC_ALPHA);


でした。

もう一度言っておきますが、①描画させるテクスチャに背景色をつけていない、②全体の描画領域はglClearColor(0.0f,0.0f,0.0f,1.0f);で塗りつぶしている、③②を行ったうえで全体の背景画像を描画、という手順で処理した場合に上記のアルファ・ブレンディングの組み合わせで上手くいきました。(②については他の色で塗りつぶした場合を試していないので、もしかしたら別の色で描画領域全体を塗りつぶした場合でも上手くいくかもしれません)。


『初めてのOPENGL ES』の著者の方も仰っていますが、アルファ・ブレンディングは「習うより慣れろ」だと思います。いろいろな組み合わせを試してベストな描画を見つけていくことが大事なんだなーと実感したわけですね、はい。


でも、テクスチャを自分で作って、それを自分でプログラミングしてっていう作業は思ったより大変でした。テキストが直接描画できればスッッッッッゴク楽なんですがOpenGLにはそれができない。なのでテキストを表示するのにもいちいち画像を準備しなくちゃいけない。気に入らなかったらまた画像の作り直し・・・ホント泣けてくるよーw


でも収穫の多い経験ができたので結果的に良かった、良かった。


そんな感じでいろいろと苦労した(「そんな大した苦労でもないだろ?」とか言わないでーw)Androidゲームアプリ『絶対に爆発させんなよ?~爆弾で運試し~』は通常版ソーシャル版ともに好評公開中です。よかったら遊んでみてください。



↓ツイッターにてつぶやき中!よろしければフォローお願いします。

Twitterボタン
Twitterブログパーツ

PageTop

Android 画面の明るさ調節機能を実装する

プログラミングに関する覚書のようなものを書いてみたいと思います(最近忘れっぽくなってきた自分のためにもw)。

今回のテーマは「画面の明るさ調節機能を実装する」です。

新作アプリ『Battery Support(バッテリーサポート)』のなかでもこの機能を実装しています(メインではありませんがw)。

実装したのはこんな感じ↓

① SeekBarでお好みの明るさを設定する
  (もちろんSeekBarを動かした時点ですぐにその明るさが画面に反映されるようにする)

② SeekBarで選択した値を「端末画面の明るさ」の値(screen_brightness)として保存する
(アプリ内画面の明るさの値ではないので注意!)

③ アプリを終了して他の画面になっても、設定した明るさが反映されている


まずやってみたのがSeekBarで選択した値を直接端末画面の明るさの値として保存しようと試みた。
一応これで上手くはいく。が重大な問題が発生。。。

それは、SeekBarを動かしてもすぐにその明るさが画面に反映されないということです。
これではユーザーにとってちょっと使い勝手が悪い。というか、悪すぎるw

そこで次に試したのが、SeekBarでは「アプリ内画面の明るさ」の値を変更するようにして、その値を上手く「端末画面の明るさの値」として設定・変更したことでした。

これはバッチリ上手くいきました。ですがちょっと面倒な問題があります。
それは「アプリ内画面の明るさの値」(WindowManager.LayoutParamsのscreenBrightness)の範囲と「端末画面の明るさの値」(Settings.System.getString(getContentResolvor(),"screen_brightness")で取得できる値)の範囲が異なるということです。
もう一つ言うと、画面の明るさをユーザーに対して数値で表示したい場合(『Battery Support』のなかでは表示していませんが)、普通は1%~100%で表示したいと思います。

つまり解決すべき問題は・・・・

「アプリ内画面の明るさの値」の範囲 → 0.0 ~ 1.0

「端末画面の明るさの値」の範囲 → 0 ~ 255

「ユーザーに表示したい明るさの値」の範囲 0 ~ 100


という3つの異なる範囲の値をうまく調節/変換してあげなければいけないということです。

このプログラミングのアプローチはこうです。

① SeekBarで「アプリ内画面の明るさの値」を取得する

② ユーザーに表示するために、取得した値を1~100までの値に変換する

③ さらにその値を「端末画面の明るさの値」の範囲である1~255までの値に変換してあげる
  (これは①で取得した「アプリ内画面の明るさの値」を変換してもOK) 

④ 最後に③の値を"Settings.System.putInt(getContentResolver(),Settings.System.SCREEN_BRIGHTNESS, "③の値");"で保存して変更してあげればOK


余談ですが、「アプリ内画面の明るさの値」にしても「端末画面の明るさの値」にしても、最小値を0もしくは0.0にしてはダメです! 真っ暗になって何も見えなくなってしまい操作できず。。。なんていう面倒なことになってしまうのでw まぁ、当然と言えば当然のことなのですがw

なので、SeekBarでの最小値設定は0ではなく1に設定してあげるようにしましょう。
(ただし、SeekBarに最小値を設定するメソッドが残念ながら無いんですよねw setMax()はあるのにw)


『Android SDK 逆引きハンドブック』の「SELECTION-241 端末画面の明るさを調べる」と「SELECTION-242 アプリケーションの画面の明るさを変更する」が情報として参考になります。チェックしてみてください。


Android SDK逆引きハンドブックAndroid SDK逆引きハンドブック
(2011/04/25)
中西葵、内村祐之 他

商品詳細を見る


↓ よければフォローお願いします

Twitterボタン
Twitterブログパーツ


PageTop
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。