2012年12月9日日曜日

[Wii U] Wii Uが届いたので開封してみた

12月8日(土) ちょうど休日に、任天堂から新しいゲーム機、Wii Uが発売されました。
とりあえず、開封してみました。

Wii U専用段ボールでとどきました。


白色がよかったので、通常版を買いました。

中身は、タンスみたいに2段になっています。


通常版でも、必要最低限ついてるんですね。HDMIケーブルまで。

付属品、並べてみた。
なんで、電源ケーブル2本あるのかと思ったら、1本はGame Pad用だったんですね(笑


さっそく、本体の更新をはじめます。購入元より案内がきてました。
>> この度、お買い上げいただきました、
>> 『Wii U本体』でございますが、
>> 任天堂より、本体の更新に関する重要なお知らせがございました。


うちのインターネットは、テザリングなので3時間くらいかかるのかなぁー
 気長に待ちます

2012年11月13日火曜日

[Android SDK] 設定画面のレイアウトをカスタマイズする

Androidアプリには設定画面がつきものです。標準で設定画面を作るためのクラス(PreferenceActivity)が用意されており、XMLで設定項目を記述するだけで簡単に作れる。

ただ、設定画面のレイアウトをカスタマイズするには特殊なやり方が必要になります。

PreferenceActivityを継承してActivityを作るのは同じですが、setContentViewメソッドでレイアウトファイル(XML)を指定するところがポイント。
  1. public class RpNotePreferenceActivity extends PreferenceActivity {  
  2.   @Override  
  3.   public void onCreate(Bundle savedInstanceState) {  
  4.     super.onCreate(savedInstanceState);  
  5.     setContentView(R.layout.act_preference);  
  6.     addPreferencesFromResource(R.xml.preference);  
  7.   }  
  8. }  

単純にレイアウトファイル(XML)を作成するだけではダメで、設定画面に置き換えるListViewを「android:id="@android:id/list"」属性付きで追加する必要があります。
簡単な例ですと次のようにすると、
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     xmlns:ads="http://schemas.android.com/apk/lib/com.google.ads"  
  4.     xmlns:tools="http://schemas.android.com/tools"  
  5.     android:layout_width="fill_parent"  
  6.     android:layout_height="fill_parent"  
  7.     android:orientation="vertical"  
  8.     tools:context=".activity.RpNotePreferenceActivity" >  
  9.   
  10.     <ListView  
  11.         android:id="@android:id/list"  
  12.         android:layout_width="fill_parent"  
  13.         android:layout_height="fill_parent"  
  14.         android:layout_weight="1" />  
  15.  <LinearLayout  
  16.         android:layout_width="fill_parent"  
  17.         android:layout_height="wrap_content"  
  18.         android:gravity="center_horizontal">  
  19.   <Button  
  20.       android:id="@+id/button1"  
  21.       android:layout_width="fill_parent"  
  22.       android:layout_height="wrap_content"  
  23.       android:text="Button" />  
  24.     </LinearLayout>  
  25. </LinearLayout>  

こんな感じで、画面下側にボタンがあるような設定画面が作れます(実際には、リストが設定項目に置き換わります)。

試してみてください。

2012年11月12日月曜日

[Android SDK] ImageViewを最前面にフローティングさせる

ドラッグ可能なリストビューを作成する過程で、ドラッグ中のアイテムを最前面でフローティングさせるのに苦労しましたので、そのやり方を記載します。
★オレンジ色の浮いているやつです。


実際は、ドラッグ対象のアイテムをBitmap化として、ImageViewで最前面に表示しています。

1.ViewをBitmapに変換する

たとえば、ListViewであれば、getChildAtでアイテムをViewとして取得できます。Bitmapを生成して、Canvasで描画すれば、簡単にViewをBitmapに変換できます。
  1. // View view;  
  2. Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888);  
  3. Canvas canvas = new Canvas();  
  4. canvas.setBitmap(bitmap);  
  5. view.draw(canvas);  
  6. // (e.g.)  
  7. // ImageView imageView;  
  8. // imageView.setImageBitmap(bitmap);  

2.ImageViewを最前面に表示する

最前面に表示するには、ImageViewをWindowManagerに追加します。
WindowManager.addView(View, WindowManager.LayoutParams)メソッドを使います。なお、いらなくなったらWindowManager.removeView(View)で削除できます。
  1. WindowManager mWindowMgr = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);  
  2. mWindowMgr.addView(imageView, layoutParams);  
レイアウトパラメータを指定する必要があり、任意の位置に表示するのであれば次の値がいいと思います。
  1. WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams();  
  2. layoutParams.gravity = Gravity.TOP | Gravity.LEFT;  
  3. layoutParams.x       = 0// 表示位置 x  
  4. layoutParams.y       = 0// 表示位置 y  
  5. layoutParams.width   = WindowManager.LayoutParams.WRAP_CONTENT;  
  6. layoutParams.height  = WindowManager.LayoutParams.WRAP_CONTENT;  
  7. layoutParams.flags   = WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;  
  8. layoutParams.format  = PixelFormat.TRANSLUCENT; // 透明を有効化  

3.ImageViewの透明度指定

ドラッグ中のアイテムを見やすくするために、ImageViewを透過します。
ImageView.setAlpha(int)メソッドを使います。0〜255で透明度を指定します。値が大きいほど不透明になります。
  1. //ImageView imageView;  
  2. imageView.setAlpha(128); // 透明度50%   

ただ、WindowManagerで透明度を有効にするには、必ず次を指定しておく必要があります。
  1. // WindowManager.LayoutParams layoutParams;  
  2. layoutParams.format  = PixelFormat.TRANSLUCENT; // 透明を有効化  

4.ImageViewを移動させるには

WindowManager.updateViewLayout(View, WindowManager.LayoutParams)メソッドでレイアウトを更新します。
WindowManager.addView(View, WindowManager.LayoutParams)メソッド時のWindowManager.LayoutParamsを保持しておき、x,y座標を変更して使いますと楽です。
  1. // WindowManager mWindowMgr;  
  2. // WindowManager.LayoutParams layoutParams;  
  3. // ImageView imageView;  
  4. layoutParams.x       = 0// 表示位置 x  
  5. layoutParams.y       = 0// 表示位置 y  
  6. mWindowMgr.updateViewLayout(imageView, layoutParams);  

こんな感じに、最前面でImageViewを自由に移動させらました。
ご参考にしてみてください。


2012年11月10日土曜日

[Android SDK] 埋め込みテキストファイルから文字列を取り出す

アプリ内に埋め込んだテキストファイルを文字列として取り出す方法を記載します。

ファイル構成

翻訳版も対応しているので、rawフォルダ名を変えて複数作成してください。
  1.  +res  
  2.   +raw  
  3.    +update.txt (英語テキストファイル)  
  4.   +raw-ja  
  5.    +update.txt (日本語テキストファイル)  

読み出しソース

ResourceクラスのopenRawResourceメソッドを使って読み出しをします。
  1. // Context c;  
  2. String text = getRawTextFile(c, R.raw.update.txt);  
  3.   
  4. private static String getRawTextFile(Context context, int resId) {  
  5.   InputStream st = null;  
  6.   byte[] buffer = null;  
  7.   try {  
  8.     st = context.getResources().openRawResource(resId);  
  9.       buffer = new byte[st.available()];  
  10.     while((st.read(buffer)) != -1) {}  
  11.   } catch (IOException e) {  
  12.   } finally{  
  13.     if (st != null) {  
  14.       try{  
  15.         st.close();  
  16.       }catch(IOException e2) {}  
  17.     }  
  18.   }  
  19.   if (buffer != null) {  
  20.     return new String(buffer);  
  21.   }  
  22.   return null;  
  23. }  

こんな感じで、アプリの更新履歴をテキストファイルとしてアプリ内に埋め込んで使っています。

2012年11月9日金曜日

[Android SDK] ResourceからカラーフィルタしたBitmapを作成する

Resourceにある画像をカラーフィルタ処理をした、Bitmapを作成する方法を書きます。

ソース

  1. // RemoteViews rv;  
  2. // int resId;  
  3. // Context context;  
  4. Bitmap icon = BitmapFactory.decodeResource(context.getResources(), resId);  
  5. Bitmap bitmap = Bitmap.createBitmap(icon.getWidth(), icon.getHeight(), icon.getConfig());  
  6. LightingColorFilter filter1 = new LightingColorFilter(0xFFFFFF, Color.WHITE);  
  7. Canvas canvas = new Canvas(bitmap);  
  8. Paint p = new Paint();  
  9. p.setColorFilter(filter1);  
  10. canvas.drawBitmap(icon, 00, p);  
  11. // rv.setImageViewBitmap(R.id.icon, bitmap);  

解説

ウィジェット作成していて、画像を貼り付けるにはResourceIDかBitmapしか方法がなくて、DrawableだったらsetColorFilterを使えば簡単にできたんだけど。仕方ないので、バッファBimapにカラーフィルタ処理付きで画像(Bitmap)を描画して作成しました。

結果

こんなアイコンをウィジェットに白色加工して貼り付けました。





色違いアイコンを作り直さなくていいから楽ちん。



[Android アプリ] メモガキ (Memogaki)の公開

自作のAndroidアプリ「メモガキ (Memogaki)」を公開しました。

ダウンロード (Google Play)

簡単に言えば、TODOリストのような、メモアプリです。
メモのカテゴリ分けができるので、買い物リスト、予定、メモといった風に同じアプリで使い回しができます。

アプリの画面

実際の画面をペタペタと、、、

メモ閲覧画面

メモが一覧で表示されます。左側のタブでカテゴリを切り替えられます。


カレンダー表示

メモを予定して使う場合は、メモに日時をつけることでカレンダーで表示できます

メモ作成画面(簡易)

メモ程度なら、サクサクつくれるような画面にしてあります。
買い物メモで画面が切り替わってしまうと、入力するのが大変ですからね。

作成のきっかけ

アプリの開発のきっかけは、忘れ物防止、手軽に入力できるアプリがほしかった。
Google Playで探してみましたが、見つからなかったので開発してみました。

TODOリストようなですから、リマインダー機能(お知らせ機能)があります。
直前にアラームが鳴って、簡単な概要さえ分かれば思い出せますからね。

僕は、予定表、買い物リスト、アプリの不具合修正リスト、バスの時刻表メモ(写真)として使っています。いろいろな使い方を模索しつつ、今後改良していきます。


以上の説明で分かりづらい箇所もあるかと思いますが、ぜひ活用してみてください。

ダウンロード (Google Play)

更新履歴

ver.0.7.0(2013/7/25)

メモのリマインダー機能を繰り返し通知できるよう機能を追加しました。
例えば、毎週行う作業(TODO)に利用すると、毎週メモを再設定しなくとも、毎週通知してくれます。
メモの作成時の日時設定から設定できます。

ver.0.6.0(2013/2/2)

ウィジェットにカレンダーを追加しました。カレンダーからいつ予定が入っているのか確認できます。

ver.0.5.0(2012/12/26)

メモ一覧表示を改善しました。メモ一覧を「今日、明日、今週、今週以降、日時なし」の5つに区切って表示するよう改善しました。

ver.0.4.0(2012/11/20)

ウィジェット作成時にプレビュー機能がつきました。

ver.0.3.0 (2012/11/17)

他アプリから共有機能で、既存ノートの本文に内容を追記できるようになりました。

ver.0.2.0 (2012/11/12)

メニューから、カテゴリの並び替えが可能になりました。長押しのドラッグで簡単に並び替えられます。

ver.0.1.1 (2012/11/8)

今日の予定数を表示するウィジェット機能がつきました。すべてもしくはカテゴリー限定で表示できます。

ver.0.0.0 (2012/11/7)

初公開

2012年9月1日土曜日

[Xperia SX] 交換用バッテリーと専用充電器を買ってみました

スマホってあまりバッテリーが持たないので、補助バッテリーを購入しました。

「モバイルチャージャー」「交換用バッテリー」で迷いましたが、交換用バッテリーだと入れ替えたらすぐ使えるから便利。あと持ち運び軽いってところかな。

Xperia SX専用の交換用バッテリーと専用充電器を購入しました。

・交換用バッテリー:BA700 (Xperia rayと型番が同じみたい)

ヤフオクに新品が安く出てたので、2つ合わせて3,500円と得しちゃった。
(バッテリーは発火事故とか怖いので、両方ともソニー純正品です)

専用充電器をちょこっと紹介。


スライド式になっています。

完全に中のトレーが外れます。

バッテリーを入れてみた。

USBケーブルをつないで充電している。側面が赤色に光る。


2012年8月28日火曜日

[Xperia SX] USB接続でMacからストレージの中を見る

MacからXperia SXの内蔵ストレージSDカードの中身を見る方法を見つけました。Android 3.0以降からでしょうか?ストレージが、本体メモリ、内蔵ストレージ、SDカードって3つに増えてますね。前の記事で紹介した「Mac OSからUSBケーブルでMicro SD中のデータを見る」と比べて、内蔵ストレージもデータ操作できます。

Android公式のAndroid File Trasfer.appを使います。

1.Xperia SXの通信モードをメディア転送モード(MTP)に変更する必要があります。
初期値は、メディア転送モード(MTP)になっていますが、変更している方は「Mac OSからUSBケーブルでMicro SD中のデータを見る」を参考に変更してください。

2.Macにファイル転送アプリをインストールをダウンロードします。
 [ダウンロード] http://www.android.com/filetransfer/

 真ん中の[Download Now >>]からダウンロードできます。

3.ダウンロードし終わったらダブルクリックで.dmgファイルを起動します。すると、次のような画面が表示されますので、[Android File Trasfer.app]をドラッグで[Applications]にコピーします。
4.コピーした[Android File Trasfer.app]を起動します。

5.USBケーブルでMacとAndroidをつなぎます。

6.Finderみたいな画面が表示されますので、ファイルをドラッグ&ドロップでコピーできます。


2012年8月22日水曜日

[Android SDK] 全画面カスタムダイアログの作成

通常のダイアログは画面中央にちょこんと小窓が表示されますが、Activityのように全画面表示に変更することができます。

以下の手順で、ダイアログをカスタマイズします。
(ダイアログを継承して全画面表示にする際には、setContentViewでレイアウトを設定してから設定変更します)

1.ダイアログの大きさが全画面にする
//Dialog dialog;
dialog.getWindow().setLayout(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);


2.ダイアログの境界線を非表示にする

//Dialog dialog;
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));


3.タイトルバーを非常にする
//Dialog dialog;
requestWindowFeature(Window.FEATURE_NO_TITLE);



以上で全画面表示されるはずです。



[Xperia SX] テザリングのON/OFFを簡単にする

Xperia SXに機種変してからテザリングを活用しはじめましたが、設定画面からON/OFFを切り替えるのが手間でした。便利なアプリを見つけましたので紹介します。

テザリングを始めたきっかけは、Xi(クロッシィ)からテザリングを使用してもパケット定額で5,985円(*1)なのがありがたい。また、自宅の光インターネット(4,500円/月)をあまり使わないので、テザリングにまとめても通信速度制限(*2)がかかる通信量7GBには達しないので通信費を押さえられる。結果、FOMA比べるとパケット定額が500円ほど増えますが、それでもインターネット費用が浮くので大助かり。自宅のインターネットをやめないとしても、外出先でパソコンを使ってインターネットができるの便利です。
(*1) 2012年9月まではパケット定額1050円引きで4,935円
(*2) 2012年10月より通信量が7GB/月を超えると128Kbpsの通信速度の制限が始まる

Widgetsoid2.x (Google Play)になります。
ホーム画面にウィジェットを配置して、タップで簡単に設定をON/OFFを切り替えられます(テザリング以外にも、Wi-fiやBluetooth等も可能)。

簡単にホーム画面に設置するまで手順を記載します。
1.Widgetsoid2.x (Google Play)をインストールしましたら、ホーム画面をタップ長押しでメニューを表示させ、[ウィジェット]を選択します。

2.ウィジェット一覧から、[Widgetsoid Switcher(1*1)]を選択します。

3.下のツールバーから[Network]をタップして、真ん中の一覧から[ポータブルアクセスポイントトグル]にチェックを入れ、右下の[Apply]ボタンをタップします。

4.ホーム画面にウィジェットが配置されますので、タップしてON/OFF切り替えができるようになります。

(追伸) ZDbox (Google Play)を使うと通信使用量が、通知バーからすぐに見えます。

ほかにも、システム情報を見たり、管理ツールとしても使えます。


2012年8月12日日曜日

[Xperia SX] スクリーンショットを撮る

Android 4.0から標準でスクリーンショットに対応したようだ。

 [電源][音量下げる]のボタンを2秒以上押すと撮れます。

 ※カメラ同様、マナーにしててもシャッター音が出ます!

ブラウザやアプリ画面等、メモするのに便利ですね。

[Xperia SX] Mac OSからUSBケーブルでMicro SD中のデータを見る

今月、Xperia SXが発売されて、さっそく購入しました。
困ったことがあったのでメモします。

MacとXperiaをUSBケーブルでつないでも、Xperiaの中のMicro SDが認識されません。
どうやら、転送モードの設定がメディア転送モード(MTP)になってて、Micro SDをディスクとして認識させない設定になってました。

メディア転送モードって、Windows向けのMedia GO用のモードなんでしょうか?
とりあず、ファイル転送モードに変えたら、Micro SDがディスクとして認識されました。

以下、設定変更手順。
1.設定画面を開いて、[Xperia]を選択する。

2.[接続設定]を選択する。

 3.USB接続モードを選択する。
 ※USBケーブルは外さないと選べないよ。

4.[ファイル転送モード(MSC)]を選択する。

5.注意書きが表示されますが、[OK]を選択する。

 おわり。








2012年7月16日月曜日

[PixelMater] 強制終了後に起動しなくなったときの回避方法


App Storeで高機能な画像編集ソフトPixelMatorを使っていたときに起きた現象の回避方法をメモします。


■現象
PixelMatorを起動したときに、前回のウィンドウを復元しますかというメッセージが表示され、どちらを選んでも数秒後に「予期しない終了」となり終了してしまう。


■調査
PixelMatorを再インストールしてみたが改善されなかった。となると変なデータが別ディレクトリに残っている可能性があるため、別ユーザでログインしてみたところ正常に起動した。

fs_usageコマンドを利用して、PixelMatorがアクセスするユーザファイルをチェックしてみた。どうやら↓のディレクトリにアクセスしている。
/Users/(ユーザ名)/Library/Containers/com.pixelmatorteam.pixelmator/

該当のディレクトリに別ディレクトリに移動させて起動したところ正常に起動した。


■回避策
PixelMatorが起動しなくなったら、↓のディレクトリを別ディレクトリに移動させてみてください。
/Users/(ユーザ名)/Library/Containers/com.pixelmatorteam.pixelmator/
 
おわり。

2012年3月4日日曜日

[Android SDK] 描画の基礎

Androidの描画の基礎として、Canvas、Paintクラスの使い方をまとめました。

2012年3月2日金曜日

[Android SDK] 加速度センサで傾きを測定する

Android携帯には様々なセンサが搭載されています。
機種によってまちまちですが、その中でも加速度センサを利用して、Android携帯の傾きを測定してみます。

まずは、SensorManagerという、センサ関連を統括して管理しているサービスを取得します。
  1. SensorManager manager = (SensorManager)getSystemService(SENSOR_SERVICE);  

続いて、センサの状態が変化したときに呼ばれるSensorEventListenerというリスナーを作成します。
サブクラスに実装するか、実装してインスタンスを作成してください。
  1. SensorEventListener lis = new SensorEventListener() {  
  2.     // センサの精度が変化したときに呼ばれる  
  3.     public void onAccuracyChanged(Sensor sensor, int accuracy) {}  
  4.     // センサの値が変化したときに呼ばれる  
  5.     public void onSensorChanged(SensorEvent event) {}  
  6. };  

試しに、Activityの中に加速度センサで取得した値を表示するサンプルを作成してみました。
  1. /* フィールド変数 */  
  2. SensorManager mSensorManager;  
  3.   
  4. /* 初期化処理メソッド */ {  
  5.  // センサーマネージャを取得  
  6.  mSensorManager = (SensorManager) c.getSystemService(Context.SENSOR_SERVICE);  
  7.  List<sensor> sensors = mSensorManager.getSensorList(Sensor.TYPE_ACCELEROMETER);  
  8.  if (sensors != null && sensors.size() > 0) {  
  9.   Sensor s = sensors.get(0);  
  10.   mSensorManager.registerListener(mSensorListener, s, SensorManager.SENSOR_DELAY_UI);  
  11.  }  
  12. }  
  13. /* 終了処理メソッド */ {  
  14.  // センサーマネージャを破棄  
  15.  mSensorManager.unregisterListener(mSensorListener);  
  16.  mSensorManager = null;  
  17. }  
  18. SensorEventListener mSensorListener = new SensorEventListener() {  
  19.  public void onAccuracyChanged(Sensor sensor, int accuracy) {  
  20.   Log.d(TAG, sensor.getName()+":"+accuracy);  
  21.  }  
  22.  public void onSensorChanged(SensorEvent event) {  
  23.   if (event.values.length == 3) {  
  24.    Log.d(TAG, event.sensor.getName()+" ("+event.values[0]+","+event.values[1]+","+event.values[2]+")");  
  25.   }  
  26.  }  
  27. }  
  28. </sensor>  

解説すると、まずは加速度センサのオブジェクトを取得するために、引数にSensor.TYPE_ACCELEROMETERを指定します。
  1. List<sensor> sensors = mSensorManager.getSensorList(Sensor.TYPE_ACCELEROMETER);  
  2. </sensor>  

Android携帯によっては同一センサが複数搭載しているケースがあるため、Listオブジェクトが返り値となっている。
とりあえず、加速度センサが複数ついていないハズなので、要素0番目を取得してリスナーに登録する。
  1. if (sensors != null && sensors.size() > 0) {  
  2.  Sensor s = sensors.get(0);  
  3.  mSensorManager.registerListener(mSensorListener, s, SensorManager.SENSOR_DELAY_UI);  
  4. }  
ここでの3番目の引数は、センサー状態を通知する際の遅延時間です。
加速度センサの使用用途に合わせて、早すぎず遅すぎず適切なものを選ぶと良い。
定数の名前からも分かるように用途が分かりますね。
  1. SensorManager.SENSOR_DELAY_FASTEST:0ms  
  2. SensorManager.SENSOR_DELAY_GAME:20ms  
  3. SensorManager.SENSOR_DELAY_UI:60ms  
  4. SensorManager.SENSOR_DELAY_NORMAL:200ms  

肝心なSensorEventの中身ですが、重要なのはvaluesの値です。
加速度センサの場合はAndroid携帯を正面に持った状態で
values[0] : X軸 左右(左+、右-)
values[1] : Y軸 上下(下+、上-)
values[2] : Z軸 前後(後ろ側+、手前-)

という風な加速度センサの値が入っている。

常に重力分(9.8m/s'2=約10.0)が働いているため、静止状態でベクトルの大きさを計算すると10.0となる。
要するに、平らな机の置くと、後ろ側方向にのみ重力がかかるので、
・values[0]:0.0
・values[1]:0.0
・values[2]:10.0
となる。

試しにやってみるのが一番です。

最後にActivity破棄されるときにはリスナーも登録破棄してくださいね。
  1. mSensorManager.unregisterListener(mSensorListener);  






2012年3月1日木曜日

[Android SDK] SurfaceViewを使った高速描画

SurfaceViewは、描画用のスレッドがアプリケーションのスレッドと独立しているため、ゲームなど定期的な描画が要求される場合に向いている。
なお、SurfaceViewはAPI Level1から利用できる。

試しに、適当なサンプルを作成してみる。
1.Activityは最初に生成されるものから変更なし
  1. package com.runpeta.android.angle;  
  2.   
  3. import android.app.Activity;  
  4. import android.os.Bundle;  
  5.   
  6. public class RpAngleActivity extends Activity {  
  7.  // アクティビティ作成時に最初に呼ばれる  
  8.     @Override  
  9.     public void onCreate(Bundle savedInstanceState) {  
  10.         super.onCreate(savedInstanceState);  
  11.         setContentView(R.layout.main);  
  12.     }  
  13. }  

2.SurfaceViewのサブクラスを作り、線だけ描画する
  1. package com.runpeta.android.angle;  
  2.   
  3. import android.content.Context;  
  4. import android.graphics.Canvas;  
  5. import android.graphics.Color;  
  6. import android.graphics.Paint;  
  7. import android.util.AttributeSet;  
  8. import android.view.SurfaceHolder;  
  9. import android.view.SurfaceView;  
  10.   
  11. public class RpAngleSurfaceView extends SurfaceView implements SurfaceHolder.Callback {  
  12.  public RpAngleSurfaceView(Context context) {  
  13.   super(context);  
  14.   getHolder().addCallback(this);  
  15.  }  
  16.  public RpAngleSurfaceView(Context context, AttributeSet attrs) {  
  17.   super(context, attrs);  
  18.   getHolder().addCallback(this);  
  19.  }  
  20.  public RpAngleSurfaceView(Context context, AttributeSet attrs, int defStyle) {  
  21.   super(context, attrs, defStyle);  
  22.   getHolder().addCallback(this);  
  23.  }  
  24.  public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {  
  25.     
  26.  }  
  27.  public void surfaceCreated(SurfaceHolder holder) {  
  28.   doDraw();  
  29.  }  
  30.  public void surfaceDestroyed(SurfaceHolder holder) {  
  31.     
  32.  }  
  33.  private void doDraw() {  
  34.      // キャンバスをロックする  
  35.      Canvas c = getHolder().lockCanvas();  
  36.      c.save();  
  37.        
  38.      // ここにCanvasに描画処理を書く  
  39.      Paint p = new Paint();  
  40.      p.setColor(Color.BLACK);  
  41.      c.drawColor(Color.WHITE);  
  42.      c.drawLines(new float[]{20,20,60,60}, p);  
  43.        
  44.      // キャンバスのロックを解除する  
  45.      c.restore();  
  46.      getHolder().unlockCanvasAndPost(c);  
  47.     }  
  48. }  

3.メインレイアウトに作成したSurfaceViewを追加します。
・id:surface (とりあえず)
・width:fill_parent
・height:fill_parent

これで線なるものが描画されているハズだ。


これは非常に分かりづらいサンプルになってしまった。

ゲームのように定期的に再描画を行ってみる。

さきほどの"onDraw"をタイマーで定期的に呼び出すために、"ScheduledExecutorService"を利用します。
こんな感じにしようできますので、(定期処理内容)で"onDraw"を呼びます。
  1. // タイマーを開始する  
  2. ScheduledExecutorService schedule;  
  3. schedule = Executors.newSingleThreadScheduledExecutor();  
  4. schedule.scheduleAtFixedRate(new Runnable(){  
  5.     public void run() {  
  6.         //定期処理内容  
  7.   
  8.     }  
  9. }, 0100, TimeUnit.MILLISECONDS);  
  10.   
  11. // タイマーを終了する  
  12. schedule.shutdown();  

さきほどの線がアニメーションで伸び縮みするようにしてみます。
  1. package com.runpeta.android.angle;  
  2.   
  3. import java.util.concurrent.Executors;  
  4. import java.util.concurrent.ScheduledExecutorService;  
  5. import java.util.concurrent.TimeUnit;  
  6.   
  7. import android.content.Context;  
  8. import android.graphics.Canvas;  
  9. import android.graphics.Color;  
  10. import android.graphics.Paint;  
  11. import android.util.AttributeSet;  
  12. import android.view.SurfaceHolder;  
  13. import android.view.SurfaceView;  
  14.   
  15. public class RpAngleSurfaceView extends SurfaceView implements SurfaceHolder.Callback {  
  16.  private ScheduledExecutorService mSchedule;  
  17.  private Runnable repeatDraw = new Runnable() {  
  18.   public void run() {  
  19.    size += 5;  
  20.    if (size > 400) {  
  21.     size = 100;  
  22.    }  
  23.    doDraw();  
  24.   }  
  25.  };  
  26.  private int size = 100;  
  27.  public RpAngleSurfaceView(Context context) {  
  28.   super(context);  
  29.   getHolder().addCallback(this);  
  30.  }  
  31.  public RpAngleSurfaceView(Context context, AttributeSet attrs) {  
  32.   super(context, attrs);  
  33.   getHolder().addCallback(this);  
  34.  }  
  35.  public RpAngleSurfaceView(Context context, AttributeSet attrs, int defStyle) {  
  36.   super(context, attrs, defStyle);  
  37.   getHolder().addCallback(this);  
  38.  }  
  39.  public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {  
  40.     
  41.  }  
  42.  public void surfaceCreated(SurfaceHolder holder) {  
  43.   doDraw();  
  44.   mSchedule = Executors.newSingleThreadScheduledExecutor();  
  45.   mSchedule.scheduleAtFixedRate(repeatDraw, 0100, TimeUnit.MILLISECONDS);  
  46.  }  
  47.  public void surfaceDestroyed(SurfaceHolder holder) {  
  48.   mSchedule.shutdown();  
  49.   mSchedule = null;  
  50.  }  
  51.  private void doDraw() {  
  52.      // キャンバスをロックする  
  53.      Canvas c = getHolder().lockCanvas();  
  54.      c.save();  
  55.        
  56.      // ここにCanvasに描画処理を書く  
  57.      Paint p = new Paint();  
  58.      p.setColor(Color.BLACK);  
  59.      c.drawColor(Color.WHITE);  
  60.      c.drawLines(new float[]{20,20,size,size}, p);  
  61.        
  62.      // キャンバスのロックを解除する  
  63.      c.restore();  
  64.      getHolder().unlockCanvasAndPost(c);  
  65.     }  
  66. }  

こんな感じで描画ができることが分かったので、後はCanvasとPaintの使い方次第でいろいろ描画できます。




2012年2月26日日曜日

[Android SDK] ステータスバーに通知する

ステータスバーを使いユーザに通知する機能があります。実物を見てもらった方が分かりやすいのです。
①ステータスバーに表示する
②ステータスバーに通知が蓄積される

これは、標準で用意されているNotificationManagerで簡単に、任意のメッセージやアイコンを持った通知を発行できます。
まずは、通知内容をNotificationに設定します。
  1. // Context context;  
  2. // String message, item_title, item_message;  
  3. Notification n = new Notification();  
  4. n.icon = R.drawable.ic_launcher;// アイコン(drawable指定)ここではアプリのアイコン  
  5. n.tickerText = message;// ステータスバーに表示する文字列(CharSequence指定)  
  6. n.when = System.currentTimeMillis();  
  7. // 通知をタップしたときに発行するインテント  
  8. Intent i = new Intent(context, RpNotifyActivity.class);  
  9. n.setLatestEventInfo(context, item_title, item_message, PendingIntent.getActivity(context, 0, i, 0));  
あとは、NotificationManagerに渡すとステータスバーに表示されます。
  1. NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);  
  2. manager.notify(1,n);  

2012年2月25日土曜日

[Android SDK] Android起動時にサービス等を起動する

Android起動時には"ACTION_REBOOT"インテントが発行されますので、BroadcastReceiverで受け取ることで任意の処理を実行できます。
1.BroadcastReceiverの準備
2.Intent Filterの登録
3.Permissionの登録

1.BroadcastReceiverの準備
参考に下記ように作成します。
  1. package com.runpeta.android.notify;  
  2.   
  3. import android.content.BroadcastReceiver;  
  4. import android.content.Context;  
  5. import android.content.Intent;  
  6. import android.util.Log;  
  7.   
  8. public class RpNotifyReceiver extends BroadcastReceiver {  
  9.  private static final String TAG = "RpNotifyReceiver";  
  10.   
  11.  @Override  
  12.  public void onReceive(Context context, Intent intent) {  
  13.   Log.d(TAG, "onReceive");  
  14.   String action = intent.getAction();  
  15.   if (action != null) {  
  16.    if (action.equals(Intent.ACTION_BOOT_COMPLETED)) {  
  17.     // システム起動完了時  
  18.     Log.d(TAG, "ACTION_BOOT_COMPLETED");  
  19.     context.startService(new Intent(context, RpNotifyService.class));  
  20.    }  
  21.   }  
  22.  }  
  23. }  
2.Intent Filterの登録
AndroidManifest.xmlを開き、BroadcastReceiverのIntent Filterに"ACTION_REBOOT"を登録します。

3.Permissionの登録
AndroidManifest.xmlを開き、Permissionに"RECEIVE_BOOT_COMPLETED"を登録します。

以上で、Android起動時にBroadcastReceiverのonReceiveが呼ばれるようになります。

[Android SDK] 画面ON/OFFを検知する

画面の電源ON/OFF時にはインテントが発行されますので、BroadcastReceiverを利用して受け取るようにします。 まずは、受け取るためにBroadcastReceiverを作成します。作成したActivityもしくはService内に作成すると良い。
  1. // ブロードキャストリスナー  
  2. BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {  
  3.  @Override  
  4.  public void onReceive(Context context, Intent intent) {  
  5.   String action = intent.getAction();  
  6.   if (action != null) {  
  7.    if (action.equals(Intent.ACTION_SCREEN_ON)) {  
  8.     // 画面ON時  
  9.     Log.d(TAG, "SCREEN_ON");  
  10.    } else if (action.equals(Intent.ACTION_SCREEN_OFF)) {  
  11.     // 画面OFF時  
  12.     Log.d(TAG, "SCREEN_OFF");  
  13.    }  
  14.   }  
  15.  }  
  16. };  
作成したBroadcastReceiverでインテントを受け取るには、IntentFilterを使い対象を登録する必要があります。 画面の電源ON/OFFでは次の二つを登録すると良い。
  1. // リスナーの登録  
  2. Context c;  
  3. c.registerReceiver(broadcastReceiver, new IntentFilter(Intent.ACTION_SCREEN_ON));  
  4. c.registerReceiver(broadcastReceiver, new IntentFilter(Intent.ACTION_SCREEN_OFF));  
また、受信するActivityまたはServiceのIntentFilterにも追加する。

なお、不要になったときは登録を削除します。
  1. // リスナーの登録削除  
  2. Context c;  
  3. c.unregisterReceiver(broadcastReceiver);  

[Android SDK] 電話の着信を監視する

TelephonyManagerを利用すると、電話の着信/通話中/待機時を検知することができる。
まずはシステムサービスからTelephonyManagerを取得し、listenでリスナーを登録する。
※Permissonに"android.permission.READ_PHONE_STATE"の登録が必要。
  1. // 電話状態監視リスナー  
  2. PhoneStateListener mListener = new PhoneStateListener() {   
  3.  public void onCallStateChanged(int state, String number) {  
  4.   switch(state) {  
  5.   case TelephonyManager.CALL_STATE_RINGING:// 着信時  
  6.    Log.d(TAG, "PhoneState: CALL_STATE_RINGING");  
  7.    break;  
  8.   case TelephonyManager.CALL_STATE_OFFHOOK:// 通話時  
  9.    Log.d(TAG, "PhoneState: CALL_STATE_OFFHOOK");  
  10.    break;  
  11.   case TelephonyManager.CALL_STATE_IDLE:// 待機時(リスナー登録時も呼ばれるようだ)  
  12.    Log.d(TAG, "PhoneState: CALL_STATE_IDLE");  
  13.    break;  
  14.   }  
  15.  }  
  16. };  
  17. TelephonyManager m = (TelephonyManager) this.getSystemService(Context.TELEPHONY_SERVICE);  
  18. m.listen(mListener, PhoneStateListener.LISTEN_CALL_STATE);  
不在着信の検知は、前回の電話状態を記録することで可能です。
・通話終了=CALL_STATE_RINGING -> CALL_STATE_OFFHOOK -> CALL_STATE_IDLE
・不在着信=CALL_STATE_RINGING -> CALL_STATE_IDLE

2012年2月24日金曜日

[マルチタイマー ver.1.1.1] 初Androidアプリを公開

Androidアプリの開発を始め2ヶ月ほどでやっと、簡単ですがタイマーアプリが完成しましたので、Android Marketで公開しました。試しに使ってみてください。

【対応言語】英語、日本語
【動作確認】MEDIAS N-04C、Xperia SX

ストップウォッチ、キッチンタイマーの2つのタイマーが使えます。
タイマーの切替はタブでき同時に使えます。

■ストップウォッチ
ラップ機能付きのストップウォッチです。


■キッチンタイマー
アラーム通知は、他アプリ操作中でも、画面ロック中でも通知されます。


■設定変更
 ・タイマー使用時のバックライトを常時点灯できます。
 ・キッチンタイマーのアラーム音、アラーム時間など変更できます。
  など




2012年1月28日土曜日

Androidアプリ開発の参考記事まとめ



今話題のスマートホン、Androidの方ですがアプリの開発を始めてみました。iPhoneのアプリと違って、公開以外は無料でできるのが初心者にやさしい。あと、Webサイトに開発に役立つ記事がたくさん有志によって公開されているところも助かります。

簡単なアプリから開発を始めてみます。その中で、逆引き的に役だった記事をまとめていきます。