goo blog サービス終了のお知らせ 

gooブログはじめました!

写真付きで日記や趣味を書くならgooブログ

android amコマンド

2011-05-04 14:40:37 | android
・adb shellでのamコマンドを実行する

adb shell amコマンドが定義されているandrod のkernel src
/base/cmds/am/src/com/android/commands/am/Am.java

・amコマンドでしていできる値は
base/core/java/android/contetns/Intent.javaで
「@SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)」のコメントがあるのが
よべると思ったが、よべないものもあるらしい。呼べるか、呼べないのかはどこで判断しているかわからず。
/system/bin/am start -a android.intent.action.SENDTOはできなかった。


・amコマンドで着信音設定のintentを起動する
$ /system/bin/am start -a android.intent.action.RINGTONE_PICKER
/system/bin/am start -a android.intent.action.RINGTONE_PICKER
Starting: Intent { act=android.intent.action.RINGTONE_PICKER }


RingTone関連のintent名は以下のように定義されている。
/base/base/media/java/android/media/RingtoneManager.java

public static final String ACTION_RINGTONE_PICKER = "android.intent.action.RINGTONE_PICKER";


@SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)


・amコマンドでMain actionのintentを起動する
$ /system/bin/am start -a android.intent.action.MAIN
/system/bin/am start -a android.intent.action.MAIN
Starting: Intent { act=android.intent.action.MAIN }


・amコマンドでEdit actionのintentを選択して起動する
$ /system/bin/am start -a android.intent.action.EDIT
/system/bin/am start -a android.intent.action.EDIT
Starting: Intent { act=android.intent.action.EDIT }

・amコマンドでPick actionのintentを選択して起動する
$ /system/bin/am start -a android.intent.action.PICK
/system/bin/am start -a android.intent.action.PICK
Starting: Intent { act=android.intent.action.PICK }


・amコマンドSearch actionのintentを選択して起動
$ /system/bin/am start -a android.intent.action.SEARCH
/system/bin/am start -a android.intent.action.SEARCH
Starting: Intent { act=android.intent.action.SEARCH }


・amコマンドでweb seach用のintentを選択して起動
$ /system/bin/am start -a android.intent.action.SEARCH
/system/bin/am start -a android.intent.action.SEARCH
Starting: Intent { act=android.intent.action.SEARCH }


・amコマンドでCall Button用(電話をかける)intentを起動
$ /system/bin/am start -a android.intent.action.CALL_BUTTON
/system/bin/am start -a android.intent.action.CALL_BUTTON
Starting: Intent { act=android.intent.action.CALL_BUTTON }

・amコマンドでPower 関連のintentを起動( 電池使用時間、bluetooth,wi-fi,アイドル状態の取得)
$ /system/bin/am start -a android.intent.action.POWER_USAGE_SUMMARY
/system/bin/am start -a android.intent.action.POWER_USAGE_SUMMARY
Starting: Intent { act=android.intent.action.POWER_USAGE_SUMMARY }

#adb shell
adb>


以下がamのusage オプションと使い方

usage: am [subcommand] [options]

start an Activity: am start [-D] [-W] <INTENT>
-D: enable debugging
-W: wait for launch to complete

start a Service: am startservice <INTENT>

send a broadcast Intent: am broadcast <INTENT>

start an Instrumentation: am instrument [flags] <COMPONENT>
-r: print raw results (otherwise decode REPORT_KEY_STREAMRESULT)
-e <NAME> <VALUE>: set argument <NAME> to <VALUE>
-p <FILE>: write profiling data to <FILE>
-w: wait for instrumentation to finish before returning

start profiling: am profile <PROCESS> start <FILE>
stop profiling: am profile <PROCESS> stop

<INTENT> specifications include these flags:
[-a <ACTION>] [-d <DATA_URI>] [-t <MIME_TYPE>]
[-c <CATEGORY> [-c <CATEGORY>] ...]
[-e|--es <EXTRA_KEY> <EXTRA_STRING_VALUE> ...]
[--esn <EXTRA_KEY> ...]
[--ez <EXTRA_KEY> <EXTRA_BOOLEAN_VALUE> ...]
[-e|--ei <EXTRA_KEY> <EXTRA_INT_VALUE> ...]
[-n <COMPONENT>] [-f <FLAGS>]
[--grant-read-uri-permission] [--grant-write-uri-permission]
[--debug-log-resolution]
[--activity-brought-to-front] [--activity-clear-top]
[--activity-clear-when-task-reset] [--activity-exclude-from-recents]
[--activity-launched-from-history] [--activity-multiple-task]
[--activity-no-animation] [--activity-no-history]
[--activity-no-user-action] [--activity-previous-is-top]
[--activity-reorder-to-front] [--activity-reset-task-if-needed]
[--activity-single-top]
[--receiver-registered-only] [--receiver-replace-pending]
[<URI>]


androidのソースを読む (TortoiseGitを使用)

2011-04-04 02:29:26 | android

androidのソースを読む (ソースを参照にするだけでビルドはしない)

1.TortoiseGitをインストール(Windows)
2.baseいう名前のディレクトリを作成
3.baseフォルダで右クリック - [Git複製(clone)]を選択し、urlに[git://android.git.kernel.org/platform/base.git]と入力してOKボタンを押す。

git://android.git.kernel.org/platform/base.gitのdescriptionには「Android framework classes and services」と記述されているので基本的な事を知りたい、ソースの内容を確認したい場合これをみればいいと思う。

urlに入力するのは[http://android.git.kernel.org/]のサイトを参考にして、自分が参考に
したいカテゴリから*.gitを選択する。urlの最初をgitに変更するのを忘れないこと。

エディタやeclipseでソースを呼んでいる人はここまでの作業でOK。

eclipseやエディタではなく、htmlでソースの関数にジャンプしたい場合は以下の

事を行う。これをやっておくと本家のソースをwebでみるよりスピーディに参考にしたいソースを見つけられる。

4.Global source tag System(http://www.gnu.org/software/global/global.html)をインストール。

5.Linux(cygwi上)で以下を実行。frameつきのhtmlでソースを参照できるようにする。

# gtags -v

# htags -saFfn


androidデバッグクラス(SDカードにログを保持)

2011-02-07 00:51:51 | android

androidデバッグクラス(SDカードにログを保持)

<form>

androidデバッグクラス

<textarea readonly="readonly" cols="75" rows="8">import java.io.File; import java.io.FileOutputStream; import java.io.OutputStream; import java.util.Date; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.util.Log; import android.view.Display; import android.view.WindowManager; import android.os.Build; import android.os.Environment; /** * Log管理クラス、LogCat.sdCardにログを記録する * @author * */ public final class MYUtilityEx {      /**      *   Context 初回にここにcontextを保持しておく      */      private static Context  m_Context = null;      /**      *   Logcat,SDcardにログを保存するかしないか true:保存する false:保存しない      */     private static boolean  m_Debugable = false;      /**      * WindowManagerから取得した画面の横幅      * これサイズより大きい値はrokonのwidthに設定できない      */      public static int m_Width = 0;      /**      * WindowManagerから取得した画面の縦幅      * これサイズより大きい値はrokonのHeightに設定できない      */      public static int m_Height = 0;      public static String m_BOARD = "";                 //ボード(基盤)名称      public static String m_DEVICE = "";                    //デバイス名      public static String m_MANUFACTURER = "";           //製造者名      public static String m_PRODUCT = "";             //製品名      public static String m_CPU_ABI="";                    //ネイティブコードの命令セット      public static void init( Context ctx )      {           m_Context = ctx;           m_BOARD = Build.BOARD;           m_DEVICE = Build.DEVICE;           m_MANUFACTURER = Build.MANUFACTURER;           m_PRODUCT = Build.PRODUCT;           m_CPU_ABI = Build.CPU_ABI;           SetScreenSize();      }      /**Debug情報の出力を有効、無効にする       *      * @param debug true:保存する false:保存しない      */     public static void SetDebugAble( boolean debug )      {     m_Debugable = debug;      }      /**  SDカードの指定ディレクトり下に指定したファイル名でログおよび、ログメッセージを保存する       *      * @param SDcarddirname   SDカードのディレクトリ名      * @param filename   SDカードのディレクトリ名の配下に保存するファイル名      */     public static void MY_LOG_FILE( String SDcarddirname, String filename,String message )      {     File path;     //SDカードの存在をチェック     String status = Environment.getExternalStorageState();     Log.d("MY_LOG_FILE","status:" + status);          if( status.equals(Environment.MEDIA_MOUNTED) )          {         //存在すれば引数で渡されたDirecotryを作成         File strSDcardpath = Environment.getExternalStorageDirectory();         if( strSDcardpath.getAbsolutePath().equals( "" ))         {         Log.d("MY_LOG_FILE","no SD card");         }         else         {         //    "/sdcard/SDcarddirname" フォルダを作成         path = new File(strSDcardpath.getAbsolutePath() + "/" + SDcarddirname + "/");         if(path.exists() == false )         {         path.mkdir();         Log.d("MY_LOG_FILE","mkdir:" + path.toString() );         }         OutputStream outputStream =null;         File file = new File( path.toString(), filename );         try         {              outputStream  = new FileOutputStream(file,true);              //Logをsdcardに書き込む              Date date = new Date();              String strData = String.format("%4d/%02d/%02d-%02d:%02d:%02d",                           (1900+date.getYear()), date.getMonth()+1, date.getDate(),                           date.getHours(), date.getMinutes(), date.getSeconds());                      String strLog = Thread.currentThread().getStackTrace()[3]                               .getFileName()                               +":"                               +Thread.currentThread().getStackTrace()[3].getLineNumber()                               +" "                               +Thread.currentThread().getStackTrace()[3].getMethodName() + "  ";                     String strWriteData = strData + ": " + strLog + message + "\n";                     outputStream.write( strWriteData.getBytes() );                     outputStream.close();         }catch(Exception e )         {         Log.d("MY_LOG_FILE","Exception:" + e.getMessage());         }         }          }      }      /** LogCat抑制のためdebugフラグをチェックする      * @return m_Debugableがtrueかfalseか      */      public static boolean isDebugAble()      {     return m_Debugable;     //not use case   apk int adcard //          if( m_Context == null ) //          { //               return false; //          } // //          PackageManager manager = m_Context.getPackageManager(); //          ApplicationInfo appInfo = null; //          try //          { //               appInfo = manager.getApplicationInfo( m_Context.getPackageName(), 0 ); //               Thread.currentThread().getStackTrace()[1].getMethodName(); //          } catch ( NameNotFoundException e ) //          { //               Log.e( e.toString(), null ); //               return false; //          } //          if (( appInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE ) ==ApplicationInfo.FLAG_DEBUGGABLE) //          { //               return true; //          } // //          return false;      }      /**      * @param TAG      *            logのTAG用の文字列      * @param msg      *            デバッグ用のメッセージを指定      */      public static void MY_LOG(String TAG, String msg)      { //           if (isDebugAble() == true )           {                String strData = Thread.currentThread().getStackTrace()[3]                        .getFileName()                        +":"                        +Thread.currentThread().getStackTrace()[3].getLineNumber()                        +" "                        +Thread.currentThread().getStackTrace()[3].getMethodName();                Log.d( TAG, strData +":" +msg );               // Log.d( TAG, GetFileMethodLine() +":" +msg );           }      }      /**      * @param context      * @return version codeを返す      */      public static int GetVersionCode()      {           int ver = -1;           if( m_Context == null )           {                return ver;           }           try           {                ver = m_Context.getPackageManager().getPackageInfo(                          m_Context.getPackageName(), 1 ).versionCode;           } catch ( NameNotFoundException e )           {           }           return ver;      }      /**      * @param context      * @return versionを返す      */      public static String GetVersionName()      {           String ver = "";           if( m_Context == null )           {                return ver;           }           try           {                ver = m_Context.getPackageManager().getPackageInfo(                          m_Context.getPackageName(), 1 ).versionName;           } catch ( NameNotFoundException e )           {                ver = "";           }           return ver;      }      /** set Screen size  ij      *      */      private static void SetScreenSize()      {           if( m_Context != null )           {               Display display = null;               WindowManager wm = (WindowManager)m_Context.getSystemService(Context.WINDOW_SERVICE);               display = wm.getDefaultDisplay();               if( display != null )               {                    m_Width = display.getWidth();                    m_Height = display.getHeight();               }               Log.d("display", "w:" + display.getWidth());               Log.d("display", "h:" + display.getHeight());           }      }      /* 傾きを返す      * @return      * Surface.ROTATION_0   :     0         Surface.ROTATION_90 :     1         Surface.ROTATION_180:     2         Surface.ROTATION_270:     3      */      public static int GetRotation()      {           int rotate = -1;           if( m_Context != null )           {               Display display = null;               WindowManager wm = (WindowManager)m_Context.getSystemService(Context.WINDOW_SERVICE);               display = wm.getDefaultDisplay();               if( display != null )               {                    return display.getRotation();               }           }           return rotate;      } } </textarea>

</form>

rokonのspriteにTouchEventを設定

2010-12-12 17:45:37 | android

せっかく使っていたrokonですが、開発者が大学の最終学年および、いそがしいからこれ以上をcommitしないと http://code.google.com/p/rokon/   
のトップに書かれていました。ちょっと残念です。
そうなると、現状、使いやすいのはAndEngineしかなくなるような気がします。

AndEngineはSpriteにTouchAreaを指定できるが、rokonはそんな機能がないが、Spriteを作成して、setTouchable();
を設定してTouchEvnetを受け取れるようにした後なら、onTouchDown,onTouchUp,onTouch,onTouchMoveの eventを受け取れるようになる。Spriteでeventを受け取るか、GameScne(Sceneを継承したクラス)で受け取るかはアプリに より決定したほうがいいみたい。



rokonのspriteにTouchEventを設定 rokonのsampleでGameScene.javaを修正

<form>

rokonのspriteにTouchEventを設定

<textarea rows="8" cols="75" readonly="readonly">package org.jp.rokon2; import android.view.MotionEvent; import com.stickycoding.rokon.FPSCounter; import com.stickycoding.rokon.Scene; import com.stickycoding.rokon.Sprite; import com.stickycoding.rokon.background.FixedBackground; import com.stickycoding.rokon.device.Accelerometer; import com.stickycoding.rokon.modifiers.Blink; import com.stickycoding.rokon.Modifier; import android.util.Log; public class GameScene extends Scene { private FixedBackground background; private Sprite bob, bob2, bob3; private Sprite m_kazan,m_kazan2; private Blink  m_blink; public GameScene() { //super(); //input sample start これだと1毎のlayerに1つだけspriteを表示できる。 //super(1, 1); //sprite sample super(5, 10); // Setup the scene to have 1 layer of sprites with a maximum of 3 sprites per layer. //layer1つでsprite10こ使える //super(1,10); //super(2,10); // (note that the background does NOT count as a sprite) // Create a fixed background (ie a non-changing background) with the texture loaded in Textures.load(). setBackground(background = new FixedBackground(Textures.background));     // Create the Bob sprite.    // bob = new Sprite(100, 220, Textures.bob.getWidth(), Textures.bob.getHeight()); bob = new Sprite(100, 50, Textures.bob.getWidth(), Textures.bob.getHeight()) { public void onTouchDown(float x, float y, MotionEvent event, int pointerCount, int pointerId) { Log.d("spriteevent","bob1 onTouchDown" + "x:" + String.valueOf( x ) + "y;" + String.valueOf( y )); } public void onTouchUp(float x, float y, MotionEvent event, int pointerCount, int pointerId) { Log.d("spriteevent","bob1 onTouchUp" + "x:" + String.valueOf( x ) + "y;" + String.valueOf( y )); } public void onTouch(float x, float y, MotionEvent event, int pointerCount, int pointerId) { Log.d("spriteevent","bob1 onTouch" + "x:" + String.valueOf( x ) + "y;" + String.valueOf( y )); } public void onTouchMove(float x1, float y1, MotionEvent event, int pointerCount, int pointerId) { Log.d("spriteevent","onTouchMove" + "x:" + String.valueOf( x1 ) + "y;" + String.valueOf( y1 )); //bobの座標をTouchMoveに合わせて更新する x = x1; y = y1; } }; //sprite bob.setTouchable();     bob.setTexture(Textures.bob); //     // Add the Bob sprite to the first layer.     add(0, bob);     bob2 = new Sprite(100, 200, Textures.bob.getWidth(), Textures.bob.getHeight()) { public void onTouchDown(float x, float y, MotionEvent event, int pointerCount, int pointerId) { Log.d("spriteevent","bob2 onTouchDown" + "x:" + String.valueOf( x ) + "y;" + String.valueOf( y )); } public void onTouchUp(float x, float y, MotionEvent event, int pointerCount, int pointerId) { Log.d("spriteevent","bob2 onTouchUp" + "x:" + String.valueOf( x ) + "y;" + String.valueOf( y )); } public void onTouch(float x, float y, MotionEvent event, int pointerCount, int pointerId) { Log.d("spriteevent","bob2 onTouch" + "x:" + String.valueOf( x ) + "y;" + String.valueOf( y )); } public void onTouchMove(float x1, float y1, MotionEvent event, int pointerCount, int pointerId) { Log.d("spriteevent","bob2 onTouchMove" + "x:" + String.valueOf( x1 ) + "y;" + String.valueOf( y1 )); } };     bob2.setTouchable();     bob2.setTexture(Textures.bob); //     // Add the Bob sprite to the first layer.     add(0, bob2); } @Override public void onGameLoop() { // This is the game loop that is called once every frame. } @Override public void onPause() { // This is called when the game is hidden. (ie when the user switches to another app without turning this one off) // (this should be used to pause the game logic so the user doesn't miss anything while he/she's gone) } @Override public void onResume() { // And when the user return to this app. } @Override public void onReady() { // This is called when the scene has been successfully created and is ready to be used. } public void onTouchDown(float x, float y, MotionEvent event, int pointerCount, int pointerId) { // This is called when you press down on the screen. } @Override public void onTouchMove(float x, float y, MotionEvent event, int pointerCount, int pointerId) { // This is called when you move your finger over the screen. (ie pretty much every frame if your holding your finger down) // Here we'll just make Bob follow your finger. } @Override public void onTouchUp(float x, float y, MotionEvent event, int pointerCount, int pointerId) { // And this is called when you stop pressing. } } </textarea>

</form>

androidゲームエンジンとライセンス

2010-10-28 01:33:26 | android

androidゲームエンジンとライセンス

GPLライセンス

GLPライセンスのモジュールをリンクして利用(dll,so,jarファイル等)し、自分で作成したプログラムを配布する場合、自分で作成した箇所もすべて公開義務が発生する。
商用利用に利用できないことはないが、全てのソースを公開義務のため扱いづらいライセンス。



LGPLライセンス

LGPLライセンスのモジュールをリンクして利用(dll,so,jarファイル等)した、自分で作成したプログラムを配布する場合、自分で作成した部分については公開義務はなし。
ただしリバースエンジニアリングを禁止してはいけない。

 

これも商用利用できなくないが、一般の商用のプロダクトの説明文にはリバースエンジニアを禁止する条文があるので 扱いづらいライセンス



Apache ライセンス バージョン2

Apache ライセンス バージョン2のモジュールを利用し自分が作成したプログラムを配布する場合,apacheライセンスを 利用していることを明記する必要がある。
Apacheライセンスのモジュールの修正、改造、再配布も許可しているため商用利用しやすい。



修正BSDライセンス

 

Apache ライセンス バージョン2のモジュールを利用し自分が作成したプログラムを配布する場合 著作権表示、ライセンス条文、無保証の旨の三点をドキュメントに記述しておけば、モジュールの修正、改造、再配布も 許可しているため商用利用しやすい。


rokon

AndEngine

Angle

loon-simple(LGame)

まとめ(LGame)

<form>

rokon

<textarea rows="8" cols="75" readonly="readonly">公式ページ: http://code.google.com/p/rokon ライセンス:修正BSDライセンス 特徴:公式ページに簡単なチュートリアル、およびjavadocページあり。 そのため、こいつをメインに使う場合は,eclipseで作成したプロジェクトで右クリック 「javadoc ロケーション」 をクリックして、「javadoc ロケーションパス」に以下のページを追加する。 http://www.rokonandroid.com/javadocs/ 注意点: RokonMusic.playでoggファイルがループ再生されない。 原因はRokonMusic くらすのplay部分に間違いがある。曲のループを再生してからMediaPlayer.reset()を呼んで しまっているから。mp3を使う場合、下記でもループできるが、oggは下記のやり方だと1ループで終わる。 mediaPlayer.setLooping(loop); mediaPlayer.reset(); mediaPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength()) 使用した感想: jbox2dの物理エンジンも利用可能。ソース自体が短いのでソースを見ながら勉強できる。修正BSDライセンスなのでエンジン自体の上記のようなバグを直して使用してもOK。 </textarea>

</form> <form>

AndEngine

<textarea rows="8" cols="75" readonly="readonly">公式ページ: http://www.andengine.org/ ライセンス:LGPL 使用した感想: 一番Sampleが豊富。あたまひとつ飛びぬけている感じ。パーティクルのサンプルおよびjbox2dで物理エンジンも使用可能。ライセンスだけがネック。 </textarea>

</form> <form>

Angle

<textarea rows="8" cols="75" readonly="readonly">公式ページ: http://code.google.com/p/angle/ ライセンス:LGPL 使用した感想: jarファイル等が存在しないため、androidのプロジェクトを作成した後、ANGLEエンジンのソースを 以下のように配置して使用する。ソースは短いので覚えやすいかも。 作成したプロジェクト名 - src - com - android - angle mGLSurfaceView(SurfaceView)にsprite等を追加して、独自処理おw追加していく。どのメンバが継承されているか しらべながら実装する必要あり。60FPSで固定でFPSを40FPS,50FPSにしたい場合独自処理追加する必要あり 注意点 他の2D gameエンジンと違って、Androidmanifest.xmlに何も追加しなくても動作するが、戻るボタン(ハードボタン)でsampleが強制終了する。他のエンジンはAndroidmanifest.xmlに横画面固定にするかactivity作成時に指定できるがこのエンジンは指定しないと横画面、縦画面の回転を許可してしまうのでコーディングには気をつけないといけない。たいていの場合回転するとonDestory()が走るため、画面は固定すると思う。 </textarea>

</form> <form>

loon-simple

<textarea rows="8" cols="75" readonly="readonly">公式ページ: http://code.google.com/p/loon-simple/ ライセンス:Apache バージョン2 使用した感想: ライセンスが緩いのが利点。日本語のサイトは皆無のため、同梱されている中国語のマニュアルを見ての開発になる。メインの開発は,loon-simpleのScreen,AVGScreen,ThreadScreen,CanvasScreenを継承して独自に処理をいれて開発していく。 FPSはonMain()のsetFPS()関数で自由に設定可能。 AVGScreenのだけandroidのsampleあり。AVGScreenを継承して使用する場合、は主にテキストメインの開発が メインになる。日本のゲームエンジネでいうところのnscripter,吉里吉里の開発方法と一緒ThreadScreen,CanvasScreenを継承すれば2Dゲームはいけそうだが、サンプルがないので簡単な動作するものしか作れなかった。 google codeにあるSampleでLLKがScreenを継承してのandroidのsampleだが、昔のエンジンでのソースのためそのままでは使用できない。 </textarea>

</form> <form>

用途別のまとめ

<textarea rows="8" cols="75" readonly="readonly">・物理エンジン(jbox2d)等がいらない場合 Angle,loon-simple ・物理エンジン(jbox2d)を利用するゲームを作成する場合 rokon,AndEngine ・自分で作成したプログラムのリバースエンジニアリングを許可してもいい場合は以下のエンジンを使用する。(自分で作成した部分の公開義務はないが、apkの中にあるclassファイルからjavaに変換(java 逆アセンブル)して内容も見ることを禁止してはいけない。) AndEngine,Angle ・商用利用でゲームエンジン自体も改造して使用する場合 rokon,loon-simpe ・結局のところ classファイルから、javaファイルに変換できるツールはたくさんある。そのためapk(zipファイル)を解凍してclassファイルをjava逆アセンブラすれば、javaソースコードができるのでソース解析はできる。逆アセンブルを禁止してもしなくても、意味がない気がする。 </textarea>

</form>