| ページ一覧 | ブログ | twitter |  書式 | 書式(表) |

MyMemoWiki

Android Tips

提供: MyMemoWiki
2020年2月15日 (土) 08:17時点におけるPiroto (トーク | 投稿記録)による版
ナビゲーションに移動 検索に移動

目次

Android Tips

AndroidJavaEclipse

概要

ブログ

書籍

基本

  • Android アプリケーション基本

Android 一連の手順概要

インストール

[Android SDKのインストール] [SDKのインストール]

  • [Android SDKのインストール] [SDKのインストール]

SDK Manager に APIの一覧が表示されない場合

  • Tools - Options からForce にチェックを入れ、HTTP接続を可能にする

0161 android sdk manager.jpg

[Android ADT Eclipse プラグイン] [ADT Eclipse プラグイン]

  • [Android ADT Eclipse プラグイン] [ADT Eclipse プラグイン]

環境構築手順

JDKのインストールから、Eclipse の日本語化まで

SDKのインストールから、エミュレータの作成まで


実機デバッグ(ADBドライバのインストール)

Eclipse Git プラグインの導入

Eclipse プロジェクトの作成とSDKソースコードをEclipseから閲覧可能に

Ubuntuに開発環境を構築

UbuntuでADTプラグインインストールエラー

Ubuntu ADBドライバに実機を認識させる

開発環境

GAE

[Android (実機) と GAE を連携させるためのデバッグ環境を Windows7 に構築する]

SDK ソースコード

[CentOS 初期設定] [Gitのインストール(Linux)]
# git clone git://android.git.kernel.org/platform/frameworks/base.git
ブラウズ
Eclipse


Eclipse 3.6.1 のコード補完で固まる対処

以下のパッチをEclipseにあてる(解凍して上書き)

エミュレータ

起動時の実際のサイズを指定する

  1. AVD Manager から、Start the selected AVD を選択
  2. 表示されたダイアログの Scale display to real size をチェック
  3. screen size にインチサイズを設定

0160 android emu.png

画面

画面モード(縦、横)が変わらないように設定

http://www.hakkaku.net/articles/20090831-579

  • XML の manifest/application/activity の属性、android:screenOrientation を、"portrait" に設定すると、縦画面のまま回転しなくなります。
設定値
  • "portrait" … 縦画面で固定
  • "landscape" … 横画面で固定
  • "unspecified" … デバイス任せ


画面モード(縦、横)が変わる、変わらないを動的に変更

if (条件) {
    // 画面の回転を抑制(現在の向きに固定)
    Configuration config = getResources().getConfiguration();
    if (config.orientation == Configuration.ORIENTATION_PORTRAIT) {
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
    } else if(config.orientation == Configuration.ORIENTATION_LANDSCAPE) {
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
    }            
} else {
    // 回転を可能に
    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
}
int orientation = getActivity().getRequestedOrientation();
int rotation = ((WindowManager) getActivity().getSystemService(
        Context.WINDOW_SERVICE)).getDefaultDisplay().getRotation();
switch (rotation) {
case Surface.ROTATION_0:
    orientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
    break;
case Surface.ROTATION_90:
    orientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
    break;
case Surface.ROTATION_180:
    orientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
    break;
default:
    orientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
    break;
}
getActivity().setRequestedOrientation(orientation);
  • 固定解除
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);

画面サイズを取得する

1
Display display = getWindowManager().getDefaultDisplay(); 
int width = display.getWidth();
int height = display.getHeight();
outSizeに格納される
Point outSize = new Point();
(WindowManager)getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getSize(outSize);

画面の向きを取得する

<blockquote>API Level 8 以降は getRotation () を使うこと 0:portrait, 1:landscape</blockquote>

Display display = getWindowManager().getDefaultDisplay(); 

switch(display.getOrientation()) {
case Surface.ROTATION_90:
case Surface.ROTATION_270:
   // TODO
	break;
default:
   // TODO
	break;
}

タイトルバーを非表示に

コード
  • requestWindowFeature(Window.FEATURE_NO_TITLE)を実行
public class ColorChoiceActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        
        setContentView(R.layout.main);
    }
}
XML
  • AndroidManifest.xml に指定
  • タイトルバーを非表示、フルスクリーン
<activity    :
         android:theme="@android:style/Theme.NoTitleBar.Fullscreen" >

最大化表示(ステータスバーを隠す)

コード
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); 
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);

<blockquote>逆の場合、add と clear を変える</blockquote>

XML
  • AndroidManifest.xml に指定
  • タイトルバーを非表示、フルスクリーン
<activity    :
         android:theme="@android:style/Theme.NoTitleBar.Fullscreen" >

UIについて

設定画面を作成する

スタイル

  • [Android スタイル] [スタイル]

色定義を行い使用する

values/colos.xml を定義
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="white">#FFFFFF</color>
    <color name="lightgrey">#C0C0C0</color>
</resources>
使い方(Activity内)
txtHoge.setTextColor(getResources().getColor(R.color.lightgrey));

<blockquote>txtHoge.setTextColor(R.color.lightgrey) とするのは、色の値として、リソースIDが渡されるためNG</blockquote>

EditText に最初にフォーカスがあたり、IMEが自動起動してしまうのを抑制

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // EditText に最初にフォーカスがあたり、IMEが自動起動してしまうのを抑制
    getWindow().setSoftInputMode(La    outParams.SOFT_INPUT_STATE_ALWA    S_HIDDEN);
    
    setContentView(R.la    out.word_editor);

App ウィジェット

App ウィジェットの作り方

イベント

EditTextの変更を検知

public void addTextChangedListener (TextWatcher watcher)
txtTitle.addTextChangedListener(new TextWatcher() {
    
    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {
    }
    
    @Override
    public void beforeTextChanged(CharSequence s, int start, int count,int after) {
    }
    
    @Override
    public void afterTextChanged(Editable s) {
         updateHogeObject();
    }
});

Activity にて戻るボタン押下を検知

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_BACK) {

    }
    return super.onKeyDown(keyCode, event);
}

ダイアログ

確認ダイアログ

ファイル削除確認
final File file = new File(path);
      
new AlertDialog.Builder(parent)
    .setTitle(R.string.lbl_file_delete_confirm)
    .setMessage(parent.getResources().getString(R.string.msg_file_delete_confirm, file.getName()))
    .setPositiveButton(R.string.lbl_yes, new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            deletreFile(file);
        }
    })
    .setNegativeButton(R.string.lbl_no, new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
        }
    })
    .create().show();

オプションリストのダイアログ

    public void showSortDialog() {
        final int[] keys = {
                MENU_SORT_BY_TITLE,
                MENU_SORT_BY_HU_LEVEL_ASC,
                MENU_SORT_BY_HU_LEVEL_DSC,
                MENU_SORT_BY_CREATE_DATE
        };
        final String[] items = {
                this.getString(R.string.lbl_sort_by_title),
                this.getString(R.string.lbl_sort_by_hu_level_asc),
                this.getString(R.string.lbl_sort_by_hu_level_dsc),
                this.getString(R.string.lbl_sort_by_create_date)
        };
        
        new AlertDialog.Builder(this)
        .setTitle(R.string.lbl_sort)
        .setSingleChoiceItems(items, 0, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                sortWorkingSet(keys[which]);
                dialog.dismiss();
            }
        })
        .setNegativeButton(R.string.lbl_cancel, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
            }
        })
        .show();
    }


プログレスダイアログ

カスタムダイアログ

Context mContext = getApplicationContext();
Dialog dialog = new Dialog(mContext);

dialog.setContentView(R.layout.custom_dialog);
dialog.setTitle("Custom Dialog");
TextView text = (TextView) dialog.findViewById(R.id.text);
dialog.show();

Activity

同じアプリケーションのアクティビティを呼び出す

マニフェストファイルの application セクションの中に以下を記述
<activity android:name=".OtherActivity"/>
インテントを利用して呼び出し
Intent intent = new Intent(getApplicationContext(),
             OtherActivity.class);
startActivity(intent);

<blockquote>データの受け渡しには、Intent.putExtra を利用</blockquote>

Activity.onCreate
Spinner spFontSize = (Spinner) findViewById(R.id.spn_font_size);
ArrayAdapter<CharSequence> spFontSizeAdapter 
    = ArrayAdapter.createFromResource(this,
            R.array.ary_font_size,
            android.R.layout.simple_spinner_item);
spFontSizeAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spFontSize.setAdapter(spFontSizeAdapter);

Activity の状態を一時的に保存する

[Activity の状態を一時的に保存する]

コンフィグレーション

  • デバイスのコンフィグレーションが変更されたら、UIはそのコンフィグレーションにマッチするように更新する必要があるため、Activitiは再スタートされる
  • コンフィグレーションの変更があってもActivityの再スタートを避けたい場合、マニフェストにandroid:configChanges属性を追加
android:configChanges="locale|orientation|"

ArrayAdapter に ラジオボタンを置く

[ArrayAdapter に ラジオボタンを置く]

TabActivity(タブによるアクティビティ切り替え) サンプル

[TabActivity]

ListActivity(リスト表示画面)サンプル

Android スケルトン ListActivity ListActivity

PreferenceActivity(設定画面の作成) サンプル

[PreferenceActivity]

透明なActivityを作成する

res/values/styles.xml に以下の内容を記述

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <style name="Theme.Transparent" parent="android:Theme">
        <item name="android:windowIsTranslucent">true</item>
        <item name="android:windowBackground">@android:color/transparent</item>
        <item name="android:windowContentOverlay">@null</item>
        <item name="android:windowNoTitle">true</item>
        <item name="android:windowIsFloating">true</item>
        <item name="android:backgroundDimEnabled">false</item>
    </style>
</resources>

AndroidManifest.xml のActivityのtheme属性にに以下の記述

<activity android:name=".EditScoreActivity" android:theme="@style/Theme.Transparent"></activity>

Activity をダイアログとして表示する

  • @android:style/Theme.Dialog を利用
<activity android:name=".EditScoreActivity" android:theme="@android:style/Theme.Dialog"></activity>

Service

[Android Service] [Service]

Fragment

  • [Android Fragment] [Fragment]

サポートライブラリ(android.support.v4)でFragmentを利用する場合の注意点

  • android.support.v4 のクラスを利用する
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
  • Activity ではなく、FragmentActivityを利用する
  • getFragmentManager() ではなく、getSupportFragmentManager() を利用する
  • invalidateOptionsMenu() ではなく、supportInvalidateOptionsMenu() を利用する

非同期処理

View

ListView の分離線を変更する

XMLから

<ListView android:id="@+id/android:list" 
          android:layout_height="wrap_content" 

android:layout_width="fill_parent" android:divider="#D7D7D7"

          android:dividerHeight="1px">
</ListView>

コードから

ListView lv = getListView(); 
lv.setDivider(new ColorDrawable(Color.GREEN));
lv.setDividerHeight(1);
  

ListViewのID

  • ListViewのIDは、以下の様にする。
  • TextViewは、リストがない場合
<ListView android:id="@android:id/list" ・・・></ListView>
<TextView android:id="@android:id/empty" ・・・></TextView>

または、

<ListView android:id="@+id/android:list" ・・・></ListView>
<TextView android:id="@+id/android:empty" ・・・></TextView>

ListViewの背景色の設定をしても、スクロールすると黒くなってしまう

android:scrollingCache="false"

ListViewのスクロールバーを大きくする

ListViewのコンテキストメニュー選択時にアイテムを取り出す

[ListViewのコンテキストメニュー選択時にアイテムを取り出す]

カスタムViewを利用する

<view xmlns:android="http://schemas.android.com/apk/res/android"
 class="info.typea.iromegane.ColorTile"
 android:id="@+id/col_tile" ></view>

カスタムViewを作成しレイアウトはXMLで行う

 public class HogeView extends LinearLayout {
     public HogeView(Context context) {
         super(context);
         
         LayoutInflater layoutInflater 
             = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
         
         View view = layoutInflater.inflate(R.layout.hoge_layout, this);
     }
 }

ページめくり

[ページをめくるサンプル]

Spinnerの使い方例

string.xml
<string-array name="ary_font_size">
    <item>70</item>
    <item>80</item>
    <item>90</item>
    <item>100</item>
</string-array>
Activity
// フォントサイズ
spFontSize = (Spinner) findViewById(R.id.spn_font_size);
ArrayAdapter<CharSequence> spFontSizeAdapter 
    = ArrayAdapter.createFromResource(this,
            R.array.ary_font_size,
            android.R.layout.simple_spinner_item);
spFontSizeAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spFontSize.setAdapter(spFontSizeAdapter);
spFontSize.setPrompt(getResources().getText(R.string.lbl_font_size));

for (int i=0; i<spFontSize.getCount(); i++) {
    int fs = Integer.parseInt(spFontSizeAdapter.getItem(i).toString());
    if (hogehoge.getFontSize() == fs) {
        spFontSize.setSelection(i);
        break;
    }
}

ダイアログボックス

検索

[Android 検索インターフェースの作成] [検索インターフェースの作成]

ContentProvider

連絡先の取得と電話をかける

プロパティ

単行

android:maxLines="1"

レイアウト

XMLからレイアウトをインスタンス化する

SystemService を直接
LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
       
prevView    = vi.inflate(R.layout.layout_previous,null);
currentView = vi.inflate(R.layout.layout_current,null);
nextView    = vi.inflate(R.layout.layout_next,null);
SystemService を View経由
EditText editor = (EditText) View.inflate(this, R.layout.editor_lined, null);

スクロールさせる

  • ScrollViewを利用
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:android="http://schemas.android.com/apk/res/android">

    <ScrollView android:id="@+id/scrl_word_editor" 
        android:layout_height="wrap_content" 
        android:layout_width="match_parent">
        
        <LinearLayout android:orientation="vertical"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
        
            <TextView></TextView>
            <EditText></EditText>
                  :
        </LinearLayout>
    </ScrollView>
</LinearLayout>

インテント

暗黙的 Intent で Twitter や Evernote と連携する

テキストエディタ等にファイルの処理をさせる

setDataAndType を使って、ファイルのURIとMIMEタイプを同時に渡す

<blockquote>個別に渡すと後に渡した方しか有効にならない(バグ?仕様 Android2.1 X06HT)</blockquote>

File f = new File(path);
	
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(f),"text/plain");
startActivity(intent);

画像ファイルを共有する

Intent intent = new Intent(android.content.Intent.ACTION_SEND);
intent.setType("image/jpeg");
intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(file));
startActivity(Intent.createChooser(intent, "title"));

ブラウザを開くなどURIの処理を行う

Uri uri = Uri.parse("https://market.android.com/details?id=info.typea.eitangoroid.pro");

Intent intent = new Intent(Intent.ACTION_VIEW, uri);
context.startActivity(intent);

ブロードキャストされたインテントを受け取る

トースト

トーストをカスタマイズして吹き出しをつくる

ノーティフィケーション

起動しているActivityを全面に表示させる

AndroidManifest.xml
  • android:launchMode="singleTop" を指定。指定しないと別のActivityが生成されてしまう。
<activity android:name=".TimeKeeperActivity"
          android:launchMode="singleTop">
          :
インテントを設定し、通知を行う
Notification notification = new Notification(R.drawable.icon, 
    text, System.currentTimeMillis());
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, 
     Intent(this, TimeKeeperActivity.class), 0);
notification.setLatestEventInfo(this, getString(R.string.msg_section_alarm),    
     text, contentIntent);
notifManager.notify(R.string.app_name, notification);

メニュー

Android 規定のアイコンを設定

@Override
public boolean onCreateOptionsMenu(Menu menu) {
   super.onCreateOptionsMenu(menu);
   menu.add(0, MENU_ADD_NEW, 0, R.string.menu_add_new_item)
     .setIcon(android.R.drawable.ic_menu_add);
   return true;
}

ListView に コンテキストメニュー(長押し)を設定

public class SampleListActivity extends ListActivity {
    private static final int MENU_EDIT    = Menu.FIRST; 
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
                     :
        // 忘れがち
        registerForContextMenu(getListView());
    }
    @Override
    public void onCreateContextMenu(ContextMenu menu, View v,
            ContextMenuInfo menuInfo) {
        
        super.onCreateContextMenu(menu, v, menuInfo);
        menu.add(0, MENU_EDIT, 0, R.string.menu_edit);
    }
    @Override
    public boolean onContextItemSelected(MenuItem item) {
        switch(item.getItemId()) {
        case MENU_EDIT:
               :
            break;
        default:
            break;
        }
        return super.onContextItemSelected(item);
    }        
}    

パーミッション

Android パーミッション

assetリソース

assetリソースディレクトリのファイルを読む

AssetManager am = context.getAssets();
InputStream in = am.open("test.txt");

assetリソースディレクトのzipファイルを読む

public void readZipFromAssets(String filename) {
    try {
        AssetManager am = context.getAssets();
        InputStream in = am.open(filename);
        ZipInputStream zin = new ZipInputStream(in);
        
        ZipEntry ze = null;
        while((ze = zin.getNextEntry()) != null) {
            if (ze.isDirectory()) {
                continue;
            }
            BufferedReader reader = new BufferedReader(new InputStreamReader(zin));
            String line = null;
            while ((line = reader.readLine()) != null) {
                Log.i(FlippadApplication.TAG, line);
            }
        }
        zin.close();

    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

文字列リソース

書式設定でXMLエラーとなる

フォーマットを行う場合、複数の%が含まれたりすると、Multiple annotations found at this エラーで、XMLが解析されない

string.xml例
<string name="msg_location_msg" formatted="false">経度 %9.6f、緯度 %9.6f 付近のメッセージ</string>
コード例
String text = getContext().getString(R.string.msg_location_msg, 
   location.getLatitude(), 
   location.getLongitude()); 

ファイル

アプリケーションのデータディレクトリ

Context
File targetdir = getFilesDir();

SDカードがマウントされているか判定

if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
    // マウントされている				
}

SDカードへ保存

パーミッション
android.permission.WRITE_EXTERNAL_STORAGE
対象ディレクトリの取得
File targetdir = Environment.getExternalStorageDirectory();

データベース

コマンドラインからSQLを発行

C:\Users\piroto>adb shell
# cd /data/data/info.typea.eitangoroid.pro/databases
cd /data/data/info.typea.eitangoroid.pro/databases
# ls
ls
webviewCache.db
FlippadDB
webview.db
# sqlite3 FlippadDB
sqlite3 FlippadDB
SQLite version 3.6.22
Enter ".help" for instructions
Enter SQL statements terminated with a ";"

画像

ビットマップのサイズ変更

Matrix matrix = new Matrix();
float w = (float)newWidth / (float)bmp.getWidth();
float h = (float)newHeight / (float)bmp.getHeight();
matrix.postScale(w,h);
bmp = Bitmap.createBitmap(bmp,0,0,bmp.getWidth(),bmp.getHeight(),matrix,true);

OutOfMemory

アイコン

ランチャーアイコンガイドライン

描画

画面サイズの取得

  • View クラスの getWidth()、getHeight()

文字列幅の取得

  • Paint クラスの measureText()

文字列の描画例

画面中央に文字列描画
 Paint paint = new Paint();
 paint.setARGB(60, 80, 80, 80);
 paint.setTextAlign(Paint.Align.CENTER);
 paint.setTextSize(80);
 paint.setTypeface(Typeface.DEFAULT_BOLD);
 canvas.drawText(str, getWidth() / 2, getHeight() / 2, paint);

0162 fontmetrics.gif

文字列領域の高さにより、フォントサイズを決定する

Paint txtPaint = new Paint();
txtPaint.setTextAlign(Paint.Align.CENTER);
txtPaint.setStyle(Paint.Style.FILL);
txtPaint.setAntiAlias(true);
FontMetrics fontMetrics = null;
for (int i=5; i<40 ; i++) {
    txtPaint.setTextSize(i);
    fontMetrics = txtPaint.getFontMetrics();
    
    if ((fontMetrics.bottom - fontMetrics.top) > baseHeight ) {
        i--;
        txtPaint.setTextSize(i);
        fontMetrics = txtPaint.getFontMetrics();
        break;
    }
}

図形描画

角が丸い図形を描画する(CornerPathEffect)

paint.setPathEffect(new CornerPathEffect(12.0f));

Bitmap

リソースからBitmapを生成し、カラーフィルターをかけてCanvasに描画

Bitmap bmpConfig = BitmapFactory.decodeResource(getResources(), R.drawable.config);
Paint paint = new Paint();
paint.setColorFilter(new PorterDuffColorFilter(Color.GREEN,Mode.SRC_IN));
float bmpConfigTop    = blindTop + iconMargin;
canvas.drawBitmap(bmpConfig, 0 ,bmpConfigTop, paint);

デバッグ

テスト

実機でデバッグ

  • AndroidManifest.xml Debuggable = true

UbuntuでデバイスIDが????と表示され実機デバッグできない

0158 android-sdk07.png

51-android.rulesを作成
$ cd /etc/udev/rules.d/
$ sudu su
# vi 51-android.rules 
HTCを登録
SYSTEM=="usb", SYSFS{idVendor}=="0bb4", MODE="0666" 
権限の設定
# chmod a+r 51-android.rules 

確認

  • 対応前
# ./adb devices
List of devices attached 
????????????	no permissions
  • 対応後
# ./adb devices
List of devices attached 
HT061PL00290	device

0159 android-sdk08.png

TraceView

  • トレース開始位置に以下を記述

<blockquote>SDカードがマウントされていること</blockquote>

Debug.startMethodTracing("test");
  • トレース終了位置に
Debug.stopMethodTracing();
  • トレースが完了したら、トレースファイルを取得
C:\work>adb pull /sdcard/test.trace
  • TraceView を実行
C:\work>cd C:\Programs\android-sdk-windows\tools
C:\Programs\android-sdk-windows\tools>traceview c:\work\test.trace

0163 traceview01.jpg

スクリーンキャプチャ

  • Android Eclipse から スクリーンキャプチャを取る

カメラアプリで、FileNotFoundException

<blockquote>カメラアプリで、FileNotFoundException /sys/android_camera2/htcwc が発生したら、端末の再起動を行う。</blockquote>

SDKソースコードのステップ実行

入力

IME ソフウェアキーボードを消す

public void onClick(View v) {
   // ボタンを押したら、ソフウェアキーボードを消す   	
   InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
   imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
}

マルチタッチ(ピンチ)

センサー

搭載センサーの値を取得

バイブレーター

宣言
private Vibrator vib;
初期化
vib = (Vibrator) getContext().getSystemService(Context.VIBRATOR_SERVICE);
利用
vib.vibrate(50L);
パーミッション
<uses-permission android:name="android.permission.VIBRATE"></uses-permission>


カメラ

画像が90度回転してしまう

  • カメラデバイスは向きを認識していないので、指定する必要がある
Camera.Parameters p = camera.getParameters();
p.setRotation(90);
camera.setParameters(p);

<blockquote>Froyo 化してからは、上記方法が使えなくなった(むしろ使えていたのがおかしかった!?)ため、以下の対応</blockquote>

カメラプレビューが横向きに表示されてしまう!の対応


カメラプレビューを縦向きにすると画面描画の座標が訳わからなくなる対応

上記を行うと、Viewに描画するときに座標が混乱してしまう対応。

サウンド

ハードウェアから、音量を制御

  • サンプルソース
  • ハードウェアから、音量を制御させるには、以下の記述が必要
setVolumeControlStream(AudioManager.STREAM_MUSIC); 

サウンドモードを判定する

audioManager = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
switch (audioManager.getRingerMode()) {
case AudioManager.RINGER_MODE_SILENT:
    break;
case AudioManager.RINGER_MODE_VIBRATE:
    break;
case AudioManager.RINGER_MODE_NORMAL:
    player.seekTo(0);
    player.start();
    break;
default:
    break;
}

ヘッドフォント着脱を検知する

電源管理

スリープ状態からの復帰、キーロック解除

private PowerManager powerManager;
private WakeLock wakeLock;
private KeyguardManager keyguardManager;
private KeyguardLock keyguardLock;

@Override
public void onCreate() {
    super.onCreate();

    powerManager = (PowerManager)getSystemService(POWER_SERVICE);
    wakeLock = powerManager.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK
                                    | PowerManager.ACQUIRE_CAUSES_WAKEUP
                                    | PowerManager.ON_AFTER_RELEASE, 
                                    ClockService.class.getName());
    keyguardManager = (KeyguardManager) getSystemService(KEYGUARD_SERVICE);
    keyguardLock = keyguardManager.newKeyguardLock(ClockService.class.getName());
}
private void hoge() {
 
    // スリープからの復帰とキーロック解除
    wakeLock.acquire();
    keyguardLock.disableKeyguard();
   
    // 何らかの処理
 
    // リリース
    wakeLock.release();
    keyguardLock.disableKeyguard();
}
必要なパーミッション
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.DISABLE_KEYGUARD"/>



アニメーション

サンプル設定ファイルの場所

{android-sdk}\samples\android-7\ApiDemos\res\anim
  1. /res/anim フォルダを作成
  2. anim フォルダでコンテキストメニューから import し適用
ViewFlipper vf = (ViewFlipper) findViewById(R.id.details);
vf.setAnimation(AnimationUtils.loadAnimation(this, R.anim.push_left_in));


非同期処理

非同期処理をAsyncTaskを使って行い進捗をProgressDialogに表示する

Web

Httpクライアントタイムアウトを設定する

[Httpクライアントタイムアウトを設定する]

HttpPost HttpGet = new HttpGet(uri);
HttpParams httpParms = new BasicHttpParams();
httpParms.setIntParameter(AllClientPNames.CONNECTION_TIMEOUT, 3000);
httpParms.setIntParameter(AllClientPNames.SO_TIMEOUT, 5000);

DefaultHttpClient client = new DefaultHttpClient(httpParms);
HttpResponse response = client.execute(httpPost);

MIMEマルチパートでファイルをアップロードする

以下を入手

<blockquote>httpmime は、httpcomponents-client に httpclient とともにアーカイブされている。</blockquote>

サンプル
DefaultHttpClient client = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(uri);
File upfile = new File(info.getPath());

MultipartEntity entity = new MultipartEntity();
entity.addPart("upload_file_name",     new StringBody(upfile.getName()));
entity.addPart("upload_file_contents", new FileBody(upfile));
httpPost.setEntity(entity);
response = client.execute(httpPost);

HttpPost に標準的なパラメータを設定する

try {
    HttpPost post =  new HttpPost("http://hogehoge.com/hoge");
    List<NameValuePair> parms = new ArrayList<NameValuePair>();
    parms.add(new BasicNameValuePair("lat", this.lat));
    parms.add(new BasicNameValuePair("lng", this.lng));
    post.setEntity(new UrlEncodedFormEntity(parms, HTTP.UTF_8));
                 :
} catch (UnsupportedEncodingException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}

Httpリクエストからレスポンスまでの概要

HttpPost post =  new HttpPost("http://hogehoge.com/hoge");

List<NameValuePair> parms = new ArrayList<NameValuePair>();
parms.add(new BasicNameValuePair("lat", String.valueOf(loc.getLatitude())));
parms.add(new BasicNameValuePair("lon", String.valueOf(loc.getLongitude())));
parms.add(new BasicNameValuePair("message", msg));
post.setEntity(new UrlEncodedFormEntity(parms, HTTP.UTF_8));

DefaultHttpClient httpClient = new DefaultHttpClient();
HttpResponse response = httpClient.execute(post);

InputStream in = response.getEntity().getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String l = null;
while((l = reader.readLine()) != null) {
    buf.append(l + "\r\n");
}        
if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
    Log.e(LocationBasedMessageApplication.TAG, buf.toString());
}

9Patch

9Patchの使い方(吹き出しをつくる)

Dropbox

NDK

Google App Engine

開発環境の構築

Google アカウントの利用

ライブラリ

チャート

UI

カードUI

画像

読み込み・キャッシュ

広告

[Android AdMob] [AdMob]

    • [Android AdMob] [AdMob]

公開

Android マーケット

SDカードにインストールを許可

  • AndroidManifest.xml に installLocation を指定 (Android SDK 2.2から対応)
android:installLocation="auto" 
内容
internalOnly 内蔵メモリへのインストールのみ許可
auto 内蔵メモリ優先
preferExternal SDカードを優先

アプリ内課金

トラブルシュート

Error generating final archive: Debug certificate expired on エラーでコンパイルできない

  1. ユーザーディレクトリの、.android/debug.keystore ファイルを削除
  2. プロジェクトのクリーン

resources.ap_ does not exist エラーで実行できない

以下の様なエラーがでて実行できない

Your project contains error(s), please fix them before running your application. 
Description	Resource	Path	Location	Type
Error generating final archive: java.io.FileNotFoundException: C:\Users\piroto\workspace\EitangoroidPro\bin\resources.ap_ does not exist

http://www.yukun.info/blog/2012/01/android-eclipse-build-error.htmlを参考に以下の手順で解決

  • Window - Android SDK Manager から、インストール済みのSDKを最新にUpdate
  • eclipse.exe -clean を実行

Android requires compiler compliance level 5.0 or 6.0. Found '1.4' instead

Android requires compiler compliance level 5.0 or 6.0. Found '1.4' instead. Please use Android Tools > Fix Project Properties.
  • プロジェクトのプロパティから、Java Compiler
  • Compiler compliance level を 1.6 等 適切なものに
  • Android Tools > Fix Project Properties
  • リビルド


Unable to resolve target

  • 以下の様なエラーは、SDKのバージョン不一致
[2013-05-27 22:43:56 - EitangoroidPro] Unable to resolve target 'android-8'
  • project.properties を修正
# Project target.
target=android-17