トップ 差分 一覧 ping ソース 検索 ヘルプ PDF RSS ログイン

Android Tips



目次



記事一覧

キーワード

Android Tips


[Android][Java][Eclipse]

概要

 ブログ


 書籍


 基本

 Android 一連の手順概要


 インストール

SDKのインストール

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

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

ADT Eclipse プラグイン


 環境構築手順

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


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



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

Eclipse Git プラグインの導入


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


Ubuntuに開発環境を構築


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

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

開発環境

 GAE

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

 SDK ソースコード

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 にインチサイズを設定

画面

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

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);

 画面の向きを取得する


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

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);

逆の場合、add と clear を変える

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

 UIについて



 設定画面を作成する


 スタイル

 色定義を行い使用する

values/colos.xml を定義
&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;resources&gt;
    &lt;color name="white"&gt;#FFFFFF&lt;/color&gt;
    &lt;color name="lightgrey"&gt;#C0C0C0&lt;/color&gt;
&lt;/resources&gt;

使い方(Activity内)
txtHoge.setTextColor(getResources().getColor(R.color.lightgrey));

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


 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);

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


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(リスト表示画面)サンプル

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

 Service

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;
    }
}

 ダイアログボックス

検索

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

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タイプを同時に渡す

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

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);


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

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が????と表示され実機デバッグできない


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

 TraceView

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

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

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

 スクリーンキャプチャ

 カメラアプリで、FileNotFoundException

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


 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);

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


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



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

上記を行うと、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マルチパートでファイルをアップロードする

以下を入手

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

サンプル
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

 画像

読み込み・キャッシュ


広告

 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



YAGI Hiroto (piroto@a-net.email.ne.jp)
twitter http://twitter.com/pppiroto

Copyright© 矢木 浩人 All Rights Reserved.