45,232 バイト追加
、 2020年2月15日 (土) 07:30
==Android Tips==
[Android][Java][Eclipse]
==概要==
===ブログ===
*[http://typea.info/portal/android/android.html 記事一覧]
===書籍===
*[http://typea.info/blg/glob/2010/11/android-3.html Android 書籍レビュー]
===基本===
*Android アプリケーション基本
===[https://docs.google.com/present/view?id=dfrdwzrx_179f7w9q4ct Android 一連の手順概要]===
*[https://docs.google.com/present/view?id=dfrdwzrx_179f7w9q4ct Android 一連の手順概要]
*[http://typea.info/blg/glob/2012/11/20-android.html 開発環境構築簡易版]
===インストール===
====[Android SDKのインストール] [SDKのインストール]====
*[Android SDKのインストール] [SDKのインストール]
====SDK Manager に APIの一覧が表示されない場合====
*Tools - Options からForce にチェックを入れ、HTTP接続を可能にする
[[File:0161_android_sdk_manager.jpg]]
====[Android ADT Eclipse プラグイン] [ADT Eclipse プラグイン]====
*[Android ADT Eclipse プラグイン] [ADT Eclipse プラグイン]
===環境構築手順===
====[http://typea.info/blg/glob/2010/12/android-1-javasdkeclipse.html JDKのインストールから、Eclipse の日本語化まで]====
*[http://typea.info/blg/glob/2010/12/android-1-javasdkeclipse.html JDKのインストールから、Eclipse の日本語化まで]
====[http://typea.info/blg/glob/2010/12/android-2-1.html SDKのインストールから、エミュレータの作成まで]====
*[http://typea.info/blg/glob/2010/12/android-2-1.html SDKのインストールから、エミュレータの作成まで]
====[http://typea.info/blg/glob/2010/12/android-3-adb.html 実機デバッグ(ADBドライバのインストール)]====
*[http://typea.info/blg/glob/2010/12/android-3-adb.html 実機デバッグ(ADBドライバのインストール)]
*[http://typea.info/blg/glob/2012/07/htc-j-android.html 実機デバッグ(HTC J)]
*[http://typea.info/blg/glob/2014/01/windows-8-android.html 実機デバッグ(Windows8)]
====[http://typea.info/blg/glob/2010/12/eclipse-git.html Eclipse Git プラグインの導入]====
*[http://typea.info/blg/glob/2010/12/eclipse-git.html Eclipse Git プラグインの導入]
====[http://typea.info/blg/glob/2011/01/android-eclipsesdk.html Eclipse プロジェクトの作成とSDKソースコードをEclipseから閲覧可能に]====
*[http://typea.info/blg/glob/2011/01/android-eclipsesdk.html Eclipse プロジェクトの作成とSDKソースコードをEclipseから閲覧可能に]
====[http://typea.info/blg/glob/2011/05/ubuntu-android.html Ubuntuに開発環境を構築]====
*[http://typea.info/blg/glob/2011/05/ubuntu-android.html Ubuntuに開発環境を構築]
====[http://typea.info/blg/glob/2011/11/ubuntu-android-adt-svn.html UbuntuでADTプラグインインストールエラー]====
*[http://typea.info/blg/glob/2011/11/ubuntu-android-adt-svn.html UbuntuでADTプラグインインストールエラー]
====Ubuntu ADBドライバに実機を認識させる====
*[http://typea.info/blg/glob/2011/05/ubuntu-android.html ???? と認識されてしまう解決法]
*[http://typea.info/blg/glob/2014/01/ubuntu-1310-64bit-adtadb-android.html 64bit でADBドライバが利用できない解決法]
==開発環境==
===GAE===
[http://typea.info/blg/glob/2010/08/android_gae_windows7.html Android (実機) と GAE を連携させるためのデバッグ環境を Windows7 に構築する]
===SDK ソースコード===
=====[CentOS 初期設定] [Gitのインストール(Linux)]=====
# git clone git://android.git.kernel.org/platform/frameworks/base.git
=====ブラウズ=====
*http://android.git.kernel.org/
**[http://android.git.kernel.org/?p=platform/frameworks/base.git;a=tree;f=core/java/android;h=67060e03dddf2bb4fc9b98fd9aaf24a5722f7369;hb=HEAD projects / platform/frameworks/base.git / tree]
=====Eclipse=====
*[http://typea.info/blg/glob/2011/01/android-eclipsesdk.html Eclipse から使用可能にする手順]
===Eclipse 3.6.1 のコード補完で固まる対処===
*[http://d.hatena.ne.jp/goriponsoft/20110210/1297305320 Eclipse 3.6のコード補完のフリーズを解消する]
=====以下のパッチをEclipseにあてる(解凍して上書き)=====
*[http://adt-addons.googlecode.com/svn/patches/org.eclipse.jdt.core_3.6.1.v_A68_R36x.zip org.eclipse.jdt.core_3.6.1.v_A68_R36x.zip]
==エミュレータ==
===起動時の実際のサイズを指定する===
#AVD Manager から、Start the selected AVD を選択
#表示されたダイアログの Scale display to real size をチェック
#screen size にインチサイズを設定
[[File:0160_android_emu.png]]
==画面==
===画面モード(縦、横)が変わらないように設定===
http://www.hakkaku.net/articles/20090831-579
*XML の manifest/application/activity の属性、android:screenOrientation を、"portrait" に設定すると、縦画面のまま回転しなくなります。
=====設定値=====
*"portrait" … 縦画面で固定
*"landscape" … 横画面で固定
*"unspecified" … デバイス任せ
===画面モード(縦、横)が変わる、変わらないを動的に変更===
*http://319ring.net/blog/archives/1502
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);
}
*逆向きにも対応版
* // @see http://stackoverflow.com/questions/2366706/how-to-lock-orientation-during-runtime
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について===
*[http://android.siprop.org/index.php?plugin=attach&pcmd=open&file=AndroidUI_20090912.pdf&refer=%B5%BB%BD%D1%BB%F1%CE%C1 Android UI]
*[http://www.pixel-arms.com/2009/04/how_to_make_android_icon/ Android風のアイコンを作成する方法]
===設定画面を作成する===
*[http://typea.info/blg/glob/2010/10/android-android-hacks.html 設定画面を作成する]
===スタイル===
*[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が自動起動してしまうのを抑制===
*http://goo.gl/LeFOK
@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 ウィジェットの作り方===
*[http://typea.info/blg/glob/2012/05/android-app.html App ウィジェットの作り方]
*[http://typea.info/blg/glob/2012/05/android-app-1.html ボタンを押した処理を実装]
*[http://typea.info/blg/glob/2012/05/android-10.html アプリに組み込む]
==イベント==
===EditTextの変更を検知===
=====[http://developer.android.com/reference/android/widget/TextView.html#addTextChangedListener(android.text.TextWatcher) 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);
}
==ダイアログ==
===確認ダイアログ===
*http://developer.android.com/guide/topics/ui/dialogs.html
=====ファイル削除確認=====
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();
}
===プログレスダイアログ===
*[http://typea.info/blg/glob/2011/05/android-asynctaskprogressdialog.html 非同期処理をAsyncTaskを使って行い進捗をProgressDialogに表示する]
===カスタムダイアログ===
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);
===[http://typea.info/blg/glob/2010/09/androidx06ht-desire-activity-activity.html Activity の状態を一時的に保存する]===
[http://typea.info/blg/glob/2010/09/androidx06ht-desire-activity-activity.html Activity の状態を一時的に保存する]
===[http://android.siprop.org/index.php?%CA%D9%B6%AF%B2%F1%2FAndroid%20SDK%20WG%20%C2%E81%B2%F3%20%A5%BB%A5%C3%A5%B7%A5%E7%A5%F3%A1%CA2008.10.25%A1%CB コンフィグレーション]===
*デバイスのコンフィグレーションが変更されたら、UIはそのコンフィグレーションにマッチするように更新する必要があるため、Activitiは再スタートされる
*コンフィグレーションの変更があってもActivityの再スタートを避けたい場合、マニフェストにandroid:configChanges属性を追加
android:configChanges="locale|orientation|"
===[http://typea.info/blg/glob/2010/09/android-arrayadapter.html ArrayAdapter に ラジオボタンを置く]===
[http://typea.info/blg/glob/2010/09/android-arrayadapter.html ArrayAdapter に ラジオボタンを置く]
===TabActivity(タブによるアクティビティ切り替え) サンプル===
[http://typea.info/blg/glob/2010/11/android-tabactivity.html TabActivity]
===ListActivity(リスト表示画面)サンプル===
[Android スケルトン ListActivity] [ListActivity]
===PreferenceActivity(設定画面の作成) サンプル===
[http://typea.info/blg/glob/2010/10/android-android-hacks.html PreferenceActivity]
===透明なActivityを作成する===
*http://stackoverflow.com/questions/2176922/how-to-create-transparent-activity-in-android
====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() を利用する
==非同期処理==
*[http://typea.info/blg/glob/2014/02/android-asynctask.html AsyncTaskを使う]
==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のスクロールバーを大きくする===
*[http://typea.info/blg/glob/2012/02/android-8.html ListViewのスクロールバーを大きくする]
===ListViewのコンテキストメニュー選択時にアイテムを取り出す===
[http://typea.info/blg/glob/2012/02/android-8.html ListViewのコンテキストメニュー選択時にアイテムを取り出す]
===カスタムViewを利用する===
*http://developer.android.com/guide/topics/ui/custom-components.html
<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);
}
}
===ページめくり===
[http://typea.info/blg/glob/2010/07/androidx06ht_desire_2.html ページをめくるサンプル]
===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;
}
}
===ダイアログボックス===
*[http://typea.info/blg/glob/2010/07/android-x06ht-desire-1.html 入力ダイアログ、確認ダイアログを共通化]
==検索==
===[Android 検索インターフェースの作成] [検索インターフェースの作成]===
==ContentProvider==
===連絡先の取得と電話をかける===
*[http://typea.info/blg/glob/2010/06/androidx06ht-desire-1.html Android(X06HT Desire) 連絡先の取得と電話をかけるサンプル]
==プロパティ==
===単行===
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 と連携する===
*[http://typea.info/blg/glob/2011/02/android-intent-twitter-evernote.html 暗黙的 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);
===ブロードキャストされたインテントを受け取る===
*[http://typea.info/blg/glob/2011/12/android-7.html ブロードキャストされたインテントを受け取る]
==トースト==
====トーストをカスタマイズして吹き出しをつくる====
*http://typea.info/blg/glob/2013/07/-android-001.html
==ノーティフィケーション==
===起動しているActivityを全面に表示させる===
*http://blog.livedoor.jp/ss_9/archives/1745734.html?ignore_lite
=====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);
}
}
==パーミッション==
*http://developer.android.com/reference/android/Manifest.permission.html
===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が解析されない
*http://stackoverflow.com/questions/4414389/android-xml-percent-symbol
*formatted="false" を指定する
=====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を発行===
*http://typea.info/blg/glob/2012/01/android-sqlite-sql.html
**エミュレータを使用する
**コマンドプロンプトのフォントおよび文字コードを変更する
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===
*[http://typea.info/blg/glob/2011/03/android-bitmapcreatebitmap-outofmemory.html Bitmap.createBitmap で OutOfMemory]
==アイコン==
====[http://typea.info/blg/glob/2012/03/android-9.html ランチャーアイコンガイドライン]====
*[http://typea.info/blg/glob/2012/03/android-9.html ランチャーアイコンガイドライン]
==描画==
===画面サイズの取得===
*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);
*http://wikiwiki.jp/android/?%A5%C6%A5%AD%A5%B9%A5%C8%A4%CE%C9%C1%B2%E8(FontMetrics)
[[File: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);
==デバッグ==
===テスト===
*[Android Activity の テスト] [Activity の テスト]
*[http://typea.info/blg/glob/2011/01/android-eclipse.html Activity の テスト2]
===実機でデバッグ===
*[http://typea.info/blg/glob/2010/06/android_x06ht_desire.html 実機(X06HT Desire)デバッグ]
*[http://typea.info/blg/glob/2010/08/android-2.html デバッグ中か否かを判定する]
*[http://typea.info/blg/glob/2010/09/android-x06ht-desire-windows-xp-adb.html Windows XP にてADBドライバを認識しない場合の対応]
*AndroidManifest.xml Debuggable = true
===UbuntuでデバイスIDが????と表示され実機デバッグできない===
[[File:0158_android-sdk07.png]]
*http://developer.android.com/guide/developing/device.html#setting-up
*http://developer.android.com/guide/developing/device.html#VendorIds
=====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
[[File: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
[[File:0163_traceview01.jpg]]
===スクリーンキャプチャ===
*Android Eclipse から スクリーンキャプチャを取る
===カメラアプリで、FileNotFoundException===
*http://www.bpsinc.jp/blog/archives/date/2010/05/08
<blockquote>カメラアプリで、FileNotFoundException /sys/android_camera2/htcwc が発生したら、端末の再起動を行う。</blockquote>
===SDKソースコードのステップ実行===
*[http://typea.info/blg/glob/2011/01/android-eclipsesdk.html Eclipse からSDKソースコードのステップ実行]
==入力==
===IME ソフウェアキーボードを消す===
public void onClick(View v) {
// ボタンを押したら、ソフウェアキーボードを消す
InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
}
===マルチタッチ(ピンチ)===
*[http://typea.info/blg/glob/2010/08/androidx06ht-desire-3.html ピンチイン・ピンチアウトのサンプル]
==センサー==
===搭載センサーの値を取得===
*[http://typea.info/blg/glob/2010/05/android-1.html エミュレータのセンサーの値を取得してみる]
*[http://typea.info/blg/glob/2010/06/androidx06ht-desire.html Android(X06HT Desire) 搭載センサーの値を取得してみる]
==バイブレーター==
=====宣言=====
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>
====[http://typea.info/blg/glob/2010/10/android-x06ht-desire-2.html カメラプレビューが横向きに表示されてしまう!の対応]====
*[http://typea.info/blg/glob/2010/10/android-x06ht-desire-2.html カメラプレビューが横向きに表示されてしまう!の対応]
====[http://typea.info/blg/glob/2011/04/android-5.html カメラプレビューを縦向きにすると画面描画の座標が訳わからなくなる対応]====
上記を行うと、Viewに描画するときに座標が混乱してしまう対応。
*[http://typea.info/blg/glob/2011/04/android-5.html カメラプレビューを縦向きにすると画面描画の座標が訳わからなくなる対応]
==サウンド==
===ハードウェアから、音量を制御===
*[http://typea.info/blg/glob/2010/06/androidx06ht_desire_1.html サンプルソース]
*ハードウェアから、音量を制御させるには、以下の記述が必要
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;
}
===ヘッドフォント着脱を検知する===
*[http://typea.info/blg/glob/2011/12/android-7.html ヘッドフォント着脱を検知する]
==電源管理==
===スリープ状態からの復帰、キーロック解除===
*http://d.hatena.ne.jp/siso9to/touch/20110212/1297540035
=====例=====
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
#/res/anim フォルダを作成
#anim フォルダでコンテキストメニューから import し適用
ViewFlipper vf = (ViewFlipper) findViewById(R.id.details);
vf.setAnimation(AnimationUtils.loadAnimation(this, R.anim.push_left_in));
==非同期処理==
===[http://typea.info/blg/glob/2011/05/android-asynctaskprogressdialog.html 非同期処理をAsyncTaskを使って行い進捗をProgressDialogに表示する]===
*[http://typea.info/blg/glob/2011/05/android-asynctaskprogressdialog.html 非同期処理をAsyncTaskを使って行い進捗をProgressDialogに表示する]
==Web==
===Httpクライアントタイムアウトを設定する===
[http://typea.info/blg/glob/2010/09/android-http.html 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マルチパートでファイルをアップロードする===
=====以下を入手=====
*[http://james.apache.org/download.cgi#Apache_Mime4J apache-mime4j]
*[http://hc.apache.org/downloads.cgi httpclient]
*[http://hc.apache.org/downloads.cgi httpcore]
*[http://hc.apache.org/downloads.cgi httpmime]
<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の使い方(吹き出しをつくる)====
*http://typea.info/blg/glob/2013/07/-android-001.html
==Dropbox==
*[http://typea.info/blg/glob/2012/06/android-dropbox.html Dropbox アプリを作成する]
*[http://typea.info/blg/glob/2012/06/dropbox-android.html Dropbox アプリを公開する]
==NDK==
*[http://typea.info/blg/glob/2012/02/android-ndk.html ネイティブライブラリを利用するため NDK を設定する]
==Google App Engine==
===開発環境の構築===
*[http://typea.info/blg/glob/2010/08/android-gae-windows7.html Android (実機) と GAE を連携させるためのデバッグ環境を Windows7 に構築]
===Google アカウントの利用===
*[http://typea.info/blg/glob/2010/08/android_google_gae.html Android アプリから Google アカウントを利用して GAE アプリケーションを利用する]
*[http://typea.info/blg/glob/2010/09/android-gae.html Android アプリから、GAE 開発サーバーのアカウントを利用]
*[http://typea.info/blg/glob/2011/04/android-googlegaeserver-error.html Android からGoogleアカウント認証でGAEアクセスするとServer Error になってしまう]
==ライブラリ==
*http://qiita.com/KeithYokoma/items/fb6872a72a75e9b6f2e6
===チャート===
*https://code.google.com/p/achartengine/
===UI===
====カードUI====
*https://github.com/gabrielemariotti/cardslib
===画像===
====読み込み・キャッシュ====
*https://github.com/nostra13/Android-Universal-Image-Loader
==広告==
===[Android AdMob] [AdMob]===
**[Android AdMob] [AdMob]
==公開==
===Android マーケット===
*[http://typea.info/blg/glob/2010/07/android-1.html Android マーケットに開発者登録]
===SDカードにインストールを許可===
*AndroidManifest.xml に installLocation を指定 (Android SDK 2.2から対応)
android:installLocation="auto"
{|class="wikitable"
!値
!内容
|-
|internalOnly
|内蔵メモリへのインストールのみ許可
|-
|auto
|内蔵メモリ優先
|-
|preferExternal
|SDカードを優先
|-
|}
===アプリ内課金===
*[http://typea.info/blg/glob/2014/03/android-11.html アプリ内課金手順]
==トラブルシュート==
===Error generating final archive: Debug certificate expired on エラーでコンパイルできない===
*http://android.roof-balcony.com/debug/certificate-expired/
#ユーザーディレクトリの、.android/debug.keystore ファイルを削除
#プロジェクトのクリーン
===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