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

Android Tips



目次



記事一覧
<<outlineプラグインは存在しません。>>
<<searchプラグインは存在しません。>>

Android Tips


[Android][Java][Eclipse]

概要

 ブログ


 書籍


 基本

 Android 一連の手順概要


 インストール

SDKのインストール

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

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

<<ref_imageプラグインは存在しません。>>

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

<<ref_imageプラグインは存在しません。>>

画面

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

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

<<ref_imageプラグインは存在しません。>>

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

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

<<ref_imageプラグインは存在しません。>>


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

<<ref_imageプラグインは存在しません。>>

 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

<<ref_imageプラグインは存在しません。>>

 スクリーンキャプチャ

 カメラアプリで、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.