<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-5859951453664122203</id><updated>2012-02-01T12:47:50.688+09:00</updated><category term='つぶやき'/><category term='Geo'/><category term='GWT'/><category term='ADK'/><category term='vcard'/><category term='Google TV'/><category term='Gimp'/><category term='Amazon'/><category term='NFC'/><category term='VirtualBox'/><category term='device'/><category term='Hanycomb'/><category term='uPhyca'/><category term='AppEngine'/><category term='日記'/><category term='Google Books Search API'/><category term='記事'/><category term='Test'/><category term='本'/><category term='Froyo'/><category term='イベント'/><category term='Libraroid'/><category term='女子部'/><category term='python'/><category term='Google API'/><category term='Hudson'/><category term='GDD'/><category term='Inkscape'/><category term='Android'/><category term='Google I/O'/><category term='ecology'/><category term='HTML5'/><category term='ListView'/><category term='linux'/><category term='AIR'/><category term='Google wave'/><category term='adb'/><category term='jQuery Mobile'/><category term='Android App'/><category term='メモ'/><category term='XML'/><category term='Java'/><category term='ICS'/><category term='JavaFX'/><category term='pyROOT'/><category term='Slim3'/><category term='C2DM'/><category term='Corona'/><category term='いろいろ'/><category term='Eclipse'/><category term='Memo'/><category term='モバイルネイティブ'/><category term='design'/><category term='Ubuntu'/><category term='Google Chrome Extension'/><title type='text'>Y.A.M の 雑記帳</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://y-anz-m.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5859951453664122203/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://y-anz-m.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/5859951453664122203/posts/default?start-index=101&amp;max-results=100'/><author><name>yanzm</name><uri>http://www.blogger.com/profile/04059587494895790858</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_HRaLqTNFL7w/TDx6XwqrmDI/AAAAAAAABMo/B1SkSHxhKu4/S220/icon4.JPG'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>484</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-5859951453664122203.post-2490285812079084290</id><published>2012-01-02T18:13:00.000+09:00</published><updated>2012-01-02T18:13:22.405+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Android'/><title type='text'>ColorPicker の Action Provider を作った</title><content type='html'>色選択するための Action Provider を作りました。&lt;br /&gt;&lt;br /&gt;HSV の領域をタッチして色を変えます。SとVはそれぞれの現在値に応じて領域の色が変わるようになっています。&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/--hn7N_SM5Uw/TwFzryVxQ_I/AAAAAAAAFJU/XrF2hqYvFZU/s1600/ColorPickerActionProvider.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="400" width="225" src="http://4.bp.blogspot.com/--hn7N_SM5Uw/TwFzryVxQ_I/AAAAAAAAFJU/XrF2hqYvFZU/s400/ColorPickerActionProvider.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;いつものように github にもおきましたー。&lt;br /&gt;&lt;a href="https://github.com/yanzm/ColorPickerActionProvider"&gt;yanzm/ColorPickerActionProvider - GitHub - &lt;/a&gt;&lt;code name="code" class="java"&gt;public class MainActivity extends Activity {    private int mSelectedColor = Color.BLACK;    @Override    public boolean onCreateOptionsMenu(Menu menu) {        super.onCreateOptionsMenu(menu);        getMenuInflater().inflate(R.menu.menu, menu);        MenuItem item = menu.findItem(R.id.menu_color_picker);        HsvColorActionProvider actionProvider = (HsvColorActionProvider) item.getActionProvider();        actionProvider.setOnColorChangedListener(new HsvColorActionProvider.OnColorChangedListener() {            @Override            public void onColorChanged(int color) {                View v = findViewById(android.R.id.content);                v.setBackgroundColor(color);            }            @Override            public void onColorSelected(int color) {                mSelectedColor = color;                View v = findViewById(android.R.id.content);                v.setBackgroundColor(color);            }            @Override            public void onCanceled() {                View v = findViewById(android.R.id.content);                v.setBackgroundColor(mSelectedColor);            }        });        return true;    }}&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;code name="code" class="java"&gt;public class HsvColorActionProvider extends ActionProvider {    public interface OnColorChangedListener {        public void onColorChanged(int color);        public void onColorSelected(int color);        public void onCanceled();    }    private OnColorChangedListener mListener;    private Context mContext;    private LayoutInflater mLayoutInflater;    private PopupWindow mPopupWindow;    private HsvColorPickerView mColorPicker;    private int mInitialColor;    public HsvColorActionProvider(Context context) {        super(context);        mContext = context;        mInitialColor = Color.HSVToColor(new float[] { 180, 0.7f, 0.8f });        mLayoutInflater = LayoutInflater.from(context);        View v = mLayoutInflater.inflate(R.layout.color_popup, null, false);        mColorPicker = (HsvColorPickerView) v.findViewById(R.id.color_picker);        mColorPicker.showPreview(true);        mColorPicker.setIniticalColor(mInitialColor);        mColorPicker.setOnColorChangedListener(new HsvColorPickerView.OnColorChangedListener() {            @Override            public void onColorChanged(int color, float[] hsv) {                if (mListener != null) {                    mListener.onColorChanged(color);                }            }        });        v.findViewById(R.id.cancel_btn).setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                mPopupWindow.dismiss();                if (mListener != null) {                    mListener.onCanceled();                }            }        });        v.findViewById(R.id.ok_btn).setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                mInitialColor = mColorPicker.getCurrentColor();                if (mListener != null) {                    mListener.onColorSelected(mInitialColor);                }                mPopupWindow.dismiss();            }        });        mPopupWindow = new PopupWindow(v);        mPopupWindow.setBackgroundDrawable(mContext.getResources().getDrawable(R.drawable.panel_bg));        mPopupWindow.setWidth(WindowManager.LayoutParams.WRAP_CONTENT);        mPopupWindow.setHeight(WindowManager.LayoutParams.WRAP_CONTENT);    }    public void setOnColorChangedListener(OnColorChangedListener l) {        mListener = l;    }    @Override    public View onCreateActionView() {        LayoutInflater layoutInflater = LayoutInflater.from(mContext);        final View actionItem = layoutInflater.inflate(R.layout.color_action_provider, null);        ImageButton button = (ImageButton) actionItem.findViewById(R.id.button);        button.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                if (!mPopupWindow.isShowing()) {                    mColorPicker.setIniticalColor(mInitialColor);                    mPopupWindow.showAsDropDown(actionItem);                } else {                    mPopupWindow.dismiss();                }            }        });        return actionItem;    }}&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;code name="code" class="java"&gt;public class HsvColorPickerView extends View {    public interface OnColorChangedListener {        void onColorChanged(int color, float[] hsv);    }    public void setOnColorChangedListener(OnColorChangedListener l) {        mListener = l;    }    /**     * 初期カラーをセットする     *      * @param color     */    public void setIniticalColor(int color) {        mCurrentColor = color;        Color.colorToHSV(mCurrentColor, mCurrentHSV);        invalidate();    }    /**     * 現在の色を返す     *      * @return     */    public int getCurrentColor() {        return mCurrentColor;    }    /**     * プレビューを表示するかどうか     *      * @param show     */    public void showPreview(boolean show) {        mIsShowPreview = show;        updateRectArea();    }    /**     * 色領域の幅をセットする     *      * @param width     */    public void setRectWidth(int width) {        mRectWidth = width;        updateRectArea();    }    /**     * 色領域の高さをセットする     *      * @param height     */    public void setRectHeight(int height) {        mRectHeight = height;        updateRectArea();    }    /**     * 色領域間のギャップをセットする     *      * @param gap     */    public void setRectGap(int gap) {        mRectGap = gap;        updateRectArea();    }    private static final int RECT_WIDTH = 400;    private static final int RECT_HEIGHT = 80;    private static final int RECT_GAP = 20;    private boolean mIsShowPreview = true;    private int mRectWidth = RECT_WIDTH;    private int mRectHeight = RECT_HEIGHT;    private int mRectGap = RECT_GAP;    private OnColorChangedListener mListener;    private int mCurrentColor = Color.RED;    private float[] mCurrentHSV = new float[3];    private Shader mHueShader;    private Shader mSaturationShader;    private Shader mValueShader;    private Paint mHuePaint;    private Paint mValuePaint;    private Paint mSaturationPaint;    private Paint mPreviewPaint;    private Paint mLinePaint;    private Rect mHueRect;    private Rect mSaturationRect;    private Rect mValueRect;    private Rect mPreviewRect;    int[] mHueList;    public HsvColorPickerView(Context c) {        super(c);        init();    }    public HsvColorPickerView(Context context, AttributeSet attrs) {        super(context, attrs);        init();    }    private void init() {        Color.colorToHSV(mCurrentColor, mCurrentHSV);        mHueList = new int[10];        float hue = 0;        for (int i = 0; i &lt; 10; i++) {            mHueList[i] = setHSVColor(hue, 255, 255);            hue += 36;        }        mHuePaint = new Paint(Paint.ANTI_ALIAS_FLAG);        mHuePaint.setStyle(Paint.Style.FILL);        mHuePaint.setStrokeWidth(2);        mValuePaint = new Paint(Paint.ANTI_ALIAS_FLAG);        mValuePaint.setStyle(Paint.Style.FILL);        mValuePaint.setStrokeWidth(2);        mSaturationPaint = new Paint(Paint.ANTI_ALIAS_FLAG);        mSaturationPaint.setStyle(Paint.Style.FILL);        mSaturationPaint.setStrokeWidth(2);        mPreviewPaint = new Paint(Paint.ANTI_ALIAS_FLAG);        mPreviewPaint.setStyle(Paint.Style.FILL);        mPreviewPaint.setStrokeWidth(5);        mLinePaint = new Paint(Paint.ANTI_ALIAS_FLAG);        mLinePaint.setStyle(Paint.Style.FILL);        mLinePaint.setStrokeWidth(5);        mLinePaint.setColor(Color.BLACK);        updateRectArea();    }    private void updateRectArea() {        mHueShader = new LinearGradient(0, 0, mRectWidth, 0, mHueList, null, Shader.TileMode.CLAMP);        mHuePaint.setShader(mHueShader);        if (mIsShowPreview) {            mPreviewRect = new Rect(0, 0, mRectWidth, mRectHeight);            mHueRect = new Rect(0, mRectHeight + mRectGap, mRectWidth, mRectHeight * 2 + mRectGap);            mSaturationRect = new Rect(0, mRectHeight * 2 + mRectGap * 2, mRectWidth, mRectHeight * 3 + mRectGap * 2);            mValueRect = new Rect(0, mRectHeight * 3 + mRectGap * 3, mRectWidth, mRectHeight * 4 + mRectGap * 3);        } else {            mHueRect = new Rect(0, 0, mRectWidth, mRectHeight);            mSaturationRect = new Rect(0, mRectHeight + mRectGap, mRectWidth, mRectHeight * 2 + mRectGap);            mValueRect = new Rect(0, mRectHeight * 2 + mRectGap * 2, mRectWidth, mRectHeight * 3 + mRectGap * 2);        }    }    @Override    protected void onDraw(Canvas canvas) {        // Hue        canvas.drawRect(mHueRect, mHuePaint);        canvas.drawLine(mCurrentHSV[0] * mRectWidth / 360, mHueRect.top, mCurrentHSV[0] * mRectWidth / 360,                mHueRect.bottom, mLinePaint);        // Saturation        int[] mSaturationList = new int[10];        float saturation = 0;        for (int i = 0; i &lt; 10; i++) {            mSaturationList[i] = setHSVColor(mCurrentHSV[0], saturation, mCurrentHSV[2]);            saturation += 0.1;        }        mSaturationShader = new LinearGradient(0, 0, mRectWidth, 0, mSaturationList, null, Shader.TileMode.CLAMP);        mSaturationPaint.setShader(mSaturationShader);        canvas.drawRect(mSaturationRect, mSaturationPaint);        canvas.drawLine(mCurrentHSV[1] * mRectWidth, mSaturationRect.top, mCurrentHSV[1] * mRectWidth,                mSaturationRect.bottom, mLinePaint);        // Value        int[] mValueList = new int[10];        float value = 0;        for (int i = 0; i &lt; 10; i++) {            mValueList[i] = setHSVColor(mCurrentHSV[0], mCurrentHSV[1], value);            value += 0.1;        }        mValueShader = new LinearGradient(0, 0, mRectWidth, 0, mValueList, null, Shader.TileMode.CLAMP);        mValuePaint.setShader(mValueShader);        canvas.drawRect(mValueRect, mValuePaint);        canvas.drawLine(mCurrentHSV[2] * mRectWidth, mValueRect.top, mCurrentHSV[2] * mRectWidth, mValueRect.bottom,                mLinePaint);        if (mIsShowPreview) {            // Preview            mPreviewPaint.setColor(mCurrentColor);            canvas.drawRect(mPreviewRect, mPreviewPaint);        }    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        if (mIsShowPreview) {            setMeasuredDimension(mRectWidth, mRectHeight * 4 + mRectGap * 3);        } else {            setMeasuredDimension(mRectWidth, mRectHeight * 3 + mRectGap * 2);        }    }    private int setHSVColor(float hue, float saturation, float value) {        float[] hsv = new float[3];        hsv[0] = Math.max(0, Math.min(359, hue));        hsv[1] = Math.max(0, Math.min(1, saturation));        hsv[2] = Math.max(0, Math.min(1, value));        return Color.HSVToColor(hsv);    }    @Override    public boolean onTouchEvent(MotionEvent event) {        float x = event.getX();        float y = event.getY();        boolean inHue = mHueRect.contains((int) x, (int) y);        boolean inSaturation = mSaturationRect.contains((int) x, (int) y);        boolean inValue = mValueRect.contains((int) x, (int) y);        switch (event.getAction()) {            case MotionEvent.ACTION_DOWN:            case MotionEvent.ACTION_MOVE:                if (inHue) {                    float unit = x / mRectWidth;                    mCurrentHSV[0] = Math.max(0, Math.min(unit * 360, 359));                    updateCurrentColor();                } else if (inSaturation) {                    mCurrentHSV[1] = Math.max(0, Math.min(x / mRectWidth, 1));                    updateCurrentColor();                } else if (inValue) {                    mCurrentHSV[2] = Math.max(0, Math.min(x / mRectWidth, 1));                    updateCurrentColor();                }                break;        }        return true;    }    private void updateCurrentColor() {        mCurrentColor = Color.HSVToColor(mCurrentHSV);        if (mListener != null) {            mListener.onColorChanged(mCurrentColor, mCurrentHSV);        }        invalidate();    }}&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5859951453664122203-2490285812079084290?l=y-anz-m.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://y-anz-m.blogspot.com/feeds/2490285812079084290/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://y-anz-m.blogspot.com/2012/01/colorpicker-action-provider.html#comment-form' title='1 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5859951453664122203/posts/default/2490285812079084290'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5859951453664122203/posts/default/2490285812079084290'/><link rel='alternate' type='text/html' href='http://y-anz-m.blogspot.com/2012/01/colorpicker-action-provider.html' title='ColorPicker の Action Provider を作った'/><author><name>yanzm</name><uri>http://www.blogger.com/profile/04059587494895790858</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_HRaLqTNFL7w/TDx6XwqrmDI/AAAAAAAABMo/B1SkSHxhKu4/S220/icon4.JPG'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/--hn7N_SM5Uw/TwFzryVxQ_I/AAAAAAAAFJU/XrF2hqYvFZU/s72-c/ColorPickerActionProvider.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5859951453664122203.post-6479695146732481708</id><published>2011-12-17T15:03:00.000+09:00</published><updated>2011-12-17T16:03:47.866+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Android'/><title type='text'>Android 4.0.3 Platform</title><content type='html'>&lt;a href="http://developer.android.com/sdk/android-4.0.3.html"&gt;Android 4.0.3 Platform&lt;/a&gt;を意訳しました。訳が正しくない可能性もあります。正確な内容を理解するには原文を参照してください。&lt;br /&gt;&lt;br /&gt;---&lt;br /&gt;API Level: &lt;span style="font-weight:bold;"&gt;15&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Android 4.0.3 は Android .4x (Ice Cream Sandwich) プラットフォームファミリーのインクリメンタルリリースです。 このリリースには、ユーザーと開発者むけの新しい機能、API の変更、いくつかのバグフィックスが含まれています。&lt;br /&gt;&lt;br /&gt;開発者は Android SDK のコンポーネントとして Android 4.0.3 platform をダウンロードできるようになりました。Android emulator を使って Android 4.0 でのアプリケーションの開発やテストを行うことができます。このプラットフォームには Android library と system image, emulator skin などが含まれていますが、外部のライブラリは含まれていません。&lt;br /&gt;&lt;br /&gt;Android 4.0.3 向けの開発とテストを始めるには、Android SDK Manager を使って自分の SDK にプラットフォームをダウンロードします。より詳しい情報は &lt;a href="http://developer.android.com/sdk/adding-components.html"&gt;Adding SDK Components&lt;/a&gt; を見てください。Android が初めての人は、まず &lt;a href="http://developer.android.com/sdk/index.html"&gt;download the SDK Starter Package&lt;/a&gt; から始めてください。&lt;br /&gt;&lt;br /&gt;ユーザーと開発者向けの新しい機能の概要は &lt;a href="http://developer.android.com/sdk/android-4.0-highlights.html"&gt;Platform Highlights&lt;/a&gt; を見てください。&lt;br /&gt;&lt;br /&gt;---&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;API Overview&lt;/h3&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Social stream API in Contacts Provider&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;ステータスアップデートやチェックインなどのソーシャルストリームデータを使うアプリケーションは各ユーザーのコンタクトにデータを同期したり、各写真といっしょにストリームのアイテムを提供することができるようになりました。&lt;br /&gt;&lt;br /&gt;個々のコンタクトのソーシャルストリームを含むデータベーステーブルは &lt;a href="http://developer.android.com/reference/android/provider/ContactsContract.StreamItems.html"&gt;ContactsContract.StreamItems&lt;/a&gt; によって定義されています。それぞれの Uri はストリームアイテムが所属する &lt;a href="http://developer.android.com/reference/android/provider/ContactsContract.RawContacts.html"&gt;ContactsContract.RawContacts&lt;/a&gt; ディレクトリ内に格納されています。各ソーシャルストリームテーブルは、ストリームアイテムのメタデータ用のいくつかのカラムを含みます。例えば情報元（アバター）を表すアイコンやアイテムのラベル、主なテキストコンテンツ、アイテムについてのコメント（他の人からのレスポンスとか）などです。ストリームに関連する写真は &lt;a href="http://developer.android.com/reference/android/provider/ContactsContract.StreamItemPhotos.html"&gt;ContactsContract.StreamItemPhotos&lt;/a&gt; で定義されるテーブルに格納されます。これあh C&lt;a href="http://developer.android.com/reference/android/provider/ContactsContract.StreamItems.html"&gt;ontactsContract.StreamItems&lt;/a&gt; Uri のサブディレクトリとして利用できます。&lt;br /&gt;&lt;br /&gt;より詳しい情報は &lt;a href="http://developer.android.com/reference/android/provider/ContactsContract.StreamItems.html"&gt;ContactsContract.StreamItems&lt;/a&gt; と &lt;a href="http://developer.android.com/reference/android/provider/ContactsContract.StreamItemPhotos.html"&gt;ContactsContract.StreamItemPhotos&lt;/a&gt; を見てください。&lt;br /&gt;&lt;br /&gt;コンタクトに対してソーシャルストリームアイテムを読み書きするには、アプリケーションはパーミッションをリクエストする必要があります。リクエストするには、マニフェストファイルに &lt;font color=green&gt;&amp;lt;uses-permission android:name="android.permission.READ_SOCIAL_STREAM"&amp;gt;&lt;/font&gt; かつ／または &lt;font color=green&gt;&amp;lt;uses-permission android:name="android.permission.WRITE_SOCIAL_STREAM"&amp;gt;&lt;/font&gt; を宣言します。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Calendar Provider&lt;/b&gt;&lt;ul&gt;&lt;li&gt; &lt;a href="http://developer.android.com/guide/topics/providers/calendar-provider.html"&gt;Calendar Provider&lt;/a&gt; でのカラーテーブルを表す新しいクラス &lt;a href="http://developer.android.com/reference/android/provider/CalendarContract.Colors.html"&gt;CalendarContract.Colors&lt;/a&gt; が追加されました。このクラスは与えられたアカウントで利用出来る色にアクセスするためのフィールドを提供します。色は &lt;a href="http://developer.android.com/reference/android/provider/CalendarContract.ColorsColumns.html#COLOR_KEY"&gt;COLOR_KEY&lt;/a&gt; によってリファレンスされ、与えられたアカウント名／タイプに対してユニークでなければなりません。これらの値は sync adapter によってのみアップデートできます。&lt;li&gt; exchange/sync サポートのための &lt;a href="http://developer.android.com/reference/android/provider/CalendarContract.CalendarColumns.html#ALLOWED_AVAILABILITY"&gt;ALLOWED_AVAILABILITY&lt;/a&gt; と &lt;a href="http://developer.android.com/reference/android/provider/CalendarContract.CalendarColumns.html#ALLOWED_ATTENDEE_TYPES"&gt;ALLOWED_ATTENDEE_TYPES&lt;/a&gt; が追加されました。&lt;li&gt; 参加者用の &lt;a href="http://developer.android.com/reference/android/provider/CalendarContract.AttendeesColumns.html#TYPE_RESOURCE"&gt;TYPE_RESOURCE&lt;/a&gt; (会議室など)、&lt;a href="http://developer.android.com/reference/android/provider/CalendarContract.EventsColumns.html#AVAILABILITY_TENTATIVE"&gt;AVAILABILITY_TENTATIVE&lt;/a&gt;、イベント用の &lt;a href="http://developer.android.com/reference/android/provider/CalendarContract.EventsColumns.html#EVENT_COLOR_KEY"&gt;EVENT_COLOR_KEY&lt;/a&gt; が追加されました。&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Home screen widgets&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Android 4.0 からホームスクリーンウィジェットはもはや自身のパディングを含みません。代わりに現在の画面の特徴に基づいて、現在のシステムが自動的に各ウィジェットにパディングを追加します。これにより、グリッド上のウィジェットにより均一で統一な表現を与えます。ホームスクリーンウィジェットをホストするアプリケーションをアシストするために、プラットフォームは新しいメソッド &lt;a href="http://developer.android.com/reference/android/appwidget/AppWidgetHostView.html#getDefaultPaddingForWidget(android.content.Context, android.content.ComponentName, android.graphics.Rect)"&gt;getDefaultPaddingForWidget()&lt;/a&gt; を提供します。アプリケーションはこのメソッドを呼んでシステムが定義したパディングを取得することができ、ウィジェットに割り当てるセルの数を計算するときにそれを考慮できます。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Spell-checking&lt;/b&gt;&lt;ul&gt;&lt;li&gt; spell-checker サービスにアクセスできるアプリでは、新しい &lt;a href="http://developer.android.com/reference/android/view/textservice/SpellCheckerSession.html#cancel()"&gt;cancel()&lt;/a&gt; メソッドを使ってセッション中で保留されていたり実行されている spell-checker タスクをキャンセルすることができます。&lt;li&gt; spell-checker サービスでは、新しい候補フラグ &lt;a href="http://developer.android.com/reference/android/view/textservice/SuggestionsInfo.html#RESULT_ATTR_HAS_RECOMMENDED_SUGGESTIONS"&gt;RESULT_ATTR_HAS_RECOMMENDED_SUGGESTIONS&lt;/a&gt; によってサービスは低信頼度の候補から高信頼度の候補を区別することができます。例えば、spell-checker はユーザーの辞書にはないが、よく候補が現れる入力ワードにフラグをセットしたり、ユーザーの辞書にないがあまり役立たない候補がでる入力ワードのフラグを外したりできます。&lt;br /&gt;spell-checker に接続したアプリは &lt;a href="http://developer.android.com/reference/android/view/textservice/SuggestionsInfo.html#getSuggestionsAttributes()"&gt;getSuggestionsAttributes()&lt;/a&gt; や &lt;a href="http://developer.android.com/reference/android/view/textservice/SuggestionsInfo.html#getSuggestionsCount()"&gt;getSuggestionsCount()&lt;/a&gt; などの他の候補属性との組み合わせで &lt;a href="http://developer.android.com/reference/android/view/textservice/SuggestionsInfo.html#RESULT_ATTR_HAS_RECOMMENDED_SUGGESTIONS"&gt;RESULT_ATTR_HAS_RECOMMENDED_SUGGESTIONS&lt;/a&gt; フラグを使うことができます。これにより入力ワードをタイポとしてマークし他の候補を出すかどうか決めることができます。&lt;li&gt; text span 用の新しい &lt;a href="http://developer.android.com/reference/android/text/style/SuggestionSpan.html#FLAG_AUTO_CORRECTION"&gt;FLAG_AUTO_CORRECTION&lt;/a&gt; スタイルは、ユーザーがタイピング／編集した文字／テキストに自動修正が適用されたことを表します。このタイプの候補は異なったレンダリングがされ、自動修正が起こったことを示します。&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Bluetooth&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;新しい public メソッド &lt;a href="http://developer.android.com/reference/android/bluetooth/BluetoothDevice.html#fetchUuidsWithSdp()"&gt;fetchUuidsWithSdp()&lt;/a&gt; と &lt;a href="http://developer.android.com/reference/android/bluetooth/BluetoothDevice.html#getUuids()"&gt;getUuids()&lt;/a&gt; によってリモートデバイスによってサポートされている機能 (UUIDs) を決めることができます。&lt;a href="http://developer.android.com/reference/android/bluetooth/BluetoothDevice.html#fetchUuidsWithSdp()"&gt;fetchUuidsWithSdp()&lt;/a&gt; の場合、システムはサポートされている UUIDs を取得するためにリモートデバイス上でサービスディスカバリを実行し、結果を &lt;a href="http://developer.android.com/reference/android/bluetooth/BluetoothDevice.html#ACTION_UUID"&gt;ACTION_UUID&lt;/a&gt; intent として発行します。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;UI toolkit&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;新しいメソッド &lt;a href="http://developer.android.com/reference/android/app/Fragment.html#setUserVisibleHint(boolean)"&gt;setUserVisibleHint()&lt;/a&gt; と &lt;a href="http://developer.android.com/reference/android/app/Fragment.html#getUserVisibleHint()"&gt;getUserVisibleHint()&lt;/a&gt; によってフラグメントは現在ユーザーに見えているかどうかのヒントをセットすることができます。システムは見えているフラグメントの Loader が実行されるまで見えていないフラグメントの開始を遅らせます。見えているかどうかのヒントはデフォルトでは "true" です。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Graphics&lt;/b&gt;&lt;ul&gt;&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/graphics/SurfaceTexture.html"&gt;SurfaceTexture&lt;/a&gt; の新しいメソッド &lt;a href="http://developer.android.com/reference/android/graphics/SurfaceTexture.html#setDefaultBufferSize(int, int)"&gt;setDefaultBufferSize(int, int)&lt;/a&gt; でイメージバッファのデフォルトサイズをセットできます。このメソッドは &lt;a href="http://developer.android.com/reference/android/graphics/Canvas.html"&gt;Canvas&lt;/a&gt; (&lt;a href="http://developer.android.com/reference/android/view/Surface.html#lockCanvas(android.graphics.Rect)"&gt;lockCanvas(Rect)&lt;/a&gt; を介して) や OpenGL ES (EGLSurface を介して) で画像を処理するときに画像サイズをセットするのに使われるでしょう。&lt;li&gt; OpenGL ES 拡張の GL_OES_EGL_image_external の enum の定義が追加されました。 - &lt;a href="http://developer.android.com/reference/android/opengl/GLES11Ext.html#GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES"&gt;GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES&lt;/a&gt;、&lt;a href="http://developer.android.com/reference/android/opengl/GLES11Ext.html#GL_SAMPLER_EXTERNAL_OES"&gt;GL_SAMPLER_EXTERNAL_OES&lt;/a&gt;、&lt;a href="http://developer.android.com/reference/android/opengl/GLES11Ext.html#GL_TEXTURE_BINDING_EXTERNAL_OES"&gt;GL_TEXTURE_BINDING_EXTERNAL_OES&lt;/a&gt;、 &lt;a href="http://developer.android.com/reference/android/opengl/GLES11Ext.html#GL_TEXTURE_EXTERNAL_OES"&gt;GL_TEXTURE_EXTERNAL_OES&lt;/a&gt;。&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Accessibility&lt;/b&gt;&lt;ul&gt;&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/widget/RemoteViews.html"&gt;RemoteViews&lt;/a&gt; のクライアントは &lt;a href="http://developer.android.com/reference/android/widget/RemoteViews.html#setContentDescription(int, java.lang.CharSequence)"&gt;setContentDescription()&lt;/a&gt; を使えるようになりました。これにより、インフレートされたレイアウト上の View に content description をセットすることができます。&lt;li&gt; 新しいメソッド &lt;a href="http://developer.android.com/reference/android/view/accessibility/AccessibilityRecord.html#getMaxScrollX()"&gt;getMaxScrollX()&lt;/a&gt;、&lt;a href="http://developer.android.com/reference/android/view/accessibility/AccessibilityRecord.html#getMaxScrollY()"&gt;getMaxScrollY()&lt;/a&gt;、&lt;a href="http://developer.android.com/reference/android/view/accessibility/AccessibilityRecord.html#setMaxScrollX(int)"&gt;setMaxScrollX()&lt;/a&gt;、&lt;a href="http://developer.android.com/reference/android/view/accessibility/AccessibilityRecord.html#setMaxScrollY(int)"&gt;setMaxScrollY()&lt;/a&gt;を使って、&lt;a href="http://developer.android.com/reference/android/view/accessibility/AccessibilityRecord.html"&gt;AccessobilityRecord&lt;/a&gt; オブジェクトに対する最大のスクロールオフセットを設定したり取得したりできます。&lt;li&gt; touch-exploration モードが有効のとき、新しいセキュア設定 &lt;a href="http://developer.android.com/reference/android/provider/Settings.Secure.html#ACCESSIBILITY_SPEAK_PASSWORD"&gt;ACCESSIBILITY_SPEAK_PASSWORD&lt;/a&gt; は、ハンドセットが使われていなくてもパスワードフィールドに入力されたテキストを IME が読み上げることをユーザーがリクエストしているかどうかを示しています。デフォルトでは、ハンドセットが使われていない場合パスワードテキストは読まれません。&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Text-to-speech&lt;/b&gt;&lt;ul&gt;&lt;li&gt; ネットワークの TTS サポートを調べたり有効にしたりするための新しいメソッド &lt;a href="http://developer.android.com/reference/android/speech/tts/TextToSpeech.html#getFeatures(java.util.Locale)"&gt;getFeatures()&lt;/a&gt; が追加されました。&lt;li&gt; 音声合成エラーの通知を受取るためにエンジンが登録する新しいリスナークラス &lt;a href="http://developer.android.com/reference/android/speech/tts/UtteranceProgressListener.html"&gt;UtteranceProgressListener&lt;/a&gt; が追加されました。&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Database&lt;/b&gt;&lt;ul&gt;&lt;li&gt; Content Provider が cross-process なクエリの結果をより効果的に返せるようにする新しいクラス &lt;a href="http://developer.android.com/reference/android/database/CrossProcessCursorWrapper.html"&gt;CrossProcessCursorWrapper&lt;/a&gt; が追加されました。この新しいクラスはリモートでプロセスに送られる cursor をラップしたブロックを作成するときに便利です。また通常の &lt;a href="http://developer.android.com/reference/android/database/Cursor.html"&gt;Cursor&lt;/a&gt; オブジェクトを &lt;a href="http://developer.android.com/reference/android/database/CrossProcessCursor.html"&gt;CrossProcessCursor&lt;/a&gt; オブジェクトに透過的に変換することもできます。&lt;br /&gt;&lt;a href="http://developer.android.com/reference/android/database/CrossProcessCursorWrapper.html"&gt;CrossProcessCursorWrappter&lt;/a&gt; クラスは Content Provider を実装するときにアプリケーションがよく遭遇する一般的なパフォーマンス問題とバグを解決します。&lt;li&gt; 入力として名前文字列を受取るコンストラクタ &lt;a href="http://developer.android.com/reference/android/database/CursorWindow.html#CursorWindow(java.lang.String)"&gt;CursorWindow(String)&lt;/a&gt; が追加されました。システムはもはやローカルとリモートの cursor window を区別しません。そのため &lt;a href="http://developer.android.com/reference/android/database/CursorWindow.html#CursorWindow(boolean)"&gt;CursorWindow(boolean)&lt;/a&gt; は無効になりました。&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Intents&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;デバイス上のアプリケーションのタイプを指定するための新しいカテゴリ（&lt;a href="http://developer.android.com/reference/android/content/Intent.html#CATEGORY_APP_BROWSER"&gt;CATEGORY_APP_BROWSER&lt;/a&gt; や &lt;a href="http://developer.android.com/reference/android/content/Intent.html#CATEGORY_APP_CALENDAR"&gt;CATEGORY_APP_CALENDAR&lt;/a&gt; や &lt;a href="http://developer.android.com/reference/android/content/Intent.html#CATEGORY_APP_MAPS"&gt;CATEGORY_APP_MAPS&lt;/a&gt; など）が追加されました。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Camera&lt;/b&gt;&lt;ul&gt;&lt;li&gt; アプリのアクセスが、画像やビデオの位置情報を取得できるように、&lt;a href="http://developer.android.com/reference/android/media/MediaMetadataRetriever.html"&gt;MediaMetadataRetriever&lt;/a&gt; に新しい定数 &lt;a href="http://developer.android.com/reference/android/media/MediaMetadataRetriever.html#METADATA_KEY_LOCATION"&gt;METADATA_KEY_LOCATION&lt;/a&gt; が追加されました。&lt;li&gt; ComcorderProfile に QVGA (320x240) 解像度プロファイルが追加されました。このクオリティレベルは &lt;a href="http://developer.android.com/reference/android/media/CamcorderProfile.html#QUALITY_QVGA"&gt;QUALITY_QVGA&lt;/a&gt; および &lt;a href="http://developer.android.com/reference/android/media/CamcorderProfile.html#QUALITY_TIME_LAPSE_QVGA"&gt;QUALITY_TIME_LAPSE_QVGA&lt;/a&gt; 定数が表しています。&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/hardware/Camera.html"&gt;Camera&lt;/a&gt; で、ビデオの安定度をチェックしたり管理したりするための新しいメソッド &lt;a href="http://developer.android.com/reference/android/hardware/Camera.Parameters.html#setVideoStabilization(boolean)"&gt;setVideoStabilization()&lt;/a&gt;、&lt;a href="http://developer.android.com/reference/android/hardware/Camera.Parameters.html#getVideoStabilization()"&gt;getVideoStabilization()&lt;/a&gt;、&lt;a href="http://developer.android.com/reference/android/hardware/Camera.Parameters.html#isVideoStabilizationSupported()"&gt;isVideoStabilizationSupported()&lt;/a&gt; が追加されました。&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Permissions&lt;/b&gt;新しいパーミッションが追加されました。&lt;ul&gt;&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/Manifest.permission.html#READ_SOCIAL_STREAM"&gt;READ_SOCIAL_STREAM&lt;/a&gt; と &lt;a href="http://developer.android.com/reference/android/Manifest.permission.html#WRITE_SOCIAL_STREAM"&gt;WRITE_SOCIAL_STREAM&lt;/a&gt; : 共有されている Contacts Provider 内の連絡先にソーシャルストリームデータを読み書きするための sync adapter を許可します。&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5859951453664122203-6479695146732481708?l=y-anz-m.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://y-anz-m.blogspot.com/feeds/6479695146732481708/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://y-anz-m.blogspot.com/2011/12/android-403-platform.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5859951453664122203/posts/default/6479695146732481708'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5859951453664122203/posts/default/6479695146732481708'/><link rel='alternate' type='text/html' href='http://y-anz-m.blogspot.com/2011/12/android-403-platform.html' title='Android 4.0.3 Platform'/><author><name>yanzm</name><uri>http://www.blogger.com/profile/04059587494895790858</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_HRaLqTNFL7w/TDx6XwqrmDI/AAAAAAAABMo/B1SkSHxhKu4/S220/icon4.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5859951453664122203.post-2941166261042993408</id><published>2011-12-09T18:08:00.001+09:00</published><updated>2011-12-09T18:31:54.687+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ADK'/><category scheme='http://www.blogger.com/atom/ns#' term='Android'/><title type='text'>Android　ADKを使ってバルスって言ったら青色LEDが光るようにしてみた。</title><content type='html'>今日の21時から「天空の城ラピュタ」が放送されるので、TLがバルスで盛り上がって楽しかったので作ってみましたw&lt;br /&gt;&lt;br /&gt;RecognizerIntent を使って認識した文字がバルスだったら ADK で LED をつけてるだけです。&lt;br /&gt;RecognizerIntent については adakoda 先生のサイト &lt;a href="http://www.adakoda.com/android/000164.html"&gt;音声認識(RecognizerIntent)を使用するには - 逆引きAndroid入門 -&lt;/a&gt;を参考にしました。&lt;br /&gt;いつもありがとうございます。&lt;br /&gt;&lt;br /&gt;Android アプリから LED の ON/OFF を切り替える方法は前回のエントリ（&lt;a href="http://y-anz-m.blogspot.com/2011/12/androidhello-adk.html"&gt;Android　Hello ADK をつくった！&lt;/a&gt;）をみてください。&lt;br /&gt;&lt;br /&gt;&lt;iframe width="420" height="243" src="http://www.youtube.com/embed/-AiPcLrnQJg" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;br /&gt;やってみたい人は GitHub においたのでどうぞ。&lt;br /&gt;&lt;a href="https://github.com/yanzm/SayBalus"&gt;yanzm/SayBalus - GitHub -&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5859951453664122203-2941166261042993408?l=y-anz-m.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://y-anz-m.blogspot.com/feeds/2941166261042993408/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://y-anz-m.blogspot.com/2011/12/androidadkled.html#comment-form' title='1 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5859951453664122203/posts/default/2941166261042993408'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5859951453664122203/posts/default/2941166261042993408'/><link rel='alternate' type='text/html' href='http://y-anz-m.blogspot.com/2011/12/androidadkled.html' title='Android　ADKを使ってバルスって言ったら青色LEDが光るようにしてみた。'/><author><name>yanzm</name><uri>http://www.blogger.com/profile/04059587494895790858</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_HRaLqTNFL7w/TDx6XwqrmDI/AAAAAAAABMo/B1SkSHxhKu4/S220/icon4.JPG'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://img.youtube.com/vi/-AiPcLrnQJg/default.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5859951453664122203.post-1197988179410667575</id><published>2011-12-08T18:02:00.001+09:00</published><updated>2011-12-09T18:32:07.469+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ADK'/><category scheme='http://www.blogger.com/atom/ns#' term='Android'/><title type='text'>Android　Hello ADK つくった！</title><content type='html'>&lt;div&gt;DemoKit を動かしてみたよエントリや、Arduino で ADK 自作したよエントリはあるのに、Android ADK 用の Android アプリのプログラミングについて初心者向けに書かれたエントリがぜーんぜんなかったので書くことにしました。&lt;br /&gt;&lt;br /&gt;ちなみにわたくし、電子工作ブランク10年くらいです。10年前にブレッドボード上にケーブルが空中回廊みたいになった電卓を作って以来です。&lt;br /&gt;&lt;br /&gt;今回は USB Accessory モードの方についてです。&lt;br /&gt;公式ドキュメントはこちら&lt;br /&gt;&lt;a href="http://developer.android.com/guide/topics/usb/accessory.html"&gt;http://developer.android.com/guide/topics/usb/accessory.html&lt;/a&gt;&lt;br /&gt;私のブログでの和訳はこちら&lt;br /&gt;&lt;a href="http://y-anz-m.blogspot.com/2011/05/usb-accessory.html"&gt;http://y-anz-m.blogspot.com/2011/05/usb-accessory.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;さて、とりあえず開発環境の準備。&lt;br /&gt;DemoKit 動かしてみたよエントリがたくさんあるのでその辺りみればだいたい書いてると思う。&lt;br /&gt;ちなみに公式ドキュメントはこちら。&lt;br /&gt;&lt;a href="http://developer.android.com/guide/topics/usb/adk.html"&gt;Android Open Accessory Development Kit | Android Developers&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;これの &lt;a href="http://developer.android.com/guide/topics/usb/adk.html#getting-started"&gt;Getting Started with the ADK&lt;/a&gt; を見ながら（私のブログでの和訳はこちら &lt;a href="http://y-anz-m.blogspot.com/2011/05/android-open-accessory-development-kit.html"&gt;http://y-anz-m.blogspot.com/2011/05/android-open-accessory-development-kit.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.arduino.cc/en/Main/software"&gt;Arduino Software&lt;/a&gt; : ADK は Arduino がベースになっているので、ADK で動かすプログラムは Arduino で書く。そのための IDE。コーディングは持ちろん、デバッグやファームインストールもこれで行う。&lt;li&gt;&lt;a href="http://www.arduino.cc/playground/Main/CapSense"&gt;CapSence library&lt;/a&gt; : 人間の静電容量を感知するためのライブラリ。DemoKit の Android シールドにあるタッチセンサーの為に必要。これいれないとタッチセンサーを触っても DemoKit アプリ側で反応しない。&lt;li&gt;&lt;a href="https://dl-ssl.google.com/android/adk/adk_release_0512.zip"&gt;The ADK package&lt;/a&gt; : ADK board 用のファームウェアおよび ADK board とシールド用の hardware design files。&lt;/ul&gt;&lt;br /&gt;をまずはとってきて、ドキュメントの手順通りにセットアップする。&lt;br /&gt;&lt;br /&gt;で、DemoKit を動かす。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;さて、ここまではできるよ。手順通りにやればいいだけだからね。&lt;br /&gt;でもさ、DemoKit 取り外して、アクセサリに LED 1個つなげて光らせるだけでも自分だけでやれって言われると、&lt;br /&gt;はて、どうしたら、、、？ってなるのですよ。&lt;br /&gt;&lt;br /&gt;とりあえず DemoKit のコード見るよねー。&lt;br /&gt;アクセサリ側はまだいいんだけど、Android アプリ側がすごく複雑。。。&lt;br /&gt;とりあえず LED を on/off するだけの最小構成が知りたいのに操作できる項目が多い（DemoKit では入力としてリレー、3色LEDx3。出力としてジョイスティック、ボタン、タッチセンサー、温度、湿度がある）のでレイアウトも複雑だし、クラスも多い。。。。&lt;br /&gt;&lt;br /&gt;やはりここは HelloWorld ならぬ HelloADK が必要なのでは。&lt;br /&gt;&lt;br /&gt;ということでつくりましたよっと。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;1. Android app&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;まずは Android アプリ側から。&lt;br /&gt;&lt;br /&gt;&lt;b&gt;注意点: Build Target は 2.3.3 (API Level 10) の Google APIs にする。&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;USB Accessory モードはもともと USB Host と同じく Android 3.0 からサポートされたものなのですが、Android 2.3.4 にバックポートされています。このバックポートを使うには 2.3.3 の Google APIs を指定する必要があります！&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-84Xi9CMmJrw/TuCEtORMuSI/AAAAAAAADoo/rDYWjLzjR6s/s1600/Screen%2BShot%2B2011-12-08%2Bat%2B6.26.29%2BPM.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="400" width="368" src="http://3.bp.blogspot.com/-84Xi9CMmJrw/TuCEtORMuSI/AAAAAAAADoo/rDYWjLzjR6s/s400/Screen%2BShot%2B2011-12-08%2Bat%2B6.26.29%2BPM.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;LED を on / off するだけなんでレイアウトはトグルボタン1個でいいよね。&lt;br /&gt;ADK に接続してるかどうかのステータスも出すようにしよう。&lt;br /&gt;&lt;br /&gt;&lt;code name="code" class="xml"&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;&amp;lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="fill_parent"    android:layout_height="fill_parent"    android:gravity="center"    android:orientation="vertical" &amp;gt;    &amp;lt;TextView        android:id="@+id/status"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_margin="10dip" /&amp;gt;    &amp;lt;ToggleButton        android:id="@+id/toggleBtn"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_margin="10dip" /&amp;gt;    &amp;lt;TextView        android:id="@+id/ledState"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_margin="10dip" /&amp;gt;&amp;lt;/LinearLayout&amp;gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;では肝心の Activity 側。まずは　&lt;a href="http://developer.android.com/reference/android/hardware/usb/UsbManager.html"&gt;UsbManager&lt;/a&gt; のインスタンスを取得します。&lt;br /&gt;Add-on library （つまり 2.3.4 にバックポートされたライブラリ）を使っている場合は&lt;br /&gt;&lt;code name="code" class="java"&gt;UsbManager manager = UsbManager.getInstance(this);&lt;/code&gt;&lt;br /&gt;3.0 以降のプラットフォーム標準の API を使う場合は&lt;br /&gt;&lt;code name="code" class="java"&gt;UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE);&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;流れ的には&lt;br /&gt;&lt;br /&gt;onCreate()&lt;br /&gt;　・UsbManager の取得&lt;br /&gt;　・オレオレIntent action でパーミッション依頼用の &lt;br /&gt;　　PendingIntent 作成&lt;br /&gt;　・オレオレIntent action とアクセサリが外されたときの &lt;br /&gt;　　BroadcastReceiver 登録&lt;br /&gt;　・画面のセットアップ&lt;br /&gt;&lt;br /&gt;onResume()&lt;br /&gt;　・USBAccessory の一覧を取得して、権限チェック。&lt;br /&gt;　　あればアクセサリとの接続を開く&lt;br /&gt;　　（UsbAccessory からファイルデスクリプタを取得し&lt;br /&gt;　　　ファイルデスクリプタから入出力用の Stream を取得。&lt;br /&gt;　　　入力を受け取るためのスレッドを開始）&lt;br /&gt;　　、なければパーミッションを依頼&lt;br /&gt;&lt;br /&gt;onPause()&lt;br /&gt;　・アクセサリとの接続閉じる&lt;br /&gt;&lt;br /&gt;onDestroy()&lt;br /&gt;　・onCreate() で登録した BroadcastReceiver 解除&lt;br /&gt;&lt;br /&gt;・View が操作されたら出力用ストリームにバイト列書き込む。&lt;br /&gt;・入力受け取り用スレッドでバイト列受け取ったらUIスレッドに渡してViewに反映&lt;br /&gt;&lt;br /&gt;こんな感じかな。あとは、コメントみてくれ。&lt;br /&gt;&lt;br /&gt;&lt;code name="code" class="java"&gt;public class MainActivity extends Activity implements Runnable {    private static final String TAG = "HelloLED";    private static final String ACTION_USB_PERMISSION = "com.uphyca.android.app.helloled.action.USB_PERMISSION";    private PendingIntent mPermissionIntent;    private boolean mPermissionRequestPending;    private UsbManager mUsbManager;    private UsbAccessory mAccessory;    ParcelFileDescriptor mFileDescriptor;    FileInputStream mInputStream;    FileOutputStream mOutputStream;        private ToggleButton mToggleButton;    private TextView mLedStatusView;    private TextView mStatusView;    private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {        @Override        public void onReceive(Context context, Intent intent) {            String action = intent.getAction();            if (ACTION_USB_PERMISSION.equals(action)) {                synchronized (this) {                    // Intent からアクセサリを取得                    UsbAccessory accessory = UsbManager.getAccessory(intent);                    // パーミッションがあるかチェック                    if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {                        // 接続を開く                        openAccessory(accessory);                    } else {                        Log.d(TAG, "permission denied for accessory " + accessory);                    }                    mPermissionRequestPending = false;                }            } else if (UsbManager.ACTION_USB_ACCESSORY_DETACHED.equals(action)) {                // Intent からアクセサリを取得                UsbAccessory accessory = UsbManager.getAccessory(intent);                if (accessory != null &amp;&amp; accessory.equals(mAccessory)) {                    // 接続を閉じる                    closeAccessory();                }            }        }    };    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        // UsbManager のインスタンスを取得        mUsbManager = UsbManager.getInstance(this);        // オレオレパーミッション用 Broadcast Intent        mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);        // オレオレパーミッション Intent とアクセサリが取り外されたときの Intent を登録        IntentFilter filter = new IntentFilter();        filter.addAction(ACTION_USB_PERMISSION);        filter.addAction(UsbManager.ACTION_USB_ACCESSORY_DETACHED);        registerReceiver(mUsbReceiver, filter);        setContentView(R.layout.main);                mToggleButton = (ToggleButton) findViewById(R.id.toggleBtn);        mLedStatusView = (TextView) findViewById(R.id.ledState);        mStatusView = (TextView) findViewById(R.id.status);                mToggleButton.setOnCheckedChangeListener(new OnCheckedChangeListener() {                        @Override            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {                byte command = 0x1;                byte value = (byte) (isChecked ? 0x1 : 0x0);                sendCommand(command, value);            }        });        enableControls(false);    }    @Override    public void onResume() {        super.onResume();        if (mInputStream != null &amp;&amp; mOutputStream != null) {            return;        }        // USB Accessory の一覧を取得        UsbAccessory[] accessories = mUsbManager.getAccessoryList();        UsbAccessory accessory = (accessories == null ? null : accessories[0]);        if (accessory != null) {            // Accessory にアクセスする権限があるかチェック            if (mUsbManager.hasPermission(accessory)) {                // 接続を開く                openAccessory(accessory);            } else {                synchronized (mUsbReceiver) {                    if (!mPermissionRequestPending) {                        // パーミッションを依頼                        mUsbManager.requestPermission(accessory, mPermissionIntent);                        mPermissionRequestPending = true;                    }                }            }        } else {            Log.d(TAG, "mAccessory is null");        }    }    @Override    public void onPause() {        super.onPause();        closeAccessory();    }    @Override    public void onDestroy() {        unregisterReceiver(mUsbReceiver);        super.onDestroy();    }    private void openAccessory(UsbAccessory accessory) {        // アクセサリにアクセスするためのファイルディスクリプタを取得        mFileDescriptor = mUsbManager.openAccessory(accessory);        if (mFileDescriptor != null) {            mAccessory = accessory;            FileDescriptor fd = mFileDescriptor.getFileDescriptor();            // 入出力用のストリームを確保            mInputStream = new FileInputStream(fd);            mOutputStream = new FileOutputStream(fd);            // この中でアクセサリとやりとりする            Thread thread = new Thread(null, this, "DemoKit");            thread.start();            Log.d(TAG, "accessory opened");            enableControls(true);        } else {            Log.d(TAG, "accessory open fail");        }    }    private void closeAccessory() {        enableControls(false);        try {            if (mFileDescriptor != null) {                mFileDescriptor.close();            }        } catch (IOException e) {        } finally {            mFileDescriptor = null;            mAccessory = null;        }    }    private void enableControls(boolean enable) {        if (enable) {            mStatusView.setText("connected");        } else {            mStatusView.setText("not connected");        }        mToggleButton.setEnabled(enable);    }    private static final int MESSAGE_LED = 1;    private class LedMsg {        private byte on;        public LedMsg(byte on) {            this.on = on;        }        public boolean isOn() {            if(on == 0x1)                return true;            else                return false;        }    }    // ここでアクセサリと通信する    @Override    public void run() {        int ret = 0;        byte[] buffer = new byte[16384];        int i;        // アクセサリ -&gt; アプリ        while (ret &gt;= 0) {            try {                ret = mInputStream.read(buffer);            } catch (IOException e) {                break;            }            i = 0;            while (i &lt; ret) {                int len = ret - i;                switch (buffer[i]) {                    case 0x1:                        // 2byte のオレオレプロトコル                        // 0x1 0x0 や 0x1 0x1 など                        if (len &gt;= 2) {                            Message m = Message.obtain(mHandler, MESSAGE_LED);                            m.obj = new LedMsg(buffer[i + 1]);                            mHandler.sendMessage(m);                        }                        i += 2;                        break;                    default:                        Log.d(TAG, "unknown msg: " + buffer[i]);                        i = len;                        break;                }            }        }    }    // UI スレッドで画面上の表示を変更    private Handler mHandler = new Handler() {        @Override        public void handleMessage(Message msg) {            switch (msg.what) {                case MESSAGE_LED:                    LedMsg o = (LedMsg) msg.obj;                    handleLedMessage(o);                    break;            }        }    };    private void handleLedMessage(LedMsg l) {        if(l.isOn()) {            mLedStatusView.setText("ON");        }        else {            mLedStatusView.setText("OFF");        }    }    // アプリ -&gt; アクセサリ    public void sendCommand(byte command, byte value) {        byte[] buffer = new byte[2];                if(value != 0x1 &amp;&amp; value != 0x0)            value = 0x0;        // 2byte のオレオレプロトコル        // 0x1 0x0 や 0x1 0x1        buffer[0] = command;        buffer[1] = value;        if (mOutputStream != null) {            try {                mOutputStream.write(buffer);            } catch (IOException e) {                Log.e(TAG, "write failed", e);            }        }    }}&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;つぎにアクセサリをフィルターするための XML ファイルを作成&lt;br /&gt;manufacturer と model と version はアクセサリ側のコードの aac() の引数をあわせる。&lt;br /&gt;&lt;br /&gt;res/xml/accessory_filter.xml&lt;br /&gt;&lt;code name="code" class="xml"&gt;&lt;?xml version="1.0" encoding="utf-8"?&gt;&lt;resources&gt;    &lt;usb-accessory manufacturer="uPhyca" model="HelloADK" version="1.0" /&gt;&lt;/resources&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;最後の AndroidManifest.xml にいろいろ宣言&lt;br /&gt;・&amp;lt;uses-library android:name="com.android.future.usb.accessory" /&amp;gt;&lt;br /&gt;・android.hardware.usb.action.USB_ACCESSORY_ATTACHED の intentfilter &lt;br /&gt;・android.hardware.usb.action.USB_ACCESSORY_ATTACHED の meta-data&lt;br /&gt;&lt;br /&gt;AndroidManifest.xml&lt;br /&gt;&lt;code name="code" class="xml"&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;&amp;lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.uphyca.android.helloadk"    android:versionCode="1"    android:versionName="1.0" &amp;gt;    &amp;lt;uses-sdk android:minSdkVersion="10" /&amp;gt;    &amp;lt;application        android:icon="@drawable/ic_launcher"        android:label="@string/app_name" &amp;gt;                &amp;lt;uses-library android:name="com.android.future.usb.accessory" /&amp;gt;        &amp;lt;activity            android:label="@string/app_name"            android:launchMode="singleInstance"            android:name=".MainActivity"            android:taskAffinity="" &amp;gt;            &amp;lt;intent-filter &amp;gt;                &amp;lt;action android:name="android.intent.action.MAIN" /&amp;gt;                &amp;lt;category android:name="android.intent.category.LAUNCHER" /&amp;gt;            &amp;lt;/intent-filter&amp;gt;            &amp;lt;intent-filter &amp;gt;                &amp;lt;action android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED" /&amp;gt;            &amp;lt;/intent-filter&amp;gt;            &amp;lt;meta-data                android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED"                android:resource="@xml/accessory_filter" /&amp;gt;        &amp;lt;/activity&amp;gt;    &amp;lt;/application&amp;gt;&amp;lt;/manifest&amp;gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;これでアプリ側は完了。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;2. アクセサリ側&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;アプリ側で定義したオレオレプロトコルに沿って LED 用のデジタル出力ピンのレベルの HIGH/LOW を切り替えるだけ。&lt;br /&gt;&lt;br /&gt;&lt;code name="code" class="c"&gt;#include &amp;lt;Wire.h&amp;gt;#include &amp;lt;Max3421e.h&amp;gt;#include &amp;lt;Usb.h&amp;gt;#include &amp;lt;AndroidAccessory.h&amp;gt;#define  LED       24AndroidAccessory acc("uPhyca",       "HelloADK",       "DemoKit Arduino Board",       "1.0",       "http://www.android.com",       "0000000012345678");void setup();void loop();void init_leds(){    // 24 の DIGITAL を LED 用の出力にする    pinMode(LED, OUTPUT);}void setup(){    Serial.begin(115200);    Serial.print("\r\nStart");    init_leds();    acc.powerOn();}void loop(){    byte msg[2];    byte led;    if (acc.isConnected()) {        int len = acc.read(msg, sizeof(msg), 1);        if (len &gt; 0) {            if (msg[0] == 0x1) {                if(msg[1] == 0x1) {                    digitalWrite(LED, HIGH);                    msg[0] = 0x1;                    msg[1] = 0x1;                    acc.write(msg, 2);                }                else {                    digitalWrite(LED, LOW);                    msg[0] = 0x1;                    msg[1] = 0x2;                    acc.write(msg, 2);                }            }        }    }     else {        digitalWrite(LED, LOW);    }    delay(10);}&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;DIGITAL の 24 を LED のアノードにつないで、カソードを抵抗につないで、抵抗を GND につないでと。&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-34Mg8qWU1Rk/TuCgaOvI7_I/AAAAAAAADpM/rKHQjYxf8-s/s1600/IMG_20111208_201003.jpg" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="400" width="300" src="http://3.bp.blogspot.com/-34Mg8qWU1Rk/TuCgaOvI7_I/AAAAAAAADpM/rKHQjYxf8-s/s400/IMG_20111208_201003.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;最初に接続を許可するか聞かれるので OK する。&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-XjAJcmoFnxg/TuCglBqSv3I/AAAAAAAADpY/N0Q0ufAyvEY/s1600/IMG_20111208_201017.jpg" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="300" width="400" src="http://1.bp.blogspot.com/-XjAJcmoFnxg/TuCglBqSv3I/AAAAAAAADpY/N0Q0ufAyvEY/s400/IMG_20111208_201017.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;トグルボタンで LED の ON /OFF できたー。&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-mKT9tC2Jgjk/TuCgKd2fKRI/AAAAAAAADo0/WgU6XUb0lOI/s1600/IMG_20111208_201122.jpg" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="400" width="300" src="http://3.bp.blogspot.com/-mKT9tC2Jgjk/TuCgKd2fKRI/AAAAAAAADo0/WgU6XUb0lOI/s400/IMG_20111208_201122.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-XPfOZzB-Th0/TuCgKvR9ucI/AAAAAAAADpA/pMJ0G6Imo6c/s1600/IMG_20111208_201133.jpg" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="400" width="300" src="http://2.bp.blogspot.com/-XPfOZzB-Th0/TuCgKvR9ucI/AAAAAAAADpA/pMJ0G6Imo6c/s400/IMG_20111208_201133.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;GitHub にもおいといたよ！&lt;br /&gt;&lt;a href="https://github.com/yanzm/HelloADK"&gt;yanzm/HelloADK - GitHub - http://goo.gl/bhG1t&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5859951453664122203-1197988179410667575?l=y-anz-m.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://y-anz-m.blogspot.com/feeds/1197988179410667575/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://y-anz-m.blogspot.com/2011/12/androidhello-adk.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5859951453664122203/posts/default/1197988179410667575'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5859951453664122203/posts/default/1197988179410667575'/><link rel='alternate' type='text/html' href='http://y-anz-m.blogspot.com/2011/12/androidhello-adk.html' title='Android　Hello ADK つくった！'/><author><name>yanzm</name><uri>http://www.blogger.com/profile/04059587494895790858</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_HRaLqTNFL7w/TDx6XwqrmDI/AAAAAAAABMo/B1SkSHxhKu4/S220/icon4.JPG'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-84Xi9CMmJrw/TuCEtORMuSI/AAAAAAAADoo/rDYWjLzjR6s/s72-c/Screen%2BShot%2B2011-12-08%2Bat%2B6.26.29%2BPM.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5859951453664122203.post-3537234449687715819</id><published>2011-12-04T22:43:00.001+09:00</published><updated>2011-12-04T22:55:56.442+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Android'/><title type='text'>Android　DialogFragmentを使うときの注意点。</title><content type='html'>4日目〜。&lt;br /&gt;&lt;br /&gt;---&lt;br /&gt;&lt;br /&gt;DialogFragment で表示される Dialog を指定するための主なメソッドは次の2つ。 onCreateView() と onCreateDialog()。&lt;br /&gt;&lt;br /&gt;Dialog のテーマと ContentView の中身だけ指定すればいい場合は onCreateView() の方だけを Override すればいいのですが、例えば OK と Cancel のある AlertDialog を作ろうとしたときは onCreateDialog() を Override して、表示したい AlertDialog のインスタンスを返すようにします。&lt;br /&gt;&lt;br /&gt;このときに、onCreateView() で null 以外を返していると落ちます。&lt;br /&gt;&lt;br /&gt;&lt;code name="code" class="java"&gt;public class MainActivity extends Activity {    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        FragmentManager manager = getFragmentManager();        MainFragmentDialog dialog = new MainFragmentDialog();        dialog.show(manager, "dialog");    }    public class MainFragmentDialog extends DialogFragment {        @Override        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {            return inflater.inflate(R.layout.main, null, false);        }                @Override        public Dialog onCreateDialog(Bundle savedInstanceState) {            AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());            builder.setTitle("タイトル");            builder.setPositiveButton("OK", null);            builder.setNegativeButton("Cancel", null);            return builder.create();        }    }}&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;code&gt;12-04 22:51:37.099: E/AndroidRuntime(586): Caused by: android.util.AndroidRuntimeException: requestFeature() must be called before adding content&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;onCreateView() を Override せずに、onCreateDialog() で返す AlertDialog に対して setView() するのはOK&lt;br /&gt;&lt;br /&gt;&lt;code name="code" class="java"&gt;public class MainActivity extends Activity {    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        FragmentManager manager = getFragmentManager();        MainFragmentDialog dialog = new MainFragmentDialog();        dialog.show(manager, "dialog");    }    public class MainFragmentDialog extends DialogFragment {        @Override        public Dialog onCreateDialog(Bundle savedInstanceState) {            LayoutInflater inflater = getActivity().getLayoutInflater();            View view = inflater.inflate(R.layout.main, null, false);            AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());            builder.setTitle("タイトル");            builder.setPositiveButton("OK", null);            builder.setNegativeButton("Cancel", null);            builder.setView(view);            return builder.create();        }    }}&lt;/code&gt;これは落ちない。&lt;br /&gt;&lt;br /&gt;onCreateDialog() を Override しないとほんとに単純なダイアログしかだせないよねー。。。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5859951453664122203-3537234449687715819?l=y-anz-m.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://y-anz-m.blogspot.com/feeds/3537234449687715819/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://y-anz-m.blogspot.com/2011/12/androiddialogfragment.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5859951453664122203/posts/default/3537234449687715819'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5859951453664122203/posts/default/3537234449687715819'/><link rel='alternate' type='text/html' href='http://y-anz-m.blogspot.com/2011/12/androiddialogfragment.html' title='Android　DialogFragmentを使うときの注意点。'/><author><name>yanzm</name><uri>http://www.blogger.com/profile/04059587494895790858</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_HRaLqTNFL7w/TDx6XwqrmDI/AAAAAAAABMo/B1SkSHxhKu4/S220/icon4.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5859951453664122203.post-6916539218225382539</id><published>2011-12-03T22:05:00.001+09:00</published><updated>2011-12-03T22:10:21.556+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Android'/><title type='text'>Android　4.0 で TextView のレイアウトが変わる？</title><content type='html'>3日目〜&lt;br /&gt;&lt;br /&gt;---&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;TextView を継承したオリジナル CheckedTextView を作って使っているのですが、&lt;br /&gt;コードは全く変えてないのにプレビューレベルで 3.2 以前と 4.0 で&lt;br /&gt;それのレイアウトが変わってしまうのです。。。&lt;br /&gt;&lt;br /&gt;これは注意ポイントかも。&lt;br /&gt;&lt;br /&gt;うーん。。。&lt;br /&gt;まだ解決法わかってないので、調査結果はあしたにでも！&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-VBbzJ4kICi0/TtofGfIff-I/AAAAAAAADoE/IMtgLf7haiU/s1600/Screenshot.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="125" width="400" src="http://1.bp.blogspot.com/-VBbzJ4kICi0/TtofGfIff-I/AAAAAAAADoE/IMtgLf7haiU/s400/Screenshot.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-S42Y-1pEVKk/TtofGlAOR8I/AAAAAAAADoQ/oe19U4-Q2uA/s1600/Screenshot-1.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="126" width="400" src="http://1.bp.blogspot.com/-S42Y-1pEVKk/TtofGlAOR8I/AAAAAAAADoQ/oe19U4-Q2uA/s400/Screenshot-1.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5859951453664122203-6916539218225382539?l=y-anz-m.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://y-anz-m.blogspot.com/feeds/6916539218225382539/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://y-anz-m.blogspot.com/2011/12/androidtextview.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5859951453664122203/posts/default/6916539218225382539'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5859951453664122203/posts/default/6916539218225382539'/><link rel='alternate' type='text/html' href='http://y-anz-m.blogspot.com/2011/12/androidtextview.html' title='Android　4.0 で TextView のレイアウトが変わる？'/><author><name>yanzm</name><uri>http://www.blogger.com/profile/04059587494895790858</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_HRaLqTNFL7w/TDx6XwqrmDI/AAAAAAAABMo/B1SkSHxhKu4/S220/icon4.JPG'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-VBbzJ4kICi0/TtofGfIff-I/AAAAAAAADoE/IMtgLf7haiU/s72-c/Screenshot.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5859951453664122203.post-987603198035601823</id><published>2011-12-02T18:28:00.001+09:00</published><updated>2011-12-02T18:43:00.750+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Android'/><title type='text'>第3回名古屋android勉強会 Fragment基礎講座/ハンズオン を行ったよ。</title><content type='html'>さぁ、２日目です。&lt;br /&gt;いつまで続けられるかな。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;---&lt;br /&gt;&lt;br /&gt;11月19日に名古屋で行った &lt;a href="https://docs.google.com/document/pub?id=1PGG5WMEFm_GXLPunXXsv8deaNXXARedK16t24bqzlwE"&gt;Fragment のハンズオンの資料&lt;/a&gt;を載せました。&lt;br /&gt;タイポとかなおってる。。。はず！&lt;br /&gt;&lt;br /&gt;&lt;iframe src="http://docs.google.com/viewer?url=https%3A%2F%2Fsites.google.com%2Fsite%2Fyukianzm%2Ffragment_fes%2F%25E7%25AC%25AC3%25E5%259B%259E%25E5%2590%258D%25E5%258F%25A4%25E5%25B1%258Bandroid%25E5%258B%2589%25E5%25BC%25B7%25E4%25BC%259A%2520Fragment%25E5%259F%25BA%25E7%25A4%258E%25E8%25AC%259B%25E5%25BA%25A7_%25E3%2583%258F%25E3%2583%25B3%25E3%2582%25B9%25E3%2582%2599%25E3%2582%25AA%25E3%2583%25B3.pdf&amp;embedded=true" width="440" height="600" style="border: none;"&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5859951453664122203-987603198035601823?l=y-anz-m.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://y-anz-m.blogspot.com/feeds/987603198035601823/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://y-anz-m.blogspot.com/2011/12/3android-fragment.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5859951453664122203/posts/default/987603198035601823'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5859951453664122203/posts/default/987603198035601823'/><link rel='alternate' type='text/html' href='http://y-anz-m.blogspot.com/2011/12/3android-fragment.html' title='第3回名古屋android勉強会 Fragment基礎講座/ハンズオン を行ったよ。'/><author><name>yanzm</name><uri>http://www.blogger.com/profile/04059587494895790858</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_HRaLqTNFL7w/TDx6XwqrmDI/AAAAAAAABMo/B1SkSHxhKu4/S220/icon4.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5859951453664122203.post-3592919635209306835</id><published>2011-12-01T18:34:00.001+09:00</published><updated>2011-12-02T18:28:29.038+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Android'/><title type='text'>Android　AlertDialog の背景を変更する for 4.x</title><content type='html'>どうも、お久しぶりです。&lt;br /&gt;あんざいゆきです。&lt;br /&gt;世の中の Advent Calendar 祭りに乗り遅れたので、一人 Advent Calendar やることにしました。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;---&lt;br /&gt;&lt;br /&gt;前に &lt;a href="http://y-anz-m.blogspot.com/2010/12/androidalertdialog.html"&gt;Android　AlertDialog の背景を変更する&lt;/a&gt;というエントリを書いたのですが、どうも 3.0 以降だとこのハックがうまくいかないという報告があり確かめてみました。&lt;br /&gt;&lt;br /&gt;このエントリの通りにやると&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_HRaLqTNFL7w/TRhddmrLqeI/AAAAAAAACF0/8J4sLZH5Z6Y/s1600/CustomAlertDialog.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 267px; height: 400px;" src="http://4.bp.blogspot.com/_HRaLqTNFL7w/TRhddmrLqeI/AAAAAAAACF0/8J4sLZH5Z6Y/s400/CustomAlertDialog.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5555292903540763106" /&gt;&lt;/a&gt;&lt;/div&gt;や&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_HRaLqTNFL7w/TRhuRV4PMYI/AAAAAAAACGM/iU9GHI8-zRk/s1600/CustomAlertDialog3.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 267px; height: 400px;" src="http://3.bp.blogspot.com/_HRaLqTNFL7w/TRhuRV4PMYI/AAAAAAAACGM/iU9GHI8-zRk/s400/CustomAlertDialog3.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5555311384571359618" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;のようなダイアログになるはずなのですが、悲しいかな、Android 4.0 のエミュレータで実行したら、こんな感じになってしまいました。&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-j94Ve_hr9ho/TtdMGZWzGUI/AAAAAAAADn4/UJ-pOVS945w/s1600/AlertDialogSample2.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="400" width="240" src="http://2.bp.blogspot.com/-j94Ve_hr9ho/TtdMGZWzGUI/AAAAAAAADn4/UJ-pOVS945w/s400/AlertDialogSample2.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-ld7SZeAPNNc/TtdLQBhxMnI/AAAAAAAADns/qppkArWzBXY/s1600/AlertDialogSample1.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="400" width="240" src="http://3.bp.blogspot.com/-ld7SZeAPNNc/TtdLQBhxMnI/AAAAAAAADns/qppkArWzBXY/s400/AlertDialogSample1.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;orz&lt;br /&gt;&lt;br /&gt;外枠はでてるけど、AlertDialog の内部の色が変わってないので、android:alertDialogStyle が効かなくなってるっぽいです。&lt;br /&gt;&lt;br /&gt;AlertDialog の内側の属性値の android:topBright などを参照しているのは AlertController です。&lt;br /&gt;この AlertController に android:topBright などが設定されたテーマを渡さなければいけないのですが、このテーマを渡すためのメソッドである AlertController#AlertParams() が呼ばれているのが &lt;a href="http://tools.oesf.biz/android-4.0.1_r1.0/xref/frameworks/base/core/java/android/app/AlertDialog.java#351"&gt;AlertDialog.Builder 内の以下の部分&lt;/a&gt;だけなのです。&lt;br /&gt;&lt;br /&gt;Android 4.0&lt;br /&gt;&lt;code name="code" class="java"&gt;    358         public Builder(Context context) {    359             this(context, resolveDialogTheme(context, 0));    360         }    373         public Builder(Context context, int theme) {    374             P = new AlertController.AlertParams(new ContextThemeWrapper(    375                     context, resolveDialogTheme(context, theme)));    376             mTheme = theme;    377         }&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;つまり、AlertDialog.Builder(context)　ではなく、AlertDialog.Builder(context, theme) で android:alertDialogStyle が定義されているテーマを渡さなければなりません。なぜなら、Builder(context) の方では、resolveDialogTheme() という内部メソッドに対して第２引数に 0、つまり android:alertDialogStyle が定義されていないものを渡しているからです。 &lt;br /&gt;&lt;br /&gt;一方、&lt;a href="http://tools.oesf.biz/android-2.3_r1.0/xref//frameworks/base/core/java/android/app/AlertDialog.java#266"&gt;Android 2.3 では第２引数にテーマを渡せるコンストラクタが AlertDialog.Builder にありません&lt;/a&gt;。&lt;br /&gt;&lt;br /&gt;Android 2.3&lt;br /&gt;&lt;code name="code" class="java"&gt;    272         public Builder(Context context) {    273             P = new AlertController.AlertParams(context);    274         }&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;しかし、AlertParams() には Builder の引数の Context をそのまま渡しているため、アプリのテーマとして設定されているものが AlertController にわたり、アプリのテーマとして android:alertDialogStyle を指定しておけば反映されるという状態でした。&lt;br /&gt;&lt;br /&gt;で、結論としては、こうすればOKです。&lt;br /&gt;&lt;br /&gt;&lt;code name="code" class="java"&gt;    // 独自ダイアログをつかってテーマを指定    public void showMyDialog(View v) {        MyAlertDialog myDialog = new MyAlertDialog(this, R.style.MyDialog);        myDialog.setTitle("dialog");        myDialog.setMessage("test!");        myDialog.setButton("OK", (OnClickListener) null);        myDialog.show();    }&lt;/code&gt;&lt;br /&gt;↑これは上記のエントリと同じ&lt;br /&gt;&lt;br /&gt;&lt;code name="code" class="xml"&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;&amp;lt;resources&amp;gt;    ...    &amp;lt;style name="MyDialog" parent="@android:style/Theme.Dialog"&amp;gt;        &amp;lt;item name="android:windowBackground"&amp;gt;@drawable/rect&amp;lt;/item&amp;gt;        &amp;lt;item name="android:buttonStyle"&amp;gt;@style/CustomButton&amp;lt;/item&amp;gt;        &amp;lt;item name="android:alertDialogStyle"&amp;gt;@style/AlertDialog&amp;lt;/item&amp;gt;    &amp;lt;/style&amp;gt;    ...&amp;lt;/resources&amp;gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;この MyDialog の方にも &lt;item name="android:alertDialogStyle"&gt;@style/AlertDialog&lt;/item&gt; をいれます！&lt;br /&gt;前はアプリケーション、もしくはアクティビティのテーマに設定していましたが、ダイアログのテーマとして指定する方にも入れると Android 4.0 でも適用されます！&lt;br /&gt;&lt;br /&gt;ちなみに、Android 4.0 から Theme の style item の android:alertDialogTheme が追加されていました。&lt;br /&gt;なので、上記のエントリで AlertDialog を継承した独自 Dialog クラスを作成していますが、これをせずに&lt;br /&gt;&lt;br /&gt;&lt;code name="code" class="xml"&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;&amp;lt;resources&amp;gt;    &amp;lt;style name="MyTheme" parent="@android:style/Theme.Black"&amp;gt;        &amp;lt;item name="android:alertDialogStyle"&amp;gt;@style/AlertDialog&amp;lt;/item&amp;gt;        &amp;lt;item name="android:alertDialogTheme"&amp;gt;@style/MyDialog&amp;lt;/item&amp;gt;    &amp;lt;/style&amp;gt;    ...    &amp;lt;style name="MyDialog" parent="@android:style/Theme.Dialog"&amp;gt;        &amp;lt;item name="android:windowBackground"&amp;gt;@drawable/rect&amp;lt;/item&amp;gt;        &amp;lt;item name="android:buttonStyle"&amp;gt;@style/CustomButton&amp;lt;/item&amp;gt;    &amp;lt;/style&amp;gt;    ...&amp;lt;/resources&amp;gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;のようにすれば外枠やボタンを反映できるようになりました。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5859951453664122203-3592919635209306835?l=y-anz-m.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://y-anz-m.blogspot.com/feeds/3592919635209306835/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://y-anz-m.blogspot.com/2011/12/androidalertdialog-for-4x.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5859951453664122203/posts/default/3592919635209306835'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5859951453664122203/posts/default/3592919635209306835'/><link rel='alternate' type='text/html' href='http://y-anz-m.blogspot.com/2011/12/androidalertdialog-for-4x.html' title='Android　AlertDialog の背景を変更する for 4.x'/><author><name>yanzm</name><uri>http://www.blogger.com/profile/04059587494895790858</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_HRaLqTNFL7w/TDx6XwqrmDI/AAAAAAAABMo/B1SkSHxhKu4/S220/icon4.JPG'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_HRaLqTNFL7w/TRhddmrLqeI/AAAAAAAACF0/8J4sLZH5Z6Y/s72-c/CustomAlertDialog.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5859951453664122203.post-3290787075631426215</id><published>2011-10-31T16:26:00.000+09:00</published><updated>2011-11-15T07:39:39.054+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='イベント'/><category scheme='http://www.blogger.com/atom/ns#' term='HTML5'/><category scheme='http://www.blogger.com/atom/ns#' term='AppEngine'/><category scheme='http://www.blogger.com/atom/ns#' term='Android'/><title type='text'>Bootcamp 2011 に行ってきました。</title><content type='html'>&lt;a href="https://sites.google.com/site/tokyogtugusersite/"&gt;Bootcamp 2011 Japan&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;今年は去年と違って、土曜日開催（去年は平日） &amp; Google Japan の六本木オフィスで行えたこともあって、たくさんの参加者に来ていただけました。よかった、よかった。&lt;br /&gt;&lt;br /&gt;ハッシュタグは #bc2011jp です。&lt;br /&gt;&lt;br /&gt;@Fumi さんが Togetter にまとめてくれました。&lt;br /&gt;&lt;a href="http://togetter.com/li/206774"&gt;GTUG Bootcamp 2011 #bc2011jp - Togetter -&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Barエリアで松尾さんに App Engine について熱く語ると App Engine Tシャツがもらえましたー。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;セッションの資料、後でチェックしなきゃ。&lt;br /&gt;&lt;br /&gt;■ セッション：「Fragment を使ってみよう」 （あんざいゆき）&lt;br /&gt;&lt;a href="http://www.slideshare.net/yanzm/fragment"&gt;資料&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;■セッション：「Google SketchUp　モデリングの初歩」 = 初めてでも簡単、3次元の世界 =&lt;br /&gt;（田中雅子、株式会社アルファコックス　CTO）&lt;br /&gt;&lt;br /&gt;■セッション：「はじめての Chrome Extension」 （吉川徹）&lt;br /&gt;&lt;a href="http://www.slideshare.net/yoshikawa_t/chrome-extension"&gt;資料&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;■セッション：「App Engine 倹約のすゝめ」 （小川 信一）&lt;br /&gt;&lt;br /&gt;■ハンズオン：「新聞風の1ページを作ってみよう！」（一條 美和子） &lt;br /&gt;&lt;a href="https://sites.google.com/site/ichi3tech/201110/bootcamp2011dehtml5hanzuon"&gt;資料&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;■ハンズオン：Google Apps Script （中村敦）&lt;br /&gt;&lt;a href="https://docs.google.com/document/d/1tPsX8jLwIyNRRk-7ZsxWL2RW-yLcXo9goCwr7ScWOBs/edit"&gt;資料1&lt;/a&gt;  &lt;a href="https://docs.google.com/document/d/11WrJ0QymQbGGPyh5c5JyfbYAvIU-N0YUVfCHEoEJKfA/edit"&gt;資料2&lt;/a&gt;  &lt;a href="https://docs.google.com/document/d/1OIrWVU0lOHFJ1V0NBTrBY8O4pB4FhWWbaIF3BbryPgU/edit"&gt;資料3&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;■ハンズオン：「Spike WebView &amp; Tough ICS」 （江川　崇）&lt;br /&gt;&lt;a href="https://docs.google.com/document/pub?id=1_T9PiCJCgMs1QdXPpdYcp7orOnRr1UU6qA5do_zsR2A"&gt;資料&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;■ハンズオン：Google+ API の体験と Hangouts の紹介 （田中洋一郎、伊藤 千光、中嶋 信博）&lt;br /&gt;&lt;a href="https://docs.google.com/presentation/d/1oDkvwodZmkBMeeInhkzDYbHKj7Ss2CoXvnU6OwpzcMQ/edit#slide=id.p"&gt;資料&lt;/a&gt;  &lt;a href="http://webos-goodies.jp/archives/how_to_use_google_hangouts_api.html"&gt;参考ブログ&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5859951453664122203-3290787075631426215?l=y-anz-m.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://y-anz-m.blogspot.com/feeds/3290787075631426215/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://y-anz-m.blogspot.com/2011/10/bootcamp-2011.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5859951453664122203/posts/default/3290787075631426215'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5859951453664122203/posts/default/3290787075631426215'/><link rel='alternate' type='text/html' href='http://y-anz-m.blogspot.com/2011/10/bootcamp-2011.html' title='Bootcamp 2011 に行ってきました。'/><author><name>yanzm</name><uri>http://www.blogger.com/profile/04059587494895790858</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_HRaLqTNFL7w/TDx6XwqrmDI/AAAAAAAABMo/B1SkSHxhKu4/S220/icon4.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5859951453664122203.post-3823167875882908909</id><published>2011-10-22T16:29:00.000+09:00</published><updated>2011-11-15T07:52:04.509+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Android'/><category scheme='http://www.blogger.com/atom/ns#' term='ICS'/><title type='text'>Android 4.0 Platform</title><content type='html'>&lt;a href="http://developer.android.com/sdk/android-4.0.html"&gt;Android 4.0 Platform&lt;/a&gt;を意訳しました。訳が正しくない可能性もあります。正確な内容を理解するには原文を参照してください。&lt;br /&gt;&lt;br /&gt;---&lt;br /&gt;API Level: &lt;span style="font-weight:bold;"&gt;14&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Android 4.0 へようこそ！&lt;br /&gt;&lt;br /&gt;Android 4.0 はユーザーと開発者むけの新しい機能を追加したメジャープラットフォームリリースです。以下で議論される新しい機能と API に加え、Android 3.x からの API セットと Holographic テーマを小さい画面向けにも拡張した Android 4.0 は重要なプラットフォームリリースです。つまり、アプリ開発者として、Android 4.0 (API Level 14) 以上で動作する ハンドセット、タブレット、その他デバイスにおいて、それぞれに最適化されたユーザー体験を提供する単一の APK を開発し公開するための、1つのプラットフォームと単一の API フレームワークを手に入れたということです。&lt;br /&gt;&lt;br /&gt;開発者は Android SDK のコンポーネントとして Android 4.0 platform をダウンロードできるようになりました。Android emulator を使って Android 4.0 でのアプリケーションの開発やテストを行うことができます。このプラットフォームには Android library と system image, emulator skin などが含まれていますが、外部のライブラリは含まれていません。&lt;br /&gt;&lt;br /&gt;Android 4.0 向けの開発とテストを始めるには、Android SDK Manager を使って自分の SDK にプラットフォームをダウンロードします。より詳しい情報は &lt;a href="http://developer.android.com/sdk/adding-components.html"&gt;Adding SDK Components&lt;/a&gt; を見てください。Android が初めての人は、まず &lt;a href="http://developer.android.com/sdk/index.html"&gt;download the SDK Starter Package&lt;/a&gt; から始めてください。&lt;br /&gt;&lt;br /&gt;&lt;b&gt;リマインダー:&lt;/b&gt; すでに Android application を公開している場合、できるだけ早く Android 4.0 上であなたのアプリケーションのテストと最適化をしてください。最新の Android-powered デバイスでベストな体験を提供していることを確認するべきです。&lt;br /&gt;&lt;br /&gt;---&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;API Overview&lt;/h3&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;■ Social APIs in Contacts Provider&lt;/h4&gt;&lt;a href="http://developer.android.com/reference/android/provider/ContactsContract.html"&gt;ContactsContract&lt;/a&gt; provider によって定義されるコンタクトAPI が新しいソーシャル向け機能をサポートするように拡張されました。例えば、デバイス所有者のパーソナルプロフィールや、デバイスにインストールされているソーシャルネットワークへ個々のコンタクトを招待する機能などです。&lt;h4&gt;User Profile&lt;/h4&gt;&lt;a href="http://developer.android.com/reference/android/provider/ContactsContract.Profile.html"&gt;ContactsContract.Profile&lt;/a&gt; table で定義される、デバイス所有者を表すパーソナルプロフィールを持つようになりました。ユーザーのアイデンティティを管理するソーシャルアプリは &lt;a href="http://developer.android.com/reference/android/provider/ContactsContract.Profile.html"&gt;ContactsContract.Profile&lt;/a&gt; 内に新しい &lt;a href="http://developer.android.com/reference/android/provider/ContactsContract.RawContacts.html"&gt;ContactsContract.RawContacts&lt;/a&gt; エントリを作成することでユーザーのプロフィールデータを提供することができます。つまり、デバイスユーザーを表す raw contacts は、&lt;a href="http://developer.android.com/reference/android/provider/ContactsContract.RawContacts.html"&gt;ContactsContract.RawContacts&lt;/a&gt; Uri によって定義されていたこれまでの raw contacts table には属さないということです。代わりに &lt;a href="http://developer.android.com/reference/android/provider/ContactsContract.Profile.html#CONTENT_RAW_CONTACTS_URI"&gt;CONTENT_RAW_CONTACTS_URI&lt;/a&gt; にあるテーブルにプロフィール用の raw contact を追加しなければなりません。このテーブルの raw contact は、"Me" というラベルの1ユーザーのプロフィールとして集約されます。&lt;br /&gt;&lt;br /&gt;プロフィール用の raw contact を追加するには &lt;a href="http://developer.android.com/reference/android/Manifest.permission.html#WRITE_PROFILE"&gt;WRITE_PROFILE&lt;/a&gt; パーミッションが必要です。同様に、プロフィールテーブルを読むには &lt;a href="http://developer.android.com/reference/android/Manifest.permission.html#READ_PROFILE"&gt;READ_PROFILE&lt;/a&gt; パーミッションが必要です。プロフィールへデータを提供するときであっても、ほとんどのアプリはプロフィールを読むべきではありません。ユーザーのプロフィールを読むことはセンシティブなパーミッションです。ユーザーがこのパーミッションを要求するアプリに対して懐疑的になると予想すべきでしょう。&lt;h4&gt;Invite Intent&lt;/h4&gt;&lt;a href="http://developer.android.com/reference/android/provider/ContactsContract.Intents.html#INVITE_CONTACT"&gt;INVITE_CONTACT&lt;/a&gt; intent のアクションは、あるアプリに対して、ユーザーがソーシャルネットワークにコンタクトを追加したいことを示すアクションの呼び出しを許可します。このアクションを行うアプリとして選ばれたアプリは、ソーシャルネットワークに指定されたコンタクトを招待します。ほとんどのアプリはこの操作の受け手側になるでしょう。例えば、ビルトインの People アプリは、コンタクト詳細にリストされた特定のソーシャルアプリに対して、ユーザーが "Add connection" を選択したときにこのインテントを呼び出します。&lt;br /&gt;&lt;br /&gt;あなたのアプリを "Add connection" リスト内に表示されるようにするには、ソーシャルネットワークからのコンタクト情報をシンクさせるための sync adapter を、あなたのアプリで提供しなければなりません。さらに、システムに対してあなたのアプリが &lt;a href="http://developer.android.com/reference/android/provider/ContactsContract.Intents.html#INVITE_CONTACT"&gt;INVITE_CONTACT&lt;/a&gt; intent に応答することを示さなければなりません。そのためには、あなたのアプリの sync configuration file に inviteContactActivity 属性を追加する必要があります。&lt;font color=green&gt;inviteContactActivity&lt;/font&gt; 属性には、システムが invite intent を送ったときに起動するための完全修飾の Activity 名も記述します。起動された Activity は intent のデータから指定された contact の URI を取得することができるので、ネットワークにコンタクトを招待したり、ユーザーのコネクションに人を追加するなど必要な処理を行えます。&lt;br /&gt;&lt;br /&gt;例として &lt;a href="http://developer.android.com/resources/samples/SampleSyncAdapter/index.html"&gt;Sample Sync Adapter&lt;/a&gt; アプリを見てください（特に、&lt;a href="http://developer.android.com/resources/samples/SampleSyncAdapter/res/xml-v14/contacts.html"&gt;contacts.xml&lt;/a&gt; ファイルを見てください）。&lt;h4&gt;Large photos&lt;/h4&gt;コンタクト用の高解像度写真をサポートするようになりました。contact record に写真を入れたとき、システムは 96x96 のサムネイル（これまでと同じ）と、新しいファイルベースの写真ストアに保存される 256x256 の "display photo" を生成します（システムが選択する実際のサイズは将来変わる可能性があります）。大きい写真を通常の &lt;a href="http://developer.android.com/reference/android/provider/ContactsContract.CommonDataKinds.Photo.html#PHOTO"&gt;PHOTO&lt;/a&gt; カラムに入れると、システムが適切なサムネイルを生成し、photo record に表示するので、コンタクトに大きい写真を追加できます。&lt;h4&gt;Contact Usage Feedback&lt;/h4&gt;新しい &lt;a href="http://developer.android.com/reference/android/provider/ContactsContract.DataUsageFeedback.html"&gt;ContactsContract.DataUsageFeedback&lt;/a&gt; API によって、人にコンタクトするための特定の方法がどの程度使用されたかをトラックすることができます。例えば、ユーザーがどのくらい頻繁に各電話番号やメールアドレスを使用したかなど。この情報は、各人に関連するコンタクトメソッドのランキング付けを改善し、コンタクトのより良い提案を行う助けになります。&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;■Calendar Provider&lt;/h4&gt;新しい Calendar API によって、カレンダー、イベント、参加者、リマインダー、アラートなどの Calendar Provider に保存されるデータを読み込み、追加、編集、削除することができます。&lt;br /&gt;&lt;br /&gt;さまざまなアプリやウィジェットがこれらの API をつかってカレンダーのイベントを読んだり編集したりできます。しかし、最も魅力的なユースケースは sync adapter です。これにより、Calendar Provider を使って他のカレンダーサービスのユーザーカレンダーを同期することができ、ユーザーの全てのイベントを表示できる1つの場所を提供できます。Google Calendar のイベントは、Google Calendar Sync Adapter による Calendar Provider で同期され、 Android のビルトインカレンダーアプリに各イベントが表示されることを許可します。&lt;br /&gt;&lt;br /&gt;カレンダーのデータモデルと、Calendar Provider 内のイベントに関連した情報は &lt;a href="http://developer.android.com/reference/android/provider/CalendarContract.html"&gt;CalendarContract&lt;/a&gt; によって定義されます。ユーザーの全てのカレンダーデータは &lt;a href="http://developer.android.com/reference/android/provider/CalendarContract.html"&gt;CalendarContract&lt;/a&gt; のいくつかのサブクラスで定義される複数のテーブルに保存されます。&lt;br /&gt;&lt;ul&gt;&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/provider/CalendarContract.Calendars.html"&gt;CalendarContract.Calendars&lt;/a&gt; テーブルはカレンダー特有の情報を保持します。テーブルの各ローは1つのカレンダーの名前、色、同期情報などの詳細を含みます。&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/provider/CalendarContract.Events.html"&gt;CalendarContract.Events&lt;/a&gt; テーブルはイベント特有の情報を保持します。テーブルの各ローは1つのイベントのタイトル、場所、開始時刻、終了時刻などの情報を含みます。イベントは1度だけ発生させることも、複数回繰り返し発生させることもできます。参加者、リマインダー、その他拡張可能なプロパティは別のテーブルに保存され、イベントの &lt;font color=green&gt;_ID&lt;/font&gt; がそれらとイベントのリンクに利用されます。&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/provider/CalendarContract.Instances.html"&gt;CalendarContract.Instances&lt;/a&gt; テーブルは1つのイベントの発生ごとの開始時刻と終了時刻を保持します。テーブルの各ローは1つの発生イベントを表します。１度だけのイベントではインスタンスとイベントは1対1でマッピングされます。繰り返し起こるイベントでは、そのイベントの複数の発生イベントに対する複数のローが自動的に生成されます。&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/provider/CalendarContract.Attendees.html"&gt;CalendarContract.Attendees&lt;/a&gt; テーブルはイベントの参加者やゲストの情報を保持します。各ローは1つのイベントの1人のゲストを表します。その人のゲストタイプとイベントでの役割を指定します。&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/provider/CalendarContract.Reminders.html"&gt;CalendarContract.Reminders&lt;/a&gt; テーブルはアラート／通知のデータを保持します。各ローはイベントに対する1つのアラートを表します。1つのイベントは複数のリマインダーを持つことができます。1イベントあたりのリマインダー数は与えられたカレンダーの sync adapter によってセットされる MAX_REMINDERS によって指定されます。リマインダーには、イベントのスケジュールされている時刻から何分前かと、ユーザーに通知するための方法（アラーム、メール、SMSなど）が指定されています。&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/provider/CalendarContract.ExtendedProperties.html"&gt;CalendarContract.ExtendedProperties&lt;/a&gt; テーブルは sync adapter によって利用される不透明なデータフィールドを保持します。provider はこのテーブルのアイテムに対して、関連するイベントが削除されたときにアイテムを削除する以外はアクションを起こしません。&lt;/ul&gt;&lt;br /&gt;Calendar Provider を使ってユーザーのカレンダーデータにアクセスするには &lt;a href="http://developer.android.com/reference/android/Manifest.permission.html#READ_CALENDAR"&gt;READ_CALENDAR&lt;/a&gt; パーミッション（読み出しアクセス用）や &lt;a href="http://developer.android.com/reference/android/Manifest.permission.html#WRITE_CALENDAR"&gt;WRITE_CALENDAR&lt;/a&gt;（書き込みアクセス用）が必要です。&lt;h4&gt;Event intent&lt;/h4&gt;行いたいことがユーザーのカレンダーにイベントを追加することだけなら、&lt;font color=green&gt;"vnd.android.cursor.item/event"&lt;/font&gt; MIME type の &lt;a href="http://developer.android.com/reference/android/content/Intent.html#ACTION_INSERT"&gt;ACTION_INSERT&lt;/a&gt; intent を使って実現することができます。この intent を呼び出すと、カレンダーアプリの新しいイベントを作成する Activity が起動します。この intent を使う場合はパーミッションは必要ありません。intent の以下の extras でイベントの詳細を指定することができます。&lt;br /&gt;&lt;ul&gt;&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/provider/CalendarContract.EventsColumns.html#TITLE"&gt;Events.TITLE&lt;/a&gt; : イベントの名前&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/provider/CalendarContract.html#EXTRA_EVENT_BEGIN_TIME"&gt;CalendarContract.EXTRA_EVENT_BEGIN_TIME&lt;/a&gt; : イベントの開始時刻（epoch からのミリ秒単位）&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/provider/CalendarContract.html#EXTRA_EVENT_END_TIME"&gt;CalendarContract.EXTRA_EVENT_END_TIME&lt;/a&gt; : イベントの終了時刻（epoch からのミリ秒単位）&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/provider/CalendarContract.EventsColumns.html#EVENT_LOCATION"&gt;Events.EVENT_LOCATION&lt;/a&gt; : イベントの場所&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/provider/CalendarContract.EventsColumns.html#DESCRIPTION"&gt;Events.DESCRIPTION&lt;/a&gt; : イベント内容&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/content/Intent.html#EXTRA_EMAIL"&gt;Intents.EXTRA_EMAIL&lt;/a&gt; : 招待するメールアドレス&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/provider/CalendarContract.EventsColumns.html#RRULE"&gt;Events.RRULE&lt;/a&gt; : イベントの繰り返し設定&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/provider/CalendarContract.EventsColumns.html#ACCESS_LEVEL"&gt;Events.ACCESS_LEVEL&lt;/a&gt; : イベントがプライベートかパブリックか&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/provider/CalendarContract.EventsColumns.html#AVAILABILITY"&gt;Events.AVAILABILITY&lt;/a&gt; : このイベントの期間中に他のイベントが同じ時間にスケジュールされるのを許可するかどうか&lt;/ul&gt;&lt;br /&gt;&lt;h4&gt;■ Voicemail Provider&lt;/h4&gt;新しい Voicemail Provider によって、ユーザーの全ての voicemail を1カ所で表示するために、デバイスに voicemail を追加することができるようになりました。例えば、電話のサービスプロバイダーからの voicemail, VoIP からの voicemail, その他代わりの音声サービスからの voicemail など、ユーザーが複数の voicemail ソースを持つことができます。これらのアプリは Voicemail Provider API を使って彼らの voicemail をデバイスに追加することができます。そして、ビルトインの Phone アプリではユーザーに全ての voicemail を一カ所にまとめて表示します。システムの Phone アプリだけが全ての voicemail を読むことができますが、voicemail を提供している各アプリは、システムに追加された彼らの voicemail を読むことはできます（ただし、他のサービスが追加した voicemail を読むことはできません）。&lt;br /&gt;&lt;br /&gt;現状では、API でサードパーティのアプリがシステムから全ての voicemail を読むことを許可していないので、サードパーティアプリが voicemail API を使ってすべきことはユーザーに届ける voicemail を持つことです。&lt;br /&gt;&lt;br /&gt;&lt;a href="http://developer.android.com/reference/android/provider/VoicemailContract.html"&gt;VoicemailContract&lt;/a&gt; クラスは Voicemail Provider の content provider を定義します。サブクラスの &lt;a href="http://developer.android.com/reference/android/provider/VoicemailContract.Voicemails.html"&gt;VoicemailContract.Voicemails&lt;/a&gt; と &lt;a href="http://developer.android.com/reference/android/provider/VoicemailContract.Status.html"&gt;VoicemailContract.Status&lt;/a&gt; は、デバイスのストレージに voicemail データを追加できるアプリを表すテーブルを提供します。voicemail provider アプリの例として &lt;a href="http://developer.android.com/resources/samples/VoicemailProviderDemo/index.html"&gt;Voicemail Provider Demo&lt;/a&gt; を見てください。&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;■ Multimedia&lt;/h4&gt;Android 4.0 では写真、ビデオ、音楽などのメディアとやりとりするアプリ向けの新しい API が追加されました。&lt;h4&gt;Media Effects&lt;/h4&gt;新しい media effect フレームワークによって、様々なビジュアルエフェクトを画像やビデオにつけることができるようになりました。例えば、画像エフェクトでは簡単に赤目を直したり、画像をグレイスケール（モノクロ）に変換したり、明るさを調整したり、彩度を調整したり、画像を回転させたり、魚眼効果をつけたり、などができます。システムは全てのエフェクト処理を最大のパフォーマンスを得るために GPU 上で行います。&lt;br /&gt;&lt;br /&gt;パフォーマンスの最大化のために、エフェクトは OpenGL テクスチャへ直接適用されます。そのため、あなたのアプリケーションではエフェクト API を使用する前に、適切な OpenGL コンテキストを持つ必要があります。エフェクトが適用されるテクスチャはビットマップやビデオやカメラからのものだと思いますが、これらのテクスチャには一定の制約があります。&lt;br /&gt;&lt;ul&gt;&lt;li&gt; 1. &lt;a href="http://developer.android.com/reference/android/opengl/GLES20.html#GL_TEXTURE_2D"&gt;GL_TEXTURE_2D&lt;/a&gt; テクスチャ画像にバウンドされていなければならない&lt;li&gt; 2. 少なくとも1つの mipmap レベルを含んでいなければならない&lt;/ul&gt;&lt;br /&gt;1つの &lt;a href="http://developer.android.com/reference/android/media/effect/Effect.html"&gt;Effect&lt;/a&gt; オブジェクトは、画像フレームに適用できる 1つの media effect を定義します。&lt;br /&gt;1つの &lt;a href="http://developer.android.com/reference/android/media/effect/Effect.html"&gt;Effect&lt;/a&gt; を作成するワークフローは&lt;br /&gt;&lt;ul&gt;&lt;li&gt; 1. &lt;a href="http://developer.android.com/reference/android/media/effect/EffectContext.html#createWithCurrentGlContext()"&gt;EffectContext.createWithCurrentGlContext()&lt;/a&gt; をあなたの OpenGL ES 2.0 コンテキストから呼び出す&lt;li&gt; 2. 返ってきた &lt;a href="http://developer.android.com/reference/android/media/effect/EffectContext.html"&gt;EffectContext&lt;/a&gt; を使って &lt;a href="http://developer.android.com/reference/android/media/effect/EffectContext.html#getFactory()"&gt;EffectContext.getFactory()&lt;/a&gt; を呼び出し、返ってくる &lt;a href="http://developer.android.com/reference/android/media/effect/EffectFactory.html"&gt;EffectFactory&lt;/a&gt; のインスタンスを取得する&lt;li&gt; 3. &lt;a href="http://developer.android.com/reference/android/media/effect/EffectFactory.html#createEffect(java.lang.String)"&gt;createEffect()&lt;/a&gt; を呼び出し、&lt;a href="http://developer.android.com/reference/android/media/effect/EffectFactory.html#EFFECT_FISHEYE"&gt;EFFECT_FISHEYE&lt;/a&gt; や &lt;a href="http://developer.android.com/reference/android/media/effect/EffectFactory.html#EFFECT_VIGNETTE"&gt;EFFECT_VIGNETTE&lt;/a&gt; など EffectFactory で定義されているエフェクト名を渡す&lt;/ul&gt;パラメータ名とパラメータ値を指定して &lt;a href="http://developer.android.com/reference/android/media/effect/Effect.html#setParameter(java.lang.String, java.lang.Object)"&gt;setParameter()&lt;/a&gt; を呼ぶことでエフェクトのパラメータを調整することができます。各エフェクトタイプによって設定できるパラメータは異なります。どのパラメータを指定できるかはエフェクト名と一緒にドキュメントに記述されています。例えば &lt;a href="http://developer.android.com/reference/android/media/effect/EffectFactory.html#EFFECT_FISHEYE"&gt;EFFECT_FISHEYE&lt;/a&gt; は歪みの scale を設定するパラメータを持っています。&lt;br /&gt;&lt;br /&gt;テクスチャにエフェクトを適用するには &lt;a href="http://developer.android.com/reference/android/media/effect/Effect.html"&gt;Effect&lt;/a&gt; 上で &lt;a href="http://developer.android.com/reference/android/media/effect/Effect.html#apply(int, int, int, int)"&gt;apply()&lt;/a&gt; を呼び、入力テクスチャ、それの横幅と縦幅、出力テクスチャを渡します。入力テクスチャは &lt;a href="http://developer.android.com/reference/android/opengl/GLES20.html#GL_TEXTURE_2D"&gt;GL_TEXTURE_2D&lt;/a&gt; テクスチャにバウンドされていなければなりません（通常は &lt;a href="http://developer.android.com/reference/android/opengl/GLES20.html#glTexImage2D(int, int, int, int, int, int, int, int, java.nio.Buffer)"&gt;glTexImage2D()&lt;/a&gt; 関数を呼ぶことで行えます）。複数の mipmap レベルを提供することができます。出力テクスチャがテクスチャイメージにまだバウンドされていない場合は、自動的にエフェクトによって mipmap レベルが1つ (0) の &lt;a href="http://developer.android.com/reference/android/opengl/GLES20.html#GL_TEXTURE_2D"&gt;GL_TEXTURE_2D&lt;/a&gt; としてバウンドされ、 入力と同じサイズになります。&lt;br /&gt;&lt;br /&gt;&lt;a href="http://developer.android.com/reference/android/media/effect/EffectFactory.html"&gt;EffectFactory&lt;/a&gt; にリストされた全てのエフェクトはサポートが保証されています。しかし、外部ライブラリから利用可能な付加的エフェクトは全てのデバイスがサポートしているとは限りません。そのため、使いたいエフェクトが外部ライブラリからのものの場合、最初に &lt;a href="http://developer.android.com/reference/android/media/effect/EffectFactory.html#isEffectSupported(java.lang.String)"&gt;isEffectSupported()&lt;/a&gt; を呼んでデバイスがサポートしているかチェックしなければなりません。&lt;h4&gt;Remote control client&lt;/h4&gt;新しい &lt;a href="http://developer.android.com/reference/android/media/RemoteControlClient.html"&gt;RemoteControlClient&lt;/a&gt; によって、デバイスロックスクリーンなどのリモートコントロールクライアントからメディアプレイヤーの再生をコントロールすることができるようになります。また、メディアプレイヤーは現在再生中の曲のトラック情報やアルバムアートなどをリモートコントロール上に表示することもできるようになります。&lt;br /&gt;&lt;br /&gt;あなたのメディアプレイヤーでリモートコントロールクライアントを有効にするには、&lt;a href="http://developer.android.com/reference/android/media/RemoteControlClient.html"&gt;RemoteControlClient&lt;/a&gt; のコンストラクタに &lt;a href="http://developer.android.com/reference/android/content/Intent.html#ACTION_MEDIA_BUTTON"&gt;ACTION_MEDIA_BUTTON&lt;/a&gt; をブロードキャストする &lt;a href="http://developer.android.com/reference/android/app/PendingIntent.html"&gt;PendingIntent&lt;/a&gt; を渡してインスタンスを生成します。さらに、インテントは &lt;a href="http://developer.android.com/reference/android/content/Intent.html#ACTION_MEDIA_BUTTON"&gt;ACTION_MEDIA_BUTTON&lt;/a&gt; イベントを処理するあなたのアプリ内の &lt;a href="http://developer.android.com/reference/android/content/BroadcastReceiver.html"&gt;BroadcastReceiver&lt;/a&gt; コンポーネントを明示的に宣言しなければなりません。&lt;br /&gt;&lt;br /&gt;どのメディアコントロール入力がプレイヤーで処理できるかを宣言するには &lt;a href="http://developer.android.com/reference/android/media/RemoteControlClient.html#setTransportControlFlags(int)"&gt;setTransportControlFlags()&lt;/a&gt; を &lt;a href="http://developer.android.com/reference/android/media/RemoteControlClient.html"&gt;RemoteControlClient&lt;/a&gt; 上で呼びます。そのさい、&lt;a href="http://developer.android.com/reference/android/media/RemoteControlClient.html#FLAG_KEY_MEDIA_PREVIOUS"&gt;FLAG_KEY_MEDIA_PREVIOUS&lt;/a&gt; や &lt;a href="http://developer.android.com/reference/android/media/RemoteControlClient.html#FLAG_KEY_MEDIA_NEXT"&gt;FLAG_KEY_MEDIA_NEXT&lt;/a&gt; などの &lt;font color=green&gt;FLAG_KEY_MEDIA_*&lt;/font&gt; 形式のフラグを渡します。&lt;br /&gt;&lt;br /&gt;そうしたら、&lt;a href="http://developer.android.com/reference/android/media/RemoteControlClient.html"&gt;RemoteControlClient&lt;/a&gt; を &lt;a href="http://developer.android.com/reference/android/media/AudioManager.html#registerRemoteControlClient(android.media.RemoteControlClient)"&gt;MediaManager.registerRemoteControlClient()&lt;/a&gt; に渡して登録する必要があります。一度登録したら、&lt;a href="http://developer.android.com/reference/android/media/RemoteControlClient.html"&gt;RemoteControlClient&lt;/a&gt; のインスタンスを生成するときに渡した BroadcastReceiver がリモートコントロール上のボタンが押されたときに &lt;a href="http://developer.android.com/reference/android/content/Intent.html#ACTION_MEDIA_BUTTON"&gt;ACTION_MEDIA_BUTTON&lt;/a&gt; イベントを受け取ります。受け取る intent には &lt;a href="http://developer.android.com/reference/android/view/KeyEvent.html"&gt;KeyEvent&lt;/a&gt; が含まれており、&lt;a href="http://developer.android.com/reference/android/content/Intent.html#getParcelableExtra(java.lang.String)"&gt;getParcelableExtra(Intent.EXTRA_KEY_EVENT)&lt;/a&gt; でどのメディアキーが押されたかを取得することができます。&lt;br /&gt;&lt;br /&gt;再生中のメディアの情報をリモートコントロール上に表示するには、&lt;a href="http://developer.android.com/reference/android/media/RemoteControlClient.html#editMetadata(boolean)"&gt;editMetaData()&lt;/a&gt; を呼び出して、返ってきた &lt;a href="http://developer.android.com/reference/android/media/RemoteControlClient.MetadataEditor.html"&gt;RemoteControlClient.MetadataEditor&lt;/a&gt; にメタデータを追加します。メディアのアートワーク用のビットマップや、経過時間などの数値情報、トラックタイトル等のテキスト情報を提供することができます。利用可能なキーの情報は &lt;a href="http://developer.android.com/reference/android/media/MediaMetadataRetriever.html"&gt;MediaMetadataRetriever&lt;/a&gt; 内の &lt;font color=green&gt;METADATA_KEY_*&lt;/font&gt; 形式のフラグを見てください。&lt;br /&gt;&lt;br /&gt;サンプル実装として、&lt;a href="http://developer.android.com/resources/samples/RandomMusicPlayer/index.html"&gt;Random Music Player&lt;/a&gt; をみてください。このサンプルでは、Android 4.0 でリモートコントロールクライアントを有効にする互換性ロジックを提供しており、Android 2.1 以上のデバイスで引き続きサポートするようになっています。&lt;h4&gt;Media player&lt;/h4&gt;&lt;ul&gt;&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/media/MediaPlayer.html"&gt;MediaPlayer&lt;/a&gt; からオンラインメディアストリーミングでは &lt;a href="http://developer.android.com/reference/android/Manifest.permission.html#INTERNET"&gt;INTERNET&lt;/a&gt; パーミッションが必要になりました。&lt;a href="http://developer.android.com/reference/android/media/MediaPlayer.html"&gt;MediaPlayer&lt;/a&gt; をインターネット上のコンテンツを再生するのに使う場合は、&lt;a href="http://developer.android.com/reference/android/Manifest.permission.html#INTERNET"&gt;INTERNET&lt;/a&gt; パーミッションがマニフェストに追加されていることを確認してください。そうしないと Android 4.0 からメディアの再生処理が動かなくなります。&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/media/MediaPlayer.html#setSurface(android.view.Surface)"&gt;setSurface()&lt;/a&gt; で video sink として振る舞う &lt;a href="http://developer.android.com/reference/android/view/Surface.html"&gt;Surface&lt;/a&gt; を定義できます。&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/media/MediaPlayer.html#setDataSource(android.content.Context, android.net.Uri, java.util.Map&amp;lt;java.lang.String, java.lang.String&amp;gt;)"&gt;setDataSource()&lt;/a&gt; で HTTP(S) live streaming を便利にする付加的な HTTP ヘッダをリクエストに追加できます。&lt;li&gt; HTTP(S) live streaming はリクエスト全体に渡って HTTP cookies に関連します。&lt;/ul&gt;&lt;h4&gt;Media tyes&lt;/h4&gt;Android 4.0 で以下のサポートが追加されました。&lt;ul&gt;&lt;li&gt; HTTP/HTTPS live streaming protocol version 3&lt;li&gt; ADTS raw AAC audio encoding&lt;li&gt; WEBP images&lt;li&gt; Matroska video&lt;/ul&gt;より詳しい情報は &lt;a href="http://developer.android.com/guide/appendix/media-formats.html"&gt;Supported Media Formats&lt;/a&gt; を見てください。&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;■ Camera&lt;/h4&gt;&lt;a href="http://developer.android.com/reference/android/hardware/Camera.html"&gt;Camera&lt;/a&gt; クラスに顔検出と、フォーカスと測定エリアのコントロールをする新しい API が追加されました。&lt;h4&gt;Face detection&lt;/h4&gt;Camera アプリは Android の顔検出 API を使った機能をより高くすることができます。これまでは単に顔の位置を検出するだけでしたが、目や口の位置など顔の特徴も検出できるようになりました。&lt;br /&gt;&lt;br /&gt;カメラアプリで顔を検出するには、まず &lt;a href="http://developer.android.com/reference/android/hardware/Camera.html#setFaceDetectionListener(android.hardware.Camera.FaceDetectionListener)"&gt;setFaceDetectionListener()&lt;/a&gt; を呼んで &lt;a href="http://developer.android.com/reference/android/hardware/Camera.FaceDetectionListener.html"&gt;Camera.FaceDetectionListener&lt;/a&gt; を登録する必要があります。そうしたら、camera surface を開始して、&lt;a href="http://developer.android.com/reference/android/hardware/Camera.html#startFaceDetection()"&gt; startFaceDetection()&lt;/a&gt; を呼ぶことで顔検出をスタートさせることができます。&lt;br /&gt;&lt;br /&gt;カメラがカメラシーン内に1つ以上の顔を検出すると、&lt;a href="http://developer.android.com/reference/android/hardware/Camera.FaceDetectionListener.html"&gt;Camera.FaceDetectionListener&lt;/a&gt; 内の &lt;a href="http://developer.android.com/reference/android/hardware/Camera.FaceDetectionListener.html#onFaceDetection(android.hardware.Camera.Face[], android.hardware.Camera)"&gt;onFaceDetection()&lt;/a&gt; コールバックが呼ばれます。このとき、&lt;a href="http://developer.android.com/reference/android/hardware/Camera.Face.html"&gt;Camera.Face&lt;/a&gt; オブジェクトの配列が渡されます。&lt;br /&gt;&lt;br /&gt;&lt;a href="http://developer.android.com/reference/android/hardware/Camera.Face.html"&gt;Camera.Face&lt;/a&gt; クラスのインスタンスは顔検出についての複数の情報を含みます：&lt;ul&gt;&lt;li&gt; 顔の領域を表す &lt;a href="http://developer.android.com/reference/android/graphics/Rect.html"&gt;Rect&lt;/a&gt; 。カメラの現在の view フィールドからの相対値&lt;li&gt; その物体が人間の顔であるとシステムが認識した信頼度をあらわす 1 - 100 までの整数値&lt;li&gt; 複数の顔をトラックするのに利用できる識別ID&lt;li&gt; 目や口の位置を表すいくつかの &lt;a href="http://developer.android.com/reference/android/graphics/Point.html"&gt;Point&lt;/a&gt; オブジェクト&lt;/ul&gt;&lt;br /&gt;注意: 顔検出はいくつかのデバイスでサポートされていない可能性があります。そのため、まず &lt;a href="http://developer.android.com/reference/android/hardware/Camera.Parameters.html#getMaxNumDetectedFaces()"&gt;getMaxNumDetectedFaces()&lt;/a&gt; を呼んで、戻り値が 0 より大きいことをチェックしてください。また、いくつかのデバイスでは目や口の識別をサポートしていないことがありえます。その場合、&lt;a href="http://developer.android.com/reference/android/hardware/Camera.Face.html"&gt;Camera.Face&lt;/a&gt; オブジェクトには null が入ります。&lt;h4&gt;Focus and metering areas&lt;/h4&gt;カメラアプリで、カメラがフォーカスやホワイトバランスや露光の測定に使う領域をコントロールできるようになりました。両方の機能とも新しい &lt;a href="http://developer.android.com/reference/android/hardware/Camera.Area.html"&gt;Camera.Area&lt;/a&gt; クラスを使って、フォーカスや測定される現在のビューの領域を指定します。1つの&lt;a href="http://developer.android.com/reference/android/hardware/Camera.Area.html"&gt; Camera.Area&lt;/a&gt; には領域を表す &lt;a href="http://developer.android.com/reference/android/graphics/Rect.html"&gt;Rect&lt;/a&gt; と、その領域が他の領域と比べてどれだけ重要かを表すレベル（整数値）が含まれます。&lt;br /&gt;&lt;br /&gt;フォーカス領域と測定領域を設定する前に、まず &lt;a href="http://developer.android.com/reference/android/hardware/Camera.Parameters.html#getMaxNumFocusAreas()"&gt;getMaxNumFocusAreas()&lt;/a&gt; や &lt;a href="http://developer.android.com/reference/android/hardware/Camera.Parameters.html#getMaxNumMeteringAreas()"&gt;getMaxNumMeteringAreas()&lt;/a&gt; を呼んで、デバイスがそれぞれの昨日をサポートしているかチェックしてください。戻り値が 0 より大きければサポートされています。&lt;br /&gt;&lt;br /&gt;使用されるフォーカス領域や測定領域を設定するには、 &lt;a href="http://developer.android.com/reference/android/hardware/Camera.Parameters.html#setFocusAreas(java.util.List&amp;lt;android.hardware.Camera.Area&amp;gt;)"&gt;setFocusArea()&lt;/a&gt; や &lt;a href="http://developer.android.com/reference/android/hardware/Camera.Parameters.html#setFocusAreas(java.util.List&amp;lt;android.hardware.Camera.Area&amp;gt;)"&gt;setMeteringArea()&lt;/a&gt; を呼びます。そのとき、フォーカスや測定として考慮する情報を含んだ &lt;a href="http://developer.android.com/reference/android/hardware/Camera.Area.html"&gt;Camera.Area&lt;/a&gt; オブジェクトのリストをそれぞれに渡します。例えば、プレビューでユーザーがタッチした領域にフォーカスするような機能を実装する場合、タッチされた領域を &lt;a href="http://developer.android.com/reference/android/hardware/Camera.Area.html"&gt;Camera.Area&lt;/a&gt; オブジェクトに変換して、その領域をフォーカス領域としてセットします。その領域のシーンが変わっても、その領域のフォーカスと露光は継続的にアップデートされます。&lt;h4&gt;Continuous auto focus for photos&lt;/h4&gt;写真を撮るときに連続して自動フォーカス (confinuous auto focusing : CAF) させることができるようになりました。あなたのカメラアプリで CAF を有効にするには、&lt;a href="http://developer.android.com/reference/android/hardware/Camera.Parameters.html#setFocusMode(java.lang.String)"&gt;setFocusMode()&lt;/a&gt; に &lt;a href="http://developer.android.com/reference/android/hardware/Camera.Parameters.html#FOCUS_MODE_CONTINUOUS_PICTURE"&gt;FOCUS_MODE_CONTINUOUS_PICTURE&lt;/a&gt; を渡します。写真をとる準備ができたら、autoFocus() を呼びます。あなたの &lt;a href="http://developer.android.com/reference/android/hardware/Camera.AutoFocusCallback.html"&gt;Camera.AutoFocusCallback&lt;/a&gt; はフォースできたかどうかを表すコールバックを直ちに受け取ります。コールバックを受け取ったあとに CAF を再開するには、&lt;a href="http://developer.android.com/reference/android/hardware/Camera.html#cancelAutoFocus()"&gt;cancelAutoFocus()&lt;/a&gt; を呼ぶ必要があります。&lt;br /&gt;&lt;br /&gt;&lt;b&gt;注意:&lt;/b&gt; 連続自動フォーカス(CAF) はビデオ撮影時もサポートしています。その場合は API level 9 で追加された &lt;a href="http://developer.android.com/reference/android/hardware/Camera.Parameters.html#FOCUS_MODE_CONTINUOUS_VIDEO"&gt;FOCUS_MODE_CONTINUOUS_VIDEO&lt;/a&gt; を指定します。&lt;h4&gt;Other camera features&lt;/h4&gt;&lt;ul&gt;&lt;li&gt; ビデオを撮影している間、&lt;a href="http://developer.android.com/reference/android/hardware/Camera.html#takePicture(android.hardware.Camera.ShutterCallback, android.hardware.Camera.PictureCallback, android.hardware.Camera.PictureCallback)"&gt;takePicture()&lt;/a&gt; を呼ぶことでビデオセッションを中断せずに写真を撮ることができます。これを行う前に、&lt;a href="http://developer.android.com/reference/android/hardware/Camera.Parameters.html#isVideoSnapshotSupported()"&gt;isVideoSnapshotSupported()&lt;/a&gt; を呼んで、ハードウェアがサポートしているかどうか確かめるべきです。&lt;li&gt; 自動的に露光とホワイトバランスのプロパティが変化するのを防ぐために、&lt;a href="http://developer.android.com/reference/android/hardware/Camera.Parameters.html#setAutoExposureLock(boolean)"&gt;setAutoExposureLock()&lt;/a&gt; や &lt;a href="http://developer.android.com/reference/android/hardware/Camera.Parameters.html#setAutoWhiteBalanceLock(boolean)"&gt;setAutoWhiteBalanceLock()&lt;/a&gt; を呼んでこれらの値をロックすることができるようになりました。&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/hardware/Camera.html#setDisplayOrientation(int)"&gt;setDisplayOrientation()&lt;/a&gt; をプレビューが走っている間も呼べるようになりました。これまではプレビューが始まる前しか呼ぶことができなかったのですが、いつでも向きを変えられるようになりました。&lt;/ul&gt;&lt;h4&gt;Camera broadcast intents&lt;/h4&gt;&lt;ul&gt;&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/hardware/Camera.html#ACTION_NEW_PICTURE"&gt;Camera.ACTION_NEW_PICTURE&lt;/a&gt;: ユーザーが新しく写真を撮影したことを示すインテントです。ビルトインのカメラアプリは写真が撮られたあとにこのブロードキャストを投げます。サードパーティのカメラアプリも写真を撮ったあとはこのインテントをブロードキャストするべきです。&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/hardware/Camera.html#ACTION_NEW_VIDEO"&gt;Camera.ACTION_NEW_VIDEO&lt;/a&gt; : ユーザーが新しくビデオを撮影したことを示すインテントです。ビルトインのカメラアプリはビデオが録画されたあとにこのブロードキャストを投げます。サードパーティのカメラアプリもビデオを撮影したあとはこのインテントをブロードキャストするべきです。&lt;/ul&gt;&lt;br /&gt;&lt;h4&gt;■ Android Beam (NDEF Push with NFC)&lt;/h4&gt;Android Beam は "NDEF Push" として知られているプロセスを使って、NDEF message をあるデバイスから別のデバイス送る、新しい NFC 機能です。Android Beam をサポートしている2台の Android デバイスがかなり近づく（4cm くらい、通常は背面同士をタッチする）と、データ転送が初期化されます。NDEF message 内にはデバイス間で共有したいさまざまなデータを入れることができます。例えば、Android Beam を使って、People アプリはコンタクトを共有しますし、YouTube アプリは動画を共有し、ブラウザアプリは URL を共有します。&lt;br /&gt;&lt;br /&gt;Android Beam を使ってデバイス間でデータを転送するには、Activity が foreground にある間に、共有したい情報を持った &lt;a href="http://developer.android.com/reference/android/nfc/NdefMessage.html"&gt;NdefMessage&lt;/a&gt; を作成する必要があります。それから、以下の2つの内、いずれかの方法を使ってシステムに &lt;a href="http://developer.android.com/reference/android/nfc/NdefMessage.html"&gt;NdefMessage&lt;/a&gt; を渡します。&lt;ul&gt;&lt;a href="http://developer.android.com/reference/android/nfc/NdefMessage.html"&gt;&lt;li&gt; activity 中に渡すための 1つの NdefMessage&lt;/a&gt; を定義する:&lt;br /&gt;&lt;a href="http://developer.android.com/reference/android/nfc/NfcAdapter.html#setNdefPushMessage(android.nfc.NdefMessage, android.app.Activity, android.app.Activity...)"&gt;setNdefPushMessage()&lt;/a&gt; を呼んで、いつでも送りたいメッセージをセットできます。例えば、Activity の &lt;a href="http://developer.android.com/reference/android/app/Activity.html#onCreate(android.os.Bundle)"&gt;onCreate()&lt;/a&gt; 中にこのメソッドを呼びだして &lt;a href="http://developer.android.com/reference/android/nfc/NdefMessage.html"&gt;NdefMessage&lt;/a&gt; を渡すとしましょう。そうすると、Activity が foreground にあって Android Beam が別の端末との間で動いているときはいつでもシステムは &lt;a href="http://developer.android.com/reference/android/nfc/NdefMessage.html"&gt;NdefMessage&lt;/a&gt; を他のデバイスに送ります。&lt;li&gt; Android Beam が初期化されたタイミングで渡すための &lt;a href="http://developer.android.com/reference/android/nfc/NdefMessage.html"&gt;NdefMessage&lt;/a&gt; を定義する:&lt;br /&gt;&lt;a href="http://developer.android.com/reference/android/nfc/NfcAdapter.CreateNdefMessageCallback.html"&gt;NfcAdapter.CreateNdefMessageCallback&lt;/a&gt; を実装し、その実装内の &lt;a href="http://developer.android.com/reference/android/nfc/NfcAdapter.CreateNdefMessageCallback.html#createNdefMessage(android.nfc.NfcEvent)"&gt;createNdefMessage()&lt;/a&gt; メソッドで送りたい &lt;a href="http://developer.android.com/reference/android/nfc/NdefMessage.html"&gt;NdefMessage&lt;/a&gt; を返すようにします。そして、&lt;a href="http://developer.android.com/reference/android/nfc/NfcAdapter.CreateNdefMessageCallback.html"&gt;NdefAdapter.CreateNdefMessageCallback&lt;/a&gt; 実装を &lt;a href="http://developer.android.com/reference/android/nfc/NfcAdapter.html#setNdefPushMessageCallback(android.nfc.NfcAdapter.CreateNdefMessageCallback, android.app.Activity, android.app.Activity...)"&gt;setNdefPushMessageCallback()&lt;/a&gt; に渡します。&lt;br /&gt;この場合、Activity が foreground にあるときに、Android Beam が他のデバイスとの間で動くようになったときに、システムが &lt;a href="http://developer.android.com/reference/android/nfc/NfcAdapter.CreateNdefMessageCallback.html#createNdefMessage(android.nfc.NfcEvent)"&gt;createNdefMessage()&lt;/a&gt; を呼んで送りたい &lt;a href="http://developer.android.com/reference/android/nfc/NdefMessage.html"&gt;NdefMessage&lt;/a&gt; を取得します。これは、Android Beam が初期化されたとき”のみ” &lt;a href="http://developer.android.com/reference/android/nfc/NdefMessage.html"&gt;NdefMessage&lt;/a&gt; を定義することを許可します。そのため、Activity のライフサイクル全体でメッセージの内容が変わることがあります。&lt;/ul&gt;システムが他のデバイスへの NDEF message の送信に成功したときに特定のコードを1度だけ実行したこともあるでしょう。そのときは、&lt;a href="http://developer.android.com/reference/android/nfc/NfcAdapter.OnNdefPushCompleteCallback.html"&gt;NdefAdapter.OnNdefPushCompleteCallback&lt;/a&gt; を実装し、&lt;a href="http://developer.android.com/reference/android/nfc/NfcAdapter.html#setOnNdefPushCompleteCallback(android.nfc.NfcAdapter.OnNdefPushCompleteCallback, android.app.Activity, android.app.Activity...)"&gt;setNdefPushCompleteCallback()&lt;/a&gt; でその実装を渡すことでできます。システムはメッセージが配送されたときに &lt;a href="http://developer.android.com/reference/android/nfc/NfcAdapter.OnNdefPushCompleteCallback.html#onNdefPushComplete(android.nfc.NfcEvent)"&gt;onNdefPushComplete()&lt;/a&gt; を呼び出します。&lt;br /&gt;&lt;br /&gt;受信側のデバイスでは、システムは NDEF Push メッセージを通常の NFC タグと同じ方法で処理します。システムは Activity を開始するために、&lt;a href="http://developer.android.com/reference/android/nfc/NdefMessage.html"&gt;NdefMessage&lt;/a&gt; 内の最初の &lt;a href="http://developer.android.com/reference/android/nfc/NdefRecord.html"&gt;NdefRecord&lt;/a&gt; の URL もしくは MIME type がセットされた  &lt;a href="http://developer.android.com/reference/android/nfc/NfcAdapter.html#ACTION_NDEF_DISCOVERED"&gt;ACTION_NDEF_DISCOVERED&lt;/a&gt; のインテントを投げます。応答したい Activity の intent filter にその URL や MIME type を設定して処理したいものにだけ反応することができます。Tag Dispatch のより詳しい情報は &lt;a href="http://developer.android.com/guide/topics/nfc/index.html#dispatch"&gt;NFC&lt;/a&gt; developer guide を見てください。&lt;br /&gt;&lt;br /&gt;もし、&lt;a href="http://developer.android.com/reference/android/nfc/NdefMessage.html"&gt;NdefMessage&lt;/a&gt; で URI を運びたいなら、そのための便利な &lt;a href="http://developer.android.com/reference/android/nfc/NdefRecord.html#createUri(android.net.Uri)"&gt;createUri&lt;/a&gt; メソッドを使って、1つの文字列もしくは1つの &lt;a href="http://developer.android.com/reference/android/net/Uri.html"&gt;Uri&lt;/a&gt; オブジェクトから &lt;a href="http://developer.android.com/reference/android/nfc/NdefRecord.html"&gt;NdefRecound&lt;/a&gt; を作成することができます。URI が Android Beam イベント中にあなたのアプリが受信したい特別なフォーマットであるならば、渡された NDEF message を受け取るために、同じ URI scheme を使って Activity に intent filter をセットしてください。&lt;br /&gt;&lt;br /&gt;また、別のアプリが同じ intent action の filter を設定していても、渡された NDEF message をあなたのアプリが確実に処理することを保証するために、渡す &lt;a href="http://developer.android.com/reference/android/nfc/NdefMessage.html"&gt;NdefMessage&lt;/a&gt; に "Android application record" も含めてください。アプリのパッケージ名を渡して &lt;a href="http://developer.android.com/reference/android/nfc/NdefRecord.html#createApplicationRecord(java.lang.String)"&gt;createApplicationRecord()&lt;/a&gt; を呼ぶことで Android application record を作成することができます。他のデバイスが application record の入った NDEF message を受信して、その intent を処理できる activity を含むアプリが複数あった場合、システムは常にそのメッセージを application record との一致によってあなたのアプリの activity に渡します。ターゲットデバイスにあなたのアプリがインストールされていない場合は、Android application record を使ってシステムは Android Market を起動し、そのアプリをインストールできるようユーザーを導きます。&lt;br /&gt;&lt;br /&gt;NDEF Push でメッセージ送る NFC API をあなたのアプリが使っていない場合、Android は通常の振る舞いを提供します。あなたのアプリがデバイス foreground にあって、Android Beam が他の Android デバイスから呼ばれたら、一方のデバイスはあなたのアプリを識別する Android application record を含んだ NDEF message を受け取ります。受け取ったデバイスにそのアプリがインストールされていたら、システムはそれを起動し、インストールされていなかったら、Android Market を開いて、アプリをインストールできるようにユーザーを導きます。&lt;br /&gt;&lt;br /&gt;&lt;a href="http://developer.android.com/guide/topics/nfc/nfc.html"&gt;NFC Basics&lt;/a&gt; developer guide で Android Beam と NFC 機能についてより詳しく読むことができます。Android Beam を使ったサンプルコードは &lt;a href="http://developer.android.com/resources/samples/AndroidBeamDemo/src/com/example/android/beam/Beam.html"&gt;Android Beam Demo&lt;/a&gt; を見てください。&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;■ Wi-Fi Direct&lt;/h4&gt;hotspot やインターネット接続なに Android デバイス間や他のタイプのデバイスと peer-to-peer (P2P) 接続するための Wi-Fi Direct をサポートするようになりました。Android フレームワークは Wi-Fi P2P API のセットを提供します。これを使うことで、Wi-Fi Direct をサポートしているデバイスを見つけて接続し、Bluetooth 接続よりも長い距離で速い通信ができます。&lt;br /&gt;&lt;br /&gt;新しい &lt;a href="http://developer.android.com/reference/android/net/wifi/p2p/package-summary.html"&gt;android.net.wifi.p2p&lt;/a&gt; パッケージには Wi-Fi で peer-to-peer 接続を行うための全ての API が含まれています。もっとも重要なクラスは &lt;a href="http://developer.android.com/reference/android/net/wifi/p2p/WifiP2pManager.html"&gt;WifiP2pManager&lt;/a&gt; です。 &lt;a href="http://developer.android.com/reference/android/app/Activity.html#getSystemService(java.lang.String)"&gt;getSystemService(WIFI_P2P_SERVICE)&lt;/a&gt; を呼ぶことで取得することができます。&lt;a href="http://developer.android.com/reference/android/net/wifi/p2p/WifiP2pManager.html"&gt;WifiP2pManager&lt;/a&gt; に含まれる API では以下のことができます:&lt;ul&gt;&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/net/wifi/p2p/WifiP2pManager.html#initialize(android.content.Context, android.os.Looper, android.net.wifi.p2p.WifiP2pManager.ChannelListener)"&gt;initialize()&lt;/a&gt; を呼んで P2P 接続のための初期化を行う&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/net/wifi/p2p/WifiP2pManager.html#discoverPeers(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pManager.ActionListener)"&gt;descoverPeers()&lt;/a&gt; を呼んで近くのデバイスを見つける&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/net/wifi/p2p/WifiP2pManager.html#connect(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pConfig, android.net.wifi.p2p.WifiP2pManager.ActionListener)"&gt;connect()&lt;/a&gt; を呼んで P2P 接続を開始する&lt;li&gt; その他いろいろ&lt;/ul&gt;その他いくつかのインタフェースとクラスも同じく必要です:&lt;ul&gt;&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/net/wifi/p2p/WifiP2pManager.ActionListener.html"&gt;WifiP2pManager.ActionListener&lt;/a&gt; インタフェースによって、デバイスの探索や接続の処理が成功または失敗したときにコールバックを受信できます。&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/net/wifi/p2p/WifiP2pManager.PeerListListener.html"&gt;WifiP2pManager.PeerListListener&lt;/a&gt; インタフェースによって、見つけた peers の情報を受け取ることができます。コールバックが提供する &lt;a href="http://developer.android.com/reference/android/net/wifi/p2p/WifiP2pDeviceList.html"&gt;WifiP2pDeviceList&lt;/a&gt; から範囲内の各デバイスの &lt;a href="http://developer.android.com/reference/android/net/wifi/p2p/WifiP2pDevice.html"&gt;WifiP2pDevice&lt;/a&gt; オブジェクトが取得でき、これにはデバイス名、アドレス、デバイスタイプ、デバイスがサポートするWPS設定などの情報が入っています。&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/net/wifi/p2p/WifiP2pManager.GroupInfoListener.html"&gt;WifiP2pManager.GroupInfoListener&lt;/a&gt; インタフェースによって、P2P グループの情報を受け取ることができます。コールバックが提供する &lt;a href="http://developer.android.com/reference/android/net/wifi/p2p/WifiP2pGroup.html"&gt;WifiP2pGroup&lt;/a&gt; オブジェクトには、オーナー、ネットワーク名、パスフレーズなどのグループ情報がふくまれています。&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/net/wifi/p2p/WifiP2pManager.ConnectionInfoListener.html"&gt;WifiP2pManager.ConnectionInfoListener&lt;/a&gt; インタフェースによって、現在の接続についての情報を受け取ることができます。コールバックが提供する &lt;a href="http://developer.android.com/reference/android/net/wifi/p2p/WifiP2pInfo.html"&gt;WifiP2pInfo&lt;/a&gt; オブジェクトには、グループが形成されたかどうかや、誰がグループのオーナーかなどの情報が含まれています。&lt;/ul&gt;Wi-Fi P2P API を使うには、次のユーザーパーミッションが必要です。&lt;ul&gt;&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/Manifest.permission.html#ACCESS_WIFI_STATE"&gt;ACCESS_WIFI_STATE&lt;/a&gt;&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/Manifest.permission.html#CHANGE_WIFI_STATE"&gt;CHANGE_WIFI_STATE&lt;/a&gt;&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/Manifest.permission.html#INTERNET"&gt;INTERNET&lt;/a&gt; (あなたのアプリが技術的にインターネットに接続しなくても、標準の java socket で Wi-Fi Direct peers を使って通信するにはインタネットのパーミッションが必要です）&lt;/ul&gt;Android システムは Wi-Fi P2P の特定のイベントごとに異なるアクションをブロードキャストします。&lt;ul&gt;&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/net/wifi/p2p/WifiP2pManager.html#WIFI_P2P_CONNECTION_CHANGED_ACTION"&gt;WIFI_P2P_CONNECTION_CHANGED_ACTION&lt;/a&gt; : P2P 接続の状態が変化した。&lt;a href="http://developer.android.com/reference/android/net/wifi/p2p/WifiP2pManager.html#EXTRA_WIFI_P2P_INFO"&gt;EXTRA_WIFI_P2P_INFO&lt;/a&gt; に &lt;a href="http://developer.android.com/reference/android/net/wifi/p2p/WifiP2pInfo.html"&gt;WifiP2pInfo&lt;/a&gt; オブジェクトが、&lt;a href="http://developer.android.com/reference/android/net/wifi/p2p/WifiP2pManager.html#EXTRA_NETWORK_INFO"&gt;EXTRA_NETWORK_INFO&lt;/a&gt; に &lt;a href="http://developer.android.com/reference/android/net/NetworkInfo.html"&gt;NetworkInfo&lt;/a&gt; オブジェクトが含まれている。&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/net/wifi/p2p/WifiP2pManager.html#WIFI_P2P_STATE_CHANGED_ACTION"&gt;WIFI_P2P_STATE_CHANGED_ACTION&lt;/a&gt; : P2P の有効／無効状態が切り替わった。&lt;a href="http://developer.android.com/reference/android/net/wifi/p2p/WifiP2pManager.html#EXTRA_WIFI_STATE"&gt;EXTRA_WIFI_STATE&lt;/a&gt; には &lt;a href="http://developer.android.com/reference/android/net/wifi/p2p/WifiP2pManager.html#WIFI_P2P_STATE_DISABLED"&gt;WIFI_P2P_STATE_DISABLED&lt;/a&gt; か &lt;a href="http://developer.android.com/reference/android/net/wifi/p2p/WifiP2pManager.html#WIFI_P2P_STATE_ENABLED"&gt;WIFI_P2P_STATE_ENABLED&lt;/a&gt; が含まれている。&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/net/wifi/p2p/WifiP2pManager.html#WIFI_P2P_PEERS_CHANGED_ACTION"&gt;WIFI_P2P_PEERS_CHANGED_ACTION&lt;/a&gt; : peer デバイスのリストが変化した。&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/net/wifi/p2p/WifiP2pManager.html#WIFI_P2P_THIS_DEVICE_CHANGED_ACTION"&gt;WIFI_P2P_THIS_DEVICE_CHANGED_ACTION&lt;/a&gt; : このデバイスの詳細が変化した。&lt;/ul&gt;より詳しい情報は &lt;a href="http://developer.android.com/reference/android/net/wifi/p2p/WifiP2pManager.html"&gt;WifiP2pManager&lt;/a&gt; ドキュメントを見てください。また、サンプルアプリは &lt;a href="http://developer.android.com/resources/samples/WiFiDirectDemo/index.html"&gt;Wi-Fi Direct Demo&lt;/a&gt; です。&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;■ Bluetooth Health Devices&lt;/h4&gt;Bluetooth Health Profile デバイスをサポートするようになりました。これにより、心拍モニターや血液メーター、体温計、測定器などの医療デバイスと Bluetooth を使って通信するアプリを作成できます。&lt;br /&gt;&lt;br /&gt;通常のヘッドセットや A2DP profile デバイスと同じように、&lt;a href="http://developer.android.com/reference/android/bluetooth/BluetoothAdapter.html#getProfileProxy(android.content.Context, android.bluetooth.BluetoothProfile.ServiceListener, int)"&gt;getProfileProxy()&lt;/a&gt; に &lt;a href="http://developer.android.com/reference/android/bluetooth/BluetoothProfile.ServiceListener.html"&gt;BluetoothProfile.ServiceListener&lt;/a&gt;  と &lt;a href="http://developer.android.com/reference/android/bluetooth/BluetoothProfile.html#HEALTH"&gt;HEALTH&lt;/a&gt; profile タイプを渡して呼んで、profile proxy オブジェクトとの接続を確立します。&lt;br /&gt;&lt;br /&gt;一度 Health Profile proxy (&lt;a href="http://developer.android.com/reference/android/bluetooth/BluetoothHealth.html"&gt;BluetoothHealth&lt;/a&gt; オブジェクト) を取得したら、次の新しい Bluetooth クラスを呼び出して、ペアの医療デバイスと接続や通信を行います。&lt;ul&gt;&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/bluetooth/BluetoothHealthCallback.html"&gt;BluetoothHealthCallback&lt;/a&gt; : このクラスを継承して、アプリの登録状態と Bluetooth channel 状態の変化のアップデート受け取るためのコールバックメソッドを実装する必要があります。&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/bluetooth/BluetoothHealthAppConfiguration.html"&gt;BluetoothHealthAppConfiguration&lt;/a&gt; : あなたの &lt;a href="http://developer.android.com/reference/android/bluetooth/BluetoothHealthCallback.html"&gt;BluetoothHealthCallback&lt;/a&gt; へコールバックしている間、このオブジェクトのインスタンスを受け取ります。これには利用可能な Bluetooth 医療デバイスについての設定情報が含まれています。これらの情報は、 &lt;a href="http://developer.android.com/reference/android/bluetooth/BluetoothHealth.html"&gt;BluetoothHealth&lt;/a&gt; API で接続の初期化や終了などいくつかの操作を実行するのに必要です。&lt;/ul&gt;Bluetooth Health Profile のより詳しい情報は &lt;a href="http://developer.android.com/reference/android/bluetooth/BluetoothHealth.html"&gt;BluetoothHealth&lt;/a&gt; ドキュメントを見てください。&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;■ Accessibility&lt;/h4&gt;Android 4.0 では視覚的にハンディのあるユーザーの accessibility を改善しました。新しく explore-by-touch mode が追加され、view コンテンツについてより情報を提供したり、高度な accessibility サービスを開発するために API が拡張されました。&lt;h4&gt;Explore-by-touch mode&lt;/h4&gt;画面上をタッチしたりドラックすることでコンテンツの説明する音声を聞くことができ、視覚のない人でも画面上のコンテンツを探すことができます。explore-by-touch mode は仮想的なカーソルとして動作し、d-pad や trackball の操作でスクリーンリーダーが説明文を見つけるのと同じ方法で、画面上での "hover" をシミュレートして音声案内する情報を見つけます。読まれる情報は &lt;a href="http://developer.android.com/reference/android/R.attr.html#contentDescription"&gt;android:contentDescription&lt;/a&gt; と &lt;a href="http://developer.android.com/reference/android/view/View.html#setContentDescription(java.lang.CharSequence)"&gt;setContentDescription()&lt;/a&gt; で提供されます。つまり、アプリの view に対して説明文を提供するよう心がけてください。特に &lt;a href="http://developer.android.com/reference/android/widget/ImageButton.html"&gt;ImageButton&lt;/a&gt;, &lt;a href="http://developer.android.com/reference/android/widget/EditText.html"&gt;EditText&lt;/a&gt;, &lt;a href="http://developer.android.com/reference/android/widget/ImageView.html"&gt;ImageView&lt;/a&gt; など通常状態で説明文を含まないものは気をつけてください。&lt;h4&gt;Accessibility for views&lt;/h4&gt;スクリーンリーダーのような accessibility サービスで利用できる情報を拡張するために、カスタム &lt;a href="http://developer.android.com/reference/android/view/View.html"&gt;View&lt;/a&gt; コンポーネントで accessibility イベントで新しいコールバックメソッドを実装できます。&lt;br /&gt;&lt;br /&gt;最初に知っておくべき重要なことは、Android 4.0 で &lt;a href="http://developer.android.com/reference/android/view/View.html#sendAccessibilityEvent(int)"&gt;sendAccessibilityEvent()&lt;/a&gt; メソッドの動作が変わったということです。以前の Android バージョンでは、ユーザーがデバイスの accessibility サービスを有効にして、クリックやホバーなどの入力イベントがおこると、対応する view の &lt;a href="http://developer.android.com/reference/android/view/View.html#sendAccessibilityEvent(int)"&gt;sendAccessibilityEvent()&lt;/a&gt; が呼ばれていました。以前は &lt;a href="http://developer.android.com/reference/android/view/View.html#sendAccessibilityEvent(int)"&gt;sendAccessibilityEvent()&lt;/a&gt; の実装は &lt;a href="http://developer.android.com/reference/android/view/accessibility/AccessibilityEvent.html"&gt;AccessibilityEvent&lt;/a&gt; を初期化し、&lt;a href="http://developer.android.com/reference/android/view/accessibility/AccessibilityManager.html"&gt;AccessibilityManager&lt;/a&gt; に送っていました。新しい動作では、view や親 view がコンテキスト情報をイベントに追加できるようにするための追加されたコールバックメソッドが含まれます : &lt;ul&gt;&lt;li&gt; 呼び出されたとき、&lt;a href="http://developer.android.com/reference/android/view/View.html#sendAccessibilityEvent(int)"&gt;sendAccessibilityEvent()&lt;/a&gt; と &lt;a href="http://developer.android.com/reference/android/view/View.html#sendAccessibilityEventUnchecked(android.view.accessibility.AccessibilityEvent)"&gt;sendAccessibilityEventUnchecked()&lt;/a&gt; メソッドは http://developer.android.com/reference/android/view/View.html#onInitializeAccessibilityEvent(android.view.accessibility.AccessibilityEvent) へ持ち越されます。&lt;br /&gt;&lt;a href="http://developer.android.com/reference/android/view/View.html"&gt;View&lt;/a&gt; のカスタム実装として 付加的な accessibility 情報を &lt;a href="http://developer.android.com/reference/android/view/accessibility/AccessibilityEvent.html"&gt;AccessibilityEvent&lt;/a&gt; につけるために &lt;a href="http://developer.android.com/reference/android/view/View.html#onInitializeAccessibilityEvent(android.view.accessibility.AccessibilityEvent)"&gt;onInitializeAccessibilityEvent()&lt;/a&gt; を実装したいでしょう。しかし、標準のコンテンツ内容やアイテムのインデックスなどデフォルト情報を提供するために親の実装も呼ぶべきです。このコールバックでは付加的なテキストコンテンツを追加するべきではありません。それは次で行います。&lt;li&gt; 一度初期化され、イベントがテキスト情報を移すべきいくつかのタイプの1つだった場合、view は &lt;a href="http://developer.android.com/reference/android/view/View.html#dispatchPopulateAccessibilityEvent(android.view.accessibility.AccessibilityEvent)"&gt;dispatchPopulateAccessibilityEvent()&lt;/a&gt; の呼び出しを受け取り、&lt;a href="http://developer.android.com/reference/android/view/View.html#onPopulateAccessibilityEvent(android.view.accessibility.AccessibilityEvent)"&gt;onPopulateAccessibilityEvent()&lt;/a&gt; コールバックに持ち越されます。&lt;br /&gt;View のカスタム実装は、&lt;a href="http://developer.android.com/reference/android/R.attr.html#contentDescription"&gt;android:contentDescription&lt;/a&gt; テキストが見つからないもしくは十分でないなら、通常、 &lt;a href="http://developer.android.com/reference/android/view/View.html#onPopulateAccessibilityEvent(android.view.accessibility.AccessibilityEvent)"&gt;onPopulateAccessibilityEvent()&lt;/a&gt; を実装して追加する付加的なテキストコンテンツを &lt;a href="http://developer.android.com/reference/android/view/accessibility/AccessibilityEvent.html"&gt;AccessibilityEvent&lt;/a&gt; に追加してください。&lt;a href="http://developer.android.com/reference/android/view/accessibility/AccessibilityEvent.html"&gt;AccessibilityEvent&lt;/a&gt; にテキスト情報を追加するには &lt;a href="http://developer.android.com/reference/android/view/accessibility/AccessibilityRecord.html#getText()"&gt;getText()&lt;/a&gt;.&lt;a href="http://developer.android.com/reference/java/util/List.html#add(E)"&gt;add()&lt;/a&gt; を呼びます。&lt;li&gt; この時点で View は &lt;a href="http://developer.android.com/reference/android/view/ViewGroup.html#requestSendAccessibilityEvent(android.view.View, android.view.accessibility.AccessibilityEvent)"&gt;requestSendAccessibilityEvent()&lt;/a&gt; を親 view 上で呼んで View 階層にイベントを渡します。イベントが最終的に root view に届くまでの間、各親 view は &lt;a href="http://developer.android.com/reference/android/view/accessibility/AccessibilityRecord.html"&gt;AccessibilityRecord&lt;/a&gt; を追加することで accessibility 情報を増やすチャンスがあります。イベントが root view に届くと、&lt;a href="http://developer.android.com/reference/android/view/View.html#sendAccessibilityEvent(int)"&gt;sendAccessibilityEvent()&lt;/a&gt; を使って &lt;a href="http://developer.android.com/reference/android/view/accessibility/AccessibilityManager.html"&gt;AccessibilityManager&lt;/a&gt; にイベントを渡します。&lt;/ul&gt;&lt;a href="http://developer.android.com/reference/android/view/View.html"&gt;View&lt;/a&gt; クラスを継承するときに便利な上記の新しいメソッドに加えて、&lt;a href="http://developer.android.com/reference/android/view/View.AccessibilityDelegate.html"&gt;AccessibilityDelegate&lt;/a&gt; を継承して view に &lt;a href="http://developer.android.com/reference/android/view/View.html#setAccessibilityDelegate(android.view.View.AccessibilityDelegate)"&gt;setAccessibilityDelegate()&lt;/a&gt; を設定することで、任意の &lt;a href="http://developer.android.com/reference/android/view/View.html"&gt;View&lt;/a&gt; のイベントコールバックに介入することもできます。こうした場合、view 内の各 accessibility メソッドは delegate 内の対応するメソッドに呼び出しを持ち越します。例えば、view が &lt;a href="http://developer.android.com/reference/android/view/View.html#onPopulateAccessibilityEvent(android.view.accessibility.AccessibilityEvent)"&gt;onPopulateAccessibilityEvent()&lt;/a&gt; の呼び出しを受けたとすると、それは&lt;a href="http://developer.android.com/reference/android/view/View.AccessibilityDelegate.html"&gt; View.AccessibilityDelegate&lt;/a&gt; 内の同じメソッドにも渡されます。delegate で処理されないメソッドはすぐにデフォルトの動作に戻ってきます。これにより、&lt;a href="http://developer.android.com/reference/android/view/View.html"&gt;View&lt;/a&gt; クラスを継承せずに必要なメソッドだけを上書きできます。&lt;br /&gt;&lt;br /&gt;新しい accessibility API をサポートしつつ、Android バージョン 4.0 以前との互換性を維持したい場合、後方互換性を持つようにデザインされた accessibility API を提供する最新バージョンの &lt;i&gt;v4 support library&lt;/i&gt; (&lt;a href="http://developer.android.com/sdk/compatibility-library.html"&gt;Compatibility Package, r4&lt;/a&gt; に含まれる) のユーティリティクラスセットを使って実現できます。&lt;h4&gt;Accessibility services&lt;/h4&gt;accessibility service を開発しているなら、いくつかの accessibility イベントについての情報は、ユーザーにより高度な accessibility フィードバックを可能にするために大幅に拡張されています。特に、イベントは View の物体に基づいて生成され、よりよいコンテキスト情報を提供し、accessibility service は付加的な view 情報の取得と特別なケースを扱うために view 階層をさかのぼることができます。もしあなたがスクリーンリーダーのような accessibility service を開発しているなら、次の手順で付加的なコンテンツ情報の追加と view 階層をさかのぼることができます。&lt;ul&gt;&lt;li&gt; アプリから&lt;a href="http://developer.android.com/reference/android/view/accessibility/AccessibilityEvent.html"&gt;AccessibilityEvent&lt;/a&gt; を受け取ったら、&lt;a href="http://developer.android.com/reference/android/view/accessibility/AccessibilityEvent.html#getRecord(int)"&gt;AccessibilityEvent.getRecord()&lt;/a&gt; を呼んで特定の&lt;a href="http://developer.android.com/reference/android/view/accessibility/AccessibilityRecord.html"&gt;AccessibilityRecord&lt;/a&gt;（1つのイベントにはいくつかの record が存在する可能性があります）を取得します。&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/view/accessibility/AccessibilityEvent.html"&gt;AccessibilityEvent&lt;/a&gt; もしくは個々の &lt;a href="http://developer.android.com/reference/android/view/accessibility/AccessibilityRecord.html"&gt;AccessibilityRecord&lt;/a&gt; に対して &lt;a href="http://developer.android.com/reference/android/view/accessibility/AccessibilityRecord.html#getSource()"&gt;getSource()&lt;/a&gt; を呼んで &lt;a href="http://developer.android.com/reference/android/view/accessibility/AccessibilityNodeInfo.html"&gt;AccessibilityNodeInfo&lt;/a&gt; オブジェクトを取得することができます。&lt;br /&gt;1つの &lt;a href="http://developer.android.com/reference/android/view/accessibility/AccessibilityNodeInfo.html"&gt;AccessibilityNodeInfo&lt;/a&gt; は window コンテンツの1つのノードを表し、ノードの accessibility 情報を取得できます。&lt;a href="http://developer.android.com/reference/android/view/accessibility/AccessibilityEvent.html"&gt;AccessibilityEvent&lt;/a&gt; から返された &lt;a href="http://developer.android.com/reference/android/view/accessibility/AccessibilityNodeInfo.html"&gt;AccessibilityNodeInfo&lt;/a&gt; オブジェクトはイベント元の情報を持ち、&lt;a href="http://developer.android.com/reference/android/view/accessibility/AccessibilityRecord.html"&gt;AccessibilityRecord&lt;/a&gt; から返された AccessibilityNodeInfo はイベント元の前の情報を持ちます。&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/view/accessibility/AccessibilityNodeInfo.html"&gt;AccessibilityNodeInfo&lt;/a&gt; で&lt;a href="http://developer.android.com/reference/android/view/accessibility/AccessibilityNodeInfo.html#getParent()"&gt; getParent()&lt;/a&gt; や &lt;a href="http://developer.android.com/reference/android/view/accessibility/AccessibilityNodeInfo.html#getChild(int)"&gt;getChild()&lt;/a&gt; を呼ぶことで view 階層をさかのぼるための情報を取得できます。また、ノードに子 view を追加することもできます。&lt;/ul&gt;あなたのアプリを accessibility service としてシステムに公開するには、&lt;a href="http://developer.android.com/reference/android/accessibilityservice/AccessibilityServiceInfo.html"&gt;AccessibilityServiceInfo&lt;/a&gt; に対応する XML 設定フィアルを宣言する必要があります。accessibility service を作るためのより詳しい情報は &lt;a href="http://developer.android.com/reference/android/accessibilityservice/AccessibilityService.html"&gt;AccessibilityService&lt;/a&gt; と &lt;a href="http://developer.android.com/reference/android/accessibilityservice/AccessibilityService.html#SERVICE_META_DATA"&gt;SERVICE_META_DATA&lt;/a&gt; を見てください。&lt;h4&gt;Other accessibility APIs&lt;/h4&gt;デバイス accessibility 状態に興味があるなら、&lt;a href="http://developer.android.com/reference/android/view/accessibility/AccessibilityManager.html"&gt;AccessibilityManager&lt;/a&gt; で以下のようないつくかの新しい API が使えます : &lt;ul&gt;&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/view/accessibility/AccessibilityManager.AccessibilityStateChangeListener.html"&gt;AccessibilityManager.AccessibilityStateChangeListener&lt;/a&gt; は accessibility が有効／無効になったときにコールバックを受け取るためのインタフェースです。&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/view/accessibility/AccessibilityManager.html#getEnabledAccessibilityServiceList(int)"&gt;getEnabledAccessibilityServiceList()&lt;/a&gt; は現在有効になっている accessibility についての情報を提供します。&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/view/accessibility/AccessibilityManager.html#isTouchExplorationEnabled()"&gt;isTouchExplorationEnabled()&lt;/a&gt; は explore-by-touch mode が有効になっているかどうかを返します。&lt;/ul&gt;&lt;br /&gt;&lt;h4&gt;■ Spell Checker Services&lt;/h4&gt;新しい spell checker フレームワークによって、input method フレームワーク（IME用）と似た方法でスペルチェッカーをアプリで作ることができるようになりました。新しいスペルチェッカーを作るには、&lt;a href="http://developer.android.com/reference/android/service/textservice/SpellCheckerService.html"&gt;SpellCheckerService&lt;/a&gt; を継承したクラスを実装し、インタフェースのコールバックメソッドで提供される文字列に基づいてスペル候補を提供する &lt;a href="http://developer.android.com/reference/android/service/textservice/SpellCheckerService.Session.html"&gt;SpellCheckerService.Session&lt;/a&gt; クラスを継承する必要があります。&lt;a href="http://developer.android.com/reference/android/service/textservice/SpellCheckerService.Session.html"&gt;SpellCheckerService.Session&lt;/a&gt; コールバックメソッドでは、&lt;a href="http://developer.android.com/reference/android/view/textservice/SuggestionsInfo.html"&gt;SuggestionsInfo&lt;/a&gt; オブジェクトとしてスペル候補を返します。&lt;br /&gt;&lt;br /&gt;spell checker service を持つアプリは、このサービスによって必要とされる &lt;a href="http://developer.android.com/reference/android/Manifest.permission.html#BIND_TEXT_SERVICE"&gt;BIND_TEXT_SERVICE&lt;/a&gt; パーミッションを宣言しなければなりません。また、そのサービスの intent filter として &lt;font color=green&gt;&amp;lt;action android:name="android.service.textservice.SpellCheckerService" /&amp;gt;&lt;/font&gt;を宣言し、&lt;font color=green&gt;&amp;lt;meta-data&amp;gt;&lt;/font&gt; エレメントでスペルチェッカーの設定情報を宣言する必要もあります。&lt;br /&gt;&lt;br /&gt;サンプルコードはサンプルアプリの &lt;a href="http://developer.android.com/resources/samples/SpellChecker/SampleSpellCheckerService/index.html"&gt;Spell Checker&lt;/a&gt; を見てください。&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;■ Text-to-speech Engines&lt;/h4&gt;Android の text-to-speech (TTS) API が大幅に拡張され、アプリがより簡単に custom TTS eingine を実装できるようになりました。TTS エンジンを使いたいアプリはエンジンを選択するためのいくつかの新しい API を使うことができます。&lt;h4&gt;Using text-to-speech engines&lt;/h4&gt;Android の以前のバージョンでは、システムが提供する TTS engine や &lt;a href="http://developer.android.com/reference/android/speech/tts/TextToSpeech.html#setEngineByPackageName(java.lang.String)"&gt;setEngineByPackageName()&lt;/a&gt; を使ってセットされた custom engine を利用して text-to-speech(TTS) 操作を行う &lt;a href="http://developer.android.com/reference/android/speech/tts/TextToSpeech.html"&gt;TextToSpeech&lt;/a&gt; クラスを使うことができました。Android 4.0 では、&lt;a href="http://developer.android.com/reference/android/speech/tts/TextToSpeech.html#setEngineByPackageName(java.lang.String)"&gt;setEngineByPackageName()&lt;/a&gt; メソッドは廃止され、TTS engine のパッケージ名を受け取る新しい &lt;a href="http://developer.android.com/reference/android/speech/tts/TextToSpeech.html"&gt;TextToSpeech&lt;/a&gt; コンストラクタを使って engine を指定できるようになりました。&lt;br /&gt;&lt;br /&gt;また、&lt;a href="http://developer.android.com/reference/android/speech/tts/TextToSpeech.html#getEngines()"&gt;getEngines()&lt;/a&gt; で利用可能な TTS engines を検索することもできます。このメソッドは &lt;a href="http://developer.android.com/reference/android/speech/tts/TextToSpeech.EngineInfo.html"&gt;TextToSpeech.EngineInfo&lt;/a&gt; オブジェクトのリストを返します。このオブジェクトには engine のアイコン、ラベル、パッケージ名などのメタデータが含まれます。&lt;h4&gt;Building text-to-speech engines&lt;/h4&gt;以前は、custom engine はドキュメント化されていない native header file を使ってビルドされている必要がありました。Android 4.0 では、TTS engine を作成するためのフレームワーク API のセットがそろっています。&lt;br /&gt;&lt;br /&gt;ベースのセットアップとして、&lt;a href="http://developer.android.com/reference/android/speech/tts/TextToSpeech.Engine.html#INTENT_ACTION_TTS_SERVICE"&gt;INTENT_ACTION_TTS_SERVICE&lt;/a&gt; intent に応答する &lt;a href="http://developer.android.com/reference/android/speech/tts/TextToSpeechService.html"&gt;TextToSpeechService&lt;/a&gt; の実装が必要です。TTS engine の一番重要な処理は &lt;a href="http://developer.android.com/reference/android/speech/tts/TextToSpeechService.html"&gt;TextToSpeechService&lt;/a&gt; を継承したサービス内の &lt;a href="http://developer.android.com/reference/android/speech/tts/TextToSpeechService.html#onSynthesizeText(android.speech.tts.SynthesisRequest, android.speech.tts.SynthesisCallback)"&gt;onSynthesizeText()&lt;/a&gt; 中に行います。システムはこのメソッドに次の2つのオブジェクトを渡します : &lt;ul&gt;&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/speech/tts/SynthesisRequest.html"&gt;SynthesisRequest&lt;/a&gt;: 合成するテキスト、ロケール、話す速度、声の高さなどいくつかのデータを含む&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/speech/tts/SynthesisCallback.html"&gt;SynthesisCallback&lt;/a&gt;: 話されたデータの結果を streaming audio として TTS engine が届けるためのインタフェース。最初に engine は &lt;a href="http://developer.android.com/reference/android/speech/tts/SynthesisCallback.html#start(int, int, int)"&gt;start()&lt;/a&gt; を呼んで engine が audio を届ける準備ができていることを示す。それから、&lt;a href="http://developer.android.com/reference/android/speech/tts/SynthesisCallback.html#audioAvailable(byte[], int, int)"&gt;audioAvailable()&lt;/a&gt; を呼んで byte buffer の audio data を渡す。全ての audio を渡し終わったら &lt;a href="http://developer.android.com/reference/android/speech/tts/SynthesisCallback.html#done()"&gt;done()&lt;/a&gt; を呼ぶ&lt;/ul&gt;フレームワークは TTS engine を作成するための（本当の） API をサポートし、native code をサポートするための実装は削除されました。compatibility layer についてのブログポストを見てください。古い TTS engine を新しいフレームワークに変換する方法がわかります。&lt;br /&gt;&lt;br /&gt;新しい API を使った TTS engine の例は &lt;a href="http://developer.android.com/resources/samples/TtsEngine/index.html"&gt;Text To Speech Engine&lt;/a&gt; サンプルアプリを見てください。&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;■ Network Usage&lt;/h4&gt;Android 4.0 では、アプリケーションが使っているネットワークデータがどのくらいあるのかを、ユーザーが正確なビジュアル（グラフとか）で見れるようになりました。ユーザーは設定アプリで、個々のアプリに対してネットワークデータ使用のリミットを設定できたり、バックグラウンドデータの使用を無効にすることもできます。ユーザーがアプリのデータへのアクセスを無効にするのを避けるために、効果的にデータ接続を使い、接続に依存した使用方法を調整する戦略を立てるべきです。&lt;br /&gt;&lt;br /&gt;もしあなたのアプリが多くのネットワーク通信を行っているなら、ユーザーがアプリのデータ習慣（どのくらいの頻度でデータをシンクするのか、Wi-Fi のときだけアップロード／ダウンロードを行うかどうか、ローミング中にデータを使うかどうか、など）をコントロールするための設定を提供するべきです。これらのコントロールが利用可能であれば、データ通信がリミットに達して、ユーザーがあなたのアプリのデータへのアクセスを無効にすることはより少なくなるでしょう。これらの設定に preference activity を提供するのであれば、マニフェストで &lt;a href="http://developer.android.com/reference/android/content/Intent.html#ACTION_MANAGE_NETWORK_USAGE"&gt;ACTION_MANAGE_NETWORK_USAGE&lt;/a&gt; action の intent filter を定義しておくべきです。例えば : &lt;code name="code" class="xml"&gt;&amp;lt;activity android:name="DataPreferences" android:label="@string/title_preferences"&amp;gt;    &amp;lt;intent-filter&amp;gt;       &amp;lt;action android:name="android.intent.action.MANAGE_NETWORK_USAGE" /&amp;gt;       &amp;lt;category android:name="android.intent.category.DEFAULT" /&amp;gt;    &amp;lt;/intent-filter&amp;gt;&amp;lt;/activity&amp;gt;&lt;/code&gt;この intent filter はシステムにこの activity はアプリケーションのデータ使用をコントロールするものだということを示します。こうすると、ユーザーが設定アプリからあなたのアプリのデータ使用量をみたときに、"View application settings" ボタンが有効になっていて、ボタンを押すとあなたのアプリの preference activity を開けるので、ユーザーがあなたのアプリのデータ使用量をよりよくすることができます。&lt;br /&gt;&lt;br /&gt;さらに、&lt;a href="http://developer.android.com/reference/android/net/ConnectivityManager.html#getBackgroundDataSetting()"&gt;getBackgroundDataSetting()&lt;/a&gt; は廃止になり常に true を返すようになりました。代わりに &lt;a href="http://developer.android.com/reference/android/net/ConnectivityManager.html#getActiveNetworkInfo()"&gt;getActiveNetworkInfo()&lt;/a&gt; を使ってください。ネットワーク通信を試みる前に、常に &lt;a href="http://developer.android.com/reference/android/net/ConnectivityManager.html#getActiveNetworkInfo()"&gt;getActiveNetworkInfo()&lt;/a&gt; を呼んで、現在のネットワークを表す &lt;a href="http://developer.android.com/reference/android/net/NetworkInfo.html"&gt;NetworkInfo&lt;/a&gt; を取得し、 &lt;a href="http://developer.android.com/reference/android/net/NetworkInfo.html#isConnected()"&gt;isConnected()&lt;/a&gt; でデバイスが接続しているかどうかチェックしてください。デバイスがローミング中かどうかや Wi-Fi で接続しているかどうかなど、その他の接続プロパティも取得することができます。&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;■ RenderScript&lt;/h4&gt;RenderScript に3つのメジャー機能が追加されました。&lt;ul&gt;&lt;li&gt; framebuffer object への Off-screen レンダリング&lt;li&gt; view 内部でのレンダリング&lt;li&gt; RS for each from the framework APIs (←意味がわからなかったので訳せませんでした m(_ _)m）&lt;/ul&gt;&lt;a href="http://developer.android.com/reference/android/renderscript/Allocation.html"&gt;Allocation&lt;/a&gt; クラスが新しく &lt;a href="http://developer.android.com/reference/android/renderscript/Allocation.html#USAGE_GRAPHICS_RENDER_TARGET"&gt;USAGE_GRAPHICS_RENDER_TARGET&lt;/a&gt; メモリースペースをサポートし、これにより直接 &lt;a href="http://developer.android.com/reference/android/renderscript/Allocation.html"&gt;Allocation&lt;/a&gt; にレンダリングしたり、 framebuffer object として扱ったりできるようになりました。&lt;br /&gt;&lt;br /&gt;&lt;a href="http://developer.android.com/reference/android/renderscript/RSTextureView.html"&gt;RSTextureView&lt;/a&gt; は &lt;a href="http://developer.android.com/reference/android/view/View.html"&gt;View&lt;/a&gt; の内部に RenderScript グラフィクスを表示する手段を提供します。別の window を作る &lt;a href="http://developer.android.com/reference/android/renderscript/RSSurfaceView.html"&gt;RSSurfaceView&lt;/a&gt; とは異なります。この大きな違いによって、Activity のレイアウト上の、内側に RenderScript グラフィック を描画した View を移動したり、変形したりアニメーションすることができます。&lt;br /&gt;&lt;br /&gt;&lt;a href="http://developer.android.com/reference/android/renderscript/Script.html#forEach(int, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.FieldPacker)"&gt;Script.forEach()&lt;/a&gt; メソッドで VM レベルから RenderScript 計算スクリプトを呼ぶことができ、自動的にデバイスの利用可能なコアへ割当てられます。このメソッド直接使わないでください。しかし、あなたが書いた計算する RenderScript は、リフレクトされた RenderScript クラスで呼べるように &lt;a href="http://developer.android.com/reference/android/renderscript/Script.html#forEach(int, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.FieldPacker)"&gt;forEach()&lt;/a&gt; メソッドを持ってください。プロセスに入力 &lt;a href="http://developer.android.com/reference/android/renderscript/Allocation.html"&gt;Allocation&lt;/a&gt; を、結果を書くところに出力 &lt;a href="http://developer.android.com/reference/android/renderscript/Allocation.html"&gt;Allocation&lt;/a&gt; を渡すことで、リフレクトされた &lt;a href="http://developer.android.com/reference/android/renderscript/Script.html#forEach(int, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.FieldPacker)"&gt;forEach()&lt;/a&gt; メソッドを呼ぶことができます。そして、 RenderScript の場合の &lt;a href="http://developer.android.com/reference/android/renderscript/FieldPacker.html"&gt;FieldPacker&lt;/a&gt; データ構造にはより情報が必要です。&lt;a href="http://developer.android.com/reference/android/renderscript/Allocation.html"&gt;Allocation&lt;/a&gt; だけが不可欠なもので、データ構造はオプションです。&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;■ Enterprise&lt;/h4&gt;Android 4.0 で企業向けアプリの機能として以下の内容が拡張されました。&lt;h4&gt;VPN service&lt;/h4&gt;新しい &lt;a href="http://developer.android.com/reference/android/net/VpnService.html"&gt;VpnService&lt;/a&gt; によって、アプリが自身の VPN (Virtual Perivate Network) を構成し、&lt;a href="http://developer.android.com/reference/android/app/Service.html"&gt;Service&lt;/a&gt; として走らせることができます。 VPN サービスは自身のアドレスとルーティング規則で virtual network へのインタフェースを作成し、ファイルディスクリプタですべての読み込みと書き込みを実行します。&lt;br /&gt;&lt;br /&gt;VPN サービスを作成するには、ネットワークアドレス、DNS サーバー、ネットワークルートなどを指定できる &lt;a href="http://developer.android.com/reference/android/net/VpnService.Builder.html"&gt;VpnService.Builder&lt;/a&gt; を使います。指定が完了したら、&lt;a href="http://developer.android.com/reference/android/os/ParcelFileDescriptor.html"&gt;ParcelFileDescriptor&lt;/a&gt; を返す &lt;a href="http://developer.android.com/reference/android/net/VpnService.Builder.html#establish()"&gt;establish()&lt;/a&gt; を呼び出してインタフェースを確立します。&lt;br /&gt;&lt;br /&gt;VPN サービスはパケットに介入するため、セキュリティへの影響があります。そのため、&lt;a href="http://developer.android.com/reference/android/net/VpnService.html"&gt;VpnService&lt;/a&gt; を実装するサービスは、システムだけがこれにバインドできることを確実にするために、 &lt;a href="http://developer.android.com/reference/android/Manifest.permission.html#BIND_VPN_SERVICE"&gt;BIND_VPN_SERVICE&lt;/a&gt; を要求しなければなりません（システムだけがバインドするパーミッションをもち、アプリはリクエストできません）。そして、あなたの VPN サービスを使うには、ユーザーが手動でシステム設定からこれを有効にする必要があります。&lt;h4&gt;Device policies&lt;/h4&gt;デバイスの制限を管理するアプリで &lt;a href="http://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#setCameraDisabled(android.content.ComponentName, boolean)"&gt;setCameraDisabled()&lt;/a&gt; と &lt;a href="http://developer.android.com/reference/android/app/admin/DeviceAdminInfo.html#USES_POLICY_DISABLE_CAMERA"&gt;USES_POLICY_DISABLE_CAMERA&lt;/a&gt; プロパティ（ポリシー設定ファイルで &lt;font color=green&gt;&amp;lt;disable-camera /&amp;gt;&lt;/font&gt; に適用される）を使ってカメラを無効にできるようになりました。&lt;h4&gt;Certificate management&lt;/h4&gt;新しい &lt;a href="http://developer.android.com/reference/android/security/KeyChain.html"&gt;KeyChain&lt;/a&gt; クラスは証明書をシステムキーストアにインポートやアクセスする API を提供します。証明書はクライアント証明書（ユーザーの身元を検証する）と認証局の証明書（サーバーの身元を検証する）の両方のインストールを合理化します。Web ブラウザやメールクライアントなどのアプリは、サーバーにユーザーを認証させるためにインストールされた証明書にアクセスできます。より詳しい情報は &lt;a href="http://developer.android.com/reference/android/security/KeyChain.html"&gt;KeyChain&lt;/a&gt; ドキュメントを見てください。&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;■ Device Sensors&lt;/h4&gt;Android 4.0 で新しいセンサータイプが追加されました。&lt;ul&gt;&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/hardware/Sensor.html#TYPE_AMBIENT_TEMPERATURE"&gt;TYPE_AMBIENT_TEMPERATURE&lt;/a&gt; : 周り（部屋）の温度をセルシウス度で提供する温度センサー&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/hardware/Sensor.html#TYPE_RELATIVE_HUMIDITY"&gt;TYPE_RELATIVE_HUMIDITY&lt;/a&gt;: 周り（部屋）の湿度をパーセントで提供する湿度センサー&lt;/ul&gt;&lt;a href="http://developer.android.com/reference/android/hardware/Sensor.html#TYPE_AMBIENT_TEMPERATURE"&gt;TYPE_AMBIENT_TEMPERATURE&lt;/a&gt; と &lt;a href="http://developer.android.com/reference/android/hardware/Sensor.html#TYPE_RELATIVE_HUMIDITY"&gt;TYPE_RELATIVE_HUMIDITY&lt;/a&gt; センサーの両方をデバイスがサポートしているなら、これらを露点と絶対湿度を計算するのに使えます。&lt;br /&gt;&lt;br /&gt;以前の温度センサーである &lt;a href="http://developer.android.com/reference/android/hardware/Sensor.html#TYPE_TEMPERATURE"&gt;TYPE_TEMPERATURE&lt;/a&gt; は廃止になりました。代わりに &lt;a href="http://developer.android.com/reference/android/hardware/Sensor.html#TYPE_AMBIENT_TEMPERATURE"&gt;TYPE_AMBIENT_TEMPERATURE&lt;/a&gt; センサーを使ってください。&lt;br /&gt;&lt;br /&gt;加えて、Android の 3つの合成センサーがかなり改善され、レイテンシが低くなり、出力がスムーズになりました。これらのセンサーには重力センサー (&lt;a href="http://developer.android.com/reference/android/hardware/Sensor.html#TYPE_GRAVITY"&gt;TYPE_GRAVITY&lt;/a&gt;)、回転ベクトルセンサー (&lt;a href="http://developer.android.com/reference/android/hardware/Sensor.html#TYPE_ROTATION_VECTOR"&gt;TYPE_ROTATION_VECTOR&lt;/a&gt;)、線形加速センサー (&lt;a href="http://developer.android.com/reference/android/hardware/Sensor.html#TYPE_LINEAR_ACCELERATION"&gt;TYPE_LINEAR_ACCELERATION&lt;/a&gt;) が含まれます。改善されたセンサーは、出力を改善するためにジャイロスコープセンサーに頼っています。そのため、これらのセンサーはジャイロスコープが搭載されたデバイスにだけ現れます。&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;■ Action Bar&lt;/h4&gt;いくつかの新しい動作をサポートするために &lt;a href="http://developer.android.com/reference/android/app/ActionBar.html"&gt;ActionBar&lt;/a&gt; がアップデートされました。もっとも重要なのことは、全ての画面サイズでオプショナルなユーザー操作を提供するために、小さい画面サイズのときにシステムが action bar のサイズと設定を優雅に管理することです。例えば、画面が狭いとき（ハンドセットで縦画面のときなど）、action bar のナビゲーションタブはメインの action bar の真下に表れる "stacked bar" 内に表示されます。また、 "split action bar" を opt-in することもできます。これにより画面が狭いときに全ての action item を画面下部の separate bar に配置することができます。&lt;h4&gt;Split action bar&lt;/h4&gt;もし action bar に複数の action item が含まれる場合、全ての項目を狭い画面上の action bar に合わせることはありません。システムはそれらのうちのいくつかを overflow menu に置きます。しかし、Android 4.0 から "split action bar" を有効にできるようになりました。これにより、より多くの action item を画面下部のセパレートバー上に表示できるようになりました。split action bar を有効にするには、&lt;font color=green&gt;"splitActionBarWhenNarrow"&lt;/font&gt; を指定した &lt;a href="http://developer.android.com/reference/android/R.attr.html#uiOptions"&gt;android:uiOptions&lt;/a&gt; 属性を manifest ファイルの &lt;a href="http://developer.android.com/guide/topics/manifest/application-element.html"&gt;&amp;lt;application&amp;gt;&lt;/a&gt; タグもしくは個々の &lt;a href="http://developer.android.com/guide/topics/manifest/activity-element.html"&gt;&amp;lt;activity&amp;gt;&lt;/a&gt; タグに指定します。有効の場合、画面が狭いときに全ての action item 用にシステムは付加的なバーを画面下部に追加します（優先的な（上部の） action bar には action item が表示されなくなります）。&lt;br /&gt;&lt;br /&gt;&lt;a href="http://developer.android.com/reference/android/app/ActionBar.Tab.html"&gt;ActionBar.Tab&lt;/a&gt; API によって提供されるナビゲーションタブを使いたいが、上部にメインの action bar は必要ない場合（上部にタブだけを表示したい場合）、上で説明した split action bar を有効にして、さらに &lt;a href="http://developer.android.com/reference/android/app/ActionBar.html#setDisplayShowHomeEnabled(boolean)"&gt;setDisplayShowHomeEnabled(false)&lt;/a&gt; を呼ぶと action bar のアプリアイコンが無効になります。メインの action bar の左には何も表示されず、画面上部にナビゲーションバー、画面下部に action item が置かれるようになります。&lt;h4&gt;Action bar styles&lt;/h4&gt;action bar のカスタマイズしたスタイルを適用したい場合は、新しいスタイルプロパティの &lt;a href="http://developer.android.com/reference/android/R.attr.html#backgroundStacked"&gt;backgroundStacked&lt;/a&gt; と &lt;a href="http://developer.android.com/reference/android/R.attr.html#backgroundSplit"&gt;backgroundSplit&lt;/a&gt; で背景の画像や色をスタックするバーと区切りバーにそれぞれ適用することができます。また、ランタイム中に &lt;a href="http://developer.android.com/reference/android/app/ActionBar.html#setStackedBackgroundDrawable(android.graphics.drawable.Drawable)"&gt;setStackedBackgroundDrawable()&lt;/a&gt; と &lt;a href="http://developer.android.com/reference/android/app/ActionBar.html#setSplitBackgroundDrawable(android.graphics.drawable.Drawable)"&gt;setSplitBackgroundDrawable()&lt;/a&gt; でこれらのスタイルをセットすることもできます。&lt;h4&gt;Action provider&lt;/h4&gt;新しい &lt;a href="http://developer.android.com/reference/android/view/ActionProvider.html"&gt;ActionProvider&lt;/a&gt; クラスによって action item を処理する特別なハンドラを作成できます。1つの action provider は 1つの action view、デフォルトの action 動作、関連した各 action item のサブメニュー を定義することができます。動的な動作（可変な action view やデフォルト動作やサブメニュー）を行う action item を作成したい場合は、fragment や activity 内で action item を変換するよりも、再利用可能なコンポーネントを作成するために、&lt;a href="http://developer.android.com/reference/android/view/ActionProvider.html"&gt;ActionProvider&lt;/a&gt; を拡張するのがいい解決法です。&lt;br /&gt;&lt;br /&gt;例えば、&lt;a href="http://developer.android.com/reference/android/widget/ShareActionProvider.html"&gt;ShareActionProvider&lt;/a&gt; は &lt;a href="http://developer.android.com/reference/android/view/ActionProvider.html"&gt;ActionProvider&lt;/a&gt; を拡張して簡単にアクションバーから "share" action を行えます。&lt;a href="http://developer.android.com/reference/android/content/Intent.html#ACTION_SEND"&gt;ACTION_SEND&lt;/a&gt; intent を呼び出すこれまでの action item を使うかわりに、この action provider を使って &lt;a href="http://developer.android.com/reference/android/content/Intent.html#ACTION_SEND"&gt;ACTION_SEND&lt;/a&gt; intent を処理するアプリ一覧のドロップダウンリストの action view を表示できます。ユーザーがリストからアプリを選択すると、&lt;a href="http://developer.android.com/reference/android/widget/ShareActionProvider.html"&gt;ShareActionProvider&lt;/a&gt; はその選択を記憶して、そのアプリでシェアするためにより速くサクセスするために action view にそれを提供します。&lt;br /&gt;&lt;br /&gt;1つの action item に対して1つの action provider を宣言するには Activity の options menu の &lt;a href="http://developer.android.com/guide/topics/resources/menu-resource.html#item-element"&gt;&amp;lt;item&amp;gt;&lt;/a&gt; エレメントに &lt;font color=green&gt;android:actionProviderClass&lt;/font&gt; 属性に action provider のクラス名を指定します。例えば : &lt;code name="code" class="xml"&gt;&amp;lt;item android:id="@+id/menu_share"      android:title="Share"      android:showAsAction="ifRoom"      android:actionProviderClass="android.widget.ShareActionProvider" /&amp;gt;&lt;/code&gt;あなたの Activity の &lt;a href="http://developer.android.com/reference/android/app/Activity.html#onCreateOptionsMenu(android.view.Menu)"&gt;onCreateOptionsMenu()&lt;/a&gt; コールバックメソッドでは、menu item から action provider のインスタンスを取得して、intent をセットします。&lt;code name="code" class="java"&gt;public boolean onCreateOptionsMenu(Menu menu) {    getMenuInflater().inflate(R.menu.options, menu);    ShareActionProvider shareActionProvider =          (ShareActionProvider) menu.findItem(R.id.menu_share).getActionProvider();    // Set the share intent of the share action provider.    shareActionProvider.setShareIntent(createShareIntent());    ...    return super.onCreateOptionsMenu(menu);}&lt;/code&gt;&lt;a href="http://developer.android.com/reference/android/widget/ShareActionProvider.html"&gt;ShareActionProvider&lt;/a&gt; を使った例として、ApiDemos の &lt;a href="http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/app/ActionBarActionProviderActivity.html"&gt;ActionBarActionProviderActivity&lt;/a&gt; を見てください。&lt;h4&gt;Collapsible action views&lt;/h4&gt;action view を提供する action item で、 action view 状態とこれまでの action item 状態を切り替えられるようになりました。以前は &lt;a href="http://developer.android.com/reference/android/widget/SearchView.html"&gt;SearchView&lt;/a&gt; だけが action view として使われたときに閉じるようサポートされてしました。しかし、任意の action item を action view として追加し、展開状態（action view が見えている）と閉じている状態（action item が見えている）を切り替えることができるようになりました。&lt;br /&gt;&lt;br /&gt;閉じられる action view を含む action item を宣言するには menu の XML ファイルの &lt;a href="http://developer.android.com/guide/topics/resources/menu-resource.html#item-element"&gt;&amp;lt;item&amp;gt;&lt;/a&gt; エレメントの &lt;font color=green&gt;android:showAsAction&lt;/font&gt; 属性に &lt;font color=green&gt;"collapseActionView"&lt;/font&gt; フラグを入れます。&lt;br /&gt;&lt;br /&gt;action view が展開した状態と閉じた状態が切り替わったことをコールバックで受け取るには、&lt;a href="http://developer.android.com/reference/android/view/MenuItem.OnActionExpandListener.html"&gt;MenuItem.OnActionExpandListener&lt;/a&gt; のインスタンスを &lt;a href="http://developer.android.com/reference/android/view/MenuItem.html#setOnActionExpandListener(android.view.MenuItem.OnActionExpandListener)"&gt;setOnActionExpandListener()&lt;/a&gt; を呼んでそれぞれの &lt;a href="http://developer.android.com/reference/android/view/MenuItem.html"&gt;MenuItem&lt;/a&gt; でに登録します。典型的には、&lt;a href="http://developer.android.com/reference/android/app/Activity.html#onCreateOptionsMenu(android.view.Menu)"&gt;onCreateOptionsMenu()&lt;/a&gt; コールバックの中で行ってください。&lt;br /&gt;&lt;br /&gt;閉じれる action view をコントロールするには、&lt;a href="http://developer.android.com/reference/android/view/MenuItem.html#collapseActionView()"&gt;collapseActionView()&lt;/a&gt; や &lt;a href="http://developer.android.com/reference/android/view/MenuItem.html#expandActionView()"&gt;expandActionView()&lt;/a&gt; を各 &lt;a href="http://developer.android.com/reference/android/view/MenuItem.html"&gt;MenuItem&lt;/a&gt; に対して呼びます。カスタム action view を作る場合は、&lt;a href="http://developer.android.com/reference/android/view/CollapsibleActionView.html"&gt;CollapsibleActionView&lt;/a&gt; インタフェースを実装して view が開いたり閉じたりしたときのコールバックを受け取ることができます。&lt;h4&gt;Other APIs for action bar&lt;/h4&gt;&lt;ul&gt;&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/app/ActionBar.html#setHomeButtonEnabled(boolean)"&gt;setHomeButtonEnabled()&lt;/a&gt; で アイコン／ロゴ がホームもしくは "up" をナビゲートするボタンとして動作するかどうかを指定できる（true を渡すとボタンとして動作する）。&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/app/ActionBar.html#setIcon(android.graphics.drawable.Drawable)"&gt;setIcon()&lt;/a&gt; と &lt;a href="http://developer.android.com/reference/android/app/ActionBar.html#setLogo(android.graphics.drawable.Drawable)"&gt;setLogo()&lt;/a&gt; でランタイム中に Action Bar のアイコンやロゴを設定できます。&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/app/Fragment.html#setMenuVisibility(boolean)"&gt;Fragment.setMenuVisibility()&lt;/a&gt; によって fragment で定義されたメニューアイテムの可視状態を有効／無効にすることができる。Activity に Fragment が追加されたが、それが不可視状態であるときに menu item を隠すのに使えます。&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/app/FragmentManager.html#invalidateOptionsMenu()"&gt;FragmentManager.invalidateOptionsMenu()&lt;/a&gt; によって Activity から同等のメソッドが利用できない可能性がある Fragment ライフサイクルのいくつかの状態の間 activity の options menu を無効にできます。&lt;/ul&gt;&lt;br /&gt;&lt;h4&gt;■ User Interface and Views&lt;/h4&gt;Android 4.0 で追加された新しい view とその他 UI コンポーネントについて紹介します。&lt;h4&gt;GridLayout&lt;/h4&gt;&lt;a href="http://developer.android.com/reference/android/widget/GridLayout.html"&gt;GridLayout&lt;/a&gt; は子 view を格子状に配置する新しい view group です。&lt;a href="http://developer.android.com/reference/android/widget/TableLayout.html"&gt;TableLayout&lt;/a&gt; と違い、&lt;a href="http://developer.android.com/reference/android/widget/GridLayout.html"&gt;GridLayout&lt;/a&gt; はフラットな階層に依存し、table rows のような構造を作るための中間の view を必要としません。代わりに子 view は配置される行（rows(s)）と列（column(s)）を指定します（セルは複数の行や列をまたぐことができます）。デフォルトでは順番に格子の行と列を占めるように配置されます。子 view の間のスペースは新しい &lt;a href="http://developer.android.com/reference/android/widget/Space.html"&gt;Space&lt;/a&gt; view のインスタンスを使ったり、関連するマージンパラメータを子viewに設定したりすることで調整できます。&lt;br /&gt;&lt;br /&gt;サンプルは &lt;a href="http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/view/index.html"&gt;ApiDemos&lt;/a&gt; の &lt;a href="http://developer.android.com/reference/android/widget/GridLayout.html"&gt;GridLayout&lt;/a&gt; です。&lt;h4&gt;TextureView&lt;/h4&gt;&lt;a href="http://developer.android.com/reference/android/view/TextureView.html"&gt;TextureView&lt;/a&gt; はビデオや OpenGL シーンなどの content stream を表示できる新しい view です。&lt;a href="http://developer.android.com/reference/android/view/SurfaceView.html"&gt;SurfaceView&lt;/a&gt; と似ていますが、&lt;a href="http://developer.android.com/reference/android/view/TextureView.html"&gt;TextureView&lt;/a&gt; は別の window をつくるのではなく、通常の view のように振る舞うという点でユニークです。そのため、他の &lt;a href="http://developer.android.com/reference/android/view/View.html"&gt;View&lt;/a&gt; object と同じように扱うことができます。例えば、&lt;a href="http://developer.android.com/reference/android/view/ViewPropertyAnimator.html"&gt;ViewPropertyAnimator&lt;/a&gt; を使って変形やアニメーションをさせたり、&lt;a href="http://developer.android.com/reference/android/view/View.html#setAlpha(float)"&gt;setAlpha()&lt;/a&gt; で透明度を調整できたりします。&lt;br /&gt;&lt;br /&gt;&lt;a href="http://developer.android.com/reference/android/view/TextureView.html"&gt;TextureView&lt;/a&gt; は hardware accelerated window 内でのみ動作するので注意してください。&lt;br /&gt;&lt;br /&gt;より詳しい情報は &lt;a href="http://developer.android.com/reference/android/view/TextureView.html"&gt;TextureView&lt;/a&gt; ドキュメントをみてください。&lt;h4&gt;Switch widget &lt;/h4&gt;新しい &lt;a href="http://developer.android.com/reference/android/widget/Switch.html"&gt;Switch&lt;/a&gt; ウィジェットは一方を反対側にスライドして（もしくは、単にタップして）2つの状態を切り替えるものです。&lt;br /&gt;&lt;br /&gt;&lt;font color=green&gt;android:textOn&lt;/font&gt; と &lt;font color=green&gt;android:textOff&lt;/font&gt; 属性を使ってスイッチ上に表示される文字を指定できます。&lt;font color=green&gt;android:text&lt;/font&gt; 属性でスイッチの横に置かれるラベル名を指定できます。&lt;br /&gt;&lt;br /&gt;スイッチを使ったサンプルは &lt;a href="http://developer.android.com/resources/samples/ApiDemos/res/layout/switches.html"&gt;switches.xml&lt;/a&gt; レイアウトファイルと関連する &lt;a href="http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/view/Switches.html"&gt;Switches&lt;/a&gt; activity を見てください。&lt;h4&gt;Popup menus&lt;/h4&gt;Android 3.0 で、小さいコンテキストメニューを指定したアンカーポイント（通常は選択されたアイテムの場所）にポップアップする &lt;a href="http://developer.android.com/reference/android/widget/PopupMenu.html"&gt;PopupMenu&lt;/a&gt; を紹介しました。Android 4.0 では &lt;a href="http://developer.android.com/reference/android/widget/PopupMenu.html"&gt;PopupMenu&lt;/a&gt; を拡張して幾つかの便利な機能を追加しました : &lt;ul&gt;&lt;li&gt; &lt;a href="http://developer.android.com/guide/topics/resources/menu-resource.html"&gt;menu resource&lt;/a&gt; ID で &lt;a href="http://developer.android.com/reference/android/widget/PopupMenu.html#inflate(int)"&gt;infalte()&lt;/a&gt; を呼ぶことで、popup menu のコンテンツを XML menu resource から簡単に作れるようになりました。&lt;li&gt;メニューが消えたことを受け取るコールバックの &lt;a href="http://developer.android.com/reference/android/widget/PopupMenu.OnDismissListener.html"&gt;PupupMenu.OnDismissListener&lt;/a&gt; を作れるようになりました。&lt;/ul&gt;&lt;h4&gt;Preferences&lt;/h4&gt;新しい &lt;a href="http://developer.android.com/reference/android/preference/TwoStatePreference.html"&gt;TwoStatePreference&lt;/a&gt; 抽象クラスは2つの状態から選択するオプション用の preference を提供します。この &lt;a href="http://developer.android.com/reference/android/preference/TwoStatePreference.html"&gt;TwoStatePreference&lt;/a&gt; を継承した新しいクラスが &lt;a href="http://developer.android.com/reference/android/preference/SwitchPreference.html"&gt;SwitchPreference&lt;/a&gt; です。この preference は &lt;a href="http://developer.android.com/reference/android/widget/Switch.html"&gt;Switch&lt;/a&gt; ウィジェットを使った preference view を提供し、ユーザーは別のスクリーンやダイアログを開くこと無く設定の on/off を切り替えられます。例えば、設定アプリでは Wi-Fi や Bluetooth の設定に &lt;a href="http://developer.android.com/reference/android/preference/SwitchPreference.html"&gt;SwitchPreference&lt;/a&gt; を使っています。&lt;h4&gt;System themes&lt;/h4&gt;Android 4.0 をターゲットとする（&lt;a href="http://developer.android.com/guide/topics/manifest/uses-sdk-element.html#target"&gt;targetSdkVersion&lt;/a&gt; か &lt;a href="http://developer.android.com/guide/topics/manifest/uses-sdk-element.html#min"&gt;minSdkVersion&lt;/a&gt; が &lt;font color=green&gt;"14"&lt;/font&gt;以上に設定されている）全てのアプリケーションのデフォルトテーマは "device default" テーマの: &lt;a href="http://developer.android.com/reference/android/R.style.html#Theme_DeviceDefault"&gt;Theme.DeviceDefault&lt;/a&gt; になります。これは dark Holo テーマか、特定のデバイスによって定義された dark theme になるでしょう。&lt;br /&gt;&lt;br /&gt;&lt;a href="http://developer.android.com/reference/android/R.style.html#Theme_Holo"&gt;Theme.Holo&lt;/a&gt; ファミリーのテーマは同じバージョンの Android が動いている場合は、デバイスによって変わらないことが保証されます。&lt;a href="http://developer.android.com/reference/android/R.style.html#Theme_Holo"&gt;Theme.Holo&lt;/a&gt; テーマをあなたの activity に明示的に適用するなら、同じプラットフォームバージョン内のデバイスならテーマによる特徴が変わらないので安心できます。&lt;br /&gt;&lt;br /&gt;もしデバイス全体のテーマ（例えば、異なる OEM が提供するシステム用の異なるデフォルトテーマ）にアプリを合わせたいなら、明示的に &lt;a href="http://developer.android.com/reference/android/R.style.html#Theme_DeviceDefault"&gt;Theme.DeviceDefault&lt;/a&gt; ファミリーを適用してください。&lt;h4&gt;Options menu button&lt;/h4&gt;Android 4.0 からハンドセットが Menu ハードボタンを必要としなくなったことに気づいたと思います。あなたのすでにあるアプリケーションで &lt;a href="http://developer.android.com/guide/topics/ui/menus.html#options-menu"&gt;option menu&lt;/a&gt; を使っていて Menu ボタンがあることを期待していても心配する必要はありません。既にあるアプリがそれらが期待した動作をちゃんとできるように、システムは Android の古いバージョン用にデザインされたアプリでは、スクリーン上に Menu ボタンを提供します。&lt;br /&gt;&lt;br /&gt;ベストなユーザー体験のために、メニューアイテムへのアクセスとして &lt;a href="http://developer.android.com/reference/android/app/ActionBar.html"&gt;ActionBar&lt;/a&gt; を使うようにアプリを新しくするかアップデートしてください。また、&lt;a href="http://developer.android.com/guide/topics/manifest/uses-sdk-element.html#target"&gt;targetSdkVersion&lt;/a&gt; に &lt;font color=green&gt;"14"&lt;/font&gt; をセットして最新のフレームワークのデフォルトの動作を活用してください。&lt;h4&gt;Controls for system UI visibility&lt;/h4&gt;以前の Android では、&lt;i&gt;status bar&lt;/i&gt; として知られていたシステムが管理する UI コンポーネントがありました。ハンドセットデバイスの上部に常駐してキャリアシグナルな時間、通知などの情報を表示していました。Android 3.0 では、画面の下部に常駐してシステムのナビゲーションコントロール（Home、Back、など) やこれまで status bar で提供してきた項目へのインタフェースを提供する &lt;i&gt;system bar&lt;/i&gt; がタブレットデバイス用に追加されました。Android 4.0 では、&lt;i&gt;navigation bar&lt;/i&gt; と呼ばれる新しいタイプのシステム UI が提供されます。navigation bar はハンドセット向けにデザインされた system bar の re-tuned バージョンだと思うかもしれません。システムをナビゲーションするためのハードウェア部分（ハードキーとか）を持たないデバイスに対して、ナビゲーションコントロールを提供しますが、 system bar の通知 UI と設定コントロールを残します。このように navigation bar を提供するデバイスでは上部に status bar も持ちます。&lt;br /&gt;&lt;br /&gt;これまでは、ハンドセット上で &lt;a href="http://developer.android.com/reference/android/view/WindowManager.LayoutParams.html#FLAG_FULLSCREEN"&gt;FLAG_FULLSCREEN&lt;/a&gt; フラグを使って status bar を隠すことができました。Android 4.0 では、system bar の可視状態をコントロールする API は system bar と navigation bar 両方の動作をよりよく反映するようにアップデートされています。&lt;ul&gt;&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/view/View.html#SYSTEM_UI_FLAG_LOW_PROFILE"&gt;SYSTEM_UI_FLAG_LOW_PROFILE&lt;/a&gt; フラグは &lt;font color=green&gt;STATUS_BAR_HIDDEN&lt;/font&gt; フラグを置き換えるものです。セットされた場合、このフラグは system bar もしくは navigation bar の "low profile" モードを有効にします。ナビゲーションボタンは薄暗くなって system bar 内の他の項目は隠れます。システムナビゲーションボタンが邪魔せず、より没入できるゲームを作るときに便利です。&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/view/View.html#SYSTEM_UI_FLAG_VISIBLE"&gt;SYSMTE_UI_FLAG_VISIBLE&lt;/a&gt; フラグは &lt;font color=green&gt;STATUS_BAR_VISIBLE&lt;/font&gt; フラグを置き換えるものです。system bar もしくは navigation bar が可視状態になることを要求します。&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/view/View.html#SYSTEM_UI_FLAG_HIDE_NAVIGATION"&gt;SYSTEM_UI_FLAG_HIDE_NAVIGATION&lt;/a&gt; は navigation bar を完全に隠すことを要求する新しいフラグです。これは navigation bar を使っているいくつかのハンドセットでのみ動作することに注意してください（タブレット上の system bar は隠せません）。navigation bar はシステムがユーザー入力を受け取るとすぐに view として返ってきます。つまり、ビデオのプレイバックなど、画面全体が必要とするがユーザーの入力が必要ではないときに便利です。&lt;/ul&gt;Activity 内のいずれかの view 上で &lt;a href="http://developer.android.com/reference/android/view/View.html#setSystemUiVisibility(int)"&gt;setSystemUiVisibility()&lt;/a&gt; を呼ぶことで、 system bar と navigation bar に対してこれらのフラグをセットできます。window manager は window 内の全ての view からの全フラグを組み合わせて（もしくは一緒にして）、window が入力フォーカスを持つのと同じくらい長くシステム UI に適用します。window が入力フォーカスを失うと（ユーザーがあなたのアプリから離れたり、ダイアログが表示されたり）、フラグの効果は中止されます。同様に、view 階層からそれらの view を取り除くと、フラグは適用されなくなります。&lt;br /&gt;&lt;br /&gt;システム UI の可視状態の変化に他のイベントを同期させる（例えば、アクションバーを隠したり、他の UI コントロールをシステム UI が隠れたときに隠すなど）には、system bar や navigation bar の可視状態が変わったことを通知する &lt;a href="http://developer.android.com/reference/android/view/View.OnSystemUiVisibilityChangeListener.html"&gt;View.OnSystemUiVisibilityChangeListener&lt;/a&gt; を登録してください。システム UI オプションの違いのデモは &lt;a href="http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/view/OverscanActivity.html"&gt;OverscanActivity&lt;/a&gt; を見てください。&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;■ Input Framework&lt;/h4&gt;Android 4.0 でカーソルのホバーイベント、新しいスタイラスとマウスボタンのイベントをサポートするようになりました。&lt;h4&gt;Hover events&lt;/h4&gt;&lt;a href="http://developer.android.com/reference/android/view/View.html"&gt;View&lt;/a&gt; クラスで新しく "hover" イベントがサポートされるようになりました。これにより、マウスなど画面上にカーソルを表示するポインタでバイスを使うときによりリッチなインタラクションが可能になります。&lt;br /&gt;&lt;br /&gt;View でホバーイベントを受け取るには、&lt;a href="http://developer.android.com/reference/android/view/View.OnHoverListener.html"&gt;View.OnHoverListener&lt;/a&gt; を実装し &lt;a href="http://developer.android.com/reference/android/view/View.html#setOnHoverListener(android.view.View.OnHoverListener)"&gt;setOnHoverListener()&lt;/a&gt; で登録します。View 上でホバーイベントが起こったら、あなたのリスナーの &lt;a href="http://developer.android.com/reference/android/view/View.OnHoverListener.html#onHover(android.view.View, android.view.MotionEvent)"&gt;onHover()&lt;/a&gt; が呼び出され、イベントを受け取った &lt;a href="http://developer.android.com/reference/android/view/View.html"&gt;View&lt;/a&gt; と起こったホバーイベントのタイプを持つ MotionEvent を受け取ります。ホバーイエベントは次のうちのいずれかになります : &lt;ul&gt;&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/view/MotionEvent.html#ACTION_HOVER_ENTER"&gt;ACTION_HOVER_ENTER&lt;/a&gt;&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/view/MotionEvent.html#ACTION_HOVER_EXIT"&gt;ACTION_HOVER_EXIT&lt;/a&gt;&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/view/MotionEvent.html#ACTION_HOVER_MOVE"&gt;ACTION_HOVER_MOVE&lt;/a&gt;&lt;/ul&gt;ホバーイベントを処理する場合は、あなたの &lt;a href="http://developer.android.com/reference/android/view/View.OnHoverListener.html"&gt;View.OnHoverListener&lt;/a&gt; の &lt;a href="http://developer.android.com/reference/android/view/View.OnHoverListener.html#onHover(android.view.View, android.view.MotionEvent)"&gt;onHover()&lt;/a&gt; で true を返してください。false を返すと、通常のように親 view にイベントが送られます。&lt;br /&gt;&lt;br /&gt;あなたのアプリでボタンのように現在の状態に応じて見た目が変わる widget を使っているなら、カーソルのホバー状態に応じて背景画像を変えるための &lt;font color=green&gt;android:state_hovered&lt;/font&gt; 属性を &lt;a href="http://developer.android.com/guide/topics/resources/drawable-resource.html#StateList"&gt;state list drawable&lt;/a&gt; で利用できます。&lt;br /&gt;&lt;br /&gt;ホバーイベントのデモとして ApiDemos の Hover クラスを見てください。&lt;h4&gt;Stylus and mouse button events&lt;/h4&gt;digitizer tablet やスタイラスが使えるタッチスクリーンなど、スタイラス入力デバイスからの入力を受ける API が提供されるようになりました。&lt;br /&gt;&lt;br /&gt;スタイラスによる入力はタッチやマウス入力と同じように動作します。スタイラスが digitizer に接触したとき、アプリは指が画面をタッチしたときと同じようなタッチイベントを受け取ります。スタイラスが digitizer 上に浮いているとき、アプリはマウスポインターがボタンを押さずに画面上を動くのと同じようなホバーイベントを受け取ります。&lt;br /&gt;&lt;br /&gt;&lt;a href="http://developer.android.com/reference/android/view/MotionEvent.html#getToolType(int)"&gt;getToolType()&lt;/a&gt; を使って &lt;a href="http://developer.android.com/reference/android/view/MotionEvent.html"&gt;MotionEvent&lt;/a&gt; のポインタに対して "tool type" を取得して、入力が指なのか、マウスなのか、スタイラスなのか、イレイサーなのか区別することができます。現在定義されている tool type は : &lt;a href="http://developer.android.com/reference/android/view/MotionEvent.html#TOOL_TYPE_UNKNOWN"&gt;TOOL_TYPE_UNKNOWN&lt;/a&gt;, &lt;a href="http://developer.android.com/reference/android/view/MotionEvent.html#TOOL_TYPE_FINGER"&gt;TOOL_TYPE_FINGER&lt;/a&gt;, &lt;a href="http://developer.android.com/reference/android/view/MotionEvent.html#TOOL_TYPE_MOUSE"&gt;TOOL_TYPE_MOUSE&lt;/a&gt;, &lt;a href="http://developer.android.com/reference/android/view/MotionEvent.html#TOOL_TYPE_STYLUS"&gt;TOOL_TYPE_STYLUS&lt;/a&gt;, &lt;a href="http://developer.android.com/reference/android/view/MotionEvent.html#TOOL_TYPE_ERASER"&gt;TOOL_TYPE_ERASER&lt;/a&gt; です。tool type を見ることで指やマウスでの入力と異なる処理をスタイラス入力で行うようにできます。&lt;br /&gt;&lt;br /&gt;&lt;a href="http://developer.android.com/reference/android/view/MotionEvent.html#getButtonState()"&gt;getButtonState()&lt;/a&gt; を使って &lt;a href="http://developer.android.com/reference/android/view/MotionEvent.html"&gt;MotionEvent&lt;/a&gt; の "button state" を調べることで、マウスやスタイラスのボタンが押されているかどうかわかります。現在定義されている button state は : &lt;a href="http://developer.android.com/reference/android/view/MotionEvent.html#BUTTON_PRIMARY"&gt;BUTTON_PRIMARY&lt;/a&gt;, &lt;a href="http://developer.android.com/reference/android/view/MotionEvent.html#BUTTON_SECONDARY"&gt;BUTTON_SECONDARY&lt;/a&gt;, &lt;a href="http://developer.android.com/reference/android/view/MotionEvent.html#BUTTON_TERTIARY"&gt;BUTTON_TERTIARY&lt;/a&gt;, &lt;a href="http://developer.android.com/reference/android/view/MotionEvent.html#BUTTON_BACK"&gt;BUTTON_BACK&lt;/a&gt;, &lt;a href="http://developer.android.com/reference/android/view/MotionEvent.html#BUTTON_FORWARD"&gt;BUTTON_FORWARD&lt;/a&gt; です。利便性のために、マウスのバックとフォーワードボタンは自動的に &lt;a href="http://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_BACK"&gt;KEYCODE_BACK&lt;/a&gt; と &lt;a href="http://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_FORWARD"&gt;KEYCODE_FORWARD&lt;/a&gt; キーに割り振られます。マウスボタンのバックとフォーワード操作をサポートするためにこれらのキーを利用できます。&lt;br /&gt;&lt;br /&gt;加えて、接触の位置と圧力を正確をはかるために、いくつかのスタイラス入力デバイスはスタイラスチップと digitizer の間の距離、スタイラスの傾き角度、スタイラスの回転角度を報告します。&lt;a href="http://developer.android.com/reference/android/view/MotionEvent.html#AXIS_DISTANCE"&gt;AXIS_DISTANCE&lt;/a&gt;, &lt;a href="http://developer.android.com/reference/android/view/MotionEvent.html#AXIS_TILT"&gt;AXIS_TILT&lt;/a&gt;, &lt;a href="http://developer.android.com/reference/android/view/MotionEvent.html#AXIS_ORIENTATION"&gt;AXIS_ORIENTATION&lt;/a&gt; で&lt;a href="http://developer.android.com/reference/android/view/MotionEvent.html#getAxisValue(int)"&gt; getAxisValue()&lt;/a&gt; を使ってこの情報を取得できます。&lt;br /&gt;&lt;br /&gt;tool type, button state, 新しい axis code のデモとして ApiDemos の &lt;a href="http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/graphics/TouchPaint.html"&gt;TouchPaint&lt;/a&gt; を見てください。&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;■ Properties&lt;/h4&gt;新しい &lt;a href="http://developer.android.com/reference/android/util/Property.html"&gt;Property&lt;/a&gt; クラスは、一般的にオブジェクトに対して set/get で呼ばれる値であるプロパティを速く、効果的に、簡単に指定する方法を提供します。また、フィールドやメソッド周りのリファレンスを渡すことを可能にし、フィールドやメソッドの詳細を知らなくてもプロパティの値を set/get するコードが可能になります。&lt;br /&gt;&lt;br /&gt;例えば、オブジェクト &lt;font color=green&gt;foo&lt;/font&gt; のフィールド &lt;font color=green&gt;bar&lt;/font&gt; に値をセットする場合、これまではこうしていました : &lt;code name="code" class="java"&gt;foo.bar = value;&lt;/code&gt;private field &lt;font color=green&gt;bar&lt;/font&gt; に対する setter を呼ぶときは、これまではこうしていました : &lt;code name="code" class="java"&gt;foo.setBar(value);&lt;/code&gt;しかし、&lt;font color=green&gt;foo&lt;/font&gt; インスタンスの周りに渡したり、&lt;font color=green&gt;bar&lt;/font&gt; value をセットする他のコードがある場合、Android 4.0 以前では行う方法がまったくありませんでした。&lt;br /&gt;&lt;br /&gt;&lt;a href="http://developer.android.com/reference/android/util/Property.html"&gt;Property&lt;/a&gt; クラスを使うと、&lt;font color=green&gt;Foo&lt;/font&gt; クラスに &lt;a href="http://developer.android.com/reference/android/util/Property.html"&gt;Property&lt;/a&gt; オブジェクト &lt;font color=green&gt;BAR&lt;/font&gt; を宣言して、&lt;font color=green&gt;Foo&lt;/font&gt; クラスの &lt;font color=green&gt;foo&lt;/font&gt; インスタンスのフィールドをこのようにセットできます : &lt;code name="code" class="java"&gt;BAR.set(foo, value);&lt;/code&gt;&lt;a href="http://developer.android.com/reference/android/view/View.html"&gt;View&lt;/a&gt; クラスでは、この &lt;a href="http://developer.android.com/reference/android/util/Property.html"&gt;Property&lt;/a&gt; クラスを利用して、Android 3.0 で追加された変形プロパティ (&lt;a href="http://developer.android.com/reference/android/view/View.html#ROTATION"&gt;ROTATION&lt;/a&gt;, &lt;a href="http://developer.android.com/reference/android/view/View.html#ROTATION_X"&gt;ROTATION_X&lt;/a&gt;, &lt;a href="http://developer.android.com/reference/android/view/View.html#TRANSLATION_X"&gt;TRANSLATION_X&lt;/a&gt; など) など、いくつかのフィールドを設定できるようになりました。&lt;br /&gt;&lt;br /&gt;&lt;a href="http://developer.android.com/reference/android/animation/ObjectAnimator.html"&gt;ObjectAnimator&lt;/a&gt; クラスも &lt;a href="http://developer.android.com/reference/android/util/Property.html"&gt;Property&lt;/a&gt; クラスを使うようになりました。そのため、&lt;a href="http://developer.android.com/reference/android/util/Property.html"&gt;Property&lt;/a&gt; を使ってより速く、効率的に、文字列ベースのアプローチよりもより型安全に &lt;a href="http://developer.android.com/reference/android/animation/ObjectAnimator.html"&gt;ObjectAnimator&lt;/a&gt; を作成できます。&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;■ Hardware Acceleration&lt;/h4&gt;Android 4.0 から、&lt;a href="http://developer.android.com/guide/topics/manifest/uses-sdk-element.html#target"&gt;targetSdkVersion&lt;/a&gt; もしくは &lt;a href="http://developer.android.com/guide/topics/manifest/uses-sdk-element.html#min"&gt;minSdkVersion&lt;/a&gt; に &lt;font color=green&gt;"14"&lt;/font&gt; 以上がセットされているアプリでは、デフォルトで hardware acceleration が全ての window で有効になっています。hardware acceleration の結果として、一般的にはアニメーションがスムーズになったり、スクロールがスムーズになったり、ユーザー操作へのレスポンスとパフォーマンスが全体的によくなったりします。&lt;br /&gt;&lt;br /&gt;必要であれば手動で hardware acceleration を無効にすることができます。それには個々の &lt;a href="http://developer.android.com/guide/topics/manifest/activity-element.html"&gt;&amp;lt;activity&amp;gt;&lt;/a&gt; エレメントもしくは &lt;a href="http://developer.android.com/guide/topics/manifest/application-element.html"&gt;&amp;lt;application&amp;gt;&lt;/a&gt; エレメントの &lt;a href="http://developer.android.com/guide/topics/manifest/activity-element.html#hwaccel"&gt;hardwareAccelerated&lt;/a&gt; 属性に false を設定します。また、個々の view で &lt;a href="http://developer.android.com/reference/android/view/View.html#setLayerType(int, android.graphics.Paint)"&gt;setLayerType(LAYER_TYPE_SOFTWARE)&lt;/a&gt; を呼ぶことでも hardware acceleration を無効にすることができます。&lt;br /&gt;&lt;br /&gt;サポートしていない描画操作のリストなどのを含む、hardware acceleration のより詳しい情報は &lt;a href="http://developer.android.com/guide/topics/graphics/hardware-accel.html"&gt;Hardware Acceleration&lt;/a&gt; ドキュメントを見てください。&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;■ JNI Changes&lt;/h4&gt;以前の Android バージョンでは、JNI local reference は間接的に扱うことができず、Android は直接ポインタを使っていました。これはガーベージコレクターがオブジェクトを動かさなかった間は問題ありませんでしたが、一見動くように見える状態はバグを含むコードを書いてしまう可能性があります。Android 4.0 では、システムはこれらのバグを検出するために間接的な reference を使うようになりました。&lt;br /&gt;&lt;br /&gt;JNI local reference の入力と出力は &lt;a href="http://developer.android.com/guide/practices/design/jni.html"&gt;JNI Tips&lt;/a&gt; の "Local and Global References" に記述されています。Android 4.0 では、これらのエラーを検出するために &lt;a href="http://android-developers.blogspot.com/2011/07/debugging-android-jni-with-checkjni.html"&gt;CheckJNI&lt;/a&gt; が拡張されています。&lt;a href="http://android-developers.blogspot.com/"&gt;Android Developer Blog&lt;/a&gt; を見て、一般的な JNI references のエラーとそれをどのように直すかのポストがくるのをチェックしてください。&lt;br /&gt;&lt;br /&gt;JNI 実装のこの変更は &lt;a href="http://developer.android.com/guide/topics/manifest/uses-sdk-element.html#target"&gt;targetSdkVersion&lt;/a&gt; か &lt;a href="http://developer.android.com/guide/topics/manifest/uses-sdk-element.html#min"&gt;minSdkVersion&lt;/a&gt; が &lt;font color=green&gt;"14"&lt;/font&gt;以上の Android 4.0 をターゲットとするアプリにのみ影響します。これらの属性にこれより小さい値をセットした場合は、JNI local reference は以前のバージョンと同じように動作します。&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;■ WebKit&lt;/h4&gt;&lt;ul&gt;&lt;li&gt; WebKit が version 534.30 にアップデートされました。&lt;li&gt; Indic fonts (Devanagari, Bengali, and Tamil, including the complex character support needed for combining glyphs) を &lt;a href="http://developer.android.com/reference/android/webkit/WebView.html"&gt;WebView&lt;/a&gt; とビルトインのブラウザでサポート&lt;li&gt; Ethiopic, Georgian, and Armenian fonts を &lt;a href="http://developer.android.com/reference/android/webkit/WebView.html"&gt;WebView&lt;/a&gt; とビルトインのブラウザでサポート&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/webkit/WebView.html"&gt;WebView&lt;/a&gt; を使うアプリのテストを楽にする &lt;a href="http://google-opensource.blogspot.com/2009/05/introducing-webdriver.html"&gt;WebDriver&lt;/a&gt; をサポート&lt;/ul&gt;&lt;h4&gt;Android Browser&lt;/h4&gt;ブラウザアプリに web アプリをサポートするための以下の機能が追加されました。&lt;ul&gt;&lt;li&gt; V8 JavaScript コンパイラがアップデートされパフォーマンスがよくなりました&lt;li&gt; 加えて、&lt;a href="http://developer.android.com/sdk/android-3.0.html"&gt;Android 3.0&lt;/a&gt; から引き継がれた注目すべき機能がハンドセットでも利用可能になりました : &lt;ul&gt;&lt;li&gt; 全てのページでのエレメントの固定位置をサポート&lt;li&gt; &lt;a href="http://dev.w3.org/2009/dap/camera/"&gt;HTML media capture&lt;/a&gt;&lt;li&gt; &lt;a href="http://dev.w3.org/geo/api/spec-source-orientation.html"&gt;Device orientation events&lt;/a&gt;&lt;li&gt; &lt;a href="http://www.w3.org/TR/css3-3d-transforms/"&gt;CSS 3D transformations&lt;/a&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;br /&gt;&lt;h4&gt;■ Permissions&lt;/h4&gt;以下は新しいパーミッションです。&lt;ul&gt;&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/Manifest.permission.html#ADD_VOICEMAIL"&gt;ADD_VOICEMAIL&lt;/a&gt; : voicemail service がデバイスに voicemail メッセージを追加することを許可する&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/Manifest.permission.html#BIND_TEXT_SERVICE"&gt;BIND_TEXT_SERVICE&lt;/a&gt; : &lt;a href="http://developer.android.com/reference/android/service/textservice/SpellCheckerService.html"&gt;SpellCheckerService&lt;/a&gt; を実装するサービスはこのパーミッションが必要&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/Manifest.permission.html#BIND_VPN_SERVICE"&gt;BIND_VPN_SERVICE&lt;/a&gt; : &lt;a href="http://developer.android.com/reference/android/net/VpnService.html"&gt;VpnService&lt;/a&gt; を実装するサービスはこのパーミッションが必要&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/Manifest.permission.html#READ_PROFILE"&gt;READ_PROFILE&lt;/a&gt; : &lt;a href="http://developer.android.com/reference/android/provider/ContactsContract.Profile.html"&gt;ContactsContract.Profile&lt;/a&gt; provider への読み込みアクセスを提供する&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/Manifest.permission.html#WRITE_PROFILE"&gt;WRITE_PROFILE&lt;/a&gt; : &lt;a href="http://developer.android.com/reference/android/provider/ContactsContract.Profile.html"&gt;ContactsContract.Profile&lt;/a&gt; provider への書き込みアクセスを提供する&lt;/ul&gt;&lt;br /&gt;&lt;h4&gt;■ Device Features&lt;/h4&gt;以下はデバイスの新しい機能です。&lt;ul&gt;&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/content/pm/PackageManager.html#FEATURE_WIFI_DIRECT"&gt;FEATURE_WIFI_DIRECT&lt;/a&gt; : アプリが Wi-Fi の peer-to-peer 通信を使うことを宣言します。&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5859951453664122203-3823167875882908909?l=y-anz-m.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://y-anz-m.blogspot.com/feeds/3823167875882908909/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://y-anz-m.blogspot.com/2011/10/android-40-paltform.html#comment-form' title='2 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5859951453664122203/posts/default/3823167875882908909'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5859951453664122203/posts/default/3823167875882908909'/><link rel='alternate' type='text/html' href='http://y-anz-m.blogspot.com/2011/10/android-40-paltform.html' title='Android 4.0 Platform'/><author><name>yanzm</name><uri>http://www.blogger.com/profile/04059587494895790858</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_HRaLqTNFL7w/TDx6XwqrmDI/AAAAAAAABMo/B1SkSHxhKu4/S220/icon4.JPG'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5859951453664122203.post-2831494064355817112</id><published>2011-10-06T11:37:00.000+09:00</published><updated>2011-10-06T11:37:25.174+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Android'/><title type='text'>Android　SimpleCursorTreeAdapter を使う</title><content type='html'>1段のリストを作る &lt;a href="http://developer.android.com/reference/android/widget/ListView.html"&gt;ListView&lt;/a&gt; 用の Adapter として、 Object配列やリストをひもづける &lt;a href="http://developer.android.com/reference/android/widget/SimpleAdapter.html"&gt;SimpleAdapter&lt;/a&gt; や データベースを検索して得られる Cursor をひもづける &lt;a href="http://developer.android.com/reference/android/widget/SimpleCursorAdapter.html"&gt;SimpleCursorAdapter&lt;/a&gt; などがあります。&lt;br /&gt;&lt;br /&gt;同じように、2段のリストを作る &lt;a href="http://developer.android.com/reference/android/widget/ExpandableListView.html"&gt;ExpandableListView&lt;/a&gt; 用の Adapter として、Object の配列やリストをひもづける &lt;a href="http://developer.android.com/reference/android/widget/SimpleExpandableListAdapter.html"&gt;SimpleExpandableListAdapter&lt;/a&gt; というのがあります。実は、Cursor データを ExpandableListView にひもづけるための実装クラスの Adapter はありません。変わりに抽象クラスの &lt;a href="http://developer.android.com/reference/android/widget/SimpleCursorTreeAdapter.html"&gt;SimpleCursorTreeAdapter&lt;/a&gt; というものがあります。&lt;br /&gt;&lt;br /&gt;# &lt;a href="http://developer.android.com/reference/android/widget/SimpleExpandableListAdapter.html"&gt;SimpleExpandableListAdapter&lt;/a&gt; の使い方は &lt;a href="http://developer.android.com/resources/samples/ApiDemos/index.html"&gt;API Demos&lt;/a&gt; の &lt;a href="http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/view/ExpandableList3.html"&gt;ExpandableList3.java&lt;/a&gt; がわかりやすいです。&lt;br /&gt;&lt;br /&gt;このクラスを継承した実装クラスを作って利用します。&lt;br /&gt;&lt;br /&gt;&lt;code name="code" class="java"&gt;public class SimpleCursorTreeAdapterSampleActivity extends ExpandableListActivity {    private static final String[] CONTACTS_PROJECTION = new String[] {        Contacts._ID,        Contacts.DISPLAY_NAME    };        private static final int GROUP_ID_COLUMN_INDEX = 0;        private static final String[] PHONE_PROJECTION = new String[] {        Phone._ID,        Phone.TYPE,        Phone.NUMBER    };    public class ExpandableListAdapter extends SimpleCursorTreeAdapter {        public ExpandableListAdapter(Context context, Cursor c,                int groupLayout, String[] groupFrom, int[] groupTo,                 int childLayout, String[] childrenFrom,int[] childrenTo) {            super(context, c, groupLayout, groupFrom, groupTo,                     childLayout, childrenFrom, childrenTo);        }        @Override        protected Cursor getChildrenCursor(Cursor groupCursor) {            Uri.Builder builder = Contacts.CONTENT_URI.buildUpon();            ContentUris.appendId(builder, groupCursor.getLong(GROUP_ID_COLUMN_INDEX));            builder.appendEncodedPath(Contacts.Data.CONTENT_DIRECTORY);            Uri phoneNumbersUri = builder.build();                        Cursor c = getContentResolver().query(phoneNumbersUri, PHONE_PROJECTION, Phone.MIMETYPE + "=?", new String[] { Phone.CONTENT_ITEM_TYPE}, null);            startManagingCursor(c);            return c;        }    }        private SimpleCursorTreeAdapter mAdapter;        @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        Cursor c = getContentResolver().query(Contacts.CONTENT_URI, CONTACTS_PROJECTION,                 Contacts.HAS_PHONE_NUMBER + "=1", null, null);        mAdapter = new ExpandableListAdapter(                this, c,                android.R.layout.simple_expandable_list_item_1,                new String[] { Contacts.DISPLAY_NAME },                 new int[] { android.R.id.text1 },                android.R.layout.simple_expandable_list_item_1,                new String[] { Phone.NUMBER },                new int[] { android.R.id.text1 });                startManagingCursor(c);                setListAdapter(mAdapter);    }}&lt;/code&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-lBvgPUVU4w8/To0T47w2jmI/AAAAAAAADhI/-I2AANITj6w/s1600/SimpleCursorTreeAdapter1.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="400" width="240" src="http://1.bp.blogspot.com/-lBvgPUVU4w8/To0T47w2jmI/AAAAAAAADhI/-I2AANITj6w/s400/SimpleCursorTreeAdapter1.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;SimpleCursorTreeAdapter にも SimpleCursorAdapter 同様 ViewBinder を設定して表示方法を変更することができます。&lt;br /&gt;&lt;br /&gt;&lt;code name="code" class="java"&gt;public class SimpleCursorTreeAdapterSampleActivity extends ExpandableListActivity {    private static final String[] CONTACTS_PROJECTION = new String[] {        Contacts._ID,        Contacts.DISPLAY_NAME    };        private static final int GROUP_ID_COLUMN_INDEX = 0;        private static final String[] PHONE_PROJECTION = new String[] {        Phone._ID,        Phone.TYPE,        Phone.NUMBER    };    private static final int[] COLOR_LIST = new int[] {        Color.parseColor("#002A42"),        Color.parseColor("#3DC3EA"),        Color.parseColor("#99417B"),        Color.parseColor("#F2AE30"),        Color.parseColor("#F2D338"),    };    public class ExpandableListAdapter extends SimpleCursorTreeAdapter {        public ExpandableListAdapter(Context context, Cursor c,                int groupLayout, String[] groupFrom, int[] groupTo,                 int childLayout, String[] childrenFrom,int[] childrenTo) {            super(context, c, groupLayout, groupFrom, groupTo,                     childLayout, childrenFrom, childrenTo);        }        @Override        protected Cursor getChildrenCursor(Cursor groupCursor) {            Uri.Builder builder = Contacts.CONTENT_URI.buildUpon();            ContentUris.appendId(builder, groupCursor.getLong(GROUP_ID_COLUMN_INDEX));            builder.appendEncodedPath(Contacts.Data.CONTENT_DIRECTORY);            Uri phoneNumbersUri = builder.build();                        Cursor c = getContentResolver().query(phoneNumbersUri, PHONE_PROJECTION, Phone.MIMETYPE + "=?", new String[] { Phone.CONTENT_ITEM_TYPE}, null);            startManagingCursor(c);            return c;        }    }        private SimpleCursorTreeAdapter mAdapter;        @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        Cursor c = getContentResolver().query(Contacts.CONTENT_URI, CONTACTS_PROJECTION,                 Contacts.HAS_PHONE_NUMBER + "=1", null, null);        mAdapter = new ExpandableListAdapter(                this, c,                android.R.layout.simple_expandable_list_item_1,                new String[] { Contacts.DISPLAY_NAME },                new int[] { android.R.id.text1 },                android.R.layout.simple_expandable_list_item_2,                new String[] { Phone.TYPE, Phone.NUMBER },                new int[] { android.R.id.text1, android.R.id.text2 });                mAdapter.setViewBinder(new SimpleCursorTreeAdapter.ViewBinder() {                        public boolean setViewValue(View view, Cursor cursor, int columnIndex) {                if (cursor.getColumnName(columnIndex).equals(Phone.TYPE)) {                    int type = cursor.getInt(columnIndex);                    String text = (String) Phone.getTypeLabel(getResources(), type, null);                                        ((TextView) view).setText(text);                    ((TextView) view).setTextColor(COLOR_LIST[type % 5]);                    return true;                }                return false;            }        });                startManagingCursor(c);                setListAdapter(mAdapter);    }}&lt;/code&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-udtS55ErGDY/To0T5NAdhaI/AAAAAAAADhQ/dFhaONjb3Co/s1600/SimpleCursorTreeAdapter2.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="400" width="240" src="http://1.bp.blogspot.com/-udtS55ErGDY/To0T5NAdhaI/AAAAAAAADhQ/dFhaONjb3Co/s400/SimpleCursorTreeAdapter2.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://y-anz-m.blogspot.com/2011/10/androidasyncqueryhandler.html"&gt;Y.A.M の 雑記帳: Android　AsyncQueryHandler を使う -&lt;/a&gt; でも触れたように、UI スレッドで Cursor を取得するためのクエリを走らせると UI スレッドをブロックしていまいます。それを避けるために SimpleCursorTreeAdapter に対しても AsyncQueryHandler を使うようにすることができます。&lt;br /&gt;&lt;br /&gt;&lt;code name="code" class="java"&gt;public class AsyncQuerySimpleCursorTreeAdapterSampleActivity extends ExpandableListActivity {    private static final String[] CONTACTS_PROJECTION = new String[] {        Contacts._ID,        Contacts.DISPLAY_NAME    };        private static final int GROUP_ID_COLUMN_INDEX = 0;        private static final String[] PHONE_PROJECTION = new String[] {        Phone._ID,        Phone.TYPE,        Phone.NUMBER    };    private static final int[] COLOR_LIST = new int[] {        Color.parseColor("#002A42"),        Color.parseColor("#3DC3EA"),        Color.parseColor("#99417B"),        Color.parseColor("#F2AE30"),        Color.parseColor("#F2D338"),    };        private static final int TOKEN_GROUP = 0;    private static final int TOKEN_CHILD = 1;        private static final class QueryHandler extends AsyncQueryHandler {        private CursorTreeAdapter mAdapter;        public QueryHandler(Context context, CursorTreeAdapter adapter) {            super(context.getContentResolver());            this.mAdapter = adapter;        }        @Override        protected void onQueryComplete(int token, Object cookie, Cursor cursor) {            switch (token) {            case TOKEN_GROUP:                mAdapter.setGroupCursor(cursor);                break;            case TOKEN_CHILD:                int groupPosition = (Integer) cookie;                mAdapter.setChildrenCursor(groupPosition, cursor);                break;            }        }    }        public class ExpandableListAdapter extends SimpleCursorTreeAdapter {        public ExpandableListAdapter(Context context,                 int groupLayout, int childLayout,                 String[] groupFrom, int[] groupTo,                 String[] childrenFrom,int[] childrenTo) {            super(context, null, groupLayout, groupFrom, groupTo,                     childLayout, childrenFrom, childrenTo);        }        @Override        protected Cursor getChildrenCursor(Cursor groupCursor) {            Uri.Builder builder = Contacts.CONTENT_URI.buildUpon();            ContentUris.appendId(builder, groupCursor.getLong(GROUP_ID_COLUMN_INDEX));            builder.appendEncodedPath(Contacts.Data.CONTENT_DIRECTORY);            Uri phoneNumbersUri = builder.build();            mQueryHandler.startQuery(TOKEN_CHILD, groupCursor.getPosition(), phoneNumbersUri,                     PHONE_PROJECTION, Phone.MIMETYPE + "=?",                     new String[] { Phone.CONTENT_ITEM_TYPE }, null);            return null;        }    }        private QueryHandler mQueryHandler;    private SimpleCursorTreeAdapter mAdapter;        @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        mAdapter = new ExpandableListAdapter(                this,                 android.R.layout.simple_expandable_list_item_1,                android.R.layout.simple_expandable_list_item_2,                new String[] { Contacts.DISPLAY_NAME },                new int[] { android.R.id.text1 },                new String[] { Phone.TYPE, Phone.NUMBER },                new int[] { android.R.id.text1, android.R.id.text2 });                mAdapter.setViewBinder(new SimpleCursorTreeAdapter.ViewBinder() {                        public boolean setViewValue(View view, Cursor cursor, int columnIndex) {                if (cursor.getColumnName(columnIndex).equals(Phone.TYPE)) {                    int type = cursor.getInt(columnIndex);                    String text = (String) Phone.getTypeLabel(getResources(), type, null);                                        ((TextView) view).setText(text);                    ((TextView) view).setTextColor(COLOR_LIST[type % 5]);                    return true;                }                return false;            }        });                setListAdapter(mAdapter);        mQueryHandler = new QueryHandler(this, mAdapter);        mQueryHandler.startQuery(TOKEN_GROUP, null, Contacts.CONTENT_URI,                 CONTACTS_PROJECTION, Contacts.HAS_PHONE_NUMBER + "=1", null, null);    }    @Override    protected void onDestroy() {        super.onDestroy();        mAdapter.changeCursor(null);        mAdapter = null;    }}&lt;/code&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-4widrVr8kCw/To0T5PJBBWI/AAAAAAAADhY/yyxVV5JqLUc/s1600/SimpleCursorTreeAdapter3.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="400" width="240" src="http://1.bp.blogspot.com/-4widrVr8kCw/To0T5PJBBWI/AAAAAAAADhY/yyxVV5JqLUc/s400/SimpleCursorTreeAdapter3.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5859951453664122203-2831494064355817112?l=y-anz-m.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://y-anz-m.blogspot.com/feeds/2831494064355817112/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://y-anz-m.blogspot.com/2011/10/androidsimplecursortreeadapter.html#comment-form' title='1 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5859951453664122203/posts/default/2831494064355817112'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5859951453664122203/posts/default/2831494064355817112'/><link rel='alternate' type='text/html' href='http://y-anz-m.blogspot.com/2011/10/androidsimplecursortreeadapter.html' title='Android　SimpleCursorTreeAdapter を使う'/><author><name>yanzm</name><uri>http://www.blogger.com/profile/04059587494895790858</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_HRaLqTNFL7w/TDx6XwqrmDI/AAAAAAAABMo/B1SkSHxhKu4/S220/icon4.JPG'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-lBvgPUVU4w8/To0T47w2jmI/AAAAAAAADhI/-I2AANITj6w/s72-c/SimpleCursorTreeAdapter1.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5859951453664122203.post-2378004801683632016</id><published>2011-10-05T12:11:00.000+09:00</published><updated>2011-10-05T12:14:17.759+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Android'/><title type='text'>Android　Localeに対応した曜日や月の表記一覧を取得する</title><content type='html'>特定の Locale に対応した、曜日や月などの表記の一覧配列を &lt;a href="http://java.sun.com/j2se/1.5.0/ja/docs/ja/api/java/text/DateFormatSymbols.html"&gt;DateFormatSymbols&lt;/a&gt; を使って取得できるので、Android で設定言語を変えた場合を取得してみた。&lt;br /&gt;&lt;br /&gt;&lt;code name="code" class="java"&gt;public class DateFormatSymbolSampleActivity extends Activity {    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.main);                LayoutInflater inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);                DateFormatSymbols symbols = new DateFormatSymbols();                TableLayout table = (TableLayout) findViewById(R.id.symbols);                addTableRow(inflater, table, "getAmPmString", Arrays.toString(symbols.getAmPmStrings()));        addTableRow(inflater, table, "getEras", Arrays.toString(symbols.getEras()));        addTableRow(inflater, table, "getMonths", Arrays.toString(symbols.getMonths()));        addTableRow(inflater, table, "getShortMonths", Arrays.toString(symbols.getShortMonths()));        addTableRow(inflater, table, "getWeekdays", Arrays.toString(symbols.getWeekdays()));    }        private void addTableRow(LayoutInflater inflater, TableLayout table, String text1, String text2) {        TableRow row = (TableRow)inflater.inflate(R.layout.row, table, false);        ((TextView)row.findViewById(R.id.text1)).setText(text1);        ((TextView)row.findViewById(R.id.text2)).setText(text2);        table.addView(row);    }}&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;code name="code" class="xml"&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;&amp;lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:orientation="vertical"    android:layout_width="fill_parent"    android:layout_height="fill_parent"    &amp;gt;    &amp;lt;TableLayout        android:id="@+id/symbols"        android:layout_width="fill_parent"         android:layout_height="wrap_content"         /&amp;gt;&amp;lt;/LinearLayout&amp;gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;code name="code" class="xml"&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;&amp;lt;TableRow xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="fill_parent"    android:layout_height="wrap_content"    android:padding="5dip"    &amp;gt;    &amp;lt;TextView        android:id="@+id/text1"        android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:padding="5dip"        /&amp;gt;    &amp;lt;TextView        android:id="@+id/text2"        android:layout_width="0dip"        android:layout_weight="1"         android:layout_height="wrap_content"         android:padding="5dip"        /&amp;gt;&amp;lt;/TableRow&amp;gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;英語ロケール&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-PWrjvUqs8kw/TovKSpy0LKI/AAAAAAAADgc/74FVMc3QqBw/s1600/DateFormatSymbolEnglish.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="400" width="234" src="http://4.bp.blogspot.com/-PWrjvUqs8kw/TovKSpy0LKI/AAAAAAAADgc/74FVMc3QqBw/s400/DateFormatSymbolEnglish.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;日本語ロケール&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-Nt1iDhvjoI4/TovKSx1S8pI/AAAAAAAADgk/ccR38Lle-9o/s1600/DateFormatSymbolJapan.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="400" width="234" src="http://3.bp.blogspot.com/-Nt1iDhvjoI4/TovKSx1S8pI/AAAAAAAADgk/ccR38Lle-9o/s400/DateFormatSymbolJapan.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;ドイツ語ロケール&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-py0tdGTvO9k/TovKTIdcnnI/AAAAAAAADgs/ZDbiyVrpzsk/s1600/DateFormatSymbolGerman.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="400" width="234" src="http://2.bp.blogspot.com/-py0tdGTvO9k/TovKTIdcnnI/AAAAAAAADgs/ZDbiyVrpzsk/s400/DateFormatSymbolGerman.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;フランス語ロケール&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-syaa9WOvq9o/TovKTKFCQ-I/AAAAAAAADg0/s119R4ZUzPg/s1600/DateFormatSymbolFrench.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="400" width="234" src="http://4.bp.blogspot.com/-syaa9WOvq9o/TovKTKFCQ-I/AAAAAAAADg0/s119R4ZUzPg/s400/DateFormatSymbolFrench.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;韓国語ロケール&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-fdbKiYQFqwk/TovKTUFev6I/AAAAAAAADg8/U6EVcOkGjRs/s1600/DateFormatSymbolKorean.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="400" width="234" src="http://1.bp.blogspot.com/-fdbKiYQFqwk/TovKTUFev6I/AAAAAAAADg8/U6EVcOkGjRs/s400/DateFormatSymbolKorean.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;ちなみに、1.6 だと、曜日名と月名がとれないバグがあるそうです。&lt;br /&gt;&lt;a href="http://code.google.com/p/android/issues/detail?id=3985"&gt;Issue 3985 - android - DateFormatSymbols bugs in Japanese locale sdk1.6 - Project Hosting on Google Code&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5859951453664122203-2378004801683632016?l=y-anz-m.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://y-anz-m.blogspot.com/feeds/2378004801683632016/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://y-anz-m.blogspot.com/2011/10/androidlocale.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5859951453664122203/posts/default/2378004801683632016'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5859951453664122203/posts/default/2378004801683632016'/><link rel='alternate' type='text/html' href='http://y-anz-m.blogspot.com/2011/10/androidlocale.html' title='Android　Localeに対応した曜日や月の表記一覧を取得する'/><author><name>yanzm</name><uri>http://www.blogger.com/profile/04059587494895790858</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_HRaLqTNFL7w/TDx6XwqrmDI/AAAAAAAABMo/B1SkSHxhKu4/S220/icon4.JPG'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-PWrjvUqs8kw/TovKSpy0LKI/AAAAAAAADgc/74FVMc3QqBw/s72-c/DateFormatSymbolEnglish.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5859951453664122203.post-2177641637464209892</id><published>2011-10-04T14:48:00.001+09:00</published><updated>2011-10-04T14:48:11.672+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Android'/><title type='text'>Android　Apache HTTP Client と HttpURLConnection どっちを使うべき？</title><content type='html'>Android Developer's Blog にちょっと面白い記事があったのでまとめてみた。&lt;br /&gt;&lt;br /&gt;&lt;a href="http://android-developers.blogspot.com/2011/09/androids-http-clients.html"&gt;Android Developers Blog: Android’s HTTP Clients - &lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Android のフレームワークは HTTP 通信をするための HTTP client の実装が2つあります。&lt;br /&gt;&lt;br /&gt;1つが HttpURLConnection (java.net パッケージ) で、もう1つのが Apache HTTP Client (org.apache.http パッケージ) です。&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Apache HTTP Client &lt;/b&gt;&lt;br /&gt;&lt;br /&gt;　&lt;a href="http://developer.android.com/reference/org/apache/http/impl/client/DefaultHttpClient.html"&gt;DefaultHttpClient&lt;/a&gt; とそれのサブクラスの &lt;a href="http://developer.android.com/reference/android/net/http/AndroidHttpClient.html"&gt;AndroidHttpClient&lt;/a&gt; は Web ブラウザに適応した拡張された HTTP Client です。そのため、大きくてフレキシブルな API を持っています。これらの実装は安定していますが、いくつかのバグも含まれています。&lt;br /&gt;&lt;br /&gt;巨大な API は互換性を破らずに改善することがとても難しく、Android チームは Apache HTTP Client に対してアクティブに活動していません。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;HttpURLConnection&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;　&lt;a href="http://developer.android.com/reference/java/net/HttpURLConnection.html"&gt;HttpURLConnection&lt;/a&gt; ほとんどのアプリケーションに適応する汎用的で軽量な HTTP Client です。API が絞られているので、徐々に改善していきやすいです。&lt;br /&gt;&lt;br /&gt;Froyo 以前では、HttpURLConnection には幾つかのイライラするバグがありました。とくに、close() を読み込み可能な InputStream で呼ぶことで connection pool を汚染することがありました。connection pooling を無効にすることでこの問題を回避するには&lt;br /&gt;&lt;code name="code" class="java"&gt;private void disableConnectionReuseIfNecessary() {    // HTTP connection reuse which was buggy pre-froyo    if (Integer.parseInt(Build.VERSION.SDK) &lt; Build.VERSION_CODES.FROYO) {        System.setProperty("http.keepAlive", "false");    }}&lt;/code&gt;&lt;br /&gt;のようにします。&lt;br /&gt;&lt;br /&gt;Gingerbread では、transparent response compression が追加されました。HttpURLConnection は自動的にリクエストにヘッダを追加し、対応するレスポンスを処理します。&lt;br /&gt;&lt;br /&gt;&lt;font color=green&gt;Accept-Encoding: gzip&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;Web server が圧縮レスポンスを利用できるクライアントに対してそれを返すように設定することで、この利点を生かすことができます。もし圧縮レスポンスで問題がある場合は、&lt;a href="http://developer.android.com/reference/java/net/HttpURLConnection.html"&gt;クラスのドキュメント&lt;/a&gt;に無効にする方法がのっています。&lt;br /&gt;&lt;br /&gt;HTTP の Content-Length ヘッダは圧縮されたサイズを返すので、非圧縮データ用のバッファサイズとして &lt;a href="http://developer.android.com/reference/java/net/URLConnection.html#getContentLength()"&gt;getContentLength()&lt;/a&gt; で取得した値を使うとエラーになります。&lt;a href="http://developer.android.com/reference/java/io/InputStream.html#read(byte[])"&gt;InputStream.read()&lt;/a&gt; が -1 を返すまで読みようにしてください。&lt;br /&gt;&lt;br /&gt;Gingerbread での HTTPS も幾つか改善されています。HttpsURLConnection は IP アドレスを共有する複数の HTTPS host を許可する Servier Name Indication (SNI) に接続を試みます。これは圧縮とセッションチケットを有効にします。コネクションが失敗した場合は、自動でこれらの機能を省いてリトライします。これは HttpsClientConnection が過去のサーバーと互換性を保ちながら最新のサーバーと接続するのに効果的です。&lt;br /&gt;&lt;br /&gt;Ice Cream Sandwich では、レスポンスキャッシュが追加されます。インストールされたキャッシュに対して、次の3つのなかのいずれかの方法で HTTP リクエストが完了します。&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt; 完全にキャッシュされたレスポンスがローカルストレージから直接提供される。ネットワーク接続がない場合、このようなレスポンスがすぐに返ってくることが必要であるため。&lt;br /&gt;&lt;li&gt; 条件付きでキャッシュされたレスポンスはウェブサーバーによって新しさが検証されます。クライアントは "もし機能から変更されていたら /foo.png をください” のようなリクエストを送り、サーバーはアップデートがあるかどうかに応じて &lt;font color=green&gt;304 Not Modified status&lt;/font&gt; かコンテンツを返します。つまり、コンテンツが変わっていなければダウンロードされません！&lt;br /&gt;&lt;li&gt; キャッシュされていないレスポンスは Web から提供されます。これらのレスポンスは後でレスポンスキャッシュに保存されます。&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;HTTP レスポンスのキャッシュをサポートしている端末で有効にするにはリフレクションを使います。例えば、以前のリリースに影響を与えずに、Ice Create Sandwich の端末でキャッシュ機能を有効にするには次のようにします。&lt;br /&gt;&lt;br /&gt;&lt;code name="code" class="java"&gt;private void enableHttpResponseCache() {    try {        long httpCacheSize = 10 * 1024 * 1024; // 10 MiB        File httpCacheDir = new File(getCacheDir(), "http");        Class.forName("android.net.http.HttpResponseCache")            .getMethod("install", File.class, long.class)            .invoke(null, httpCacheDir, httpCacheSize);    } catch (Exception httpResponseCacheNotAvailable) {    }}&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;もちろん、HTTP レスポンスにキャッシュヘッダをセットするよう Web server を設定する必要があります。&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Which client is best?どっちのクライアントがいい？&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Eclair と Froyo では Apache HTTP client のほうがバグがすくないので、こちらがベストです。&lt;br /&gt;&lt;br /&gt;Gingerbread 以降では、HttpURLConnection がベストです。API がシンプルでサイズも小さいので Android に適しています。Transparent compression とレスポンスキャッシュはネットワークの利用を減らし、速度やバッテリーのもちを改善します。&lt;br /&gt;&lt;br /&gt;---&lt;br /&gt;&lt;br /&gt;# さらっと Ice Cream Sandwich のことが書かれてたね。&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5859951453664122203-2177641637464209892?l=y-anz-m.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://y-anz-m.blogspot.com/feeds/2177641637464209892/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://y-anz-m.blogspot.com/2011/10/androidapache-http-client.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5859951453664122203/posts/default/2177641637464209892'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5859951453664122203/posts/default/2177641637464209892'/><link rel='alternate' type='text/html' href='http://y-anz-m.blogspot.com/2011/10/androidapache-http-client.html' title='Android　Apache HTTP Client と HttpURLConnection どっちを使うべき？'/><author><name>yanzm</name><uri>http://www.blogger.com/profile/04059587494895790858</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_HRaLqTNFL7w/TDx6XwqrmDI/AAAAAAAABMo/B1SkSHxhKu4/S220/icon4.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5859951453664122203.post-7996675656106733264</id><published>2011-10-04T12:55:00.002+09:00</published><updated>2011-10-04T12:55:50.823+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Android'/><title type='text'>PreferenceActivity の CheckBox マークを変える</title><content type='html'>PreferenceActivity の各UI は Android のフレームワークの &lt;a href="http://tools.oesf.biz/android-2.3_r1.0/xref/frameworks/base/core/res/res/values/themes.xml"&gt;theme.xml&lt;/a&gt; に定義されています。&lt;br /&gt;&lt;br /&gt;/frameworks/base/core/res/res/values/themes.xml&lt;code name="code" class="java"&gt;    194         &amp;lt;!-- Preference styles --&amp;gt;    195         &amp;lt;item name="preferenceScreenStyle"&amp;gt;@android:style/Preference.PreferenceScreen&amp;lt;/item&amp;gt;    196         &amp;lt;item name="preferenceCategoryStyle"&amp;gt;@android:style/Preference.Category&amp;lt;/item&amp;gt;    197         &amp;lt;item name="preferenceStyle"&amp;gt;@android:style/Preference&amp;lt;/item&amp;gt;    198         &amp;lt;item name="preferenceInformationStyle"&amp;gt;@android:style/Preference.Information&amp;lt;/item&amp;gt;    199         &amp;lt;item name="checkBoxPreferenceStyle"&amp;gt;@android:style/Preference.CheckBoxPreference&amp;lt;/item&amp;gt;    200         &amp;lt;item name="yesNoPreferenceStyle"&amp;gt;@android:style/Preference.DialogPreference.YesNoPreference&amp;lt;/item&amp;gt;    201         &amp;lt;item name="dialogPreferenceStyle"&amp;gt;@android:style/Preference.DialogPreference&amp;lt;/item&amp;gt;    202         &amp;lt;item name="editTextPreferenceStyle"&amp;gt;@android:style/Preference.DialogPreference.EditTextPreference&amp;lt;/item&amp;gt;    203         &amp;lt;item name="ringtonePreferenceStyle"&amp;gt;@android:style/Preference.RingtonePreference&amp;lt;/item&amp;gt;    204         &amp;lt;item name="preferenceLayoutChild"&amp;gt;@android:layout/preference_child&amp;lt;/item&amp;gt;&lt;/code&gt;&lt;br /&gt;ここをそれぞれオリジナルテーマに置き換えればOK&lt;br /&gt;&lt;br /&gt;もともとはこうなってる&lt;br /&gt;&lt;br /&gt;/frameworks/base/core/res/res/values/styles.xml&lt;code name="code" class="xml"&gt;    769     &amp;lt;!-- Preference Styles --&amp;gt;    770     771     &amp;lt;style name="Preference"&amp;gt;    772         &amp;lt;item name="android:layout"&amp;gt;@android:layout/preference&amp;lt;/item&amp;gt;    773     &amp;lt;/style&amp;gt;    774         775     &amp;lt;style name="Preference.Information"&amp;gt;    776         &amp;lt;item name="android:layout"&amp;gt;@android:layout/preference_information&amp;lt;/item&amp;gt;    777         &amp;lt;item name="android:enabled"&amp;gt;false&amp;lt;/item&amp;gt;    778         &amp;lt;item name="android:shouldDisableView"&amp;gt;false&amp;lt;/item&amp;gt;    779     &amp;lt;/style&amp;gt;    780         781     &amp;lt;style name="Preference.Category"&amp;gt;    782         &amp;lt;item name="android:layout"&amp;gt;@android:layout/preference_category&amp;lt;/item&amp;gt;    783         &amp;lt;!-- The title should not dim if the category is disabled, instead only the preference children should dim. --&amp;gt;    784         &amp;lt;item name="android:shouldDisableView"&amp;gt;false&amp;lt;/item&amp;gt;    785         &amp;lt;item name="android:selectable"&amp;gt;false&amp;lt;/item&amp;gt;    786     &amp;lt;/style&amp;gt;    787         788     &amp;lt;style name="Preference.CheckBoxPreference"&amp;gt;    789         &amp;lt;item name="android:widgetLayout"&amp;gt;@android:layout/preference_widget_checkbox&amp;lt;/item&amp;gt;    790     &amp;lt;/style&amp;gt;    791         792     &amp;lt;style name="Preference.PreferenceScreen"&amp;gt;    793     &amp;lt;/style&amp;gt;    794     795     &amp;lt;style name="Preference.DialogPreference"&amp;gt;    796         &amp;lt;item name="android:positiveButtonText"&amp;gt;@android:string/ok&amp;lt;/item&amp;gt;    797         &amp;lt;item name="android:negativeButtonText"&amp;gt;@android:string/cancel&amp;lt;/item&amp;gt;    798         &amp;lt;item name="android:widgetLayout"&amp;gt;@android:layout/preference_dialog&amp;lt;/item&amp;gt;    799     &amp;lt;/style&amp;gt;    800         801     &amp;lt;style name="Preference.DialogPreference.YesNoPreference"&amp;gt;    802         &amp;lt;item name="android:positiveButtonText"&amp;gt;@android:string/yes&amp;lt;/item&amp;gt;    803         &amp;lt;item name="android:negativeButtonText"&amp;gt;@android:string/no&amp;lt;/item&amp;gt;    804     &amp;lt;/style&amp;gt;    805         806     &amp;lt;style name="Preference.DialogPreference.EditTextPreference"&amp;gt;    807         &amp;lt;item name="android:dialogLayout"&amp;gt;@android:layout/preference_dialog_edittext&amp;lt;/item&amp;gt;    808     &amp;lt;/style&amp;gt;    809         810     &amp;lt;style name="Preference.RingtonePreference"&amp;gt;    811         &amp;lt;item name="android:ringtoneType"&amp;gt;ringtone&amp;lt;/item&amp;gt;    812         &amp;lt;item name="android:showSilent"&amp;gt;true&amp;lt;/item&amp;gt;    813         &amp;lt;item name="android:showDefault"&amp;gt;true&amp;lt;/item&amp;gt;    814         &amp;lt;item name="android:widgetLayout"&amp;gt;@android:layout/preference_dialog&amp;lt;/item&amp;gt;    815     &amp;lt;/style&amp;gt;&lt;/code&gt;&lt;br /&gt;これを置き換え。&lt;br /&gt;&lt;br /&gt;android:widgetLayout というのが左側に配置される部品（チェックボックスとか、○に下三角のやつ）&lt;br /&gt;&lt;br /&gt;結論。CheckBoxPreference のチェックボックスと EditTextPreference の下三角は変更できる。&lt;br /&gt;ただし、EditTextPreference のダイアログのレイアウトは変更できたけど、レイアウトファイル内の @+android:id/edittext_container が public ではないため、入力ボックスがでなくなっちゃうのでダメだった。&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-DLjROcsAwMg/ToqBz9ouqgI/AAAAAAAADgU/95dlzuSgSeU/s1600/CustomPreference.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="400" width="240" src="http://2.bp.blogspot.com/-DLjROcsAwMg/ToqBz9ouqgI/AAAAAAAADgU/95dlzuSgSeU/s400/CustomPreference.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;PreferenceDialog を継承したクラスを作ったほうが早そう。&lt;br /&gt;&lt;br /&gt;res/xml/prefs.xml&lt;code name="code" class="xml"&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;&amp;lt;PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"&amp;gt;    &amp;lt;PreferenceCategory android:title="Setting"&amp;gt;        &amp;lt;CheckBoxPreference             android:key="checkbox_value"            android:title="Setting1"             android:summary="sample of checkbox setting" /&amp;gt;        &amp;lt;EditTextPreference             android:key="edittext_value"            android:title="Setting2"             android:summary="sample of edittext setting"            android:dialogTitle="Setting edittext"            android:dialogMessage="please set values" /&amp;gt;    &amp;lt;/PreferenceCategory&amp;gt;&amp;lt;/PreferenceScreen&amp;gt;&lt;/code&gt;res/values/styles.xml&lt;code name="code" class="xml"&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;&amp;lt;resources&amp;gt;    &amp;lt;style name="CustomTheme" parent="@android:style/Theme.Light"&amp;gt;        &amp;lt;item name="android:windowBackground"&amp;gt;@color/window_bg&amp;lt;/item&amp;gt;        &amp;lt;item name="android:colorBackground"&amp;gt;@color/window_bg&amp;lt;/item&amp;gt;        &amp;lt;item name="android:checkBoxPreferenceStyle"&amp;gt;@style/CustomCheckBoxPreference&amp;lt;/item&amp;gt;        &amp;lt;item name="android:editTextPreferenceStyle"&amp;gt;@style/CustomDialogPreference.CustomEditTextPreference        &amp;lt;/item&amp;gt;    &amp;lt;/style&amp;gt;    &amp;lt;style name="CustomCheckBoxPreference"&amp;gt;        &amp;lt;item name="android:widgetLayout"&amp;gt;@layout/preference_widget_checkbox&amp;lt;/item&amp;gt;    &amp;lt;/style&amp;gt;    &amp;lt;style name="CustomDialogPreference.CustomEditTextPreference"&amp;gt;        &amp;lt;item name="android:dialogLayout"&amp;gt;@layout/preference_dialog_edittext&amp;lt;/item&amp;gt;    &amp;lt;/style&amp;gt;    &amp;lt;style name="CustomDialogPreference"&amp;gt;        &amp;lt;item name="android:positiveButtonText"&amp;gt;@android:string/ok&amp;lt;/item&amp;gt;        &amp;lt;item name="android:negativeButtonText"&amp;gt;@android:string/cancel&amp;lt;/item&amp;gt;        &amp;lt;item name="android:widgetLayout"&amp;gt;@layout/preference_dialog&amp;lt;/item&amp;gt;    &amp;lt;/style&amp;gt;    &amp;lt;style name="CustomDialogPreference.YesNoPreference"&amp;gt;        &amp;lt;item name="android:positiveButtonText"&amp;gt;@android:string/yes&amp;lt;/item&amp;gt;        &amp;lt;item name="android:negativeButtonText"&amp;gt;@android:string/no&amp;lt;/item&amp;gt;    &amp;lt;/style&amp;gt;&amp;lt;/resources&amp;gt;&lt;/code&gt;res/layout/preference_widget_checkbox.xml&lt;code name="code" class="xml"&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;&amp;lt;CheckBox xmlns:android="http://schemas.android.com/apk/res/android"    android:id="@+android:id/checkbox"     android:layout_width="wrap_content"    android:layout_height="wrap_content"    android:layout_marginRight="4dip"    android:layout_gravity="center_vertical"    android:button="@drawable/btn_check"    android:focusable="false"    android:clickable="false" /&amp;gt;&lt;/code&gt;res/layoutpreference_dialog.xml&lt;code name="code" class="xml"&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;&amp;lt;ImageView xmlns:android="http://schemas.android.com/apk/res/android"     android:layout_width="wrap_content"     android:layout_height="wrap_content"     android:layout_marginRight="6dip"     android:layout_marginTop="@dimen/margin_check"     android:layout_marginLeft="@dimen/margin_check"     android:layout_marginBottom="@dimen/margin_check"     android:layout_gravity="center_vertical"     android:background="@drawable/btn_circle"     android:src="@drawable/ic_btn_round_more"     android:scaleType="center"      /&amp;gt;&lt;/code&gt;res/layoutpreference_dialog_edittext.xml&lt;code name="code" class="xml"&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;&amp;lt;ScrollView xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="fill_parent"    android:layout_height="fill_parent"&amp;gt;    &amp;lt;LinearLayout        android:id="@*android:id/edittext_container"        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:padding="5dip"        android:orientation="vertical"&amp;gt;        &amp;lt;TextView             android:id="@android:id/message"            style="?android:attr/textAppearanceMedium"            android:layout_width="fill_parent"            android:layout_height="wrap_content"            android:textColor="@color/color2" /&amp;gt;                &amp;lt;/LinearLayout&amp;gt;&amp;lt;/ScrollView&amp;gt;&lt;/code&gt;res/values/dimens.xml&lt;code name="code" class="xml"&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;&amp;lt;resources&amp;gt;    &amp;lt;dimen name="size_check"&amp;gt;32dip&amp;lt;/dimen&amp;gt;    &amp;lt;dimen name="size_more"&amp;gt;32dip&amp;lt;/dimen&amp;gt;    &amp;lt;dimen name="size_radio"&amp;gt;32dip&amp;lt;/dimen&amp;gt;    &amp;lt;dimen name="margin_check"&amp;gt;3dip&amp;lt;/dimen&amp;gt;    &amp;lt;dimen name="size_circle"&amp;gt;14dip&amp;lt;/dimen&amp;gt;&amp;lt;/resources&amp;gt;&lt;/code&gt;res/values/colors.xml&lt;code name="code" class="xml"&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;&amp;lt;resources&amp;gt;    &amp;lt;color name="color1"&amp;gt;#FDF3DE&amp;lt;/color&amp;gt;    &amp;lt;color name="color2"&amp;gt;#9C0C0A&amp;lt;/color&amp;gt;    &amp;lt;color name="color3"&amp;gt;#E88833&amp;lt;/color&amp;gt;    &amp;lt;color name="color4"&amp;gt;#8F6031&amp;lt;/color&amp;gt;    &amp;lt;color name="color5"&amp;gt;#3B3013&amp;lt;/color&amp;gt;    &amp;lt;color name="color6"&amp;gt;#690806&amp;lt;/color&amp;gt;    &amp;lt;color name="color7"&amp;gt;#dfd3d0&amp;lt;/color&amp;gt;    &amp;lt;color name="window_bg"&amp;gt;@color/color1&amp;lt;/color&amp;gt;    &amp;lt;color name="component_frame_normal"&amp;gt;@color/color3&amp;lt;/color&amp;gt;    &amp;lt;color name="component_frame_pressed"&amp;gt;@color/color2&amp;lt;/color&amp;gt;    &amp;lt;color name="component_frame_pressed_top"&amp;gt;@color/color2&amp;lt;/color&amp;gt;    &amp;lt;color name="component_frame_pressed_bottom"&amp;gt;@color/color6&amp;lt;/color&amp;gt;    &amp;lt;color name="component_frame_disabled"&amp;gt;@color/color7&amp;lt;/color&amp;gt;    &amp;lt;color name="component_text_normal"&amp;gt;@color/color6&amp;lt;/color&amp;gt;    &amp;lt;color name="component_text_pressed"&amp;gt;@color/color1&amp;lt;/color&amp;gt;    &amp;lt;color name="component_button_top"&amp;gt;#fff&amp;lt;/color&amp;gt;    &amp;lt;color name="component_button_bottom"&amp;gt;@color/color7&amp;lt;/color&amp;gt;&amp;lt;/resources&amp;gt;&lt;/code&gt;res/drawable/btn_check_bg.xml&lt;code name="code" class="xml"&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;&amp;lt;shape xmlns:android="http://schemas.android.com/apk/res/android"&amp;gt;    &amp;lt;padding android:left="38dip" android:right="0dip" /&amp;gt;    &amp;lt;solid android:color="#0000" /&amp;gt;&amp;lt;/shape&amp;gt;&lt;/code&gt;res/drawable/btn_bg.xml&lt;code name="code" class="xml"&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;&amp;lt;selector xmlns:android="http://schemas.android.com/apk/res/android"&amp;gt;    &amp;lt;item android:state_checked="true" android:state_pressed="true"        android:state_enabled="true"&amp;gt;        &amp;lt;layer-list&amp;gt;            &amp;lt;item android:top="@dimen/margin_check" android:bottom="@dimen/margin_check"                android:left="@dimen/margin_check" android:right="@dimen/margin_check"&amp;gt;                &amp;lt;shape android:shape="rectangle"&amp;gt;                    &amp;lt;corners android:radius="5dip" /&amp;gt;                    &amp;lt;gradient android:angle="270"                        android:startColor="@color/component_frame_pressed_top"                        android:endColor="@color/component_frame_pressed_bottom" /&amp;gt;                    &amp;lt;size android:width="@dimen/size_check"                        android:height="@dimen/size_check" /&amp;gt;                    &amp;lt;stroke android:width="2dip"                        android:color="@color/component_frame_pressed" /&amp;gt;                &amp;lt;/shape&amp;gt;            &amp;lt;/item&amp;gt;            &amp;lt;item android:top="10dip" android:bottom="10dip"                android:left="8dip" android:right="8dip"                android:drawable="@drawable/check_on" /&amp;gt;        &amp;lt;/layer-list&amp;gt;    &amp;lt;/item&amp;gt;    &amp;lt;item android:state_checked="false" android:state_pressed="true"        android:state_enabled="true"&amp;gt;        &amp;lt;layer-list&amp;gt;            &amp;lt;item android:top="@dimen/margin_check" android:bottom="@dimen/margin_check"                android:left="@dimen/margin_check" android:right="@dimen/margin_check"&amp;gt;                &amp;lt;shape android:shape="rectangle"&amp;gt;                    &amp;lt;corners android:radius="5dip" /&amp;gt;                    &amp;lt;gradient android:angle="270"                        android:startColor="@color/component_frame_pressed_top"                        android:endColor="@color/component_frame_pressed_bottom" /&amp;gt;                    &amp;lt;size android:width="@dimen/size_check"                        android:height="@dimen/size_check" /&amp;gt;                    &amp;lt;stroke android:width="2dip"                        android:color="@color/component_frame_pressed" /&amp;gt;                &amp;lt;/shape&amp;gt;            &amp;lt;/item&amp;gt;            &amp;lt;item android:top="10dip" android:bottom="10dip"                android:left="8dip" android:right="8dip"                android:drawable="@drawable/check_off" /&amp;gt;        &amp;lt;/layer-list&amp;gt;    &amp;lt;/item&amp;gt;    &amp;lt;item android:state_checked="true" android:state_focused="true"        android:state_enabled="true"&amp;gt;        &amp;lt;layer-list&amp;gt;            &amp;lt;item android:top="@dimen/margin_check" android:bottom="@dimen/margin_check"                android:left="@dimen/margin_check" android:right="@dimen/margin_check"&amp;gt;                &amp;lt;shape android:shape="rectangle"&amp;gt;                    &amp;lt;corners android:radius="5dip" /&amp;gt;                    &amp;lt;gradient android:angle="90"                        android:startColor="#ffffff" android:endColor="#fefefe" /&amp;gt;                    &amp;lt;size android:width="@dimen/size_check"                        android:height="@dimen/size_check" /&amp;gt;                    &amp;lt;stroke android:width="2dip"                        android:color="@color/component_frame_pressed" /&amp;gt;                &amp;lt;/shape&amp;gt;            &amp;lt;/item&amp;gt;            &amp;lt;item android:top="10dip" android:bottom="10dip"                android:left="8dip" android:right="8dip"                android:drawable="@drawable/check_on" /&amp;gt;        &amp;lt;/layer-list&amp;gt;    &amp;lt;/item&amp;gt;    &amp;lt;item android:state_checked="false" android:state_focused="true"        android:state_enabled="true"&amp;gt;        &amp;lt;layer-list&amp;gt;            &amp;lt;item android:top="@dimen/margin_check" android:bottom="@dimen/margin_check"                android:left="@dimen/margin_check" android:right="@dimen/margin_check"&amp;gt;                &amp;lt;shape android:shape="rectangle"&amp;gt;                    &amp;lt;corners android:radius="5dip" /&amp;gt;                    &amp;lt;gradient android:angle="90"                        android:startColor="#ffffff" android:endColor="#fefefe" /&amp;gt;                    &amp;lt;size android:width="@dimen/size_check"                        android:height="@dimen/size_check" /&amp;gt;                    &amp;lt;stroke android:width="2dip"                        android:color="@color/component_frame_pressed" /&amp;gt;                &amp;lt;/shape&amp;gt;            &amp;lt;/item&amp;gt;            &amp;lt;item android:top="10dip" android:bottom="10dip"                android:left="8dip" android:right="8dip"                android:drawable="@drawable/check_off" /&amp;gt;        &amp;lt;/layer-list&amp;gt;    &amp;lt;/item&amp;gt;    &amp;lt;item android:state_checked="false" android:state_enabled="true"&amp;gt;        &amp;lt;layer-list&amp;gt;            &amp;lt;item android:top="@dimen/margin_check" android:bottom="@dimen/margin_check"                android:left="@dimen/margin_check" android:right="@dimen/margin_check"&amp;gt;                &amp;lt;shape android:shape="rectangle"&amp;gt;                    &amp;lt;corners android:radius="5dip" /&amp;gt;                    &amp;lt;gradient android:angle="90"                        android:startColor="#ffffff" android:endColor="#fefefe" /&amp;gt;                    &amp;lt;size android:width="@dimen/size_check"                        android:height="@dimen/size_check" /&amp;gt;                    &amp;lt;stroke android:width="2dip"                        android:color="@color/component_frame_normal" /&amp;gt;                &amp;lt;/shape&amp;gt;            &amp;lt;/item&amp;gt;            &amp;lt;item android:top="10dip" android:bottom="10dip"                android:left="8dip" android:right="8dip"                android:drawable="@drawable/check_off" /&amp;gt;        &amp;lt;/layer-list&amp;gt;    &amp;lt;/item&amp;gt;    &amp;lt;item android:state_checked="true" android:state_enabled="true"&amp;gt;        &amp;lt;layer-list&amp;gt;            &amp;lt;item android:top="@dimen/margin_check" android:bottom="@dimen/margin_check"                android:left="@dimen/margin_check" android:right="@dimen/margin_check"&amp;gt;                &amp;lt;shape android:shape="rectangle"&amp;gt;                    &amp;lt;corners android:radius="5dip" /&amp;gt;                    &amp;lt;gradient android:angle="90"                        android:startColor="#ffffff" android:endColor="#fefefe" /&amp;gt;                    &amp;lt;size android:width="@dimen/size_check"                        android:height="@dimen/size_check" /&amp;gt;                    &amp;lt;stroke android:width="2dip"                        android:color="@color/component_frame_normal" /&amp;gt;                &amp;lt;/shape&amp;gt;            &amp;lt;/item&amp;gt;            &amp;lt;item android:top="10dip" android:bottom="10dip"                android:left="8dip" android:right="8dip"                android:drawable="@drawable/check_on" /&amp;gt;        &amp;lt;/layer-list&amp;gt;    &amp;lt;/item&amp;gt;    &amp;lt;!-- Disabled states --&amp;gt;    &amp;lt;item&amp;gt;        &amp;lt;layer-list&amp;gt;            &amp;lt;item android:top="@dimen/margin_check" android:bottom="@dimen/margin_check"                android:left="@dimen/margin_check" android:right="@dimen/margin_check"&amp;gt;                &amp;lt;shape android:shape="rectangle"&amp;gt;                    &amp;lt;corners android:radius="5dip" /&amp;gt;                    &amp;lt;gradient android:angle="90"                        android:startColor="#ffffff" android:endColor="#fefefe" /&amp;gt;                    &amp;lt;size android:width="@dimen/size_check"                        android:height="@dimen/size_check" /&amp;gt;                    &amp;lt;stroke android:width="2dip"                        android:color="@color/component_frame_disabled" /&amp;gt;                &amp;lt;/shape&amp;gt;            &amp;lt;/item&amp;gt;            &amp;lt;item android:top="10dip" android:bottom="10dip"                android:left="8dip" android:right="8dip"                android:drawable="@drawable/check_off" /&amp;gt;        &amp;lt;/layer-list&amp;gt;    &amp;lt;/item&amp;gt;&amp;lt;/selector&amp;gt;&lt;/code&gt;res/drawable/btn_circle.xml&lt;code name="code" class="xml"&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;&amp;lt;selector xmlns:android="http://schemas.android.com/apk/res/android"&amp;gt;    &amp;lt;item android:state_enabled="true"&amp;gt;        &amp;lt;shape android:shape="ring" android:useLevel="false"            android:innerRadius="0dip" android:thickness="@dimen/size_circle"&amp;gt;            &amp;lt;size android:width="@dimen/size_check" android:height="@dimen/size_check" /&amp;gt;            &amp;lt;stroke android:width="2dip"                android:color="@color/component_frame_normal" /&amp;gt;            &amp;lt;solid android:color="#fff" /&amp;gt;        &amp;lt;/shape&amp;gt;    &amp;lt;/item&amp;gt;    &amp;lt;item&amp;gt;        &amp;lt;shape android:shape="ring" android:useLevel="false"            android:innerRadius="0dip" android:thickness="@dimen/size_circle"&amp;gt;            &amp;lt;size android:width="@dimen/size_check" android:height="@dimen/size_check" /&amp;gt;            &amp;lt;stroke android:width="2dip"                android:color="@color/component_frame_disabled" /&amp;gt;            &amp;lt;solid android:color="#fff" /&amp;gt;        &amp;lt;/shape&amp;gt;    &amp;lt;/item&amp;gt;&amp;lt;/selector&amp;gt;&lt;/code&gt;ic_btn_round_more.xml は SDK プラットフォームのリソースのものを利用。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5859951453664122203-7996675656106733264?l=y-anz-m.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://y-anz-m.blogspot.com/feeds/7996675656106733264/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://y-anz-m.blogspot.com/2011/10/preferenceactivity-checkbox.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5859951453664122203/posts/default/7996675656106733264'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5859951453664122203/posts/default/7996675656106733264'/><link rel='alternate' type='text/html' href='http://y-anz-m.blogspot.com/2011/10/preferenceactivity-checkbox.html' title='PreferenceActivity の CheckBox マークを変える'/><author><name>yanzm</name><uri>http://www.blogger.com/profile/04059587494895790858</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_HRaLqTNFL7w/TDx6XwqrmDI/AAAAAAAABMo/B1SkSHxhKu4/S220/icon4.JPG'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-DLjROcsAwMg/ToqBz9ouqgI/AAAAAAAADgU/95dlzuSgSeU/s72-c/CustomPreference.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5859951453664122203.post-6080959242065171024</id><published>2011-10-04T10:56:00.001+09:00</published><updated>2011-10-04T11:24:46.954+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Android'/><title type='text'>Android　AsyncQueryHandler を使う</title><content type='html'>UI スレッド上で getContentResolver().query() とかをすると、処理が重たい場合にスレッドをブロックしてしまって ANR になることもあるので、別スレッドで非同期に query() するための &lt;a href="http://developer.android.com/reference/android/content/AsyncQueryHandler.html"&gt;AsyncQueryHandler&lt;/a&gt; というクラスがあります。&lt;br /&gt;&lt;br /&gt;AsyncQueryHandler は abstract クラスなので、継承したクラスを作って、&lt;a href="http://developer.android.com/reference/android/content/AsyncQueryHandler.html#onQueryComplete(int, java.lang.Object, android.database.Cursor)"&gt;onQueryComplete()&lt;/a&gt; や &lt;a href="http://developer.android.com/reference/android/content/AsyncQueryHandler.html#onInsertComplete(int, java.lang.Object, android.net.Uri)"&gt;onQueryInsertComplete()&lt;/a&gt; を Override し、ここで Adapter に Cursor をセットします。&lt;br /&gt;こんな感じで使います。&lt;br /&gt;&lt;br /&gt;&lt;code name="code" class="java"&gt;public class AsyncQueryHandlerSampleActivity extends ListActivity {    private static final String[] PHONE_PROJECTION = new String[] {        Phone._ID,        Phone.TYPE,        Phone.NUMBER    };    private static final int COLUMN_TYPE = 1;    private static final int[] COLOR_LIST = new int[] {        Color.parseColor("#002A42"),        Color.parseColor("#3DC3EA"),        Color.parseColor("#99417B"),        Color.parseColor("#F2AE30"),        Color.parseColor("#F2D338"),    };        public class CustomAsyncQueryHandler extends AsyncQueryHandler {        public CustomAsyncQueryHandler(ContentResolver cr) {            super(cr);        }                @Override        protected void onQueryComplete(int token, Object cookie, Cursor cursor) {            super.onQueryComplete(token, cookie, cursor);                        SimpleCursorAdapter adapter = new SimpleCursorAdapter(                    AsyncQueryHandlerSampleActivity.this,                    android.R.layout.simple_list_item_2,                     cursor,                    new String[] { Phone.TYPE, Phone.NUMBER },                    new int[] { android.R.id.text1, android.R.id.text2 });                        adapter.setViewBinder(new SimpleCursorAdapter.ViewBinder() {                                public boolean setViewValue(View view, Cursor cursor, int columnIndex) {                    if (columnIndex == COLUMN_TYPE) {                        int type = cursor.getInt(COLUMN_TYPE);                        String text = (String) Phone.getTypeLabel(getResources(), type, null);                                                ((TextView) view).setText(text);                        ((TextView) view).setTextColor(COLOR_LIST[type % 5]);                        return true;                    }                    return false;                }            });            setListAdapter(adapter);        }            }        @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);                CustomAsyncQueryHandler asyncQueryHandler = new CustomAsyncQueryHandler(getContentResolver());        asyncQueryHandler.startQuery(                0, // token                null, // cookie                Phone.CONTENT_URI,                PHONE_PROJECTION,   // projection                null,   // selection                null,   // selectionArgs                null    // orderBy                );    }}&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5859951453664122203-6080959242065171024?l=y-anz-m.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://y-anz-m.blogspot.com/feeds/6080959242065171024/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://y-anz-m.blogspot.com/2011/10/androidasyncqueryhandler.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5859951453664122203/posts/default/6080959242065171024'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5859951453664122203/posts/default/6080959242065171024'/><link rel='alternate' type='text/html' href='http://y-anz-m.blogspot.com/2011/10/androidasyncqueryhandler.html' title='Android　AsyncQueryHandler を使う'/><author><name>yanzm</name><uri>http://www.blogger.com/profile/04059587494895790858</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_HRaLqTNFL7w/TDx6XwqrmDI/AAAAAAAABMo/B1SkSHxhKu4/S220/icon4.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5859951453664122203.post-3224512462063876568</id><published>2011-10-04T09:59:00.000+09:00</published><updated>2011-10-04T11:25:19.481+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Android'/><title type='text'>Android　SimpleCursorAdapter で ViewBinder を使う</title><content type='html'>SimpleAdapter で ViewBinder を使う方法は Android Layout CookBook に書いたので、SimpleCursorAdapter で ViewBinder を使う方法を紹介します。&lt;br /&gt;&lt;br /&gt;&lt;a href="http://developer.android.com/reference/android/widget/SimpleCursorAdapter.ViewBinder.html"&gt;SimpleCursorAdapter.ViewBinder&lt;/a&gt; の &lt;a href="http://developer.android.com/reference/android/widget/SimpleCursorAdapter.ViewBinder.html#setViewValue(android.view.View, android.database.Cursor, int)"&gt;setViewValue()&lt;/a&gt; メソッドでは第２引数としてその行の Cursor と、第３引数として列の columnIndex が渡されるので、これを使ってそのカラムに表示したいデータを取得して、色を変えたり文字の大きさを変えたり表示するデータを別のテーブルからとってきたりして、対象の View にセットします。&lt;br /&gt;&lt;br /&gt;&lt;code name="code" class="java"&gt;public class SimpleCursorAdapterSampleActivity extends ListActivity {    private static final String[] PHONE_PROJECTION = new String[] {        Phone._ID,        Phone.TYPE,        Phone.NUMBER    };    private static final int COLUMN_TYPE = 1;    private static final int[] COLOR_LIST = new int[] {        Color.parseColor("#002A42"),        Color.parseColor("#3DC3EA"),        Color.parseColor("#99417B"),        Color.parseColor("#F2AE30"),        Color.parseColor("#F2D338"),    };        @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        Cursor c = getContentResolver().query(                Phone.CONTENT_URI,                PHONE_PROJECTION,   // projection                null,   // selection                null,   // selectionArgs                null    // orderBy                );        startManagingCursor(c);        SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,                android.R.layout.simple_list_item_2,                 c,                new String[] { Phone.TYPE, Phone.NUMBER },                new int[] { android.R.id.text1, android.R.id.text2 });                adapter.setViewBinder(new SimpleCursorAdapter.ViewBinder() {                        public boolean setViewValue(View view, Cursor cursor, int columnIndex) {                if (columnIndex == COLUMN_TYPE) {                    int type = cursor.getInt(COLUMN_TYPE);                    String text = (String) Phone.getTypeLabel(getResources(), type, null);                                        ((TextView) view).setText(text);                    ((TextView) view).setTextColor(COLOR_LIST[type % 5]);                    return true;                }                return false;            }        });        setListAdapter(adapter);    }}&lt;/code&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-E6CjVrsc1VU/TopZ5j9YMyI/AAAAAAAADgM/mmz6XfdlFFo/s1600/SimpleCursorAdapterSample.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="400" width="240" src="http://3.bp.blogspot.com/-E6CjVrsc1VU/TopZ5j9YMyI/AAAAAAAADgM/mmz6XfdlFFo/s400/SimpleCursorAdapterSample.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5859951453664122203-3224512462063876568?l=y-anz-m.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://y-anz-m.blogspot.com/feeds/3224512462063876568/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://y-anz-m.blogspot.com/2011/10/simplecursoradapter-viewbinder.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5859951453664122203/posts/default/3224512462063876568'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5859951453664122203/posts/default/3224512462063876568'/><link rel='alternate' type='text/html' href='http://y-anz-m.blogspot.com/2011/10/simplecursoradapter-viewbinder.html' title='Android　SimpleCursorAdapter で ViewBinder を使う'/><author><name>yanzm</name><uri>http://www.blogger.com/profile/04059587494895790858</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_HRaLqTNFL7w/TDx6XwqrmDI/AAAAAAAABMo/B1SkSHxhKu4/S220/icon4.JPG'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-E6CjVrsc1VU/TopZ5j9YMyI/AAAAAAAADgM/mmz6XfdlFFo/s72-c/SimpleCursorAdapterSample.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5859951453664122203.post-4317417292034539268</id><published>2011-09-30T22:13:00.001+09:00</published><updated>2011-09-30T22:14:29.445+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='イベント'/><category scheme='http://www.blogger.com/atom/ns#' term='Android'/><category scheme='http://www.blogger.com/atom/ns#' term='Android App'/><title type='text'>Sharp ハッカソンで作ったアプリを公開しました。</title><content type='html'>子供向けのホームアプリ（正確には、自分が普段使っているスマホでときどき子供にゲームとかさせる親向け）です。&lt;br /&gt;&lt;br /&gt;&lt;a href="https://market.android.com/details?id=com.pakaroid.android.app"&gt;Pakaroid - Android Market&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;「子供にスマートフォンのアプリで遊ばせたいけど、関係ないアプリを勝手に起動させたくない。」&lt;br /&gt;「子供用のアプリに簡単にアクセスしたい。」&lt;br /&gt;「子供でも使えるようなホームアプリに、アプリをまとめておきたい。」&lt;br /&gt;&lt;br /&gt;そのためにどういうアプリがいいかな、ということで、&lt;br /&gt;&lt;br /&gt;&lt;b&gt;・ホームから子供が自分でアプリを起動できる&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;　　- Pakaroid（パカロイド）というゆるキャラをタップして&lt;br /&gt;　　　アプリ一覧を表示（しかもキャラがでかいからタップしやすい）&lt;br /&gt;　　- 全体的にポップな感じ&lt;br /&gt;　　- アニメーションをつけて楽しく&lt;br /&gt;&lt;br /&gt;&lt;b&gt;・関係ない操作をさせない&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;　　- メニューキーのロングタップや検索キーのロングタップを無効化&lt;br /&gt;　　- 設定アプリなどへの入口であるダイアログの表示方法を&lt;br /&gt;　　　　メニューキーをタップ&lt;br /&gt;　　　　メニューキーをロングタップ&lt;br /&gt;　　　　メニューキーをタップしながらボリュームアップボタンを押す&lt;br /&gt;　　から選択できる&lt;br /&gt;　　（メニューキーをタップしながらボリュームアップボタンを押す、なら&lt;br /&gt;　　　知らなければ子供が誤って押しちゃうことはまずないだろうと）&lt;br /&gt;&lt;br /&gt;　　- もし誤ってダイアログを表示しちゃっても10秒で自動的に&lt;br /&gt;　　　ダイアログを閉じる&lt;br /&gt;&lt;br /&gt;&lt;b&gt;・関係ないアプリを起動させない&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;　　- 選択したアプリだけを一覧に表示&lt;br /&gt;&lt;br /&gt;などの機能をいれました。&lt;br /&gt;&lt;br /&gt;他にも&lt;br /&gt;&lt;br /&gt;　- バッテリーの残量に応じて草の量が変わる&lt;br /&gt;　- 充電ケーブルをつなぐと雨が降るなど&lt;br /&gt;&lt;br /&gt;など、ちょっとしたところに凝ってます。&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-lQ-7bATzBlA/ToW797Jrp3I/AAAAAAAADes/fO7XS5cC9lU/s1600/PakaroidCapture1.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="400" width="240" src="http://2.bp.blogspot.com/-lQ-7bATzBlA/ToW797Jrp3I/AAAAAAAADes/fO7XS5cC9lU/s400/PakaroidCapture1.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-YkLAVm_75n8/ToW7-ILFDgI/AAAAAAAADe0/t-g5cmg6Mfw/s1600/PakaroidCapture2.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="400" width="240" src="http://1.bp.blogspot.com/-YkLAVm_75n8/ToW7-ILFDgI/AAAAAAAADe0/t-g5cmg6Mfw/s400/PakaroidCapture2.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-B2mBb4L3-gM/ToW7-R3am2I/AAAAAAAADe8/IM6d0RVrb9o/s1600/PakaroidCapture4.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="400" width="240" src="http://3.bp.blogspot.com/-B2mBb4L3-gM/ToW7-R3am2I/AAAAAAAADe8/IM6d0RVrb9o/s400/PakaroidCapture4.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;ぜひ使ってみてください！&lt;br /&gt;&lt;br /&gt;Team Pakaroid のメンバーです。&lt;br /&gt;- Yuki Anzai (@yanzm)&lt;br /&gt;- Rin Yano (@yanorin)&lt;br /&gt;- Kazuya Matsubara (@Toro_kun)&lt;br /&gt;- Masahide Fukagawa (@PUKa)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;---&lt;br /&gt;&lt;br /&gt;ここからは広島旅行の思い出ということで。&lt;br /&gt;7月23日&lt;br /&gt;&lt;br /&gt;飛行機にのって&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-5yAqkp96bo4/ToW8rl3gSbI/AAAAAAAADfE/VBK2dib54iM/s1600/IMG_20110723_091937.jpg" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="300" width="400" src="http://2.bp.blogspot.com/-5yAqkp96bo4/ToW8rl3gSbI/AAAAAAAADfE/VBK2dib54iM/s400/IMG_20110723_091937.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;空港からバスで白市駅まで行き、&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-vylu7UMIB50/ToW8rsuXDHI/AAAAAAAADfM/6__h-VdjZ5o/s1600/IMG_20110723_095025.jpg" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="300" width="400" src="http://1.bp.blogspot.com/-vylu7UMIB50/ToW8rsuXDHI/AAAAAAAADfM/6__h-VdjZ5o/s400/IMG_20110723_095025.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;白市駅から電車で八本松駅まで行き、&lt;br /&gt;八本松駅からタクシーで工場まで行きました。&lt;br /&gt;タクシーの運転手さんの話だと、昔、枝が八本あるように見える松があったから八本松駅なんだそうです。（でもちょっと記憶があいまい、、、）&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-Vs8waeYH29U/ToW8r7vpClI/AAAAAAAADfU/TBWl97Hsfl4/s1600/IMG_20110723_102847.jpg" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="300" width="400" src="http://4.bp.blogspot.com/-Vs8waeYH29U/ToW8r7vpClI/AAAAAAAADfU/TBWl97Hsfl4/s400/IMG_20110723_102847.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;1階に携帯電話の展示コーナーがあって、IS03 の三枚おろしみたいなのとかありました。&lt;br /&gt;面白かった。&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-uNOqRQbnUm4/ToW8r-tQVGI/AAAAAAAADfc/T-hxIwsSwjQ/s1600/IMG_20110723_103034.jpg" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="300" width="400" src="http://3.bp.blogspot.com/-uNOqRQbnUm4/ToW8r-tQVGI/AAAAAAAADfc/T-hxIwsSwjQ/s400/IMG_20110723_103034.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;ハッカソンシールもらいました。&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-HYVCei8WX3g/ToW8sB4OgzI/AAAAAAAADfk/cFnTB3uVCkM/s1600/IMG_20110723_114326.jpg" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="300" width="400" src="http://2.bp.blogspot.com/-HYVCei8WX3g/ToW8sB4OgzI/AAAAAAAADfk/cFnTB3uVCkM/s400/IMG_20110723_114326.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;お弁当が豪華でした。おいしかったです。&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-qXgVQmpszLY/ToW-UwH6e-I/AAAAAAAADfs/U9rn3umwPjg/s1600/IMG_20110723_115526.jpg" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="300" width="400" src="http://1.bp.blogspot.com/-qXgVQmpszLY/ToW-UwH6e-I/AAAAAAAADfs/U9rn3umwPjg/s400/IMG_20110723_115526.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;ちーむぱかろいどのアイディアまとめとかの残骸&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-vY4eNA0KWyk/ToW-VE9bmJI/AAAAAAAADf0/kZ3m-Z217BI/s1600/IMG_20110723_170640.jpg" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="300" width="400" src="http://3.bp.blogspot.com/-vY4eNA0KWyk/ToW-VE9bmJI/AAAAAAAADf0/kZ3m-Z217BI/s400/IMG_20110723_170640.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;帰りの空港で時間があったので矢野さんと女二人でビール飲んできました。&lt;br /&gt;ごちそうさまでした！&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-nUmbGfGeJXg/ToW-VNCB8dI/AAAAAAAADf8/0UJMr6FovT0/s1600/IMG_20110724_165827.jpg" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="300" width="400" src="http://1.bp.blogspot.com/-nUmbGfGeJXg/ToW-VNCB8dI/AAAAAAAADf8/0UJMr6FovT0/s400/IMG_20110724_165827.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5859951453664122203-4317417292034539268?l=y-anz-m.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://y-anz-m.blogspot.com/feeds/4317417292034539268/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://y-anz-m.blogspot.com/2011/09/sharp.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5859951453664122203/posts/default/4317417292034539268'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5859951453664122203/posts/default/4317417292034539268'/><link rel='alternate' type='text/html' href='http://y-anz-m.blogspot.com/2011/09/sharp.html' title='Sharp ハッカソンで作ったアプリを公開しました。'/><author><name>yanzm</name><uri>http://www.blogger.com/profile/04059587494895790858</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_HRaLqTNFL7w/TDx6XwqrmDI/AAAAAAAABMo/B1SkSHxhKu4/S220/icon4.JPG'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-lQ-7bATzBlA/ToW797Jrp3I/AAAAAAAADes/fO7XS5cC9lU/s72-c/PakaroidCapture1.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5859951453664122203.post-5975991340029371842</id><published>2011-09-21T17:04:00.001+09:00</published><updated>2011-09-21T17:22:40.202+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Android'/><title type='text'>Android　SharedPreference の実体ファイルの場所</title><content type='html'>&lt;a href="http://tools.oesf.biz/android-2.3.3_r1.0/xref/frameworks/base/core/java/android/app/ContextImpl.java#333"&gt;ContextImpl.java&lt;/a&gt; をみると場所が書いてる&lt;code name="code" class="java"&gt;    333     public File getSharedPrefsFile(String name) {    334         return makeFilename(getPreferencesDir(), name + ".xml");    335     }&lt;/code&gt;&lt;code name="code" class="java"&gt;    391     private File getPreferencesDir() {    392         synchronized (mSync) {    393             if (mPreferencesDir == null) {    394                 mPreferencesDir = new File(getDataDirFile(), "shared_prefs");    395             }    396             return mPreferencesDir;    397         }    398     }&lt;/code&gt;ということで、&lt;br /&gt;&lt;br /&gt;　/data/data/[package_name]/shared_prefs/[name].xml&lt;br /&gt;&lt;br /&gt;にあります。&lt;br /&gt;エミュレータなら File Explorer や adb shell から見れます。&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5859951453664122203-5975991340029371842?l=y-anz-m.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://y-anz-m.blogspot.com/feeds/5975991340029371842/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://y-anz-m.blogspot.com/2011/09/androidsharedpreference.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5859951453664122203/posts/default/5975991340029371842'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5859951453664122203/posts/default/5975991340029371842'/><link rel='alternate' type='text/html' href='http://y-anz-m.blogspot.com/2011/09/androidsharedpreference.html' title='Android　SharedPreference の実体ファイルの場所'/><author><name>yanzm</name><uri>http://www.blogger.com/profile/04059587494895790858</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_HRaLqTNFL7w/TDx6XwqrmDI/AAAAAAAABMo/B1SkSHxhKu4/S220/icon4.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5859951453664122203.post-1634158520994402111</id><published>2011-09-20T19:26:00.000+09:00</published><updated>2011-10-04T09:59:26.020+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Android'/><title type='text'>Android　Scroll の終端のピカッを消す</title><content type='html'>Android 2.3 (Gingergread) からスクロールが終端までいくと、（デフォルトでは）オレンジ色にピカッと光ります。&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-j8pijZECZs4/Tnhh-n3qzGI/AAAAAAAADeY/lJLhmN_j_aI/s1600/edge_grow.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="400" width="240" src="http://3.bp.blogspot.com/-j8pijZECZs4/Tnhh-n3qzGI/AAAAAAAADeY/lJLhmN_j_aI/s400/edge_grow.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;これはこれでいいんですけど、デザインに合わないときもあります。&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-CHISggRyCDQ/Tnhh-j-7P2I/AAAAAAAADeg/cazhYXr50Bw/s1600/edge_grow2.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="400" width="240" src="http://4.bp.blogspot.com/-CHISggRyCDQ/Tnhh-j-7P2I/AAAAAAAADeg/cazhYXr50Bw/s400/edge_grow2.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;このピカッがどこで設定されているか調べると&lt;br /&gt;&lt;a href="http://tools.oesf.biz/android-2.3_r1.0/xref/frameworks/base/core/java/android/widget/AbsListView.java#650"&gt;AbsListView の setOverScrollMode()&lt;/a&gt; でした。&lt;br /&gt;ここをみると、OverScrollMode が OVER_SCROLL_NEVER であれば、ピカッがなしになることがわかります。&lt;code name="code" class="java"&gt;    650     public void setOverScrollMode(int mode) {    651         if (mode != OVER_SCROLL_NEVER) {    652             if (mEdgeGlowTop == null) {    653                 final Resources res = getContext().getResources();    654                 final Drawable edge = res.getDrawable(R.drawable.overscroll_edge);    655                 final Drawable glow = res.getDrawable(R.drawable.overscroll_glow);    656                 mEdgeGlowTop = new EdgeGlow(edge, glow);    657                 mEdgeGlowBottom = new EdgeGlow(edge, glow);    658             }    659         } else {    660             mEdgeGlowTop = null;    661             mEdgeGlowBottom = null;    662         }    663         super.setOverScrollMode(mode);    664     }&lt;/code&gt;ということで、ピカッとさせたくない場合は&lt;code name="code" class="java"&gt;mListView.setOverScrollMode(View.OVER_SCROLL_NEVER);&lt;/code&gt;とすれば OK。&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5859951453664122203-1634158520994402111?l=y-anz-m.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://y-anz-m.blogspot.com/feeds/1634158520994402111/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://y-anz-m.blogspot.com/2011/09/androidscroll.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5859951453664122203/posts/default/1634158520994402111'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5859951453664122203/posts/default/1634158520994402111'/><link rel='alternate' type='text/html' href='http://y-anz-m.blogspot.com/2011/09/androidscroll.html' title='Android　Scroll の終端のピカッを消す'/><author><name>yanzm</name><uri>http://www.blogger.com/profile/04059587494895790858</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_HRaLqTNFL7w/TDx6XwqrmDI/AAAAAAAABMo/B1SkSHxhKu4/S220/icon4.JPG'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-j8pijZECZs4/Tnhh-n3qzGI/AAAAAAAADeY/lJLhmN_j_aI/s72-c/edge_grow.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5859951453664122203.post-7669694490924814831</id><published>2011-09-15T22:33:00.000+09:00</published><updated>2011-10-04T09:59:34.938+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Android'/><title type='text'>Android　コードからステータスバーを開く</title><content type='html'>Launcher アプリにはステータスバーを開くメニューがある。&lt;br /&gt;&lt;br /&gt;該当部分がこれ&lt;code name="code" class="java"&gt;public static final String STATUS_BAR_SERVICE = "statusbar";...private void showNotifications() {    final StatusBarManager statusBar = (StatusBarManager) getSystemService(STATUS_BAR_SERVICE);    if (statusBar != null) {        statusBar.expand();   }}&lt;/code&gt;StatusBarManager を使う。が、&lt;a href="http://tools.oesf.biz/android-2.3_r1.0/xref/frameworks/base/core/java/android/app/StatusBarManager.java#StatusBarManager"&gt;StatusBarManager&lt;/a&gt; は @hide である。&lt;br /&gt;&lt;br /&gt;よって、これを使いたい場合の方法は、@hide を含む android.jar を使ってアプリを作る or リフレクションする。&lt;br /&gt;&lt;br /&gt;例えばリフレクションするならこんな感じ&lt;code name="code" class="java"&gt;private void showNotifications() {            try {         Object service = getSystemService("statusbar");         Class&lt;?&gt; clazz = Class.forName("android.app.StatusBarManager");         Method method = clazz.getMethod("expand");         method.invoke(service);      } catch (Exception e) {          e.printStackTrace();     } }&lt;/code&gt;&lt;br /&gt;ちなみに、AndroidManifest.xml で uses-permission に &lt;a href="http://developer.android.com/reference/android/Manifest.permission.html#EXPAND_STATUS_BAR"&gt;android.permission.EXPAND_STATUS_BAR&lt;/a&gt; が必要。&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5859951453664122203-7669694490924814831?l=y-anz-m.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://y-anz-m.blogspot.com/feeds/7669694490924814831/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://y-anz-m.blogspot.com/2011/09/android_15.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5859951453664122203/posts/default/7669694490924814831'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5859951453664122203/posts/default/7669694490924814831'/><link rel='alternate' type='text/html' href='http://y-anz-m.blogspot.com/2011/09/android_15.html' title='Android　コードからステータスバーを開く'/><author><name>yanzm</name><uri>http://www.blogger.com/profile/04059587494895790858</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_HRaLqTNFL7w/TDx6XwqrmDI/AAAAAAAABMo/B1SkSHxhKu4/S220/icon4.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5859951453664122203.post-6578839081452409056</id><published>2011-09-15T16:38:00.000+09:00</published><updated>2011-09-15T16:38:21.940+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='GWT'/><title type='text'>GWT で SimpleDateFormat がつかえない</title><content type='html'>java.text.* をサポートしてないらしい。&lt;br /&gt;&lt;br /&gt;同じ機能の &lt;a href="http://google-web-toolkit.googlecode.com/svn/javadoc/2.0/com/google/gwt/i18n/client/DateTimeFormat.html"&gt;DateTimeFormat&lt;/a&gt; が用意されているので、こっちを使うべし。めもめも。&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5859951453664122203-6578839081452409056?l=y-anz-m.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://y-anz-m.blogspot.com/feeds/6578839081452409056/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://y-anz-m.blogspot.com/2011/09/gwt-simpledateformat.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5859951453664122203/posts/default/6578839081452409056'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5859951453664122203/posts/default/6578839081452409056'/><link rel='alternate' type='text/html' href='http://y-anz-m.blogspot.com/2011/09/gwt-simpledateformat.html' title='GWT で SimpleDateFormat がつかえない'/><author><name>yanzm</name><uri>http://www.blogger.com/profile/04059587494895790858</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_HRaLqTNFL7w/TDx6XwqrmDI/AAAAAAAABMo/B1SkSHxhKu4/S220/icon4.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5859951453664122203.post-6050154837534990239</id><published>2011-09-11T16:04:00.000+09:00</published><updated>2011-10-04T09:59:42.805+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Android'/><title type='text'>Android　Menu の背景を変える その2</title><content type='html'>昔は Menu の背景を簡単に変えることができなかったんです。それで &lt;a href="http://y-anz-m.blogspot.com/2010/08/androidmenu.html"&gt;Y.A.M の 雑記帳  Android　Menu の背景を変える&lt;/a&gt; というエントリを書いたりしていたのですが、今は style から指定できるようになっているので紹介します。&lt;code name="code" class="xml"&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;&amp;lt;resources&amp;gt;  &amp;lt;style name="CustomTheme.Light" parent="@android:style/Theme.Light"&amp;gt;    ...&amp;lt;!-- パネル(Menu) の背景 --&amp;gt;    &amp;lt;item name="android:panelBackground"&amp;gt;@color/menu_bg&amp;lt;/item&amp;gt;    &amp;lt;item name="android:panelFullBackground"&amp;gt;@color/menu_bg&amp;lt;/item&amp;gt;  &amp;lt;/style&amp;gt;...&amp;lt;/resources&amp;gt;&lt;/code&gt;のようにして、このテーマを AndroidManifest.xml の application や activity タグの android:theme 属性で指定すれば OK です。&lt;br /&gt;&lt;br /&gt;ちなみに、できる限り style を使ってカスタマイズする勉強会を去年蒲郡でやりました。その資料にいろいろ書きましたので、ここにも貼っておきます。（Menu の背景を変える部分の書いてます）&lt;br /&gt;&lt;br /&gt;&lt;iframe src="http://docs.google.com/viewer?url=https%3A%2F%2Fsites.google.com%2Fsite%2Fyukianzm%2FHome%2Fyanzm_ui_event%2Fyanzm_ui_fes_with_image.pdf&amp;embedded=true" width="440" height="600" style="border: none;"&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;br /&gt;↑ &lt;a href="https://docs.google.com/viewer"&gt;Google Docs Viewer&lt;/a&gt; 使ってみました。&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5859951453664122203-6050154837534990239?l=y-anz-m.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://y-anz-m.blogspot.com/feeds/6050154837534990239/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://y-anz-m.blogspot.com/2011/09/androidmenu-2.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5859951453664122203/posts/default/6050154837534990239'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5859951453664122203/posts/default/6050154837534990239'/><link rel='alternate' type='text/html' href='http://y-anz-m.blogspot.com/2011/09/androidmenu-2.html' title='Android　Menu の背景を変える その2'/><author><name>yanzm</name><uri>http://www.blogger.com/profile/04059587494895790858</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_HRaLqTNFL7w/TDx6XwqrmDI/AAAAAAAABMo/B1SkSHxhKu4/S220/icon4.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5859951453664122203.post-4855002171022534551</id><published>2011-09-11T14:14:00.000+09:00</published><updated>2011-09-11T14:14:23.504+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Android'/><title type='text'>Android アプリのサイズ関係めも</title><content type='html'>1.  apk ファイルサイズの上限&lt;br /&gt;　・50MB app package &lt;font color=red&gt;*&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;2.  Android Market に archive できるサイズ&lt;br /&gt;　・ Support up to 4 GB &lt;font color=red&gt;*&lt;/font&gt;&lt;br /&gt;　・ Up to two 2GB archives &lt;font color=red&gt;*&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;3.  asset フォルダ&lt;br /&gt;　・ 1ファイルの上限は 1M&lt;br /&gt;　・ 例えば、asset 内のDBファイルを初回起動時にデバイスの&lt;br /&gt;　　 sqlite にコピーする場合など、ファイルが 1M を超えるなら&lt;br /&gt;　　分割する必要がある。 &lt;br /&gt;&lt;br /&gt;4.  Internal Storage の容量 (/data/data/(app_name)/フォルダ以下)&lt;br /&gt;　・ 端末の内部メモリの空き容量 - α ？&lt;br /&gt;&lt;br /&gt;　&lt;font color=red&gt;*&lt;/font&gt; &lt;a href="http://www.google.com/events/io/2011/sessions/android-market-for-developers.html"&gt;Google I/O 2011 の Android Merket for Developers&lt;/a&gt; セッションで紹介されている Android Market での制限&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5859951453664122203-4855002171022534551?l=y-anz-m.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://y-anz-m.blogspot.com/feeds/4855002171022534551/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://y-anz-m.blogspot.com/2011/09/android.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5859951453664122203/posts/default/4855002171022534551'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5859951453664122203/posts/default/4855002171022534551'/><link rel='alternate' type='text/html' href='http://y-anz-m.blogspot.com/2011/09/android.html' title='Android アプリのサイズ関係めも'/><author><name>yanzm</name><uri>http://www.blogger.com/profile/04059587494895790858</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_HRaLqTNFL7w/TDx6XwqrmDI/AAAAAAAABMo/B1SkSHxhKu4/S220/icon4.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5859951453664122203.post-6692396699230297612</id><published>2011-09-11T11:39:00.000+09:00</published><updated>2011-09-11T12:57:46.094+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Android'/><title type='text'>Android　NumberPicker を拡張して ItemPicker を作ってみた。</title><content type='html'>Android には日時を設定するための DatePicker, 時刻を設定するための TimePicker が用意されています。これらの Picker の元になっているのが NumberPicker です。ちなみに NumberPicker は非公開クラスになっています。&lt;br /&gt;&lt;br /&gt;この NumberPicker のレイアウトでは、 + ボタンが上にあるために、+ ボタンを押している間、設定している値が指で見えなくなってしまいます。そこで、この NumberPicker を元にして + ボタンと - ボタンが設定値の左右にある Picker を作ってみました。&lt;br /&gt;&lt;br /&gt;&lt;a href="https://github.com/yanzm/yanzm-s-Custom-View-Project/tree/master/ItemPicker"&gt;ItemPicker at  yanzm/yanzm-s-Custom-View-Project - GitHub&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-gM1PavaI2UY/TmwdB6VokWI/AAAAAAAADeQ/GIU4ELsfpiM/s1600/ItemPickerSample.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="400" width="240" src="http://2.bp.blogspot.com/-gM1PavaI2UY/TmwdB6VokWI/AAAAAAAADeQ/GIU4ELsfpiM/s400/ItemPickerSample.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;ついでに、ボタンと入力部分の画像リソースと、選択範囲および選択アイテムを attribute として指定できるようにしました。&lt;br /&gt;&lt;br /&gt;こんな感じで、XML から値の設定などが全部できます。&lt;code name="code" class="xml"&gt;&amp;lt;LinearLayout     xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:custom="http://schemas.android.com/apk/res/yanzm.products.customview.itempicker"        android:orientation="vertical"    android:layout_width="fill_parent"    android:layout_height="fill_parent"    &amp;gt;    &amp;lt;DatePicker         android:id="@+id/datePicker1"         android:layout_width="wrap_content"         android:layout_height="wrap_content"/&amp;gt;        &amp;lt;TimePicker         android:id="@+id/timePicker1"         android:layout_width="wrap_content"         android:layout_height="wrap_content"/&amp;gt;    &amp;lt;yanzm.products.customview.itempicker.ItemPicker        android:layout_width="180dip"         android:layout_height="wrap_content"        android:focusable="true"        android:focusableInTouchMode="true"        android:text="+"        custom:start="0"        custom:end="10"        custom:current="2"                 /&amp;gt;    &amp;lt;yanzm.products.customview.itempicker.ItemPicker        android:layout_width="240dip"         android:layout_height="wrap_content"        android:focusable="true"        android:focusableInTouchMode="true"        android:text="+"        custom:start="1"        custom:end="9"        custom:current="2"           custom:speed="100"        custom:displayedValue="@array/color_names"              /&amp;gt;            &amp;lt;yanzm.products.customview.itempicker.ItemPicker        android:layout_width="240dip"         android:layout_height="wrap_content"        android:focusable="true"        android:focusableInTouchMode="true"        android:text="+"        custom:start="1"        custom:end="9"        custom:current="4"        custom:incrementBackground="@drawable/picker_bg"        custom:decrementBackground="@drawable/picker_bg"        custom:editTextBackground="@drawable/input_bg"        custom:displayedValue="@array/color_names"              /&amp;gt;                         &amp;lt;/LinearLayout&amp;gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;attribute として用意したのは&lt;ul&gt;&lt;li&gt; incrementSrc : 増加ボタン (ImageButton) の 画像リソース&lt;li&gt; decrementSrc : 減少ボタン (ImageButton) の画像リソース&lt;li&gt; incrementBackground : 増加ボタン (ImageButton) の 背景画像リソース&lt;li&gt; decrementBackground : 減少ボタン (ImageButton) の背景画像リソース&lt;li&gt; editTextBackground : 設定値 (EditText) の背景画像リソース&lt;li&gt; start : 最少値 (int)&lt;li&gt; end : 最大値 (int)&lt;li&gt; current : 現在の値 (int)&lt;li&gt; speed : ボタン長押し時の自動増加／減少の切り替え速度&lt;li&gt; displayedValue : 数字ではなく文字を設定値にする場合の文字列配列。最小値が index 0 にあたる&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5859951453664122203-6692396699230297612?l=y-anz-m.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://y-anz-m.blogspot.com/feeds/6692396699230297612/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://y-anz-m.blogspot.com/2011/09/numberpicker-itempicker.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5859951453664122203/posts/default/6692396699230297612'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5859951453664122203/posts/default/6692396699230297612'/><link rel='alternate' type='text/html' href='http://y-anz-m.blogspot.com/2011/09/numberpicker-itempicker.html' title='Android　NumberPicker を拡張して ItemPicker を作ってみた。'/><author><name>yanzm</name><uri>http://www.blogger.com/profile/04059587494895790858</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_HRaLqTNFL7w/TDx6XwqrmDI/AAAAAAAABMo/B1SkSHxhKu4/S220/icon4.JPG'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-gM1PavaI2UY/TmwdB6VokWI/AAAAAAAADeQ/GIU4ELsfpiM/s72-c/ItemPickerSample.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5859951453664122203.post-8404169958891697466</id><published>2011-08-19T10:31:00.009+09:00</published><updated>2011-08-19T11:08:36.792+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Android'/><title type='text'>Android 3.2 でサポートされた Zoom to fill screen 機能</title><content type='html'>Android 3.2 から、Android 3.0 向けではなくかつ xlarge をサポートしていないアプリを起動すると、System bar に画面のストレッチみたいなアイコンがでます。このアイコンをタップすると、Stretch to fill screen と Zoom to fill screen のいずれをか選ぶことができます。&lt;br /&gt;&lt;br /&gt;こんなやつ&lt;br /&gt;&lt;img src="http://4.bp.blogspot.com/-HY4vGH-SfJI/ThsvGKmWKOI/AAAAAAAAAiE/Gxb173A0kzE/s400/compat-toggle.png"/&gt;&lt;br /&gt;&lt;br /&gt;詳しくは &lt;br /&gt;&lt;a href="http://android-developers.blogspot.com/2011/07/new-mode-for-apps-on-large-screens.html"&gt;Android Developers Blog: New Mode for Apps on Large Screens -&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;とか&lt;br /&gt;&lt;br /&gt;&lt;a href="http://developer.android.com/guide/practices/screens_support.html#DeclaringTabletLayouts"&gt;Declaring Tablet Layouts for Android 3.2 | Supporting Multiple Screens | Android Developers - &lt;/a&gt;&lt;br /&gt;&lt;br /&gt;にありますが、まとめると&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;■ Stretch to fill screen&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;通常のモード。Android の多解像度対応のルールに従って画面のレイアウトが決まる（リサイズされる）。&lt;br /&gt;&lt;br /&gt;画像やレイアウトなどは、その解像度＆画面サイズの識別子がついたものが使われる (= drawable-hdpi, とか layout-xlarge が使われる）&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;■ Zoom to fill screen&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;アプリを normal/mdpi スクリーン（だいたい 320dp x 480dp）に描画した場合のものを画面に拡大して表示する。&lt;br /&gt;&lt;br /&gt;電話に描画したものを 200 % ズームしたと想像すればよい。&lt;br /&gt;&lt;br /&gt;画像やレイアウトなどは、normal /mdpi の場合のものが使われる (= drawable-hdpi があったとしても、drawable-mdpi や layout-normal が使われる）ので、画素化（pixelated）された感じになる。ピクセルが目立つというかがたがたしてる感じかな。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;■ Zoom to fill screen が出ない条件&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;　・ AndroidManifest.xml で &lt;font color=green&gt;android:minSdkVersion&lt;/font&gt; に&lt;br /&gt;　　 11 以上を指定している&lt;br /&gt;　・ AndroidManifest.xml で &lt;font color=green&gt;android:targetSdkVersion&lt;/font&gt; に&lt;br /&gt;　　 11 以上を指定している&lt;br /&gt;　・ AndroidManifest.xml で以下を指定している&lt;br /&gt;&lt;code name="code" class="xml"&gt;&lt;br /&gt;&amp;lt;manifest ... &amp;gt;&lt;br /&gt;    &amp;lt;supports-screens android:xlargeScreens="true" /&amp;gt;&lt;br /&gt;    ...&lt;br /&gt;&amp;lt;/manifest&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;　のどれか1つでも満たしている場合、Zoom to fill screen は出ない&lt;br /&gt;　（＝ System bar に画像のストレッチみたいなアイコンがでない）&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;■ Zoom to fill screen が出る条件&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;　Zoom to fill screen が出ない条件を満たしていない場合&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/-_6VIHkFH3bU/ThsveqS49hI/AAAAAAAAAiM/dg7ZNWQqqqE/s1600/compat-compare.png"&gt;&lt;img src="http://4.bp.blogspot.com/-_6VIHkFH3bU/ThsveqS49hI/AAAAAAAAAiM/dg7ZNWQqqqE/s400/compat-compare.png" /&gt;&lt;/a&gt;&lt;br /&gt;左が Stretch to fill screen、右が Zoom to fill screen&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;# Honeycomb で画面がすっかすかーになってしまった&lt;br /&gt;# アプリにはいいモードですね。&lt;br /&gt;# normal/mdpi の拡大なのでどのくらいピクセル化が&lt;br /&gt;# 目立つのかちょっと気になるなぁ。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5859951453664122203-8404169958891697466?l=y-anz-m.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://y-anz-m.blogspot.com/feeds/8404169958891697466/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://y-anz-m.blogspot.com/2011/08/android-32-zoom-to-fill-screen.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5859951453664122203/posts/default/8404169958891697466'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5859951453664122203/posts/default/8404169958891697466'/><link rel='alternate' type='text/html' href='http://y-anz-m.blogspot.com/2011/08/android-32-zoom-to-fill-screen.html' title='Android 3.2 でサポートされた Zoom to fill screen 機能'/><author><name>yanzm</name><uri>http://www.blogger.com/profile/04059587494895790858</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_HRaLqTNFL7w/TDx6XwqrmDI/AAAAAAAABMo/B1SkSHxhKu4/S220/icon4.JPG'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-HY4vGH-SfJI/ThsvGKmWKOI/AAAAAAAAAiE/Gxb173A0kzE/s72-c/compat-toggle.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5859951453664122203.post-5751663902796699952</id><published>2011-08-18T15:43:00.006+09:00</published><updated>2011-08-18T16:48:53.691+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Android'/><title type='text'>Android　FLAG_DISMISS_KEYGUARD と FLAG_SHOW_WHEN_LOCKED を使う</title><content type='html'>&lt;a href="http://developer.android.com/reference/android/app/KeyguardManager.html"&gt;KeyguardManager&lt;/a&gt; の &lt;a href="http://developer.android.com/reference/android/app/KeyguardManager.html#exitKeyguardSecurely(android.app.KeyguardManager.OnKeyguardExitResult)"&gt;exitKeyguardSecurely()&lt;/a&gt; メソッド及び &lt;a href="http://developer.android.com/reference/android/app/KeyguardManager.html#newKeyguardLock(java.lang.String)"&gt;newKeyguardLock()&lt;/a&gt; メソッドと、サブクラスの &lt;a href="KeyguardManager.KeyguardLock"&gt;KeyguardManager.KeyguardLock&lt;/a&gt; は &lt;span style="font-weight:bold;"&gt;deprecated&lt;/span&gt; になっています。&lt;br /&gt;&lt;br /&gt;これらのメソッドの代わりに &lt;a href="http://developer.android.com/reference/android/view/WindowManager.LayoutParams.html"&gt;WindowManager.LayoutParams&lt;/a&gt; クラスの &lt;a href="http://developer.android.com/reference/android/view/WindowManager.LayoutParams.html#FLAG_DISMISS_KEYGUARD"&gt;FLAG_DISMISS_KEYGUARD&lt;/a&gt; と &lt;a href="http://developer.android.com/reference/android/view/WindowManager.LayoutParams.html#FLAG_SHOW_WHEN_LOCKED"&gt;FLAG_SHOW_WHEN_LOCKED&lt;/a&gt; を使うことが推奨されています。&lt;br /&gt;&lt;br /&gt;■ FLAG_DISMISS_KEYGUARD&lt;br /&gt;&lt;br /&gt;　このフラグが設定されると、secure lock keyguard でない場合、ウィンドウによって keyguard が表示されなくなる。security が必要でない keyguard では、ユーザーが他のウィンドウに移動したときに再表示されない（反対に FLAG_SHOW_WHEN_LOCKED では、secure、non-secure 両方の key guard を一時的に隠して、ユーザーがこれらを隠さない設定の他の UI に移動したときに再表示する。&lt;br /&gt;&lt;br /&gt;　FLAG_SHOW_WHEN_LOCKED が同時に設定されていないと、keyguard が現在アクティブでユーザーより secure な場合（＝ unlock pattern を要求している場合）、ウィンドウを表示する前に lock pattern を確認する必要がある。&lt;br /&gt;&lt;br /&gt;■ FLAG_SHOW_WHEN_LOCKED&lt;br /&gt;&lt;br /&gt;　スクリーンがロックされたときに Windows に表示させるための特別なフラグで、このフラグをセットすると、アプリケーションウィンドウが key guard や他のロックスクリーンよりも優先される。&lt;br /&gt;　&lt;br /&gt;　&lt;a href="http://developer.android.com/reference/android/view/WindowManager.LayoutParams.html#FLAG_KEEP_SCREEN_ON"&gt;FLAG_KEEP_SCREEN_ON&lt;/a&gt; と組み合わせて使うことで、画面をオンした後、 key guard を表示する前に直接ウィンドウを表示できる。&lt;br /&gt;　&lt;br /&gt;　&lt;a href="http://developer.android.com/reference/android/view/WindowManager.LayoutParams.html#FLAG_DISMISS_KEYGUARD"&gt;FLAG_DISMISS_KEYGUARD&lt;/a&gt; と組み合わせて使うことで、自動で non-secure keyguards を表示させないようにできる。このフラグは一番上の full-screen window にのみ適用される。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;関連するフラグ&lt;br /&gt;&lt;br /&gt;■ &lt;a href="http://developer.android.com/reference/android/view/WindowManager.LayoutParams.html#FLAG_ALLOW_LOCK_WHILE_SCREEN_ON"&gt;FLAG_ALLOW_LOCK_WHILE_SCREEN_ON&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;■ &lt;a href="http://developer.android.com/reference/android/view/WindowManager.LayoutParams.html#FLAG_KEEP_SCREEN_ON"&gt;FLAG_KEEP_SCREEN_ON&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;code name="code" class="java"&gt;&lt;br /&gt;public class KeyguardSampleActivity extends Activity {&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    public void onCreate(Bundle savedInstanceState) {&lt;br /&gt;        super.onCreate(savedInstanceState);&lt;br /&gt;        setContentView(R.layout.main);&lt;br /&gt;        &lt;br /&gt;        Window window = getWindow();&lt;br /&gt;        &lt;br /&gt;        // lock pattern を設定していても、&lt;br /&gt;        // このアプリ起動中は画面オン時にロックはでない&lt;br /&gt;        // 別のアプリやホームに移動するときにロックがでる&lt;br /&gt;        window.setFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED, &lt;br /&gt;                WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);&lt;br /&gt;&lt;br /&gt;        // lock pattern を設定していない場合、&lt;br /&gt;        // このアプリ起動中は画面オン時にロックはでない&lt;br /&gt;        window.setFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD, &lt;br /&gt;                WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;■ まとめ&lt;br /&gt;&lt;br /&gt;1. lock pattern あり、FLAG_SHOW_WHEN_LOCKED &lt;br /&gt;&lt;br /&gt;　このアプリ起動中は画面オン時にロックはでない&lt;br /&gt;　別のアプリやホームに移動するときにロックがでる&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;2. lock pattern あり、FLAG_DISMISS_KEYGUARD &lt;br /&gt;&lt;br /&gt;　普通にロックがでる&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;3. lock pattern あり、FLAG_SHOW_WHEN_LOCKED, FLAG_DISMISS_KEYGUARD &lt;br /&gt;&lt;br /&gt;　このアプリ起動中は画面オン時にロックはでない&lt;br /&gt;　別のアプリやホームに移動するときにロックがでる&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;4. lock pattern なし、FLAG_SHOW_WHEN_LOCKED &lt;br /&gt;&lt;br /&gt;　このアプリ起動中は画面オン時にロックはでない&lt;br /&gt;　別のアプリやホームに移動するときにロックがでる&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;5. lock pattern なし、FLAG_DISMISS_KEYGUARD &lt;br /&gt;&lt;br /&gt;　このアプリ起動中は画面オン時にロックはでない&lt;br /&gt;　別のアプリやホームに移動するときもロックはでない&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;6. lock pattern なし、FLAG_SHOW_WHEN_LOCKED, FLAG_DISMISS_KEYGUARD &lt;br /&gt;&lt;br /&gt;　このアプリ起動中は画面オン時にロックはでない&lt;br /&gt;　別のアプリやホームに移動するときもロックはでない&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5859951453664122203-5751663902796699952?l=y-anz-m.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://y-anz-m.blogspot.com/feeds/5751663902796699952/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://y-anz-m.blogspot.com/2011/08/androidflagdismisskeyguard.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5859951453664122203/posts/default/5751663902796699952'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5859951453664122203/posts/default/5751663902796699952'/><link rel='alternate' type='text/html' href='http://y-anz-m.blogspot.com/2011/08/androidflagdismisskeyguard.html' title='Android　FLAG_DISMISS_KEYGUARD と FLAG_SHOW_WHEN_LOCKED を使う'/><author><name>yanzm</name><uri>http://www.blogger.com/profile/04059587494895790858</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_HRaLqTNFL7w/TDx6XwqrmDI/AAAAAAAABMo/B1SkSHxhKu4/S220/icon4.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5859951453664122203.post-8830759570542587934</id><published>2011-08-18T15:27:00.004+09:00</published><updated>2011-08-18T15:32:59.633+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Android'/><title type='text'>Android　Keygurad が外されたことを検知する</title><content type='html'>ロックを設定している場合、&lt;a href="http://developer.android.com/reference/android/content/Intent.html#ACTION_SCREEN_ON"&gt;Intent.ACTION_SCREEN_ON&lt;/a&gt; だと画面がオンになった状態で通知がくるので、ロックが外れる前に通知がきてしまいます。画面がオンになったあと、ロックが外れた時に通知を受け取るには &lt;a href="http://developer.android.com/reference/android/content/Intent.html#ACTION_USER_PRESENT"&gt;Intent.ACTION_USER_PRESENT&lt;/a&gt; を拾うようにします。&lt;br /&gt;&lt;br /&gt;&lt;code name="code" class="java"&gt;&lt;br /&gt;public class UserPresentSampleActivity extends Activity {&lt;br /&gt;&lt;br /&gt;    private static final String TAG = "UserPresentSampleActivity";&lt;br /&gt;    &lt;br /&gt;    @Override&lt;br /&gt;    public void onCreate(Bundle savedInstanceState) {&lt;br /&gt;        super.onCreate(savedInstanceState);&lt;br /&gt;        setContentView(R.layout.main);&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    @Override&lt;br /&gt;    protected void onResume() {&lt;br /&gt;        super.onResume();&lt;br /&gt;&lt;br /&gt;        IntentFilter filter = new IntentFilter();&lt;br /&gt;        filter.addAction(Intent.ACTION_USER_PRESENT);&lt;br /&gt;        filter.addAction(Intent.ACTION_SCREEN_ON);&lt;br /&gt;        filter.addAction(Intent.ACTION_SCREEN_OFF);&lt;br /&gt;        registerReceiver(mReceiver, filter);&lt;br /&gt;    };&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    protected void onPause() {&lt;br /&gt;        super.onPause();&lt;br /&gt;        &lt;br /&gt;        unregisterReceiver(mReceiver);&lt;br /&gt;    };&lt;br /&gt;    &lt;br /&gt;    BroadcastReceiver mReceiver = new BroadcastReceiver() {&lt;br /&gt;&lt;br /&gt;        @Override&lt;br /&gt;        public void onReceive(Context context, Intent intent) {&lt;br /&gt;            String action = intent.getAction();&lt;br /&gt;&lt;br /&gt;            Log.d(TAG, "mReceiver received : " + action);&lt;br /&gt;&lt;br /&gt;            if(action.equals(Intent.ACTION_USER_PRESENT)){&lt;br /&gt;            }&lt;br /&gt;            else if(action.equals(Intent.ACTION_SCREEN_ON)){&lt;br /&gt;            }&lt;br /&gt;            else if(action.equals(Intent.ACTION_SCREEN_OFF)){                &lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    };    &lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;D/UserPresentSampleActivity( 9858): mReceiver received : android.intent.action.SCREEN_ON&lt;br /&gt;D/UserPresentSampleActivity( 9858): mReceiver received : android.intent.action.USER_PRESENT&lt;br /&gt;D/UserPresentSampleActivity( 9858): mReceiver received : android.intent.action.SCREEN_OFF&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5859951453664122203-8830759570542587934?l=y-anz-m.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://y-anz-m.blogspot.com/feeds/8830759570542587934/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://y-anz-m.blogspot.com/2011/08/androidkeygurad.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5859951453664122203/posts/default/8830759570542587934'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5859951453664122203/posts/default/8830759570542587934'/><link rel='alternate' type='text/html' href='http://y-anz-m.blogspot.com/2011/08/androidkeygurad.html' title='Android　Keygurad が外されたことを検知する'/><author><name>yanzm</name><uri>http://www.blogger.com/profile/04059587494895790858</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_HRaLqTNFL7w/TDx6XwqrmDI/AAAAAAAABMo/B1SkSHxhKu4/S220/icon4.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5859951453664122203.post-6790422730654914670</id><published>2011-08-17T11:42:00.012+09:00</published><updated>2011-08-17T12:42:29.502+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Android'/><title type='text'>Android Market　Multiple APK Support</title><content type='html'>2011年7月11日から Android Market で Multiple APK がサポートされるようになりました。&lt;br /&gt;&lt;br /&gt;詳細は Android Developers のブログ記事&lt;br /&gt;&lt;a href="http://android-developers.blogspot.com/2011/07/multiple-apk-support-in-android-market.html"&gt;Android Developers Blog: Multiple APK Support in Android Market -&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;や&lt;br /&gt;&lt;br /&gt;Android のドキュメント&lt;br /&gt;&lt;a href="http://developer.android.com/guide/market/publishing/multiple-apks.html"&gt;Multiple APK Support | Android Developers -&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;を参照してください。&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.google.com/support/androidmarket/bin/topic.py?hl=en&amp;topic=1100168&amp;rd=1"&gt;Android Market の Help Center&lt;/a&gt; もあります。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;■まとめ&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt; Multiple APK support は Android Market の新しいパブリッシュオプション (つまり、その他の配布プラットフォーム、例えば au one market とか、では使えません）&lt;br /&gt;&lt;br /&gt;&lt;li&gt; APK を1つだけ Developer Console からアップしている場合はこれまでと同じ&lt;br /&gt;&lt;br /&gt;&lt;li&gt; 複数の APK をアップロードしている場合、Android Market は1つのプロダクトの一部として扱う（ = アプリの詳細ページはどのユーザーからも同じ内容になる）&lt;br /&gt;つまり、以下の項目は複数の APK で共通、もしくは合算になる&lt;br /&gt;&lt;ul&gt;&lt;li&gt; アプリの詳細情報（バナーなど、スクリーンショット、ビデオ）&lt;br /&gt;&lt;li&gt; レーティング&lt;br /&gt;&lt;li&gt; コメント&lt;br /&gt;&lt;li&gt; アプリのダウンロード統計&lt;br /&gt;&lt;li&gt; レビュー&lt;br /&gt;&lt;li&gt; 購入データ&lt;/ul&gt;&lt;br /&gt;&lt;li&gt; Multiple APK で分割できる項目&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt; &lt;span style="font-weight:bold;"&gt;target API version&lt;/span&gt;&lt;br /&gt;Android Manifest の &lt;a href="http://developer.android.com/guide/topics/manifest/uses-sdk-element.html"&gt;&amp;lt;uses-sdk&amp;gt;&lt;/a&gt; に基づく &lt;br /&gt;異なる APK レベルのサポートを指定するために、&lt;a href="http://developer.android.com/guide/topics/manifest/uses-sdk-element.html#min"&gt;android:minSdkVersion&lt;/a&gt; および &lt;a href="http://developer.android.com/guide/topics/manifest/uses-sdk-element.html#max"&gt;android:maxSdkVersion&lt;/a&gt; 属性の両方を使うことができる&lt;br /&gt;将来の API バージョンに自動で対応するために、&lt;a href="http://developer.android.com/guide/topics/manifest/uses-sdk-element.html#max"&gt;android:maxSdkVersion&lt;/a&gt; は指定しないほうがよい&lt;br /&gt;&lt;br /&gt;&lt;li&gt; &lt;span style="font-weight:bold;"&gt;画面サイズ（オプションで画面解像度）&lt;/span&gt;&lt;br /&gt;Android Manifest の &lt;a href="http://developer.android.com/guide/topics/manifest/supports-screens-element.html"&gt;&amp;lt;supports-screens&amp;gt&lt;/a&gt;; や &lt;a href="http://developer.android.com/guide/topics/manifest/compatible-screens-element.html"&gt;&amp;lt;compatible-screens&amp;gt;&lt;/a&gt; エレメントに基づく&lt;br /&gt;この2つを同時に使用するべきではない&lt;br /&gt;可能な限り &lt;a href="http://developer.android.com/guide/topics/manifest/supports-screens-element.html"&gt;&amp;lt;supports-screens&amp;gt;&lt;/a&gt; だけを使う&lt;br /&gt;&lt;br /&gt;&lt;li&gt; &lt;span style="font-weight:bold;"&gt;GL texture-compression フォーマット&lt;/span&gt;&lt;br /&gt;Android Manifest の &lt;a href="http://developer.android.com/guide/topics/manifest/supports-gl-texture-element.html"&gt;&amp;lt;supports-gl-texture&amp;gt;&lt;/a&gt; エレメントに基づく&lt;/ul&gt;&lt;br /&gt;&lt;li&gt; Multiple APK の利点&lt;br /&gt;&lt;ul&gt;&lt;li&gt; API のバージョンで APK を分割できる (例えば、電話用とタブレット用の APK を分けられる）&lt;br /&gt;&lt;li&gt; ハードウェア機能のあり・なしで APK を分割できる&lt;br /&gt;&lt;li&gt; 新しい API がリリースされたときに、それをターゲットにしたバージョンを別 APK で開発できるので、既存のユーザーに影響がない&lt;br /&gt;&lt;li&gt; 1つの APK で様々な解像度の端末に対応する場合、resource （特に画像）が多くなることで APK サイズが大きくなるが、これを防げる&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;注意： &lt;a href="http://developer.android.com/guide/market/publishing/multiple-apks.html"&gt;Multiple APK Support | Android Developers -&lt;/a&gt; に&lt;br /&gt;Currently, these are the only device characteristics that Android Market supports for publishing multiple APKs as the same application.&lt;br /&gt;とあるように、&lt;br /&gt;現状では、マルチ APK を同じアプリとして配布するために Android Market がサポートしているのはデバイスの特徴（ハードウェア機能のある・なし）のみのようです。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;注意2: 基本的には、1つの APK のサイズが 50M を超えるときだけ Multiple APK をつかって、それ以外はなるべく1つの APK で複数のデバイスコンフィグレーションに対応するべき。そのほうがアップデートがシンプルになるし、開発管理も複雑にならなくてすむ。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;　　&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5859951453664122203-6790422730654914670?l=y-anz-m.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://y-anz-m.blogspot.com/feeds/6790422730654914670/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://y-anz-m.blogspot.com/2011/08/android-marketmultiple-apk-support.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5859951453664122203/posts/default/6790422730654914670'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5859951453664122203/posts/default/6790422730654914670'/><link rel='alternate' type='text/html' href='http://y-anz-m.blogspot.com/2011/08/android-marketmultiple-apk-support.html' title='Android Market　Multiple APK Support'/><author><name>yanzm</name><uri>http://www.blogger.com/profile/04059587494895790858</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_HRaLqTNFL7w/TDx6XwqrmDI/AAAAAAAABMo/B1SkSHxhKu4/S220/icon4.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5859951453664122203.post-6662774365731579514</id><published>2011-08-13T12:38:00.004+09:00</published><updated>2011-08-13T13:00:18.486+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Android'/><title type='text'>Android　TransitionDrawable を使う</title><content type='html'>&lt;a href="http://developer.android.com/reference/android/graphics/drawable/TransitionDrawable.html"&gt;TransitionDrawable&lt;/a&gt; は &lt;a href="http://developer.android.com/reference/android/graphics/drawable/LayerDrawable.html"&gt;LayerDrawble&lt;/a&gt; の拡張で、2つのレイヤーの間をクロスフェードさせることが可能。&lt;br /&gt;&lt;br /&gt;主なメソッドは次の3つ&lt;br /&gt;&lt;ul&gt;&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/graphics/drawable/TransitionDrawable.html#startTransition(int)"&gt;startTransition(int durationMillis)&lt;/a&gt;&lt;br /&gt;引数で指定された durationMillis [millisecond] かけて1つ目のレイヤーから2つ目のレイヤーにクロスフェード&lt;br /&gt;&lt;br /&gt;&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/graphics/drawable/TransitionDrawable.html#reverseTransition(int)"&gt;reverseTransition(int durationMillis)&lt;/a&gt;&lt;br /&gt;引数で指定された durationMillis [millisecond] かけて現在レイヤーからもう一つのレイヤーにクロスフェード&lt;br /&gt;&lt;br /&gt;&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/graphics/drawable/TransitionDrawable.html#resetTransition()"&gt;resetTransition()&lt;/a&gt;&lt;br /&gt;1つ目のレイヤーを表示&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;次のコンストラクタで Drawable の配列を渡して生成することもできるし&lt;br /&gt;&lt;br /&gt;・&lt;a href="http://developer.android.com/reference/android/graphics/drawable/TransitionDrawable.html#TransitionDrawable(android.graphics.drawable.Drawable[])"&gt;TransitionDrawable(Drawable[] layers)&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;transition&amp;gt; タグを使って XML で定義することもできる。&lt;br /&gt;&lt;br /&gt;例えばこんな感じ&lt;br /&gt;&lt;code name="code" class="xml"&gt;&lt;br /&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;&lt;br /&gt;&amp;lt;transition xmlns:android="http://schemas.android.com/apk/res/android"&amp;gt;&lt;br /&gt;    &amp;lt;item android:drawable="@drawable/trash"  /&amp;gt;&lt;br /&gt;    &amp;lt;item android:drawable="@drawable/trash2"  /&amp;gt;&lt;br /&gt;&amp;lt;/transition&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;code name="code" class="xml"&gt;&lt;br /&gt;public class TransitionDrawableSampleActivity extends Activity {&lt;br /&gt;&lt;br /&gt;    TransitionDrawable mTransitionDrawable;&lt;br /&gt;    &lt;br /&gt;    private static final int TRANSITION_DURATION = 1000;&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    public void onCreate(Bundle savedInstanceState) {&lt;br /&gt;        super.onCreate(savedInstanceState);&lt;br /&gt;        setContentView(R.layout.main);&lt;br /&gt;        &lt;br /&gt;        ImageView iv = (ImageView)findViewById(R.id.imageview);&lt;br /&gt;        mTransitionDrawable = (TransitionDrawable)iv.getDrawable();&lt;br /&gt;        mTransitionDrawable.setCrossFadeEnabled(false);&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    public void onResetClick(View v) {&lt;br /&gt;    	mTransitionDrawable.resetTransition();&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    public void onTransitionClick(View v) {&lt;br /&gt;    	mTransitionDrawable.startTransition(TRANSITION_DURATION);&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    public void onReverseClick(View v) {&lt;br /&gt;    	mTransitionDrawable.reverseTransition(TRANSITION_DURATION);&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/-UMimy1uWaZc/TkX2E87As0I/AAAAAAAADbo/bT4MntjIMzI/s1600/TransitionDrawable1.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 240px; height: 400px;" src="http://3.bp.blogspot.com/-UMimy1uWaZc/TkX2E87As0I/AAAAAAAADbo/bT4MntjIMzI/s400/TransitionDrawable1.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5640184673284961090" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/-5ydPc6N9Tgk/TkX2FMnl1PI/AAAAAAAADbw/qFe80s7R2JE/s1600/TransitionDrawable2.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 240px; height: 400px;" src="http://1.bp.blogspot.com/-5ydPc6N9Tgk/TkX2FMnl1PI/AAAAAAAADbw/qFe80s7R2JE/s400/TransitionDrawable2.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5640184677498475762" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5859951453664122203-6662774365731579514?l=y-anz-m.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://y-anz-m.blogspot.com/feeds/6662774365731579514/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://y-anz-m.blogspot.com/2011/08/androidtransitiondrawable.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5859951453664122203/posts/default/6662774365731579514'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5859951453664122203/posts/default/6662774365731579514'/><link rel='alternate' type='text/html' href='http://y-anz-m.blogspot.com/2011/08/androidtransitiondrawable.html' title='Android　TransitionDrawable を使う'/><author><name>yanzm</name><uri>http://www.blogger.com/profile/04059587494895790858</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_HRaLqTNFL7w/TDx6XwqrmDI/AAAAAAAABMo/B1SkSHxhKu4/S220/icon4.JPG'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-UMimy1uWaZc/TkX2E87As0I/AAAAAAAADbo/bT4MntjIMzI/s72-c/TransitionDrawable1.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5859951453664122203.post-4838749452161136644</id><published>2011-08-11T08:24:00.030+09:00</published><updated>2011-08-13T01:42:19.840+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Android'/><title type='text'>Android　Spannable を使って文字列の一部を装飾する</title><content type='html'>&lt;a href="http://developer.android.com/reference/android/text/SpannableStringBuilder.html"&gt;SpannableStringBuilder&lt;/a&gt; を使って、文字列の一部を装飾（bold, italic, typeface, color, size) することができます。&lt;br /&gt;&lt;br /&gt;こんな感じ。&lt;br /&gt;&lt;br /&gt;&lt;code name="code" class="java"&gt;&lt;br /&gt;public class SpannableSampleActivity extends Activity {&lt;br /&gt;&lt;br /&gt; private static StyleSpan sBoldStyleSpan = new StyleSpan(Typeface.BOLD);&lt;br /&gt; private static TypefaceSpan sSerifTypefaceSpan = new TypefaceSpan("serif");&lt;br /&gt;&lt;br /&gt; @Override&lt;br /&gt; public void onCreate(Bundle savedInstanceState) {&lt;br /&gt;   super.onCreate(savedInstanceState);&lt;br /&gt;   setContentView(R.layout.main);&lt;br /&gt;&lt;br /&gt;   TextAppearanceSpan cyanTextAppearanceSpan =&lt;br /&gt;       new TextAppearanceSpan(this, R.style.MyTextAppearance);&lt;br /&gt;&lt;br /&gt;   SpannableStringBuilder sb = new SpannableStringBuilder();&lt;br /&gt;   sb.append(getString(R.string.pretext) + " ");&lt;br /&gt;&lt;br /&gt;   int start = sb.length();&lt;br /&gt;   sb.append(getString(R.string.boldtext));&lt;br /&gt;   sb.setSpan(sBoldStyleSpan, start, sb.length(),&lt;br /&gt;       Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);&lt;br /&gt;&lt;br /&gt;   sb.append(" " + getString(R.string.posttext) + " ");&lt;br /&gt;&lt;br /&gt;   start = sb.length();&lt;br /&gt;   sb.append(getString(R.string.seriftext));&lt;br /&gt;   sb.setSpan(sSerifTypefaceSpan, start, sb.length(),&lt;br /&gt;       Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);&lt;br /&gt;&lt;br /&gt;   sb.append(" " + getString(R.string.posttext) + " ");&lt;br /&gt;&lt;br /&gt;   start = sb.length();&lt;br /&gt;   sb.append(getString(R.string.cyantext));&lt;br /&gt;   sb.setSpan(cyanTextAppearanceSpan, start, sb.length(),&lt;br /&gt;       Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);&lt;br /&gt;&lt;br /&gt;   sb.append(" " + getString(R.string.posttext));&lt;br /&gt;&lt;br /&gt;   ((TextView)findViewById(R.id.textview)).setText(sb);&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;res/values/styles.xml&lt;br /&gt;&lt;code name="code" class="xml"&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;&lt;br /&gt;&amp;lt;resources&amp;gt;&lt;br /&gt;&amp;lt;style name="MyTextAppearance" parent="@android:style/TextAppearance"&amp;gt;&lt;br /&gt; &amp;lt;item name="android:textColor"&amp;gt;#00ffff&amp;lt;/item&amp;gt;&lt;br /&gt; &amp;lt;item name="android:textSize"&amp;gt;30sp&amp;lt;/item&amp;gt;&lt;br /&gt; &amp;lt;item name="android:textStyle"&amp;gt;italic&amp;lt;/item&amp;gt;&lt;br /&gt;&amp;lt;/style&amp;gt;&lt;br /&gt;&amp;lt;/resources&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/-_r2lMz7f0tY/TkNROl06JHI/AAAAAAAADbg/Kz89gx2oy6I/s1600/SpannableStringBuilderSample.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"&gt;&lt;img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 240px; height: 400px;" src="http://2.bp.blogspot.com/-_r2lMz7f0tY/TkNROl06JHI/AAAAAAAADbg/Kz89gx2oy6I/s400/SpannableStringBuilderSample.png" alt="" id="BLOGGER_PHOTO_ID_5639440469512037490" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;SpannableStringBuilder には複数の Span が設定可能で、それぞれ &lt;a href="http://developer.android.com/reference/android/text/SpannableStringBuilder.html#setSpan%28java.lang.Object,%20int,%20int,%20int%29"&gt;setSpan()&lt;/a&gt; メソッドで設定できます。&lt;br /&gt;&lt;br /&gt;設定されている Span オブジェクトの一覧は &lt;a href="http://developer.android.com/reference/android/text/SpannableStringBuilder.html#getSpans%28int,%20int,%20java.lang.Class%3CT%3E%29"&gt;getSpans()&lt;/a&gt; メソッドで取得でき、特定の Span オブジェクトの設定されている開始位置や終了位置、フラグなどは &lt;a href="http://developer.android.com/reference/android/text/SpannableStringBuilder.html#getSpanStart%28java.lang.Object%29"&gt;getSpanStart()&lt;/a&gt;, &lt;a href="http://developer.android.com/reference/android/text/SpannableStringBuilder.html#getSpanEnd%28java.lang.Object%29"&gt;getSpanEnd()&lt;/a&gt;, &lt;a href="http://developer.android.com/reference/android/text/SpannableStringBuilder.html#getSpanFlags%28java.lang.Object%29"&gt;getSpanFlags()&lt;/a&gt; で取得できます。 Span を削除する場合は &lt;a href="http://developer.android.com/reference/android/text/SpannableStringBuilder.html#removeSpan%28java.lang.Object%29"&gt;removeSpan()&lt;/a&gt; を呼び出します。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;SpannalbeStringBuilder の Span 操作&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/text/SpannableStringBuilder.html#setSpan%28java.lang.Object,%20int,%20int,%20int%29"&gt;setSpan()&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/text/SpannableStringBuilder.html#removeSpan%28java.lang.Object%29"&gt;removeSpan()&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/text/SpannableStringBuilder.html#getSpans%28int,%20int,%20java.lang.Class%3CT%3E%29"&gt;getSpans()&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/text/SpannableStringBuilder.html#getSpanStart%28java.lang.Object%29"&gt;getSpanStart()&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/text/SpannableStringBuilder.html#getSpanEnd%28java.lang.Object%29"&gt;getSpanEnd()&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://developer.android.com/reference/android/text/SpannableStringBuilder.html#getSpanFlags%28java.lang.Object%29"&gt;getSpanFlags()&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://developer.android.com/reference/android/text/SpannableStringBuilder.html#setSpan%28java.lang.Object,%20int,%20int,%20int%29"&gt;setSpan()&lt;/a&gt; の4つ目の引数で、この span の範囲内に文字が挿入されたときにどう振舞うかを指定することができます。指定できるフラグは &lt;a href="http://developer.android.com/reference/android/text/Spanned.html"&gt;Spanned&lt;/a&gt; に定義されている SPAN_* の定数のうち次の5個です。&lt;br /&gt;&lt;ul&gt;&lt;li&gt; SPAN_INCLUSIVE_EXCLUSIVE&lt;br /&gt;&lt;/li&gt;&lt;li&gt; SPAN_INCLUSIVE_INCLUSIVE&lt;br /&gt;&lt;/li&gt;&lt;li&gt; SPAN_EXCLUSIVE_EXCLUSIVE&lt;br /&gt;&lt;/li&gt;&lt;li&gt; SPAN_EXCLUSIVE_INCLUSIVE&lt;br /&gt;&lt;/li&gt;&lt;li&gt; SPAN_PARAGRAPH&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;SpannableStringBuilder の文字列操作&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt; append()&lt;br /&gt;&lt;/li&gt;&lt;li&gt; insert()&lt;br /&gt;&lt;/li&gt;&lt;li&gt; replace()&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;など&lt;br /&gt;&lt;br /&gt;Span オブジェクトとして指定できるクラスとしていくつかあります。&lt;br /&gt;&lt;ul&gt;&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/text/style/StyleSpan.html"&gt;StyleSpan&lt;/a&gt;&lt;br /&gt;bold, italic を指定&lt;br /&gt;&lt;/li&gt;&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/text/style/TypefaceSpan.html"&gt;TypefaceSpane&lt;/a&gt;&lt;br /&gt;"monospace", "serif", "sans-serif" を指定&lt;br /&gt;&lt;/li&gt;&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/text/style/TextAppearanceSpan.html"&gt;TextAppearanceSpan&lt;/a&gt;&lt;br /&gt;文字の色、サイズ、style、typeface を一致する TextAppearance リソースに設定&lt;br /&gt;&lt;/li&gt;&lt;li&gt; AbsoluteSizeSpan&lt;br /&gt;&lt;/li&gt;&lt;li&gt; RelativeSizeSpan&lt;br /&gt;&lt;/li&gt;&lt;li&gt; ReplacementSpan&lt;br /&gt;&lt;/li&gt;&lt;li&gt; ScaleXSpan&lt;br /&gt;&lt;/li&gt;&lt;li&gt; SubscriptSpan&lt;br /&gt;&lt;/li&gt;&lt;li&gt; SuperscriptSpan&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://developer.android.com/reference/android/text/style/StyleSpan.html"&gt;StyleSpan&lt;/a&gt; を使うときの注意点として、このスタイルが累積するものなので、例えば bold と italic 両方を別々の span で設定したり、ベースのスタイルが bold で italic の span を呼び出した場合、 bold italic になります。ベーススタイルからのスタイルはオフにすることができません。&lt;br /&gt;&lt;br /&gt;コンストラクタの引数でスタイルを設定します。設定できるスタイルは &lt;a href="http://developer.android.com/reference/android/graphics/Typeface.html"&gt;Typeface&lt;/a&gt; クラスで定義されている次の4個です。&lt;br /&gt;&lt;ul&gt;&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/graphics/Typeface.html#BOLD"&gt;BOLD&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/graphics/Typeface.html#BOLD_ITALIC"&gt;BOLD_ITALIC&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/graphics/Typeface.html#ITALIC"&gt;ITALIC&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/graphics/Typeface.html#NORMAL"&gt;NORMAL&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://developer.android.com/reference/android/text/style/TypefaceSpan.html"&gt;TypefaceSpane&lt;/a&gt; のコンストラクタで指定できる family は次の3個です。&lt;br /&gt;&lt;ul&gt;&lt;li&gt; "monospace"&lt;br /&gt;&lt;/li&gt;&lt;li&gt; "serif"&lt;br /&gt;&lt;/li&gt;&lt;li&gt; "sans-serif"&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://developer.android.com/reference/android/text/style/TextAppearanceSpan.html"&gt;TextAppearanceSpan&lt;/a&gt; には、文字の typeface、大きさ、色を引数で指定する&lt;br /&gt;&lt;br /&gt;- &lt;a href="http://developer.android.com/reference/android/text/style/TextAppearanceSpan.html#TextAppearanceSpan%28java.lang.String,%20int,%20int,%20android.content.res.ColorStateList,%20android.content.res.ColorStateList%29"&gt;public TextAppearanceSpan (String family, int style, int size, ColorStateList color, ColorStateList linkColor)&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;と、TextAppearance のリソース ID を指定する&lt;br /&gt;&lt;br /&gt;- &lt;a href="http://developer.android.com/reference/android/text/style/TextAppearanceSpan.html#TextAppearanceSpan%28android.content.Context,%20int%29"&gt;public TextAppearanceSpan (Context context, int appearance)&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;- &lt;a href="http://developer.android.com/reference/android/text/style/TextAppearanceSpan.html#TextAppearanceSpan%28android.content.Context,%20int,%20int%29"&gt;public TextAppearanceSpan (Context context, int appearance, int colorList)&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;があります。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5859951453664122203-4838749452161136644?l=y-anz-m.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://y-anz-m.blogspot.com/feeds/4838749452161136644/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://y-anz-m.blogspot.com/2011/08/androidspannable.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5859951453664122203/posts/default/4838749452161136644'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5859951453664122203/posts/default/4838749452161136644'/><link rel='alternate' type='text/html' href='http://y-anz-m.blogspot.com/2011/08/androidspannable.html' title='Android　Spannable を使って文字列の一部を装飾する'/><author><name>yanzm</name><uri>http://www.blogger.com/profile/04059587494895790858</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_HRaLqTNFL7w/TDx6XwqrmDI/AAAAAAAABMo/B1SkSHxhKu4/S220/icon4.JPG'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-_r2lMz7f0tY/TkNROl06JHI/AAAAAAAADbg/Kz89gx2oy6I/s72-c/SpannableStringBuilderSample.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5859951453664122203.post-4232810208810105885</id><published>2011-07-31T14:42:00.017+09:00</published><updated>2011-08-11T13:23:48.786+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Android'/><category scheme='http://www.blogger.com/atom/ns#' term='Android App'/><title type='text'>カッコいい時計ウィジェットをリリースしました。</title><content type='html'>&lt;a href="https://market.android.com/details?id=com.uphyca.android.app.bandoclock" target="_blank"&gt;&lt;span style="font-weight:bold;"&gt;Band O'clock&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/-rp95TZwCNbk/TjTr5j6N0eI/AAAAAAAADUU/tqyNJ-oUUpI/s1600/a.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 195px;" src="http://2.bp.blogspot.com/-rp95TZwCNbk/TjTr5j6N0eI/AAAAAAAADUU/tqyNJ-oUUpI/s400/a.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5635388407871820258" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;複数並べて世界時計のようにしたり&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/-JF0esZGouxA/TjTrbKtzE-I/AAAAAAAADUM/LOmEVafAIKY/s1600/BandOClockCapture5.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 240px; height: 400px;" src="http://2.bp.blogspot.com/-JF0esZGouxA/TjTrbKtzE-I/AAAAAAAADUM/LOmEVafAIKY/s400/BandOClockCapture5.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5635387885712774114" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;好きなフォントにしてみたり&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/-a7ultqXQBK4/TjTs1_ODRmI/AAAAAAAADUc/k9NX9immko4/s1600/BandOClockCapture6.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 240px; height: 400px;" src="http://1.bp.blogspot.com/-a7ultqXQBK4/TjTs1_ODRmI/AAAAAAAADUc/k9NX9immko4/s400/BandOClockCapture6.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5635389445994923618" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;できます。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;ウィジェット本体よりも設定画面にかなりこだわってます。&lt;br /&gt;&lt;br /&gt;デフォルトの PreferenceActivity を使って簡単に作ることもできますが、それって使いにくくないですか？&lt;br /&gt;&lt;br /&gt;・その設定によってウィジェットがどう変わるのかわからない&lt;br /&gt;・設定をやり直すのに毎回ダイアログを開かないといけない&lt;br /&gt;&lt;br /&gt;このあたりを改善したくて、&lt;br /&gt;&lt;br /&gt;・設定画面にウィジェットのプレビューをつけて設定によってリアルタイムで変わるように&lt;br /&gt;・複数の選択肢から1つを選ぶのに Spinner を使わない&lt;br /&gt;&lt;br /&gt;というポリシーで、こんな感じの画面になってます。&lt;br /&gt;各画面にはフリックで移動できます。&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/-Tipfa-eAx88/TjTz94ngBaI/AAAAAAAADU0/Oj6xxWlV5O8/s1600/BandOClockCapture4.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 240px; height: 400px;" src="http://2.bp.blogspot.com/-Tipfa-eAx88/TjTz94ngBaI/AAAAAAAADU0/Oj6xxWlV5O8/s400/BandOClockCapture4.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5635397278242964898" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;フォントも変えられます。&lt;br /&gt;フォントインポート機能を購入すると、自分の用意した好きなフォントも使うことができます。&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/-BvBOOAceU2A/TjT0N_2W6BI/AAAAAAAADU8/GMgA2bl9gus/s1600/BandOClockCapture3.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 240px; height: 400px;" src="http://4.bp.blogspot.com/-BvBOOAceU2A/TjT0N_2W6BI/AAAAAAAADU8/GMgA2bl9gus/s400/BandOClockCapture3.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5635397555062237202" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;色を変えたり&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/-77nGh4bQa8Q/TjTzxTA-LUI/AAAAAAAADUk/ZB4iwk3tP2s/s1600/BandOClockCapture1.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 240px; height: 400px;" src="http://2.bp.blogspot.com/-77nGh4bQa8Q/TjTzxTA-LUI/AAAAAAAADUk/ZB4iwk3tP2s/s400/BandOClockCapture1.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5635397061990821186" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;都市名やタイムゾーンを設定できます。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/-bAI5aUJ-bj8/TjT59LvJ2uI/AAAAAAAADVE/n2fSsOZIwyE/s1600/BandOClockCapture2.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 240px; height: 400px;" src="http://4.bp.blogspot.com/-bAI5aUJ-bj8/TjT59LvJ2uI/AAAAAAAADVE/n2fSsOZIwyE/s400/BandOClockCapture2.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5635403863265237730" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;タイムゾーンの設定中もプレビューが隠れないようになってます。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;よかったらぜひ使ってみてくださいませ〜。&lt;br /&gt;&lt;a href="http://market.android.com/details?id=com.uphyca.android.app.bandoclock" target="_blank"&gt;&lt;br /&gt;  &lt;img src="http://www.android.com/images/brand/60_avail_market_logo2.png" /&gt;&lt;br /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;　　&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5859951453664122203-4232810208810105885?l=y-anz-m.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://y-anz-m.blogspot.com/feeds/4232810208810105885/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://y-anz-m.blogspot.com/2011/07/blog-post.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5859951453664122203/posts/default/4232810208810105885'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5859951453664122203/posts/default/4232810208810105885'/><link rel='alternate' type='text/html' href='http://y-anz-m.blogspot.com/2011/07/blog-post.html' title='カッコいい時計ウィジェットをリリースしました。'/><author><name>yanzm</name><uri>http://www.blogger.com/profile/04059587494895790858</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_HRaLqTNFL7w/TDx6XwqrmDI/AAAAAAAABMo/B1SkSHxhKu4/S220/icon4.JPG'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-rp95TZwCNbk/TjTr5j6N0eI/AAAAAAAADUU/tqyNJ-oUUpI/s72-c/a.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5859951453664122203.post-4549712092827408074</id><published>2011-07-31T11:43:00.001+09:00</published><updated>2011-07-31T14:13:01.147+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Android'/><title type='text'>Android 3.2 Platform</title><content type='html'>Android 3.2 Platform&lt;br /&gt;&lt;br /&gt;API Level: &lt;span style="font-weight:bold;"&gt;13&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Android 3.2 へようこそ！&lt;br /&gt;&lt;br /&gt;Android 3.2 はユーザーと開発者むけの新しい機能を追加したインクリメンタルプラットフォームリリースです。このセクションでは、新しい機能と developer APIs のオーバービューを紹介します。&lt;br /&gt;&lt;br /&gt;開発者は Android SDK のコンポーネントとして Android 3.2 platform をダウンロードできるようになりました。このプラットフォームには Android library と system image, emulator skin などが含まれていますが、外部のライブラリは含まれていません。&lt;br /&gt;&lt;br /&gt;Android 3.2 向けの開発とテストを始めるには、Android SDK Manager を使って自分の SDK にプラットフォームをダウンロードします。より詳しい情報は &lt;a href="http://developer.android.com/sdk/adding-components.html"&gt;Adding SDK Components&lt;/a&gt; を見てください。Android が初めての人は、まず &lt;a href="http://developer.android.com/sdk/index.html"&gt;download the SDK Starter Package&lt;/a&gt; から始めてください。&lt;br /&gt;&lt;br /&gt;リマインダー: すでに Android application を公開している場合、できるだけ早く Android 3.2 上であなたのアプリケーションのテストと最適化をしてください。最新の Android-powered デバイスでベストな体験を提供していることを確認するべきです。そのためにあなたができることについての情報は &lt;a href="http://developer.android.com/guide/practices/optimizing-for-3.0.html"&gt;Optimizing Apps for Android 3.x&lt;/a&gt; を見てください。&lt;br /&gt;&lt;br /&gt;---&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Platform Highlights&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;New user features&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt; ワイドレンジのタブレット用の最適化&lt;br /&gt;Android 3.2 はワイドレンジのタブレットデバイスでユーザー体験をすばらしいものにするためのシステム全体にわたるさまざまな最適化を含んでいます。&lt;br /&gt;&lt;br /&gt;&lt;li&gt; 固定サイズのアプリ用ズーム互換性&lt;br /&gt;Android 3.2 は、大画面のデバイス上の固定サイズアプリを見る新しい方法である、&lt;i&gt;compatibility zoom&lt;/i&gt; mode (ズーム互換性モード）をサポートします。新しいモードは、タブレットのような大画面サイズ上で動くようにデザインされていない標準の UI ストレッチに代わって pixel-scaled を提供します。ユーザーは、互換性サポートが必要なアプリに対して、システムバーのメニューアイコンから新しいモードにアクセスできます。&lt;br /&gt;&lt;br /&gt;&lt;li&gt; SD card からの Media sync&lt;br /&gt;SD card をサポートしているデバイスで、ユーザーはメディアファイルを SD card からそれを使用するアプリへ直接ロードできるようになりました。システムの機能によって、アプリがシステムメディアストアからファイルにアクセスできるようになりました。&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;New developer features&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt; 画面サポートを管理する API の拡張&lt;br /&gt;Android 3.2 は、さまざまな Android-powered device でのアプリケーション UI の管理方法に新しいものを追加した、プラットフォームスクリーンサポート API の拡張を提供します。API は新しいリソース識別子と manifest 属性を含みます。これにより異なるサイズ上でのアプリの表示を、一般的なサイズのカテゴリに頼るよりも正確にコントロールできます。&lt;br /&gt;fixed-sized アプリと、いくつかのスクリーンサイズむけの限定的なサポートをしているアプリに対しては、最も可能性のあるディスプレイを確認してください。プラットフォームは、UI を小さいスクリーン領域に描画して、それをディスプレイの可能な領域に拡大する、新しいズーム互換性モードも提供します。スクリーンサポート API のより詳しい情報とその使い方は以降のセクションをみてください。&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;---&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;API Overview&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Screens Support APIs&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Android 3.2 は新しいスクリーンサポート API を紹介します。これにより異なる画面サイズに渡ってどのようにアプリケーションが表示されるかをより細かくコントロールできます。新しい API は、プラットフォームの一般的なスクリーンサイズモデルを含む既存のスクリーンサポート API 上に作られ、一般的なスクリーンサイズ (large や xlarge) よりも、"dpi" 単位で測定されたサイズ (600dp や 720dp) で指定したスクリーン範囲に正確にターゲットします。&lt;br /&gt;&lt;br /&gt;アプリケーションの UI をデザインする際、プラットフォームが提供する抽象化された解像度に頼ることももちろんできます。これはつまり、アプリケーションがさまざまなデバイスの実際のピクセル密度の違いを補う必要がないということです。アプリケーションの UI を横および縦の利用可能な領域によってデザインすることができます。プラットフォームは利用可能な領域の量を新しい3つの特徴で表現します：smallestWidth, width, height&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt; スクリーンの smallestWidth は "dp" 単位での基礎的な最小サイズです。スクリーンの高さおよび幅の短い方です。縦向きのスクリーンでは、smallestWidth は通常横幅に基づき、横向きでは縦幅に基づきます。全ての場合で、smallestWidth は固定の画面特性から導き出され、画面の向きによって値は変化しません。smallestWidth はアプリケーション UI が描画に必要とする最も短い幅（システムによって予約されている領域を含まない）を表すので、アプリケーションにとって重要です。&lt;br /&gt;&lt;br /&gt;&lt;li&gt; 対照的に、スクリーンの width と height は現在の横および縦のアプリケーションのレイアウトで利用可能な領域（"dp"単位、システムによって予約されている領域を含まない）を表します。width と height はユーザーが画面の向きを縦向きや横向きに変更すると変わります。&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;新しいスクリーンサポート API は現在の画面の smallestWidth によってアプリケーションの UI を管理するようデザインされています。さらに必要に応じて、現在の横幅と縦幅によっても UI を管理することができます。これらの目的のため API は次のツールを提供します：&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt; 最小 smallestWidth, width, height にレイアウトや他のリソースをターゲットするための新しい識別子&lt;br /&gt;&lt;br /&gt;&lt;li&gt; アプリの互換性を持つ範囲の最大スクリーンサイズを指定する新しいマニフェスト属性&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;加えて、アプリケーションはプラットフォームの以前のバージョンの起動時のリソース読み込みや UI の管理やシステムへの問い合わせもそのままできます。&lt;br /&gt;&lt;br /&gt;新しい API では smallestWidth, width, height を使ってより直接的に画面サイズをターゲットできます。そのため、典型的なスクリーンタイプの異なる特徴を理解することは訳に立ちます。次の表でいくつかの例を "dp" 単位で載せました。&lt;br /&gt;&lt;br /&gt;典型的なデバイスの解像度と画面サイズ&lt;br /&gt;&lt;table&gt;&lt;br /&gt;&lt;tr&gt;&lt;th&gt;Type&lt;/th&gt;&lt;th&gt;Density(generalized)&lt;/th&gt;&lt;th&gt;Dimensions(dp)&lt;/th&gt;&lt;th&gt;smallestWidth(dp)&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Baseline phone&lt;/td&gt;&lt;td&gt;mdpi&lt;/td&gt;&lt;td&gt;320x480&lt;/td&gt;&lt;td&gt;320&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Small tablet/large phone&lt;/td&gt;&lt;td&gt;mdpi&lt;/td&gt;&lt;td&gt;480x800&lt;/td&gt;&lt;td&gt;480&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;7-inch tablet&lt;/td&gt;&lt;td&gt;mdpi&lt;/td&gt;&lt;td&gt;600x1024&lt;/td&gt;&lt;td&gt;600&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;10-inch tablet&lt;/td&gt;&lt;td&gt;mdpi&lt;/td&gt;&lt;td&gt;800x1280&lt;/td&gt;&lt;td&gt;800&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;次のセクションでは新しいスクリーン識別子とマニフェスト属性のより詳しい情報を提供します。スクリーンサポート API の完全な情報については &lt;a href="http://developer.android.com/guide/practices/screens_support.html"&gt;Supporting Multiple Screens&lt;/a&gt; を見てください。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;New resource qualifiers for screens support&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Android 3.2 の新しいリソース識別子によってさまざまなスクリーンサイズに対してレイアウトをよりうまくターゲットさせることができます。識別子を使って特定の最小 smallestWidth, 現在の横幅もしくは縦幅、に対してデザインされたリソース設定を作ることができます。&lt;br /&gt;&lt;br /&gt;新しい識別子は：&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt; &lt;font color=green&gt;swNNNdp&lt;/font&gt; — 最小の smallestWidth を指定する。 smallestWidth はリソースが使用されるべき "dp" 単位でのサイズ。上記で述べたように、スクリーンの smallestWidth は画面の向きによらず定数である。例えば: &lt;font color=green&gt;sw320dp, sw720dp, sw720dp&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;li&gt; &lt;font color=green&gt;wNNNdp&lt;/font&gt; and &lt;font color=green&gt;hNNNdp&lt;/font&gt; — リソースが使用されるべき "dp" 単位での最小の横幅もしくは縦幅を指定する。上記で述べたように、スクリーンの横幅と縦幅は画面の向きに応じて変わる。例えば: &lt;font color=green&gt;w320dp, w720dp, h1024dp&lt;/font&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;複数にオーバーラップするリソース設定を作成することもできます。例えば、いくつかのリソースを画面が 480dp より広い場合にタグ付し、その他では 600dp より大きいもの、その他で 720dp より大きいもののようにできます。複数のリソース設定がスクリーン対して識別子と付けられている場合、システムは最も一致する設定を選択します。与えられたスクリーンに対してどのリソースが割り当てられるか正確にコントロールするために、リソースを1つの識別子、もしくは複数の識別子の組み合わせにタグ付することができます。&lt;br /&gt;&lt;br /&gt;すでに表記した典型的なサイズに基づいた新しい識別子を使った例です：&lt;br /&gt;&lt;pre name="code" class="python"&gt;&lt;br /&gt;# For phones&lt;br /&gt;res/layout/main_activity.xml&lt;br /&gt;&lt;br /&gt;# For 7” tablets&lt;br /&gt;res/layout-sw600dp/main_activity.xml   &lt;br /&gt;&lt;br /&gt;# For 10” tablets&lt;br /&gt;res/layout-sw720dp/main_activity.xml&lt;br /&gt;&lt;br /&gt;# Multi-pane when enough width&lt;br /&gt;res/layout-w600dp/main_activity.xml&lt;br /&gt;&lt;br /&gt;# For large width&lt;br /&gt;res/layout-sw600dp-w720dp/main_activity.xml&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;platform の古いバージョンでは新しい識別子は無視されます。そのため、すべてのデバイスに対応するために必要に応じてこれらをミックスすることができます。&lt;br /&gt;&lt;pre name="code" class="python"&gt;&lt;br /&gt;# For phones&lt;br /&gt;res/layout/main_activity.xml&lt;br /&gt;&lt;br /&gt;# For pre-3.2 tablets&lt;br /&gt;res/layout-xlarge/main_activity.xml&lt;br /&gt;&lt;br /&gt;# For 3.2 and up tablets&lt;br /&gt;res/layout-sw600dp/main_activity.xml&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;どのように新しい識別子を使うかの完全な情報は Using new size qualifiers を見てください。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;New manifest attributes for screen-size compatibility&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;framework は新しい &lt;a href="http://developer.android.com/"&gt;&amp;lt;supports-screens&amp;gt;&lt;/a&gt; マニフェスト属性のセットを提供します。これにより異なるスクリーンサイズに対するアプリのサポートを管理することができます。特に、動くようにデザインされた最大と最小のスクリーンサイズを指定することができ、また最大サイズはシステムの新しい &lt;a href="http://developer.android.com/guide/practices/screen-compat-mode.html"&gt;screen compatibility mode&lt;/a&gt; が必要としないようデザインされたサイズです。上記で説明したリソース識別子のように、新しいマニフェスト属性はアプリケーションがサポートするスクリーンの範囲を指定します。&lt;br /&gt;&lt;br /&gt;スクリーンサポートの新しいマニフェスト属性は：&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt; &lt;font color=green&gt;android:compatibleWidthLimitDp="&lt;span style="font-style:italic;"&gt;numDp&lt;/span&gt;"&lt;/font&gt; — 最大の largestWidth を指定します。largestWidth はアプリケーションが compatibility mode を必要としないで動作できるサイズです。現在のスクリーンが指定した値より大きい場合、システムはアプリケーションを通常のモードで表示します。しかし、ユーザーはオプションとしてシステムバーの設定から compatibility mode に切り替えることが可能です。&lt;br /&gt;&lt;br /&gt;&lt;li&gt; &lt;font color=green&gt;android:largestWidthLimitDp="&lt;span style="font-style:italic;"&gt;numDp&lt;/span&gt;"&lt;/font&gt; — 最大の largestWidth を指定します。largestWidth はアプリケーションが動作するようデザインされたサイズです。現在のスクリーンが指定した値より大きい場合、現在のスクリーン上でベストな表示を行うために、システムは強制的にアプリケーションを compatibility mode で表示します。&lt;br /&gt;&lt;br /&gt;&lt;li&gt; &lt;font color=green&gt;android:smallestWidthLimitDp="&lt;span style="font-style:italic;"&gt;numDp&lt;/span&gt;"&lt;/font&gt; — 最小の smallestWidth を指定します。smallestWidth はアプリケーションが動作するようデザインされたサイズです。現在のスクリーンが指定した値より小さい場合、システムはアプリケーションがこのデバイスと非互換だと考えますが、インストールして実行することを防いだりはしません。&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;注意: 現状では、Android Market は上記の属性に基づいてフィルターしません。フィルタリングのサポートは後の platform リリースで追加される予定です。スクリーンサイズに基づいたフィルタリングが必要なアプリケーションは既存の &lt;font color=green&gt;&amp;lt;supports-screens&amp;gt;&lt;/font&gt; 属性を使うことができます。&lt;br /&gt;&lt;br /&gt;新しい属性をどのように使うかの完全な情報は &lt;a href="http://developer.android.com/guide/practices/screens_support.html#DeclaringScreenSizeSupport"&gt;Declaring screen size support&lt;/a&gt; を見てください。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Screen compatibility mode&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Android 3.2 から新しいスクリーン互換性モードが提供されるようになりました。このモードは、走っているなかでできるだけ大きいスクリーンをサポートしないことを明示的に宣言します。この新しい "zoom" モードはピクセルスケールです。つまり、アプリケーションを小さい画面領域に描画して、それを現在の画面を覆うようにピクセルをスケールします。&lt;br /&gt;&lt;br /&gt;デフォルトでは、システムはスクリーン互換性モードを必要としているアプリに対して、このモードをユーザーオプションとして提供します。ユーザーはシステムバーから利用可能なコントロールでズームモードのオンオフを切り替えることができます。&lt;br /&gt;&lt;br /&gt;新しいスクリーン互換性モードは全てのアプリケーションに対して適切ではないため、プラットフォームはアプリケーションがマニフェストファイルを使ってそれを無効にすることを許可しています。アプリによって無効にされた場合、システムはアプリが走っている間ユーザーに対して "zoom" 互換性モードをオプションとして提供しません。&lt;br /&gt;&lt;br /&gt;注意：どのように互換性モードをアプリケーションでコントロールするかの重要な情報については、Android Developer Blog の &lt;a href="http://android-developers.blogspot.com/2011/07/new-mode-for-apps-on-large-screens.html"&gt;New Mode for Apps on Large Screens&lt;/a&gt; 記事を参照してください。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;New screen density for 720p televisions and similar devices&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;720p のテレビや、それに似た解像度のデバイス上でアプリケーションを動かすために Android 3.2 から新しい一般的な解像度 &lt;font color=green&gt;tvdpi&lt;/font&gt; が追加されました。これはおよそ 213 dpi です。アプリケーションは新しい解像度を &lt;a href="http://developer.android.com/reference/android/util/DisplayMetrics.html#densityDpi"&gt;densityDpi&lt;/a&gt; で問い合わせることができ、また &lt;font color=green&gt;tvdpi&lt;/font&gt; 識別子をテレビや似たようなデバイス向けのタグとして使うことができます。&lt;br /&gt;例えば&lt;br /&gt;&lt;pre name="code" class="python"&gt;&lt;br /&gt;# Bitmap for tv density&lt;br /&gt;res/drawable-tvdpi/my_icon.png&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;一般的には、アプリケーションはこの解像度で動くことはありません。720p のスクリーンに出力する必要がある場合、UI エレメントは platform によって自動的にスケールされます。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;UI framework&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Fragments&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt; 新しい &lt;a href="http://developer.android.com/reference/android/app/Fragment.SavedState.html"&gt;Fragment.SavedState&lt;/a&gt; クラスが &lt;a href="http://developer.android.com/reference/android/app/FragmentManager.html#saveFragmentInstanceState(android.app.Fragment)"&gt;saveFragmentInstanceState()&lt;/a&gt; を通して Fragment のインスタンスから取得した状態情報を保持します。&lt;br /&gt;&lt;li&gt; 新しいメソッド &lt;a href="http://developer.android.com/reference/android/app/FragmentManager.html#saveFragmentInstanceState(android.app.Fragment)"&gt;saveFragmentInstanceState()&lt;/a&gt; が与えられた Fragment の現在のインスタンス状態を保存します。状態は、現在の状態と一致する Fragment の新しいインスタンスが後で生成されたときに使うことができます。&lt;br /&gt;&lt;li&gt; 新しいメソッド &lt;a href="http://developer.android.com/reference/android/app/Fragment.html#setInitialSavedState(android.app.Fragment.SavedState)"&gt;setInitialSavedState()&lt;/a&gt; が最初に生成された Fragment に対して初期の保存状態をセットします。&lt;br /&gt;&lt;li&gt; 新しい &lt;a href="http://developer.android.com/reference/android/app/Fragment.html#onViewCreated(android.view.View, android.os.Bundle)"&gt;onViewCreated()&lt;/a&gt; コールバックメソッド では、&lt;a href="http://developer.android.com/reference/android/app/Fragment.html#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle)"&gt;onCreateView()&lt;/a&gt; が返されたことを Fragment に知らせますが、以前の保存状態はその View に再保存されています。&lt;br /&gt;&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/app/Fragment.html#isDetached()"&gt;isDetached()&lt;/a&gt; メソッドは Fragment が明示的に UI から切り離されているかどうかを決定します。&lt;br /&gt;&lt;li&gt; 新しい &lt;a href="http://developer.android.com/reference/android/app/FragmentTransaction.html#attach(android.app.Fragment)"&gt;attach()&lt;/a&gt; と &lt;a href="http://developer.android.com/reference/android/app/FragmentTransaction.html#detach(android.app.Fragment)"&gt;detach()&lt;/a&gt; メソッドによってアプリケーションは UI に Fragment を再取り付け、取り離しすることができます。&lt;br /&gt;&lt;li&gt; 新しい &lt;a href="http://developer.android.com/reference/android/app/FragmentTransaction.html#setCustomAnimations(int, int, int, int)"&gt;setCustomAnimations()&lt;/a&gt; オーバーロードメソッドによって、指定したアニメーションリソースをエンター／イグジット操作およびバックスタックをポップするときの操作で走るよう指定できます。既存の実装はバックスタックをポップするときの Fragment のデフォルトの振る舞いには寄与しません。&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;li&gt;Screen size information in ActivityInfo and ApplicationInfo&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/R.attr.html#configChanges"&gt;configChanges&lt;/a&gt; のビットマスクとして新しく &lt;a href="http://developer.android.com/reference/android/content/pm/ActivityInfo.html#CONFIG_SCREEN_SIZE"&gt;CONFIG_SCREEN_SIZE&lt;/a&gt; と &lt;a href="http://developer.android.com/reference/android/content/pm/ActivityInfo.html#CONFIG_SMALLEST_SCREEN_SIZE"&gt;CONFIG_SMALLEST_SCREEN_SIZE&lt;/a&gt; が &lt;a href="http://developer.android.com/reference/android/content/pm/ActivityInfo.html"&gt;ActivityInfo&lt;/a&gt; に追加されました。ビットは Activity 自身が画面サイズと最小画面サイズをハンドルするかどうかを意味します。&lt;br /&gt;&lt;li&gt;アプリケーションマニフェストファイルの &lt;font color=green&gt;&amp;lt;supports-screens&amp;gt;&lt;/font&gt; 属性に対応する &lt;a href="http://developer.android.com/reference/android/content/pm/ApplicationInfo.html#largestWidthLimitDp"&gt;largestWidthLimitDp&lt;/a&gt;, &lt;a href="http://developer.android.com/reference/android/content/pm/ApplicationInfo.html#compatibleWidthLimitDp"&gt;compatibleWidthLimitDp&lt;/a&gt;, &lt;a href="http://developer.android.com/reference/android/content/pm/ApplicationInfo.html#requiresSmallestWidthDp"&gt;requiresSmallestWidthLimitDp&lt;/a&gt; が &lt;a href="http://developer.android.com/reference/android/content/pm/ApplicationInfo.html"&gt;ApplicationInfo&lt;/a&gt; のフィールドとして追加されました。&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;li&gt;WindowManager から画面サイズを取得するためのヘルパー&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;新しいメソッド &lt;a href="http://developer.android.com/reference/android/view/Display.html#getSize(android.graphics.Point)"&gt;getSize()&lt;/a&gt; と &lt;a href="http://developer.android.com/reference/android/view/Display.html#getRectSize(android.graphics.Rect)"&gt;getRectSize()&lt;/a&gt; によってアプリケーションは画面の生のサイズを取得できるようになりました。&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;li&gt;新しい公開 "holographic" スタイル&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt; text, actionbar widgets, tabs などに対する多くの公開 "holographic" スタイル提供されるようになりました。完全なリストは &lt;a href="http://developer.android.com/reference/android/R.style.html"&gt;R.style&lt;/a&gt; を見てください。&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://developer.android.com/reference/android/app/LocalActivityManager.html"&gt;LocalActivityManager&lt;/a&gt;, &lt;a href="http://developer.android.com/reference/android/app/ActivityGroup.html"&gt;ActivityGroup&lt;/a&gt;, &lt;a href="http://developer.android.com/reference/android/app/LocalActivityManager.html"&gt;LocalActivityManager&lt;/a&gt; が deprecated になりました。&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt; 新しいアプリケーションはこれらのクラスの代わりに Fragment を使ってください。古いバージョンのプラットフォームでも動くようにするために、Android SDK で利用できる v4 Support Library (compatibility library) を使うことができます。v4 Support Library は Android 1.6 (API level 4) まで互換性のある Fragment API のバージョンを提供します。&lt;br /&gt;&lt;li&gt; Android 3.0 (API level 11) 以上に対して開発しているアプリでは、タブをアクションバー領域に置くための新しい &lt;a href="http://developer.android.com/reference/android/app/ActionBar.html#newTab()"&gt;ActionBar.newTab()&lt;/a&gt; や関連する API を使って、典型的にはタブをアクションバー内に表示させます。&lt;br /&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Media framework&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt; platform のメディアプロバイダー(MediaStore)を使うアプリケーションはデバイスによってサポートされている取り外しできる SD カードから直接メディアデータを読むことができるようになりました。また、MTP API を使って直接 SD カードのファイルとやりとりすることもできるようになりました。&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Graphics&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt; Parcelable utilities in Point and PointF&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/graphics/Point.html"&gt;Point&lt;/a&gt; と &lt;a href="http://developer.android.com/reference/android/graphics/PointF.html"&gt;PointF&lt;/a&gt; クラスが &lt;a href="http://developer.android.com/reference/android/os/Parcelable.html"&gt;Parcelable&lt;/a&gt; インタフェースとユーティリティメソッドの &lt;a href="http://developer.android.com/reference/android/graphics/Point.html#describeContents()"&gt;describeContents()&lt;/a&gt;, &lt;a href="http://developer.android.com/reference/android/graphics/Point.html#readFromParcel(android.os.Parcel)"&gt;readFromParcel()&lt;/a&gt;, &lt;a href="http://developer.android.com/reference/android/graphics/Point.html#writeToParcel(android.os.Parcel, int)"&gt;writeToParcel()&lt;/a&gt; を含むようになりました。&lt;br /&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;IME framework&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt; 修飾キーの現在の状態を取得するための新しいメソッド &lt;a href="http://developer.android.com/reference/android/view/KeyEvent.html#getModifiers()"&gt;getModifiers()&lt;/a&gt; が追加されました。&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;USB framework&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;デバイスの生の USB デスクリプタを取得するために新しく &lt;a href="http://developer.android.com/reference/android/hardware/usb/UsbDeviceConnection.html#getRawDescriptors()"&gt;getRawDescriptors()&lt;/a&gt; メソッドが追加されました。ハイレベルの API 介したアクセスがサポートされていないデスクリプタにこのメソッドを使ってアクセスできます。&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Network&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt; Network type constants&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/net/ConnectivityManager.html"&gt;ConnectivityManager&lt;/a&gt; に定数 &lt;a href="http://developer.android.com/reference/android/net/ConnectivityManager.html#TYPE_ETHERNET"&gt;TYPE_ETHERNET&lt;/a&gt; と &lt;a href="http://developer.android.com/reference/android/net/ConnectivityManager.html#TYPE_BLUETOOTH"&gt;TYPE_BLUETOOTH&lt;/a&gt; が追加されました。&lt;br /&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Telephony&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt; 新しい &lt;a href="http://developer.android.com/reference/android/telephony/TelephonyManager.html#NETWORK_TYPE_HSPAP"&gt;NETWORK_TYPE_HSPAP&lt;/a&gt; ネットワークタイプ定数が追加されました。&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Core utilities&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt; Parcelable utilities&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt; 新しいインタフェース &lt;a href="http://developer.android.com/reference/android/os/Parcelable.ClassLoaderCreator.html"&gt;Parcelable.ClassLoaderCreator&lt;/a&gt; によって、アプリケーションは、オブジェクトが生成される ClassLoader を受け取ることができます。&lt;br /&gt;&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/os/ParcelFileDescriptor.html"&gt;ParcelFileDescriptor&lt;/a&gt; オブジェクトを管理するために新しく &lt;a href="http://developer.android.com/reference/android/os/ParcelFileDescriptor.html#adoptFd(int)"&gt;adoptFd&lt;/a&gt;, &lt;a href="http://developer.android.com/reference/android/os/ParcelFileDescriptor.html#dup(java.io.FileDescriptor)"&gt;dup()&lt;/a&gt;, &lt;a href="http://developer.android.com/reference/android/os/ParcelFileDescriptor.html#fromFd(int)"&gt;fromFd()&lt;/a&gt; が追加されました。&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;li&gt;Binder and IBinder&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt; &lt;a href="http://developer.android.com/reference/android/os/Binder.html"&gt;Binder&lt;/a&gt; と &lt;a href="http://developer.android.com/reference/android/os/IBinder.html"&gt;IBinder&lt;/a&gt; の新しいメソッド &lt;a href="http://developer.android.com/reference/android/os/Binder.html#dumpAsync(java.io.FileDescriptor, java.lang.String[])"&gt;dumpAsync()&lt;/a&gt; によって、アプリケーションは指定されたファイルへのダンプを非同期に実行することができます。&lt;br /&gt;&lt;li&gt; 新しい &lt;a href="http://developer.android.com/reference/android/os/IBinder.html"&gt;IBinder&lt;/a&gt; プロトコルトランザクションコード &lt;a href="http://developer.android.com/reference/android/os/IBinder.html#TWEET_TRANSACTION"&gt;TWEET_TRANSACTION&lt;/a&gt; によってアプリケーションはターゲットオブジェクトにツイートを送ることができます。&lt;br /&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;New feature constants&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Android マニフェストで宣言できるハードウェア機能の定数が追加されました。これを宣言することで Android Market のような外部のエンティティに、必要なハードウェア・ソフトウェアの機能を知らせることができます。これらと他の機能定数は &lt;a href="http://developer.android.com/guide/topics/manifest/uses-feature-element.html"&gt;&amp;lt;uses-feature&amp;gt;&lt;/a&gt; マニフェストエレメントに宣言します。&lt;br /&gt;&lt;br /&gt;Android Market はこれら &lt;font color=green&gt;&amp;lt;uses-feature&amp;gt;&lt;/font&gt; 属性に基づいてアプリケーションをフィルターします。これにより、必要条件を満たしたデバイスでのみ利用可能にすることができます。&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt; landspace (横向き), portrait (縦向き) が必要条件の場合の機能定数&lt;br /&gt;Android 3.2 でアプリケーションが横向き、縦向き、もしくは両方の画面向きを必要としているかを指定できる機能定数が増えました。これらの定数を宣言することは、アプリケーションが求める画面向きに対応しないデバイスにはインストールされないことを意味します。逆に、1つもしくは両方の定数が宣言されていないのであれば、宣言されていない向きに対する設定をアプリケーションが持っていないことを意味し、それらを提供しないデバイスにもインストールされます。&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://developer.android.com/reference/android/content/pm/PackageManager.html#FEATURE_SCREEN_LANDSCAPE"&gt;android.hardware.screen.landscape&lt;/a&gt; — アプリケーションは横向きの画面を必要とする&lt;br /&gt;&lt;li&gt;&lt;a href="http://developer.android.com/reference/android/content/pm/PackageManager.html#FEATURE_SCREEN_PORTRAIT"&gt;android.hardware.screen.landscape&lt;/a&gt; — アプリケーションは縦向きの画面を必要とする&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;横と縦両方の向きに対して適切に動く典型的なアプリケーションでは通常は画面向きの必要条件を宣言する必要はありません。テレビ向けにデザインされているような1つの向きにだけ主にデザインされているアプリケーションでは、その向きを提供していないデバイスで利用できないようにするために定数のいずれかを宣言することができます。&lt;br /&gt;もしアプリケーションが API Level 12 以下をターゲットとしている場合、プラットフォームは portrait, landscape いずれかを必要と指定していなければ、両方の向きが必要とされていると仮定します。&lt;br /&gt;&lt;br /&gt;&lt;li&gt;Other feature constants&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://developer.android.com/reference/android/content/pm/PackageManager.html#FEATURE_FAKETOUCH_MULTITOUCH_DISTINCT"&gt;android.hardware.faketouch.multitouch.distinct&lt;/a&gt; — アプリケーションは2つ以上のポイントを別々にトラッキングできるエミュレートされたマルチタッチ入力のサポートを必要とする&lt;br /&gt;&lt;li&gt;&lt;a href="http://developer.android.com/reference/android/content/pm/PackageManager.html#FEATURE_FAKETOUCH_MULTITOUCH_JAZZHAND"&gt;android.hardware.faketouch.multitouch.jazzhand&lt;/a&gt; — アプリケーションは5つ以上のポイントを別々にトラッキングできるエミュレートされたマルチタッチ入力のサポートを必要とする&lt;br /&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;API Differences Report&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Android 3.2(API Level 13) の全ての API 変更の詳細については、&lt;a href="http://developer.android.com/sdk/api_diff/13/changes.html"&gt;API Differences Report&lt;/a&gt; を見てください。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;---&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;API Level&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Android 3.2 platform は framework API のアップデートバージョンとして提供されます。Android 3.2 API には整数値の識別子 - &lt;span style="font-weight:bold;"&gt;13&lt;/span&gt; - が割り当てられ、システム自身に保存されます。この識別子は "API Level" と呼ばれ、アプリケーションをインストールする前に、そのアプリケーションがシステムと互換性があるかどうかシステムが正しく決定するために利用されます。&lt;br /&gt;&lt;br /&gt;Android 3.2 で紹介された API をあなたのアプリケーションで使用するには、Android 3.2 SDK platform で提供されている　Android library に対してアプリケーションをコンパイルする必要があります。あなたの必要に応じて、アプリケーションのマニフェストの &lt;font color=green&gt;&amp;lt;uses-sdk&amp;gt;&lt;/font&gt; エレメントに &lt;font color=green&gt;android:minSdkVersion="13"&lt;/font&gt; 属性を追加する必要があるかもしれません。&lt;br /&gt;&lt;br /&gt;API Level を利用するためのより詳しい情報は、&lt;a href="http://developer.android.com/guide/appendix/api-levels.html"&gt;API Levels&lt;/a&gt; ドキュメントを見てください。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5859951453664122203-4549712092827408074?l=y-anz-m.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://y-anz-m.blogspot.com/feeds/4549712092827408074/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://y-anz-m.blogspot.com/2011/07/android-32-platform.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5859951453664122203/posts/default/4549712092827408074'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5859951453664122203/posts/default/4549712092827408074'/><link rel='alternate' type='text/html' href='http://y-anz-m.blogspot.com/2011/07/android-32-platform.html' title='Android 3.2 Platform'/><author><name>yanzm</name><uri>http://www.blogger.com/profile/04059587494895790858</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_HRaLqTNFL7w/TDx6XwqrmDI/AAAAAAAABMo/B1SkSHxhKu4/S220/icon4.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5859951453664122203.post-6979716880227645825</id><published>2011-07-26T09:34:00.004+09:00</published><updated>2011-07-26T09:43:38.676+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Android'/><title type='text'>Android　resource で integer を定義する</title><content type='html'>strings.xml で&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&lt;br /&gt;  &amp;lt;string name="one"&amp;gt;1&amp;lt;/string&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;と定義して&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;int one = Integer.parseInt(getString(R.string.one));&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;とかやっちゃダメですよ！&lt;br /&gt;コードみせたら笑われry&lt;br /&gt;&lt;br /&gt;ちゃんと integer で定義してくださいまし。&lt;br /&gt;&lt;a href="http://developer.android.com/guide/topics/resources/more-resources.html#Integer"&gt;More Resource Types | Android Developers&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;res/values/hoge.xml の &amp;lt;resources&amp;gt; の中に&lt;br /&gt;こうですよ！&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&lt;br /&gt;  &amp;lt;integer name="one"&amp;gt;1&amp;lt;/integer&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;と定義して&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;int one = getResources().getInteger(R.integer.one);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;　&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5859951453664122203-6979716880227645825?l=y-anz-m.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://y-anz-m.blogspot.com/feeds/6979716880227645825/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://y-anz-m.blogspot.com/2011/07/androidresrouce-integer.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5859951453664122203/posts/default/6979716880227645825'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5859951453664122203/posts/default/6979716880227645825'/><link rel='alternate' type='text/html' href='http://y-anz-m.blogspot.com/2011/07/androidresrouce-integer.html' title='Android　resource で integer を定義する'/><author><name>yanzm</name><uri>http://www.blogger.com/profile/04059587494895790858</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_HRaLqTNFL7w/TDx6XwqrmDI/AAAAAAAABMo/B1SkSHxhKu4/S220/icon4.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5859951453664122203.post-8337468838751579470</id><published>2011-07-12T01:09:00.005+09:00</published><updated>2011-07-12T01:17:45.546+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Android'/><title type='text'>Android　AppWidget の PendingIntent で putExtra するときの注意</title><content type='html'>AppWidget 上のボタンをタップしたときに編集画面を開いたりする場合、RemoteViews を使った次のようなコードがよく紹介されています。&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;RemoteViews remoteView = new RemoteViews(context.getPackageName(), R.layout.appwidget);&lt;br /&gt;Intent intent = new Intent(context, WidgetConfigure.class);&lt;br /&gt;&lt;br /&gt;PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);&lt;br /&gt;// or&lt;br /&gt;// PendingIntent pendingIntent = PendingIntent.getService(context, 0, intent, 0);&lt;br /&gt;// or&lt;br /&gt;// PendingIntent pendingIntent = PendingIntent.Broadcast(context, 0, intent, 0);&lt;br /&gt;&lt;br /&gt;remoteView.setOnClickPendingIntent(R.id.button, pendingIntent);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;画面に同じアプリのウィジェットが複数個ある場合、AppWidgetId を Intent の extras に詰めて渡したくなります。なるでしょう？&lt;br /&gt;&lt;br /&gt;そこで&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;Intent intent = new Intent(context, WidgetConfigure.class);&lt;br /&gt;intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);&lt;br /&gt;PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent,0);  &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;とやるとうまくいきません。画面にウィジェットが複数ある場合、どれをタップしてもどれか1つのボタンが押された挙動になってしまいます。&lt;br /&gt;&lt;br /&gt;正しく動かすには、こう&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;PendingIntent pendingIntent = PendingIntent.getActivity(context, appWidgetId, intent, 0);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;---&lt;br /&gt;注意：&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;PendingIntent pendingIntent = PendingIntent.getActivity(context, appWidgetId, intent, PendingIntent.FLAG_UPDATE_CURRENT);&lt;br /&gt;// or&lt;br /&gt;PendingIntent pendingIntent = PendingIntent.getActivity(context, appWidgetId, intent, PendingIntent.FLAG_CANCEL_CURRENT);  &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;でも動きますが、今回の目的では第4引数フラグを指定する必要はありません。&lt;br /&gt;詳しくはこの後で説明します。&lt;br /&gt;---&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;PeindingIntent の getActivity() (getService(), getBroadcast() も同じ) の第2引数に AppWidget の ID （同じアプリの各 AppWidget で一意になるならなんでもよい）を指定します！&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;ちょっと、ちゃんと &lt;a href="http://developer.android.com/reference/android/app/PendingIntent.html"&gt;PendingIntent&lt;/a&gt; の説明を読んでみましょう。&lt;br /&gt;&lt;br /&gt;---&lt;br /&gt;A description of an Intent and target action to perform with it. Instances of this class are created with getActivity(Context, int, Intent, int), getBroadcast(Context, int, Intent, int), getService(Context, int, Intent, int); the returned object can be handed to other applications so that they can perform the action you described on your behalf at a later time.&lt;br /&gt;&lt;br /&gt;By giving a PendingIntent to another application, you are granting it the right to perform the operation you have specified as if the other application was yourself (with the same permissions and identity). As such, you should be careful about how you build the PendingIntent: often, for example, the base Intent you supply will have the component name explicitly set to one of your own components, to ensure it is ultimately sent there and nowhere else.&lt;br /&gt;&lt;br /&gt;A PendingIntent itself is simply a reference to a token maintained by the system describing the original data used to retrieve it. This means that, even if its owning application's process is killed, the PendingIntent itself will remain usable from other processes that have been given it. If the creating application later re-retrieves the same kind of PendingIntent (same operation, same Intent action, data, categories, and components, and same flags), it will receive a PendingIntent representing the same token if that is still valid, and can thus call cancel() to remove it.&lt;br /&gt;---&lt;br /&gt;&lt;br /&gt;Intent と、その Intent を実行したい Action の記述。このクラスのインスタンスは &lt;a href="http://developer.android.com/reference/android/app/PendingIntent.html#getActivity(android.content.Context, int, android.content.Intent, int)"&gt;getActivity(Context, int, Intent, int)&lt;/a&gt;, &lt;a href="http://developer.android.com/reference/android/app/PendingIntent.html#getBroadcast(android.content.Context, int, android.content.Intent, int)"&gt;getBroadcast(Context, int, Intent, int)&lt;/a&gt;, &lt;a href="http://developer.android.com/reference/android/app/PendingIntent.html#getService(android.content.Context, int, android.content.Intent, int)"&gt;getService(Context, int, Intent, int)&lt;/a&gt;; で生成されます。後で他のアプリケーションが記述されたアクションを実行できるように、これらのメソッドで返されるオブジェクトは他のアプケーションに受け渡すことができます。&lt;br /&gt;&lt;br /&gt;PendingIntent を他のアプリケーションに渡すことで、他のアプリケーションが自分自身であるかのように（同じパーミッションとIDで）指定した操作を実行する権限を付与します。&lt;br /&gt;このようなことから、PendingIntent をどのように作成するのかについて注意するべきです。よく起こることで、例えば、あなたが渡す base Intent が他のところではなく最終的にそこに届けられることを確認するために、あなた自身のコンポーネントの1つとして明示的に設定された component name を持つようにしてください。&lt;br /&gt;&lt;br /&gt;PendingIntent 自身は、単にシステムによって管理されるトークンへのリファレンスです。これは、PendingIntent を受信するために使用されるオリジナルデータを記述しています。&lt;br /&gt;これはつまり、自身のアプリケーションプロセスが殺されても、PendingIntent 自身は他のプロセス（すでに受け取っている）から使用可能な状態のまま残ることを意味しています。もし作成したアプリケーションがあとで同じ種類の PendingIntent を再取得した場合（同じ操作、同じアクション、データ、カテゴリ、コンポーネント、フラグ）、同じトークンがまだ有効な場合、その同じトークンを代表する PendingIntent を受信します。したがって、&lt;a href="http://developer.android.com/reference/android/app/PendingIntent.html#cancel()"&gt;cancel()&lt;/a&gt; を呼んでそれを削除することができます。&lt;br /&gt;&lt;br /&gt;---&lt;br /&gt;&lt;br /&gt;ふむふむ。&lt;br /&gt;&lt;br /&gt;---&lt;br /&gt;&lt;br /&gt;&lt;a href="http://developer.android.com/reference/android/app/PendingIntent.html#getActivity(android.content.Context, int, android.content.Intent, int)"&gt;public static PendingIntent getActivity (Context context, int requestCode, Intent intent, int flags)&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Since: API Level 1&lt;br /&gt;&lt;a href="http://developer.android.com/reference/android/content/Context.html#startActivity(android.content.Intent)"&gt;Context.startActivity(Intent)&lt;/a&gt; を呼ぶように、新しい Activity を開始する PendingIntent を取得する。既存の activity の context の外で新しい activity が開始されるので、Intent に &lt;a href="http://developer.android.com/reference/android/content/Intent.html#FLAG_ACTIVITY_NEW_TASK"&gt;Intent.FLAG_ACTIVITY_NEW_TASK&lt;/a&gt; launch flag を使わなければならない。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Parameters&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;context&lt;/span&gt; : この PendingIntent が activity を開始する context&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;requestCode&lt;/span&gt; : sender 用のプライベートな request code&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;intent&lt;/span&gt; : 起動される Activity の Intent&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;flags&lt;/span&gt; : &lt;a href="http://developer.android.com/reference/android/app/PendingIntent.html#FLAG_ONE_SHOT"&gt;FLAG_ONE_SHOT&lt;/a&gt;, &lt;a href="http://developer.android.com/reference/android/app/PendingIntent.html#FLAG_NO_CREATE"&gt;FLAG_NO_CREATE&lt;/a&gt;, &lt;a href="http://developer.android.com/reference/android/app/PendingIntent.html#FLAG_CANCEL_CURRENT"&gt;FLAG_CANCEL_CURRENT&lt;/a&gt;, &lt;a href="http://developer.android.com/reference/android/app/PendingIntent.html#FLAG_UPDATE_CURRENT"&gt;FLAG_UPDATE_CURRENT&lt;/a&gt; のいずれか。もしくは &lt;a href="http://developer.android.com/reference/android/content/Intent.html#fillIn(android.content.Intent, int)"&gt;Intent.fillIn()&lt;/a&gt; でサポートされる全てのフラグ。intent の指定されてない部分のコントロール用。実際の送信が起こったときに intent に適用される。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Returns&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;与えられたパラメータにマッチする既存の、もしくは新しい PendingIntent を返す。&lt;a href="http://developer.android.com/reference/android/app/PendingIntent.html#FLAG_NO_CREATE"&gt;FLAG_NO_CREATE&lt;/a&gt; が与えられたときのみ null が返る場合がある。&lt;br /&gt;&lt;br /&gt;---&lt;br /&gt;&lt;br /&gt;ふむふむふむ。&lt;br /&gt;flags に指定する。FLAG_ONE_SHOT, FLAG_NO_CREATE, FLAG_CANCEL_CURRENT, FLAG_UPDATE_CURRENT の説明も見てみるか。&lt;br /&gt;&lt;br /&gt;---&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Constants&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;public static final int FLAG_CANCEL_CURRENT&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Since: API Level 1&lt;br /&gt;getActivity(Context, int, Intent, int), getBroadcast(Context, int, Intent, int),　getService(Context, int, Intent, int) 用のフラグ : 記述された PendingIntent がすでに存在していた場合、新しいのが生成される前に現在のはキャンセルされる。Intent の extra data だけを変更する場合に新しい PendingIntent を取得するのに使える。以前の pending intent をキャンセルすることによって、新しいデータを与えられた実体だけが起動できることを保証する。この保証が問題はない場合、FLAG_UPDATE_CURRENT を検証する。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;public static final int FLAG_NO_CREATE&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Since: API Level 1&lt;br /&gt;getActivity(Context, int, Intent, int), getBroadcast(Context, int, Intent, int),　getService(Context, int, Intent, int) 用のフラグ : 記述された PendingIntent がまだ存在していない場合、生成せずに単に null を返す。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;public static final int FLAG_ONE_SHOT&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Since: API Level 1&lt;br /&gt;getActivity(Context, int, Intent, int), getBroadcast(Context, int, Intent, int),　getService(Context, int, Intent, int) 用のフラグ : この PendingIntent は1度だけ使える。このフラグがセットされた場合、send() が呼ばれた後に試みた send は自動的にキャンセルされる。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;public static final int FLAG_UPDATE_CURRENT&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Since: API Level 3&lt;br /&gt;getActivity(Context, int, Intent, int), getBroadcast(Context, int, Intent, int),　getService(Context, int, Intent, int) 用のフラグ : 記述された PendingIntent がすでに存在している場合、それをキープして extra data を新しい Intent のものに置き換える。extras だけを変えた intent を作成し、以前の PendingIntent が受け取った実体が、明示的に与えなくても新しい extras で起動できるのを気にしない場合に使える。&lt;br /&gt;&lt;br /&gt;---&lt;br /&gt;&lt;br /&gt;FLAG_UPDATE_CURRENT で問題ない場合は、こっちを考えてねって FLAG_CANCEL_CURRENT にあるので、FLAG_UPDATE_CURRENT の方がいいのかな？&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;第2引数についても検証してみた。&lt;br /&gt;リファレンスには&lt;br /&gt;&lt;br /&gt;---&lt;br /&gt;&lt;br /&gt;requestCode Private request code for the sender (currently not used).&lt;br /&gt;&lt;br /&gt;---&lt;br /&gt;&lt;br /&gt;(currently not used) = 現在は使っていない&lt;br /&gt;&lt;br /&gt;って書いてあるけど、どうもそうではないみたい。&lt;br /&gt;&lt;br /&gt;例えば、同じ AppWidget を画面に2個配置して、それぞれに&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;Intent intent = new Intent(context, WidgetConfigure.class);&lt;br /&gt;intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);&lt;br /&gt;PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);  &lt;br /&gt;views.setOnClickPendingIntent(R.id.widgetbase, pendingIntent);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;を指定すると、先に追加した方の PendingIntent はキャンセルされるので、先に張り付けた AppWidget のボタンをタップしても反応しなくなります（PedingIntent が実行されなくなる）。&lt;br /&gt;&lt;br /&gt;これは、extras 以外が同じ PendingIntent なので、以前のがキャンセルされるからです。&lt;br /&gt;これを&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;Intent intent = new Intent(context, WidgetConfigure.class);&lt;br /&gt;intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);&lt;br /&gt;PendingIntent pendingIntent = PendingIntent.getActivity(context, appWidgetId, intent, PendingIntent.FLAG_CANCEL_CURRENT);  &lt;br /&gt;views.setOnClickPendingIntent(R.id.widgetbase, pendingIntent);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;にすると、先に張り付けた AppWidget のボタンもちゃんと反応します。&lt;br /&gt;extras 以外に appWidgetId も違うので、同じ PendingIntent だと判定されないのでキャンセルされないからです。&lt;br /&gt;&lt;br /&gt;FLAG_UPDATE_CURRENT も同じことです。&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;Intent intent = new Intent(context, WidgetConfigure.class);&lt;br /&gt;intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);&lt;br /&gt;PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);  &lt;br /&gt;views.setOnClickPendingIntent(R.id.widgetbase, pendingIntent);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;を指定すると、先に追加した方の PendingIntent はキャンセルされないので起動できますが、新しい Extras が適用されてしまう（FLAG_UPDATE_CURRENT のところに説明されている通り) ので、どの AppWidget でも同じ Extras の Activity が起動されることになります。&lt;br /&gt;&lt;br /&gt;これを&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;Intent intent = new Intent(context, WidgetConfigure.class);&lt;br /&gt;intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);&lt;br /&gt;PendingIntent pendingIntent = PendingIntent.getActivity(context, appWidgetId, intent, PendingIntent.FLAG_UPDATE_CURRENT);  &lt;br /&gt;views.setOnClickPendingIntent(R.id.widgetbase, pendingIntent);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;にすれば、同じ PendingIntent と判定されないので、以前の Extras が新しいのに置き換わることはなくなります。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;。。。あれれ、結局第2引数で同じ PendingIntent と判定されないようにするなら、第4引数いらなくね？&lt;br /&gt;&lt;br /&gt;てことで、&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;Intent intent = new Intent(context, WidgetConfigure.class);&lt;br /&gt;intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);&lt;br /&gt;PendingIntent pendingIntent = PendingIntent.getActivity(context, appWidgetId, intent, 0);  &lt;br /&gt;views.setOnClickPendingIntent(R.id.widgetbase, pendingIntent);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;でいいじゃん！ちゃんと意図した通り動きました。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;ちなみに、コードをちょっと追ってみました。&lt;br /&gt;&lt;br /&gt;PendingIntent.java#189&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;    189     public static PendingIntent getActivity(Context context, int requestCode,&lt;br /&gt;    190             Intent intent, int flags) {&lt;br /&gt;    191         String packageName = context.getPackageName();&lt;br /&gt;    192         String resolvedType = intent != null ? intent.resolveTypeIfNeeded(&lt;br /&gt;    193                 context.getContentResolver()) : null;&lt;br /&gt;    194         try {&lt;br /&gt;    195             IIntentSender target =&lt;br /&gt;    196                 ActivityManagerNative.getDefault().getIntentSender(&lt;br /&gt;    197                     IActivityManager.INTENT_SENDER_ACTIVITY, packageName,&lt;br /&gt;    198                     null, null, requestCode, intent, resolvedType, flags);&lt;br /&gt;    199             return target != null ? new PendingIntent(target) : null;&lt;br /&gt;    200         } catch (RemoteException e) {&lt;br /&gt;    201         }&lt;br /&gt;    202         return null;&lt;br /&gt;    203     }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;ActivityManagerNative.java#2233&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;   2233     public IIntentSender getIntentSender(int type,&lt;br /&gt;   2234             String packageName, IBinder token, String resultWho,&lt;br /&gt;   2235             int requestCode, Intent intent, String resolvedType, int flags)&lt;br /&gt;   2236             throws RemoteException {&lt;br /&gt;   2237         Parcel data = Parcel.obtain();&lt;br /&gt;   2238         Parcel reply = Parcel.obtain();&lt;br /&gt;   2239         data.writeInterfaceToken(IActivityManager.descriptor);&lt;br /&gt;   2240         data.writeInt(type);&lt;br /&gt;   2241         data.writeString(packageName);&lt;br /&gt;   2242         data.writeStrongBinder(token);&lt;br /&gt;   2243         data.writeString(resultWho);&lt;br /&gt;   2244         data.writeInt(requestCode);&lt;br /&gt;   2245         if (intent != null) {&lt;br /&gt;   2246             data.writeInt(1);&lt;br /&gt;   2247             intent.writeToParcel(data, 0);&lt;br /&gt;   2248         } else {&lt;br /&gt;   2249             data.writeInt(0);&lt;br /&gt;   2250         }&lt;br /&gt;   2251         data.writeString(resolvedType);&lt;br /&gt;   2252         data.writeInt(flags);&lt;br /&gt;   2253         mRemote.transact(GET_INTENT_SENDER_TRANSACTION, data, reply, 0);&lt;br /&gt;   2254         reply.readException();&lt;br /&gt;   2255         IIntentSender res = IIntentSender.Stub.asInterface(&lt;br /&gt;   2256             reply.readStrongBinder());&lt;br /&gt;   2257         data.recycle();&lt;br /&gt;   2258         reply.recycle();&lt;br /&gt;   2259         return res;&lt;br /&gt;   2260     }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;requestCode もちゃんと Parcel に入れられてます = 使ってるじゃん！&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;   2244         data.writeInt(requestCode);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;　　　&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5859951453664122203-8337468838751579470?l=y-anz-m.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://y-anz-m.blogspot.com/feeds/8337468838751579470/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://y-anz-m.blogspot.com/2011/07/androidappwidget-pendingintent-putextra.html#comment-form' title='1 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5859951453664122203/posts/default/8337468838751579470'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5859951453664122203/posts/default/8337468838751579470'/><link rel='alternate' type='text/html' href='http://y-anz-m.blogspot.com/2011/07/androidappwidget-pendingintent-putextra.html' title='Android　AppWidget の PendingIntent で putExtra するときの注意'/><author><name>yanzm</name><uri>http://www.blogger.com/profile/04059587494895790858</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_HRaLqTNFL7w/TDx6XwqrmDI/AAAAAAAABMo/B1SkSHxhKu4/S220/icon4.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5859951453664122203.post-5110760630988068873</id><published>2011-07-06T09:38:00.011+09:00</published><updated>2011-07-06T21:43:13.244+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Android'/><title type='text'>Android　In-app Billing Overview</title><content type='html'>&lt;span style="font-weight:bold;"&gt;In-app Billing Architecture&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt; 請求リクエストと請求レスポンスのやりとりを非同期メッセージループを使って、アプリと Android Market サーバ間で行う&lt;br /&gt;&lt;li&gt; 実際にはアプリは Android Market サーバと直接やりとりすることはない&lt;br /&gt;&lt;li&gt; アプリは請求リクエストを Android Market application に interprocess communication (IPC) を介して送り、Android Market application から購入レスポンスを非同期の broadcast intent として受け取る&lt;br /&gt;&lt;li&gt; コンテンツを配送したり、トランザクションを検証するためのプライベートなリモートサーバを使うアプリ内課金の実装もあるが、in-app billing の実装にリモートサーバは必須ではない&lt;br /&gt;&lt;li&gt; メディアファイルや写真等をユーザーのデーバイスに配送する必要があるデジタルコンテンツを売る場合、リモートサーバーは役に立つ&lt;br /&gt;&lt;li&gt; ユーザーのトランザクション履歴を保存したり、署名検証などのアプリ内課金用セキュリティタスクを実行するためにリモートサーバを使うこともある&lt;br /&gt;&lt;li&gt; セキュリティに関連した全てのタスクをアプリ内で処理することも可能だが、セキュリティアタックへの脆弱性を減らすためにこれらのタスクをリモートサーバで行うことが推奨される&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;典型的な in-app billing の実装は3つのコンポーネントに依存している&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt; &lt;span style="font-weight:bold;"&gt;Service&lt;/span&gt; &lt;br /&gt;(サンプルアプリでは &lt;font color=green&gt;BillingService&lt;/font&gt; という名前)&lt;br /&gt;アプリからの購入メッセージを処理し、Android Market の in-app billing service に請求リクエストを送る&lt;br /&gt;&lt;br /&gt;&lt;li&gt; &lt;span style="font-weight:bold;"&gt;BroadcastReceiver&lt;/span&gt;&lt;br /&gt;(サンプルアプリでは &lt;font color=green&gt;BillingReceiver&lt;/font&gt; という名前)&lt;br /&gt;Android Market application からの全ての非同期請求レスポンスを受け取る&lt;br /&gt;&lt;br /&gt;&lt;li&gt; &lt;span style="font-weight:bold;"&gt;セキュリティコンポーネント&lt;/span&gt;&lt;br /&gt;(サンプルアプリでは Security という名前)&lt;br /&gt;署名検証やワンタイムトークンの生成などセキュリティに関連したタスクを実行する&lt;br /&gt;in-app billing のセキュリティに関するより詳しい情報は &lt;a href="http://developer.android.com/guide/market/billing/billing_overview.html#billing-security"&gt;Security controls&lt;/a&gt; を参照する&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;必要に応じて in-app billing をサポートする以下のコンポーネントを組み込む&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt; &lt;span style="font-weight:bold;"&gt;response Handler&lt;/span&gt;&lt;br /&gt;(サンプルアプリでは &lt;font color=green&gt;ResponseHandler&lt;/font&gt; という名前)&lt;br /&gt;購入の通知、エラー、その他ステータスメッセージのアプリケーション固有の処理を提供する&lt;br /&gt;&lt;br /&gt;&lt;li&gt; &lt;span style="font-weight:bold;"&gt;observer&lt;/span&gt;&lt;br /&gt;(サンプルアプリでは &lt;font color=green&gt;PurchaseObserver&lt;/font&gt; という名前)&lt;br /&gt;アプリへのコールバック送信に責任をもち、これによりアプリは購入情報やステータスなどで、ユーザーのインタフェースをアップデートする&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;これらのコンポーネントに加えて&lt;br /&gt;・ユーザーの購入情報を保存する方法&lt;br /&gt;・ユーザーが購入アイテムを選択できるユーザーインタフェース&lt;br /&gt;を提供しなければならない&lt;br /&gt;&lt;br /&gt;アプリは checkout 用のユーザーインタフェースを用意する必要はない（Android Market application が提供する)&lt;br /&gt;ユーザーの checkout プロセスが完了したら、アプリが再開される&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="http://developer.android.com/images/billing_arch.png" width=400&gt;&lt;br /&gt;from &lt;a href="http://developer.android.com/guide/market/billing/billing_overview.html"&gt;http://developer.android.com/guide/market/billing/billing_overview.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;---&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;In-app Billing Messages&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt; ユーザーが購入を開始したら、アプリは Android Market の in-app billing service (&lt;font color=green&gt;MarketBillingService&lt;/font&gt; という名前) に単一の IPC メソッド呼び出しと使って請求メッセージを送る。&lt;br /&gt;&lt;li&gt; Android Market application は全ての請求リクエストに対して同期にレスポンスを返し、ステータス通知と他の情報をアプリに提供する&lt;br /&gt;&lt;li&gt; Android Market アプリはいくつかの請求リクエストに対して非同期でもレスポンスを返し、エラーメッセージと詳細なトランザクション情報をアプリに提供する&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;■ &lt;span style="font-weight:bold;"&gt;In-app billing requests&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt; アプリは &lt;font color=green&gt;MarketBillingService&lt;/font&gt; インタフェースで公開されている single IPC method (&lt;font color=green&gt;sendBillingRequest()&lt;/font&gt;) を呼び出すことで請求リクエストを送る&lt;br /&gt;&lt;li&gt; このインタフェースは &lt;a href="http://developer.android.com/guide/developing/tools/aidl.html"&gt;Android Interface Definition Language&lt;/a&gt; ファイル (&lt;font color=green&gt;IMarketBillingService.aidl&lt;/font&gt;) で定義されている&lt;br /&gt;&lt;li&gt; この AIDL ファイルは in-app billing のサンプルアプリと一緒に&lt;a href="http://developer.android.com/guide/market/billing/billing_integrate.html#billing-download"&gt;ダウンロード&lt;/a&gt;できる&lt;br /&gt;&lt;/ul&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt; &lt;font color=green&gt;sendBillingRequest()&lt;/font&gt; メソッドは引数として &lt;a href="http://developer.android.com/reference/android/os/Bundle.html"&gt;Bundle&lt;/a&gt; パラメータを一つ持つ&lt;br /&gt;&lt;li&gt; アプリが渡すこの Bundle には、リクエストのパラメータを指定するための、いくつかの key-value ペアが含まれていなければならない&lt;br /&gt;&lt;li&gt; リクエストで送る Bundle keys の詳細は &lt;a href="http://developer.android.com/guide/market/billing/billing_reference.html#billing-interface"&gt;In-app Billing Service Interface&lt;/a&gt; を参照する&lt;br /&gt;&lt;/ul&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt; 一番重要な key は各リクエスト Bundle で必須な &lt;font color=green&gt;BILLING_REQUEST&lt;/font&gt; key&lt;br /&gt;&lt;li&gt; この key で作成する請求リクエストのタイプを指定する&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;Android Market の in-app billing service は次の 5 タイプの請求リクエストをサポートしている：&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt; &lt;font color=green&gt;CHECK_BILLING_SUPPORTED&lt;/font&gt;&lt;br /&gt;Android Market application が in-app billing をサポートしているかどうか確かめるリクエスト&lt;br /&gt;アプリケーションの開始時にこのリクエストを送って in-app billing が利用できるときのみ UI を有効にするべき&lt;br /&gt;&lt;br /&gt;その他の必須な key-value pairs&lt;br /&gt;・API_VERSION : 1&lt;br /&gt;・PACKAGE_NAME : package name&lt;br /&gt;&lt;br /&gt;同期レスポンス Bundle のキー&lt;br /&gt;・RESPONSE_CODE&lt;br /&gt;&lt;br /&gt;RESPONSE_CODE の可能な値&lt;br /&gt;・RESULT_OK&lt;br /&gt;・RESULT_BILLING_UNAVAILABLE&lt;br /&gt;・RESULT_ERROR&lt;br /&gt;・RESULT_DEVELOPER_ERROR&lt;br /&gt;&lt;br /&gt;&lt;li&gt; &lt;font color=green&gt;REQUEST_PURCHASE&lt;/font&gt;&lt;br /&gt;Android Market application に購入メッセージを送るリクエスト&lt;br /&gt;in-app billing の基盤&lt;br /&gt;ユーザーがアプリのアイテムを購入したいことを示したときにこのリクエストを送る&lt;br /&gt;Android Market は checkout のユーザーインタフェースを表示して購入のトランザクションを処理する&lt;br /&gt;&lt;br /&gt;その他の必須な key-value pairs&lt;br /&gt;・API_VERSION : 1&lt;br /&gt;・PACKAGE_NAME : package name&lt;br /&gt;・ITEM_ID : 有効な製品（アイテム）の識別子&lt;br /&gt;&lt;br /&gt;同期レスポンス Bundle のキー&lt;br /&gt;・RESPONSE_CODE&lt;br /&gt;・PURCHASE_INTENT&lt;br /&gt;・REQUEST_ID&lt;br /&gt;&lt;br /&gt;RESPONSE_CODE の可能な値&lt;br /&gt;・RESULT_OK&lt;br /&gt;・RESULT_ERROR&lt;br /&gt;・RESULT_DEVELOPER_ERROR&lt;br /&gt;&lt;br /&gt;非同期レスポンス&lt;br /&gt;・IN_APP_NOTIFY（broadcast intent）&lt;br /&gt;　　　・a notification ID（データ）&lt;br /&gt;&lt;br /&gt;&lt;li&gt; &lt;font color=green&gt;GET_PURCHASE_INFORMATION&lt;/font&gt;&lt;br /&gt;購入状態の変化の詳細を取得するためのリクエスト&lt;br /&gt;リクエストした購入の支払いが成功した場合やユーザーが checkout 中にトランザクションをキャンセルした場合に購入の状態が変わる&lt;br /&gt;事前の購入がリファンドされたときにも購入状態が変わる&lt;br /&gt;購入状態が変更になったとき Android Market はアプリに通知するので、取得したいトランザクション情報がある場合だけこのリクエストを送ればいい&lt;br /&gt;&lt;br /&gt;その他の必須な key-value pairs&lt;br /&gt;・API_VERSION : 1&lt;br /&gt;・PACKAGE_NAME : package name&lt;br /&gt;・NONCE : 有効な &lt;font color=green&gt;long&lt;/font&gt; 値&lt;br /&gt;・NOTIFY_IDS : 有効な &lt;font color=green&gt;long&lt;/font&gt; 値の配列&lt;br /&gt;&lt;br /&gt;同期レスポンス Bundle のキー&lt;br /&gt;・RESPONSE_CODE&lt;br /&gt;・REQUEST_ID&lt;br /&gt;&lt;br /&gt;RESPONSE_CODE の可能な値&lt;br /&gt;・RESULT_OK&lt;br /&gt;・RESULT_ERROR&lt;br /&gt;・RESULT_DEVELOPER_ERROR&lt;br /&gt;&lt;br /&gt;非同期レスポンス&lt;br /&gt;・PURCHASE_STATE_CHANGED（broadcast intent）&lt;br /&gt;&lt;br /&gt;&lt;li&gt; &lt;font color=green&gt;CONFIRM_NOTIFICATIONS&lt;/font&gt;&lt;br /&gt;購入状態変更の詳細をアプリが取得したこと知らせるためのリクエスト&lt;br /&gt;Android Market はアプリが購入状態変更の通知を受け取ったことを確認するまで通知を送る&lt;br /&gt;&lt;br /&gt;その他の必須な key-value pairs&lt;br /&gt;・API_VERSION : 1&lt;br /&gt;・PACKAGE_NAME : package name&lt;br /&gt;・NOTIFY_IDS : 有効な &lt;font color=green&gt;long&lt;/font&gt; 値の配列&lt;br /&gt;&lt;br /&gt;同期レスポンス Bundle のキー&lt;br /&gt;・RESPONSE_CODE&lt;br /&gt;・REQUEST_ID&lt;br /&gt;&lt;br /&gt;RESPONSE_CODE の可能な値&lt;br /&gt;・RESULT_OK&lt;br /&gt;・RESULT_ERROR&lt;br /&gt;・RESULT_DEVELOPER_ERROR&lt;br /&gt;&lt;br /&gt;&lt;li&gt; &lt;font color=green&gt;RESTORE_TRANSACTIONS&lt;/font&gt;&lt;br /&gt;購入を管理する(managed purchases)ためのユーザーのトランザクションを取得するリクエスト&lt;br /&gt;ユーザーのトランザクション状態を取得する必要があるときだけこのリクエストを送る&lt;br /&gt;通常はアプリケーションがデバイスに最初にインストールされたときか、再インストールされたとき&lt;br /&gt;&lt;br /&gt;その他の必須な key-value pairs&lt;br /&gt;・API_VERSION : 1&lt;br /&gt;・PACKAGE_NAME : package name&lt;br /&gt;・NONCE : 有効な &lt;font color=green&gt;long&lt;/font&gt; 値&lt;br /&gt;&lt;br /&gt;同期レスポンス Bundle のキー&lt;br /&gt;・RESPONSE_CODE&lt;br /&gt;・REQUEST_ID&lt;br /&gt;&lt;br /&gt;RESPONSE_CODE の可能な値&lt;br /&gt;・RESULT_OK&lt;br /&gt;・RESULT_ERROR&lt;br /&gt;・RESULT_DEVELOPER_ERROR&lt;br /&gt;&lt;br /&gt;非同期レスポンス&lt;br /&gt;・RESPONSE_CODE（broadcast intent）&lt;br /&gt;・PURCHASE_STATE_CHANGED（broadcast intent）&lt;br /&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;---&lt;br /&gt;&lt;br /&gt;■ &lt;span style="font-weight:bold;"&gt;In-app Billing Responses&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Android Market application からの in-app billing リクエストに対するレスポンスには、同期・非同期両方のレスポンスがある&lt;br /&gt;同期的なレスポンスは &lt;a href="http://developer.android.com/reference/android/os/Bundle.html"&gt;Bundle&lt;/a&gt; で、次の 3 つのキーの値をもつ&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt; &lt;font color=green&gt;RESPONSE_CODE&lt;/font&gt;&lt;br /&gt;リクエストのステータス情報とエラー情報を提供するキー&lt;br /&gt;&lt;li&gt; &lt;font color=green&gt;PURCHASE_INTENT&lt;/font&gt;&lt;br /&gt;checkout activit を起動するための &lt;a href="http://developer.android.com/reference/android/app/PendingIntent.html"&gt;PendingIntent&lt;/a&gt; を提供するキー&lt;br /&gt;&lt;li&gt; &lt;font color=green&gt;REQUEST_ID&lt;/font&gt;&lt;br /&gt;リクエストと非同期のレスポンスを一致させるためのリクエスト識別子を提供するキー&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;いくつかのキーは全てのリクエストで使えるわけではない&lt;br /&gt;より詳しい情報は、&lt;a href="http://developer.android.com/guide/market/billing/billing_overview.html#billing-message-sequence"&gt;Messaging sequence&lt;/a&gt; を参照する&lt;br /&gt;&lt;br /&gt;非同期レスポンスはそれそれが broadcast intent の形式で送られる&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt; &lt;font color=green&gt;com.android.vending.billing.RESPONSE_CODE&lt;/font&gt;&lt;br /&gt;Android Market server の response code を含む&lt;br /&gt;in-app billing リクエストを作成した後に送られる&lt;br /&gt;レスポンスコードによって、Android Market に billing request が正しく送れたか、もしくはエラーがリクエスト中に起こったかを判別できる&lt;br /&gt;このレスポンスは購入状態の変化（リファンドや購入の情報）をレポートするものでは&lt;span style="font-weight:bold;"&gt;ない&lt;/span&gt;&lt;br /&gt;レスポンスコードの詳細は &lt;a href="http://developer.android.com/guide/market/billing/billing_reference.html#billing-codes"&gt;Server Response Codes for In-app Billing&lt;/a&gt; を参照する&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Extras&lt;/span&gt;&lt;br /&gt;・&lt;font color=green&gt;request_id&lt;/font&gt; : long : request ID を表す&lt;br /&gt;・&lt;font color=green&gt;response_code&lt;/font&gt; : int : Android Market server のレスポンスコードを表す&lt;br /&gt;&lt;br /&gt;&lt;font color=green&gt;response_code&lt;/font&gt; extras に含まれるレスポンスコード&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt; &lt;span style="font-weight:bold;"&gt;RESULT_OK&lt;/span&gt;&lt;br /&gt;値 : 0&lt;br /&gt;リクエストが正しくサーバーに送れたことを意味する&lt;br /&gt;このコードが &lt;font green=font&gt;CHECK_BILLING_SUPPORTED&lt;/font&gt; のレスポンスとして返された場合は、billing がサポートされていることを意味する&lt;br /&gt;&lt;br /&gt;&lt;li&gt; &lt;span style="font-weight:bold;"&gt;RESULT_USER_CANCELED&lt;/span&gt;&lt;br /&gt;値 : 1&lt;br /&gt;checkout ページでユーザーがアイテムを購入しようとせずに戻るボタンを押したことを意味する&lt;br /&gt;&lt;br /&gt;&lt;li&gt; &lt;span style="font-weight:bold;"&gt;RESULT_SERVICE_UNAVAILABLE&lt;/span&gt;&lt;br /&gt;値 : 2&lt;br /&gt;ネットワークコネクションがダウンしていることを意味する&lt;br /&gt;&lt;br /&gt;&lt;li&gt; &lt;span style="font-weight:bold;"&gt;RESULT_BILLING_UNAVAILABLE&lt;/span&gt;&lt;br /&gt;値 : 3&lt;br /&gt;指定した &lt;font color=green&gt;API_VERSION&lt;/font&gt; が Android Market application に認識されなかった、もしくはユーザーが in-app billing に不適格（例えば、ユーザーが in-app purchase が禁止されている国にいるなど）なことにより in-app billing が使えないことを意味する&lt;br /&gt;&lt;br /&gt;&lt;li&gt; &lt;span style="font-weight:bold;"&gt;RESULT_ITEM_UNAVAILABLE&lt;/span&gt;&lt;br /&gt;値 : 4&lt;br /&gt;Android Market がリクエストされたアイテムをアプリケーションの product list に見つけられなかったことを意味する。&lt;font color=green&gt;REQUEST_PURCHASE&lt;/font&gt; で product ID をミススペルしている場合、もしくはアイテムがアプリケーションの product list にパブリッシュされていない場合におこる&lt;br /&gt;&lt;br /&gt;&lt;li&gt; &lt;span style="font-weight:bold;"&gt;RESULT_DEVELOPER_ERROR&lt;/span&gt;&lt;br /&gt;値 : 5&lt;br /&gt;アプリケーションが in-app billing リクエストをしようとしたが、アプリケーションが &lt;font color=green&gt;com.android.vending.BILLING&lt;/font&gt; パーミッションを manifest で宣言していないことを意味する。アプリケーションが適切に署名されていない、もしくは変なリクエスト（例えば、request type を識別するための Bundle keys がないリクエストなど）を送ったことも意味しうる&lt;br /&gt;&lt;br /&gt;&lt;li&gt; &lt;span style="font-weight:bold;"&gt;RESULT_ERROR&lt;/span&gt;&lt;br /&gt;値 : 6&lt;br /&gt;予測できないサーバーエラーを意味する。自分で自分のアイテムを購入しようとした場合、このエラーが起こる&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;li&gt; &lt;font color=green&gt;com.android.vending.billing.IN_APP_NOTIFY&lt;/font&gt;&lt;br /&gt;購入状態（購入に成功した、キャンセルされた、リファンドされた）が変わったことを意味するレスポンス&lt;br /&gt;このレスポンスには 1つ以上の notification ID が含まれる&lt;br /&gt;ID は特定のサーバサイドメッセージとひもづいており、各メッセージは1つ上のトランザクションに関する情報を含む&lt;br /&gt;&lt;font color=green&gt;IN_APP_NOTIFY&lt;/font&gt; broadcast intent を受け取った後、アプリケーションは受け取った ID で&lt;font color=green&gt;GET_PURCHASE_INFOMATION&lt;/font&gt; リクエストを送ってメッセージの詳細を受け取るべき&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Extras&lt;/span&gt;&lt;br /&gt;・&lt;font color=green&gt;notification_id&lt;/font&gt; : String : notification ID を表す&lt;br /&gt;&lt;br /&gt;&lt;li&gt; &lt;font color=green&gt;com.android.vending.billing.PURCHASE_STATE_CHANGED&lt;/font&gt;&lt;br /&gt;1つ以上のトランザクションに関する詳細状態を含むレスポンス&lt;br /&gt;トランザクション情報は JSON string に含まれる&lt;br /&gt;JSON string は署名され、JSON string と一緒に signature が送られる (暗号化はされていない）&lt;br /&gt;あなたの in-app billing メッセージのセキュリティを確保するために、この JSON string の signature を使ってアプリケーションを検証する&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Extras&lt;/span&gt;&lt;br /&gt;・&lt;font color=green&gt;inapp_signed_data&lt;/font&gt; : String : signed された JSON string&lt;br /&gt;・&lt;font color=green&gt;inapp_signature&lt;/font&gt; : String : signature を表す String&lt;br /&gt;&lt;br /&gt;JSON string の例&lt;br /&gt;&lt;pre name="code"&gt;&lt;br /&gt;{ "nonce" : 1836535032137741465,&lt;br /&gt;  "orders" :&lt;br /&gt;    { "notificationId" : "android.test.purchased",&lt;br /&gt;      "orderId" : "transactionId.android.test.purchased",&lt;br /&gt;      "packageName" : "com.example.dungeons",&lt;br /&gt;      "productId" : "android.test.purchased",&lt;br /&gt;      "developerPayload" : "bGoa+V7g/yqDXvKRqq+JTFn4uQZbPiQJo4pf9RzJ",&lt;br /&gt;      "purchaseTime" : 1290114783411,&lt;br /&gt;      "purchaseState" : 0 }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;JSON string のフィールドの情報は &lt;a href="http://developer.android.com/guide/market/billing/billing_reference.html#billing-intents"&gt; In-app Billing Broadcast Intents &lt;/a&gt;を参照する&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt; &lt;span style="font-weight:bold;"&gt;nonce&lt;/span&gt;&lt;br /&gt;1回だけ使われる数字。自分のアプリケーションで nonce を生成して &lt;font color=green&gt;GET_PURCHASE_INFOMATION&lt;/font&gt; と一緒に送る。Android Market は JSON string の一部として nonce を送り返す。これによりメッセージを識別できる。&lt;br /&gt;&lt;br /&gt;&lt;li&gt; &lt;span style="font-weight:bold;"&gt;notificationId&lt;/span&gt;&lt;br /&gt;&lt;font color=green&gt;IN_APP_NOTIFY&lt;/font&gt; broadcast intent と一緒に送られるユニークな識別子。各 &lt;font color=green&gt;notificationId&lt;/font&gt; は Android Market server に受信されるのを待っている特定のメッセージと対応する。&lt;font color=green&gt;notificationId&lt;/font&gt; を &lt;font color=green&gt;GET_PURCHASE_INFORMATION&lt;/font&gt; メッセージと一緒に送り返すことで、アプリケーションがメッセージを受信したかどうかを Android Market が判断できる。&lt;br /&gt;&lt;br /&gt;&lt;li&gt; &lt;span style="font-weight:bold;"&gt;orderId&lt;/span&gt;&lt;br /&gt;トランザクション用のユニークなオーダー識別子。Google Checkout Order ID とひもづいている。&lt;br /&gt;&lt;br /&gt;&lt;li&gt; &lt;span style="font-weight:bold;"&gt;packageName&lt;/span&gt;&lt;br /&gt;購入が発生したアプリケーションのパッケージ名&lt;br /&gt;&lt;br /&gt;&lt;li&gt; &lt;span style="font-weight:bold;"&gt;productId&lt;/span&gt;&lt;br /&gt;アイテムの product 識別子。各アイテムは Android Market publisher site でアプリケーションの product list として指定された product ID をもたなければならない。&lt;br /&gt;&lt;br /&gt;&lt;li&gt; &lt;span style="font-weight:bold;"&gt;purchaseTime&lt;/span&gt;&lt;br /&gt;product が購入された時間。epoch (Jan 1, 1970) からの経過ミリ秒数&lt;br /&gt;&lt;br /&gt;&lt;li&gt; &lt;span style="font-weight:bold;"&gt;purchaseState&lt;/span&gt;&lt;br /&gt;オーダーの購入状態。可能は値は &lt;span style="font-weight:bold;"&gt;0 (purchased), 1 (canceled), 2 (refunded)&lt;/span&gt; のいずれか。&lt;br /&gt;&lt;br /&gt;&lt;li&gt; &lt;span style="font-weight:bold;"&gt;developerPayload&lt;/span&gt;&lt;br /&gt;開発者が指定した文字列。オーダーの付加情報を含む。&lt;font color=green&gt;REQUEST_PURCHASE&lt;/font&gt; リクエストを発行するときにこのフィールドを指定することができる。&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5859951453664122203-5110760630988068873?l=y-anz-m.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://y-anz-m.blogspot.com/feeds/5110760630988068873/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://y-anz-m.blogspot.com/2011/07/androidin-app-billing-overview.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5859951453664122203/posts/default/5110760630988068873'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5859951453664122203/posts/default/5110760630988068873'/><link rel='alternate' type='text/html' href='http://y-anz-m.blogspot.com/2011/07/androidin-app-billing-overview.html' title='Android　In-app Billing Overview'/><author><name>yanzm</name><uri>http://www.blogger.com/profile/04059587494895790858</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_HRaLqTNFL7w/TDx6XwqrmDI/AAAAAAAABMo/B1SkSHxhKu4/S220/icon4.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5859951453664122203.post-4086518931014701450</id><published>2011-07-06T08:02:00.003+09:00</published><updated>2011-07-06T08:21:49.849+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Android'/><title type='text'>Android　android:duplicateParentState</title><content type='html'>子View の状態（クリックされた、フォーカスがあたった、選択されたなど）を親と共有したい場合、&lt;br /&gt;&lt;br /&gt;android:duplicateParentState="true or false"&lt;br /&gt;&lt;br /&gt;setDuplicateParentStateEnabled(boolean)&lt;br /&gt;&lt;br /&gt;が使えます。&lt;br /&gt;&lt;br /&gt;これを設定すると、自身の状態よりも親の状態が優先され、親の状態と同じ状態をとるようになります。&lt;br /&gt;&lt;br /&gt;例えば、ダッシュボードで&lt;br /&gt;&lt;br /&gt;(ボタン1)&lt;br /&gt;-----------&lt;br /&gt;|画像|画像|&lt;br /&gt;-----------&lt;br /&gt;(ボタン2)&lt;br /&gt;-----------&lt;br /&gt;|画像|画像|&lt;br /&gt;-----------&lt;br /&gt;(ボタン3)&lt;br /&gt;-----------&lt;br /&gt;|画像|画像|&lt;br /&gt;-----------&lt;br /&gt;・・・&lt;br /&gt;&lt;br /&gt;があって、どっちの画像を押しても、両方の画像が状態に応じて変わるようにするには、両方の画像の親Viewにクリック処理をさせ、子View に android:duplicateParentState="true" を設定します。&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&lt;br /&gt;    &amp;lt;LinearLayout&lt;br /&gt;        android:orientation="horizontal"&lt;br /&gt;        android:layout_width="wrap_content"&lt;br /&gt;        android:layout_height="wrap_content"&lt;br /&gt;        android:clickable="true"&lt;br /&gt;        android:focusable="true"&lt;br /&gt;        &amp;gt;&lt;br /&gt;        &amp;lt;ImageView &lt;br /&gt;            android:background="@android:drawable/btn_default"&lt;br /&gt;            android:layout_width="50dip" &lt;br /&gt;            android:layout_height="wrap_content"&lt;br /&gt;            android:duplicateParentState="true"&lt;br /&gt;            /&amp;gt;&lt;br /&gt;        &amp;lt;ImageView &lt;br /&gt;            android:background="@android:drawable/btn_default"&lt;br /&gt;            android:layout_width="100dip" &lt;br /&gt;            android:layout_height="wrap_content"&lt;br /&gt;            android:duplicateParentState="true"&lt;br /&gt;            /&amp;gt;&lt;br /&gt;    &amp;lt;/LinearLayout&amp;gt;&lt;br /&gt;&lt;br /&gt;    ...&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;この場合、LinearLayout 部分をクリックすると、2つの ImageView 両方が LinearLayout の状態（押された、フォーカスがあたったなど）に応じて変わります。&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/-kFAIzBwhdHM/ThObziod7sI/AAAAAAAAC8w/0Xmn5XsewNM/s1600/DuplicateParentStateTest1.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 240px; height: 400px;" src="http://1.bp.blogspot.com/-kFAIzBwhdHM/ThObziod7sI/AAAAAAAAC8w/0Xmn5XsewNM/s400/DuplicateParentStateTest1.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5626011669288054466" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;ちなみに、これを使ったダッシュボードの例が「Android Layout Cookbook」の 8.4 レイアウトサンプル4 です。&lt;br /&gt;ここから、Android Layout Cookbook デモあぷりを落として実際の動きをみることができます。&lt;br /&gt;&lt;br /&gt;&lt;a href="https://market.android.com/details?id=yanzm.products.photoviewer"&gt;Android Layout CookBook デモあぷり - Android マーケット -&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;本もよろしくね！&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;実は、親 View の enabled/disabled も伝えることができます。&lt;br /&gt;例えば、&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&lt;br /&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;&lt;br /&gt;&amp;lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"&lt;br /&gt;    android:id="@+id/container"&lt;br /&gt;    android:orientation="vertical"&lt;br /&gt;    android:layout_width="fill_parent"&lt;br /&gt;    android:layout_height="fill_parent"&lt;br /&gt;    &amp;gt;&lt;br /&gt;    &amp;lt;Button &lt;br /&gt;        android:text="Button" &lt;br /&gt;        android:id="@+id/button1" &lt;br /&gt;        android:layout_width="wrap_content" &lt;br /&gt;        android:layout_height="wrap_content"&lt;br /&gt;        android:duplicateParentState="true"&lt;br /&gt;        /&amp;gt;&lt;br /&gt;    &amp;lt;Button &lt;br /&gt;        android:text="Button" &lt;br /&gt;        android:id="@+id/button2" &lt;br /&gt;        android:layout_width="wrap_content" &lt;br /&gt;        android:layout_height="wrap_content"&lt;br /&gt;        android:duplicateParentState="false"&lt;br /&gt;        /&amp;gt;&lt;br /&gt;    &amp;lt;Button &lt;br /&gt;        android:text="Button" &lt;br /&gt;        android:id="@+id/button3" &lt;br /&gt;        android:layout_width="wrap_content" &lt;br /&gt;        android:layout_height="wrap_content"&lt;br /&gt;        android:duplicateParentState="true"&lt;br /&gt;        /&amp;gt;&lt;br /&gt;    &amp;lt;Button &lt;br /&gt;        android:text="Button" &lt;br /&gt;        android:id="@+id/button4" &lt;br /&gt;        android:layout_width="wrap_content" &lt;br /&gt;        android:layout_height="wrap_content"&lt;br /&gt;        android:duplicateParentState="true"&lt;br /&gt;        /&amp;gt;&lt;br /&gt;    &amp;lt;Button &lt;br /&gt;        android:text="Button" &lt;br /&gt;        android:id="@+id/button5" &lt;br /&gt;        android:layout_width="wrap_content" &lt;br /&gt;        android:layout_height="wrap_content"&lt;br /&gt;        android:duplicateParentState="true"&lt;br /&gt;        /&amp;gt;&lt;br /&gt;&amp;lt;/LinearLayout&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;    @Override&lt;br /&gt;    public void onCreate(Bundle savedInstanceState) {&lt;br /&gt;        super.onCreate(savedInstanceState);&lt;br /&gt;        setContentView(R.layout.main);&lt;br /&gt;        &lt;br /&gt;        View container = findViewById(R.id.container); &lt;br /&gt;        container.setEnabled(false);&lt;br /&gt;        &lt;br /&gt;        View button4 = findViewById(R.id.button4);&lt;br /&gt;        button4.setEnabled(true);&lt;br /&gt;&lt;br /&gt;        View button5 = findViewById(R.id.button5);&lt;br /&gt;        button5.setDuplicateParentStateEnabled(false);&lt;br /&gt;        button5.setEnabled(true);&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;の結果は次のようになります。&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/-5zAI1avuh_8/ThObzSF1KZI/AAAAAAAAC8o/h8uSlw3qZUE/s1600/DuplicationParentStateTest2.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 240px; height: 400px;" src="http://4.bp.blogspot.com/-5zAI1avuh_8/ThObzSF1KZI/AAAAAAAAC8o/h8uSlw3qZUE/s400/DuplicationParentStateTest2.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5626011664847808914" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;setDuplicateParentStateEnabled(false) を指定しないと、子 View だけ setEnabled(true) しないと親 View が disabled の場合は enabled になりません。&lt;br /&gt;&lt;br /&gt;このパラメータは一度に有効／無効を切り替えるのに使うにはちょっと向いてないかなー。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5859951453664122203-4086518931014701450?l=y-anz-m.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://y-anz-m.blogspot.com/feeds/4086518931014701450/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://y-anz-m.blogspot.com/2011/07/androidandroidduplicateparentstate.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5859951453664122203/posts/default/4086518931014701450'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5859951453664122203/posts/default/4086518931014701450'/><link rel='alternate' type='text/html' href='http://y-anz-m.blogspot.com/2011/07/androidandroidduplicateparentstate.html' title='Android　android:duplicateParentState'/><author><name>yanzm</name><uri>http://www.blogger.com/profile/04059587494895790858</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_HRaLqTNFL7w/TDx6XwqrmDI/AAAAAAAABMo/B1SkSHxhKu4/S220/icon4.JPG'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-kFAIzBwhdHM/ThObziod7sI/AAAAAAAAC8w/0Xmn5XsewNM/s72-c/DuplicateParentStateTest1.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5859951453664122203.post-1372283630699576396</id><published>2011-07-05T22:30:00.007+09:00</published><updated>2011-07-05T23:24:10.504+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Android'/><title type='text'>Android ListFragment でカスタムレイアウトを使うと setEmptyText() が使えない</title><content type='html'>もともとは adakoda さんのブログのエントリ&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.adakoda.com/adakoda/2011/07/android-listfragment-view.html"&gt;[Android] ListFragment の View をカスタマイズする方法 - adakoda - http://goo.gl/UBgyu&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;で、onCreateView() を override してカスタムレイアウトを指定すると setEmptyText() で落ちるという話があって、正しい ID を指定してないからでは〜？的な流れになったのですが、どうもそうではないようなので調べてみました。&lt;br /&gt;&lt;br /&gt;まず、&lt;a href="http://developer.android.com/reference/android/app/ListFragment.html#setEmptyText(java.lang.CharSequence)"&gt;setEmptyText(CharSequence text)&lt;/a&gt; は API Level 11 (Android 3.0) で追加された API です。&lt;br /&gt;&lt;br /&gt;結果をまとめると&lt;br /&gt;&lt;br /&gt;・ListActivity&lt;br /&gt;　　・setEmptyView() : 使える&lt;br /&gt;　　・getEmptyView() : 使える&lt;br /&gt;　　・@android:id/list, @android:id/empty を使った&lt;br /&gt;　　　カスタムレイアウト : 使える&lt;br /&gt;&lt;br /&gt;・ListFragment&lt;br /&gt;　　・@android:id/list, @android:id/empty を使った&lt;br /&gt;　　　カスタムレイアウト : 使える&lt;br /&gt;&lt;br /&gt;　　・カスタムレイアウトを使わない場合&lt;br /&gt;　　　　・getListView().setEmptyView() : なにもおこらない&lt;br /&gt;　　　　・getListView().getEmptyView() : 使える&lt;br /&gt;　　　　・setEmptyText() : 使える&lt;br /&gt;&lt;br /&gt;　　・カスタムレイアウトを使った場合&lt;br /&gt;　　　　・getListView().setEmptyView() : なにもおこらない &lt;br /&gt;　　　　　(@android:id/empty がそのまま表示される)&lt;br /&gt;　　　　・getListView().getEmptyView() : 使える&lt;br /&gt;　　　　・setEmptyText() : 落ちる&lt;br /&gt;&lt;br /&gt;ListFragment で、カスタムレイアウトで setEmptyText() を使いたい場合は、次のように override しておくこと&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt; @Override&lt;br /&gt; public void setEmptyText(CharSequence text) {&lt;br /&gt;  TextView tv = (TextView)getListView().getEmptyView();&lt;br /&gt;  tv.setText(text);&lt;br /&gt; }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;ちなみに、このときのカスタムレイアウトはこんな感じ&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&lt;br /&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;&lt;br /&gt;&amp;lt;FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"&lt;br /&gt;    android:layout_width="match_parent"&lt;br /&gt;    android:layout_height="match_parent"&amp;gt;&lt;br /&gt;    &lt;br /&gt;    &amp;lt;ListView &lt;br /&gt;        android:id="@android:id/list"&lt;br /&gt;        android:layout_width="match_parent"&lt;br /&gt;        android:layout_height="match_parent"&lt;br /&gt;        android:drawSelectorOnTop="false" /&amp;gt;&lt;br /&gt;        &lt;br /&gt;    &amp;lt;TextView &lt;br /&gt;        android:id="@android:id/empty"&lt;br /&gt;        android:layout_width="match_parent"&lt;br /&gt;        android:layout_height="match_parent"&lt;br /&gt;        android:text="No data" &lt;br /&gt;        android:textSize="30sp"/&amp;gt;&lt;br /&gt;&amp;lt;/FrameLayout&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;さて、結論をいったので、それまでの過程もちょっと紹介。&lt;br /&gt;&lt;br /&gt;まずは、ListFragment の onCreateView() で生成される View のなかから empty 用っぽい View を見つけて、それの ID から resourceName とればわかるんじゃね？と思ってやってみました。&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;@Override&lt;br /&gt;public View onCreateView(LayoutInflater inflater, ViewGroup container,&lt;br /&gt;     Bundle savedInstanceState) {&lt;br /&gt;&lt;br /&gt;    View v = super.onCreateView(inflater, container, savedInstanceState);&lt;br /&gt;    Log.d("NoteListFragment", v.getClass().getName() + ", " + v.getId());&lt;br /&gt;&lt;br /&gt;    if (v instanceof ViewGroup) {&lt;br /&gt;        ViewGroup vg = (ViewGroup) v;&lt;br /&gt;        for (int i = 0; i &lt; vg.getChildCount(); i++) {&lt;br /&gt;            View child = vg.getChildAt(i);&lt;br /&gt;&lt;br /&gt;            String resourcename = getResourceNameByID(android.R.id.class, child.getId());&lt;br /&gt;&lt;br /&gt;            Log.d("NoteListFragment", child.getClass().getName() + ", "&lt;br /&gt;                          + child.getId() + ", " + resourcename);&lt;br /&gt;    &lt;br /&gt;            if(child instanceof ViewGroup) {&lt;br /&gt;                ViewGroup vg2 = (ViewGroup) child;&lt;br /&gt;                for (int j = 0; j &lt; vg2.getChildCount(); j++) {&lt;br /&gt;                    View child2 = vg2.getChildAt(j);&lt;br /&gt;&lt;br /&gt;                    String resourcename2 = getResourceNameByID(android.R.id.class, child2.getId());&lt;br /&gt;&lt;br /&gt;                    Log.d("NoteListFragment", child2.getClass().getName() + ", "&lt;br /&gt;                                 + child2.getId() + ", " + resourcename2);&lt;br /&gt;                }     &lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }  &lt;br /&gt;    return v;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public String getResourceNameByID(Class&amp;lt;?&amp;gt; clazz, int resourceId)&lt;br /&gt;    throws IllegalArgumentException {&lt;br /&gt;&lt;br /&gt;    Field[] fields = clazz.getFields();&lt;br /&gt;    for (Field f : fields) {&lt;br /&gt;        try {&lt;br /&gt;            if (resourceId == f.getInt(null)) {&lt;br /&gt;                return f.getName();&lt;br /&gt;            }&lt;br /&gt;        } catch (Exception e) {&lt;br /&gt;            e.printStackTrace();&lt;br /&gt;            throw new IllegalArgumentException();&lt;br /&gt;       }&lt;br /&gt;    }&lt;br /&gt;    return null;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;リフレクション。リフレクション。&lt;br /&gt;結果はこんな感じ&lt;br /&gt;&lt;br /&gt;07-05 13:46:40.090: DEBUG/NoteListFragment(30597): android.widget.FrameLayout, -1&lt;br /&gt;07-05 13:46:40.090: DEBUG/NoteListFragment(30597): android.widget.LinearLayout, 16908904, null&lt;br /&gt;07-05 13:46:40.090: DEBUG/NoteListFragment(30597): android.widget.ProgressBar, -1, null&lt;br /&gt;07-05 13:46:40.090: DEBUG/NoteListFragment(30597): android.widget.TextView, -1, null&lt;br /&gt;07-05 13:46:40.090: DEBUG/NoteListFragment(30597): android.widget.FrameLayout, 16908905, null&lt;br /&gt;07-05 13:46:40.090: DEBUG/NoteListFragment(30597): &lt;span style="font-weight:bold;"&gt;android.widget.ListView, 16908298, list&lt;/span&gt;&lt;br /&gt;07-05 13:46:40.090: DEBUG/NoteListFragment(30597): &lt;span style="font-weight:bold;"&gt;android.widget.TextView, 16908906, null&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;ListView には list (= android.R.id.list) が割当てられているのに、その下の TextView (EmptyView だと思われる) には null が入っている。つまり、android.R.id.** に対象の ID がなかったということです。コードで動的に生成してるのかな？&lt;br /&gt;&lt;br /&gt;念のためこの TextView が EmptyView なのかチェック&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt; @Override&lt;br /&gt; public void onActivityCreated(Bundle savedInstanceState) {&lt;br /&gt;  super.onActivityCreated(savedInstanceState);&lt;br /&gt;  ...&lt;br /&gt;  &lt;br /&gt;  setEmptyText(getActivity().getString(R.string.no_notes));&lt;br /&gt;  Log.d("NoteListFragment", getListView().getEmptyView().getId() + "");&lt;br /&gt; }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;結果は&lt;br /&gt;&lt;br /&gt;07-05 13:56:22.510: DEBUG/NoteListFragment(30953): 16908906&lt;br /&gt;&lt;br /&gt;ビンゴ。&lt;br /&gt;&lt;br /&gt;ちなみに  setEmptyText() する前に getListView().getEmptyView().getId() するとヌルポになります。&lt;br /&gt;EmptyView が生成されてないんですね。このことからも EmptyView が動的に生成されてるのがわかります。&lt;br /&gt;&lt;br /&gt;なので、レイアウトをカスタムしないで setEmptyText を override するときは super.setEmpty() を忘れずに最初にしてください。そうしないとその後の getListView().getEmptyView() には null が返ってきてしまいます。&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt; @Override&lt;br /&gt; public void setEmptyText(CharSequence text) {&lt;br /&gt;  super.setEmptyText(text);  // don't forget&lt;br /&gt;  TextView tv = (TextView)getListView().getEmptyView();&lt;br /&gt;  tv.setText(text);&lt;br /&gt; }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;カスタムを使っていてもいなくても、カスタムレイアウトに android:empty が入っていてもいなくても動くようにするには、こんな感じかなぁ。。。&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt; @Override&lt;br /&gt; public void setEmptyText(CharSequence text) {&lt;br /&gt;  try {&lt;br /&gt;   super.setEmptyText(text);&lt;br /&gt;  }&lt;br /&gt;  catch (IllegalStateException e1){&lt;br /&gt;   e1.printStackTrace();&lt;br /&gt;   Log.d("NoteListFragment", e1.getClass().getName() + " : " + e1.getMessage());&lt;br /&gt;&lt;br /&gt;   try {&lt;br /&gt;    TextView tv = (TextView)getListView().getEmptyView();&lt;br /&gt;    tv.setText(text);    &lt;br /&gt;   }&lt;br /&gt;   catch(NullPointerException e2) {    &lt;br /&gt;    e2.printStackTrace();&lt;br /&gt;    Log.d("NoteListFragment", e2.getClass().getName() + " : " + e2.getMessage());&lt;br /&gt;&lt;br /&gt;    TextView tv = new TextView(getActivity());&lt;br /&gt;    tv.setText(text);&lt;br /&gt;    tv.setId(android.R.id.empty);&lt;br /&gt;    &lt;br /&gt;    ViewParent v = getListView().getParent();&lt;br /&gt;    if(v instanceof ViewGroup) {&lt;br /&gt;     ((ViewGroup)v).addView(tv);&lt;br /&gt;    }&lt;br /&gt;    getListView().setEmptyView(tv);&lt;br /&gt;   }&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;　　&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5859951453664122203-1372283630699576396?l=y-anz-m.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://y-anz-m.blogspot.com/feeds/1372283630699576396/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://y-anz-m.blogspot.com/2011/07/android-listfragment-setemptytext.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5859951453664122203/posts/default/1372283630699576396'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5859951453664122203/posts/default/1372283630699576396'/><link rel='alternate' type='text/html' href='http://y-anz-m.blogspot.com/2011/07/android-listfragment-setemptytext.html' title='Android ListFragment でカスタムレイアウトを使うと setEmptyText() が使えない'/><author><name>yanzm</name><uri>http://www.blogger.com/profile/04059587494895790858</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_HRaLqTNFL7w/TDx6XwqrmDI/AAAAAAAABMo/B1SkSHxhKu4/S220/icon4.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5859951453664122203.post-5189474639788819756</id><published>2011-07-04T04:58:00.009+09:00</published><updated>2011-07-04T09:13:31.959+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Android'/><title type='text'>Android Developer Lab Tokyo 2011 のノートパッドをカスタマイズしてみた。</title><content type='html'>7月2日と3日に 「Android デベロッパーラボ 東京 2011」が開催されました。&lt;br /&gt;&lt;br /&gt;&lt;a href="http://googledevjp.blogspot.com/2011/06/android-2011.html"&gt;「Android デベロッパーラボ 東京 2011」開催のお知らせ - Google Japan Developer Relations Blog - &lt;/a&gt;&lt;br /&gt;&lt;br /&gt;私は両日ともチューターとして参加してきました。&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/-GGXCCkdYDfE/ThDOK0pNoLI/AAAAAAAAC7s/u2fh3YwvPsU/s1600/IMG_20110702_094234.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 300px; height: 400px;" src="http://3.bp.blogspot.com/-GGXCCkdYDfE/ThDOK0pNoLI/AAAAAAAAC7s/u2fh3YwvPsU/s400/IMG_20110702_094234.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5625222619911266482" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;参加者は80人 x 2 くらい&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/-UywIMHzU_bE/ThDOK9NGpoI/AAAAAAAAC70/XSvt0TQE5H4/s1600/IMG_20110703_100304.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 300px;" src="http://4.bp.blogspot.com/-UywIMHzU_bE/ThDOK9NGpoI/AAAAAAAAC70/XSvt0TQE5H4/s400/IMG_20110703_100304.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5625222622209287810" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;午前中に Android の Advocate の方のセッションがあって、&lt;br /&gt;午後から実際に手を動かすという内容でした。&lt;br /&gt;&lt;br /&gt;ハッシュタグは &lt;span style="font-weight:bold;"&gt;#adl11jp&lt;/span&gt; で&lt;br /&gt;&lt;br /&gt;すでに Togetter にまとめがあります。ありがとう @mrshiromi さん。&lt;br /&gt;&lt;a href="http://togetter.com/li/156662"&gt;Togetter - 「#adl11jp Android Developer Lab 2011 7/2-3」 -&lt;/a&gt; &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;午後のコードラボの資料は&lt;br /&gt;&lt;br /&gt;&lt;a href="https://docs.google.com/document/pub?id=1p5-wnxA3M-LvVI2cUH5p6XltP8LUL8RFrUWGveVr3UQ"&gt;Android Developer Lab — Tokyo 2011&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;にあります。(http://j.mp/adltokyo2011)&lt;br /&gt;&lt;br /&gt;Android developers のサイトにある &lt;a href="http://developer.android.com/resources/tutorials/notepad/index.html"&gt;Notepad Tutorial&lt;/a&gt; を Honeycomb 用にカスタマイズするというコンテンツです。&lt;br /&gt;もともとは &lt;a href="https://sites.google.com/site/iobootcamphclab/home"&gt;I/O Bootcamp Honeycomb Codelab&lt;/a&gt; で行われたものなのですが、これよりも簡単になっています。&lt;br /&gt;&lt;br /&gt;最後までいくと、こんな感じになります。&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/-9lj1LtaJjKM/ThDTYZjW42I/AAAAAAAAC78/_KQPGKzcTB0/s1600/honeycombpad_default.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 240px;" src="http://2.bp.blogspot.com/-9lj1LtaJjKM/ThDTYZjW42I/AAAAAAAAC78/_KQPGKzcTB0/s400/honeycombpad_default.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5625228350715257698" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;せっかくなので、カスタマイズしてみました。&lt;br /&gt;&lt;br /&gt;・全体的に余白をいれる&lt;br /&gt;・背景を変える&lt;br /&gt;・レイアウトを変える&lt;br /&gt;　　・保存ボタンの位置を変える&lt;br /&gt;　　・Body 部分を上揃えにする&lt;br /&gt;　　・Title 部分を１行固定にする&lt;br /&gt;　　・保存ボタンのスタイルを変える&lt;br /&gt;　　・リストの区切り線を変える&lt;br /&gt;　　・Title と Body の文字の大きさを変える&lt;br /&gt;・アクションバーをカスタマイズする&lt;br /&gt;　　・背景を変える&lt;br /&gt;　　・ロゴを使う&lt;br /&gt;　　・メニューボタンの文字色を変える&lt;br /&gt;　　・メニューボタンを押したときの色を変える&lt;br /&gt;・ノートがないときにリスト部分に "No Notes Yet" とでるようにする&lt;br /&gt;・開いているノートがどれかわかるように&lt;br /&gt;　　・リストのアイテムを CheckedTextView にする&lt;br /&gt;　　・チェックマークを変える&lt;br /&gt;・タイトルなしで保存しようとしたとき、日時の入ったタイトルを自動でつける&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;やったのはこのくらいかなー。&lt;br /&gt;&lt;br /&gt;ソースは github で公開しました。&lt;br /&gt;&lt;a href="https://github.com/yanzm/CustomizedHoneycombNotepad"&gt;yanzm/CustomizedHoneycombNotepad - GitHub -&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;できあがりはこんな感じ。&lt;br /&gt;&lt;br /&gt;まだノートがない場合&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/-L4A6-tyP3k4/ThDTYeuBybI/AAAAAAAAC8E/O3cLFEh9hyY/s1600/honeycombnote1.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 240px;" src="http://1.bp.blogspot.com/-L4A6-tyP3k4/ThDTYeuBybI/AAAAAAAAC8E/O3cLFEh9hyY/s400/honeycombnote1.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5625228352102189490" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;リスト部分にチェックマークでるようにしてみた。&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/-i9ArBem35X8/ThDTYhznKRI/AAAAAAAAC8M/1mFYyjKbwlE/s1600/honeycombnote2.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 240px;" src="http://4.bp.blogspot.com/-i9ArBem35X8/ThDTYhznKRI/AAAAAAAAC8M/1mFYyjKbwlE/s400/honeycombnote2.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5625228352930916626" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;アクションバーのボタンを押したとき。赤くしてみた。&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/-i19VOyZPxKg/ThDTY-8KHQI/AAAAAAAAC8U/BeXJd3_F_NE/s1600/honeycombnote3.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 240px;" src="http://4.bp.blogspot.com/-i19VOyZPxKg/ThDTY-8KHQI/AAAAAAAAC8U/BeXJd3_F_NE/s400/honeycombnote3.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5625228360751389954" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;保存ボタンを押したとき。これも赤くしてみた。&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/-_Q1fxD82BCU/ThDTYyZjPOI/AAAAAAAAC8c/La_4sBsFOrw/s1600/honeycombnote4.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 240px;" src="http://1.bp.blogspot.com/-_Q1fxD82BCU/ThDTYyZjPOI/AAAAAAAAC8c/La_4sBsFOrw/s400/honeycombnote4.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5625228357385010402" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;個々のカスタマイズ tips もいずれブログに書きたいなー。。。&lt;br /&gt;&lt;br /&gt;　&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5859951453664122203-5189474639788819756?l=y-anz-m.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://y-anz-m.blogspot.com/feeds/5189474639788819756/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://y-anz-m.blogspot.com/2011/07/android-developer-lab-2011-tokyo.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5859951453664122203/posts/default/5189474639788819756'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5859951453664122203/posts/default/5189474639788819756'/><link rel='alternate' type='text/html' href='http://y-anz-m.blogspot.com/2011/07/android-developer-lab-2011-tokyo.html' title='Android Developer Lab Tokyo 2011 のノートパッドをカスタマイズしてみた。'/><author><name>yanzm</name><uri>http://www.blogger.com/profile/04059587494895790858</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_HRaLqTNFL7w/TDx6XwqrmDI/AAAAAAAABMo/B1SkSHxhKu4/S220/icon4.JPG'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-GGXCCkdYDfE/ThDOK0pNoLI/AAAAAAAAC7s/u2fh3YwvPsU/s72-c/IMG_20110702_094234.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5859951453664122203.post-6594561760846122039</id><published>2011-07-03T11:15:00.005+09:00</published><updated>2011-07-04T01:03:50.040+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Android'/><title type='text'>Android　Action Bar をカスタマイズする</title><content type='html'>&lt;a href="http://android-developers.blogspot.com/2011/04/customizing-action-bar.html"&gt;Android Developers Blog: Customizing the Action Bar&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Action Bar のデザインパターンを&lt;a href="http://android-developers.blogspot.com/2010/05/twitter-for-android-closer-look-at.html"&gt;紹介&lt;/a&gt;してから、多くのアプリケーションが Action Bar を使うようになりました。&lt;br /&gt;そして、このデザインパターンは Android 3.0 でデフォルトの機能になりました。&lt;br /&gt;Honeycomb をターゲットとしたアプリで Action Bar を使う方法は &lt;a href="http://developer.android.com/guide/topics/ui/actionbar.html"&gt;using Action Bar&lt;/a&gt; を参照してください。&lt;br /&gt;&lt;br /&gt;Theme.Holo.* を継承した独自スタイルを定義して、ここで Action Bar をカスタマイズしていきます。&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&lt;br /&gt;&amp;lt;style name="Theme.MyTheme" parent="android:style/Theme.Holo.Light"&amp;gt;&lt;br /&gt;…&lt;br /&gt;&amp;lt;/style&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;■ Icon&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://android-ui-utils.googlecode.com/hg/asset-studio/dist/icons-actionbar.html"&gt;Android Asset Studio&lt;/a&gt; を使って Action Bar 用のアイコンを作ることができます。&lt;br /&gt;また、ブランド化するためにスタートポイントに次のようなロゴを使ったりします。&lt;br /&gt;&lt;br /&gt;&lt;img src="http://4.bp.blogspot.com/-VjORQbP9RUs/TaXcTZo3yxI/AAAAAAAAAU8/u8setg3cDd0/s400/I1.png" /&gt;&lt;br /&gt;&lt;br /&gt;ロゴ (android:logo) を Action Bar に使うには&lt;br /&gt;&lt;a href="http://developer.android.com/reference/android/app/ActionBar.html#setDisplayUseLogoEnabled(boolean)"&gt;setDisplayUseLogoEnabled (boolean useLogo)&lt;/a&gt;&lt;br /&gt;を使います。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;■ Navigation&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Action Bar のナビゲーションセクションには3つの異なる mode があります。&lt;br /&gt;・&lt;a href="http://developer.android.com/reference/android/app/ActionBar.html#NAVIGATION_MODE_STANDARD"&gt;NAVIGATION_MODE_STANDARD&lt;/a&gt;&lt;br /&gt;・&lt;a href="http://developer.android.com/reference/android/app/ActionBar.html#NAVIGATION_MODE_LIST"&gt;NAVIGATION_MODE_LIST&lt;/a&gt;&lt;br /&gt;・&lt;a href="http://developer.android.com/reference/android/app/ActionBar.html#NAVIGATION_MODE_TABS"&gt;NAVIGATION_MODE_TABS&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;ナビゲーションのモードを設定するには&lt;br /&gt;&lt;a href="http://developer.android.com/reference/android/app/ActionBar.html#setNavigationMode(int)"&gt;setNavigationMode(int)&lt;/a&gt; &lt;br /&gt;を使います。&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt; &lt;span style="font-weight:bold;"&gt;Standard&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Action Bar のスタンダートナビゲーションモードは単純に Activity のタイトルを表示します。&lt;br /&gt;&lt;br /&gt;&lt;li&gt; &lt;span style="font-weight:bold;"&gt;List&lt;span style="font-weight:bold;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;左側が標準のリストドロップダウン、右側が実現したいエフェクト&lt;br /&gt;&lt;br /&gt;&lt;img src="http://1.bp.blogspot.com/-iq8YXQBQjTo/TaXccBS9wZI/AAAAAAAAAVE/3NdspdF2eB4/s400/I2.png" /&gt;&lt;br /&gt;&lt;br /&gt;デフォルトのナビゲーションモードは青色のカラースキームでスタイルされています。&lt;br /&gt;これは、トップバーと拡張リストの選択ハイライトの両方で、タッチされたことを表すために青色になります。&lt;br /&gt;&lt;br /&gt;&lt;a href="http://developer.android.com/reference/android/R.styleable.html#Theme_actionDropDownStyle"&gt;android:actionDropDownStyle&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;をオーバーライドすることでこのエレメントのテーマをすきなカラースキームにカスタマイ
