<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>@blog.justoneplanet.info &#187; Java</title>
	<atom:link href="http://blog.justoneplanet.info/category/computer-language/java/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.justoneplanet.info</link>
	<description>日々勉強</description>
	<lastBuildDate>Wed, 08 Feb 2012 02:57:17 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>android-support-v4.jarを使ったプロジェクトのテストをする</title>
		<link>http://blog.justoneplanet.info/2012/01/16/android-support-v4-jar%e3%82%92%e4%bd%bf%e3%81%a3%e3%81%9f%e3%83%97%e3%83%ad%e3%82%b8%e3%82%a7%e3%82%af%e3%83%88%e3%81%ae%e3%83%86%e3%82%b9%e3%83%88%e3%82%92%e3%81%99%e3%82%8b/</link>
		<comments>http://blog.justoneplanet.info/2012/01/16/android-support-v4-jar%e3%82%92%e4%bd%bf%e3%81%a3%e3%81%9f%e3%83%97%e3%83%ad%e3%82%b8%e3%82%a7%e3%82%af%e3%83%88%e3%81%ae%e3%83%86%e3%82%b9%e3%83%88%e3%82%92%e3%81%99%e3%82%8b/#comments</comments>
		<pubDate>Sun, 15 Jan 2012 16:38:48 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[android]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[テスト]]></category>

		<guid isPermaLink="false">http://blog.justoneplanet.info/?p=4948</guid>
		<description><![CDATA[テスト対象のプロジェクトにおいて以下の操作をする。 propaties &#62; Java Build Path &#62; Order and Export &#62; android-support-v4.jarにチェッ [...]]]></description>
			<content:encoded><![CDATA[<p>テスト対象のプロジェクトにおいて以下の操作をする。</p>
<p>propaties &gt; Java Build Path &gt; Order and Export &gt; android-support-v4.jarにチェックを入れる。</p>
<h4>.classpath</h4>
<p>以下のようにexported属性が付加されている。</p>
<pre class="brush: xml;">
&lt;classpathentry exported=&quot;true&quot; kind=&quot;lib&quot; path=&quot;libs/android-support-v4.jar&quot;/&gt;
</pre>
<h4>悪い例</h4>
<p>テストプロジェクトにandroid-support-v4.jarをインポートすると以下のようなエラーがでる。</p>
<pre class="brush: plain;">
java.lang.RuntimeException: Exception during suite construction
at android.test.suitebuilder.TestSuiteBuilder$FailedToCreateTests.testSuiteConstructionFailed(TestSuiteBuilder.java:239)
at java.lang.reflect.Method.invokeNative(Native Method)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:169)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:154)
at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:529)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1448)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Constructor.constructNative(Native Method)
at java.lang.reflect.Constructor.newInstance(Constructor.java:415)
at android.test.suitebuilder.TestMethod.instantiateTest(TestMethod.java:87)
at android.test.suitebuilder.TestMethod.createTest(TestMethod.java:73)
at android.test.suitebuilder.TestSuiteBuilder.addTest(TestSuiteBuilder.java:263)
at android.test.suitebuilder.TestSuiteBuilder.build(TestSuiteBuilder.java:185)
at android.test.InstrumentationTestRunner.onCreate(InstrumentationTestRunner.java:373)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:3285)
at android.app.ActivityThread.access$2200(ActivityThread.java:117)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:987)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:123)
at android.app.ActivityThread.main(ActivityThread.java:3728)
at java.lang.reflect.Method.invokeNative(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:864)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:622)
at dalvik.system.NativeStart.main(Native Method)
</pre>
<section class="kakomi">
<h4>参考</h4>
<ul>
<li><a href="http://dtmilano.blogspot.com/2009/12/android-testing-external-libraries.html">Android Testing: External libraries</a></li>
</ul>
</section>
]]></content:encoded>
			<wfw:commentRss>http://blog.justoneplanet.info/2012/01/16/android-support-v4-jar%e3%82%92%e4%bd%bf%e3%81%a3%e3%81%9f%e3%83%97%e3%83%ad%e3%82%b8%e3%82%a7%e3%82%af%e3%83%88%e3%81%ae%e3%83%86%e3%82%b9%e3%83%88%e3%82%92%e3%81%99%e3%82%8b/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>androidでレンダリング後のViewのサイズを取得する</title>
		<link>http://blog.justoneplanet.info/2012/01/15/android%e3%81%a7%e3%83%ac%e3%83%b3%e3%83%80%e3%83%aa%e3%83%b3%e3%82%b0%e5%be%8c%e3%81%aeview%e3%81%ae%e3%82%b5%e3%82%a4%e3%82%ba%e3%82%92%e5%8f%96%e5%be%97%e3%81%99%e3%82%8b/</link>
		<comments>http://blog.justoneplanet.info/2012/01/15/android%e3%81%a7%e3%83%ac%e3%83%b3%e3%83%80%e3%83%aa%e3%83%b3%e3%82%b0%e5%be%8c%e3%81%aeview%e3%81%ae%e3%82%b5%e3%82%a4%e3%82%ba%e3%82%92%e5%8f%96%e5%be%97%e3%81%99%e3%82%8b/#comments</comments>
		<pubDate>Sun, 15 Jan 2012 08:51:19 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[android]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[View]]></category>

		<guid isPermaLink="false">http://blog.justoneplanet.info/?p=4944</guid>
		<description><![CDATA[onClickなどのユーザイベント実行時に取得するならば以下の方法で取得ができる。 mView.setOnClickListener(new View.OnClickListener(){ @Override publi [...]]]></description>
			<content:encoded><![CDATA[<p>onClickなどのユーザイベント実行時に取得するならば以下の方法で取得ができる。</p>
<pre class="brush: java;">
mView.setOnClickListener(new View.OnClickListener(){
    @Override
    public void onClick(View v) {
        int width = v.getWidth();
        int height = v.getHeight();
    }
});
</pre>
<p>これを利用して以下のようにすると正しく取得できない。</p>
<pre class="brush: java;">
@Override
public void onCreate(Bundle savedInstanceState) {
    // ...
    int width = mView.getWidth();// 0
    int height = mView.getHeight();// 0
}
</pre>
<p>onCreate, onStart, onResumeではレンダリングが終了していないためサイズが0となる。</p>
<h3>■解決策</h3>
<p>以下のようにViewTreeObserverを利用することでレンダリング後のサイズを取得することができる。</p>
<pre class="brush: java;">
@Override
public void onCreate(Bundle savedInstanceState) {
    // ...
    ViewTreeObserver viewTreeObserver = mView.getViewTreeObserver();
    viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            int width = mView.getWidth();
            int height = mView.getHeight();
        }
    });
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.justoneplanet.info/2012/01/15/android%e3%81%a7%e3%83%ac%e3%83%b3%e3%83%80%e3%83%aa%e3%83%b3%e3%82%b0%e5%be%8c%e3%81%aeview%e3%81%ae%e3%82%b5%e3%82%a4%e3%82%ba%e3%82%92%e5%8f%96%e5%be%97%e3%81%99%e3%82%8b/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>androidでActivityが切り替わるときのアニメーションを変える</title>
		<link>http://blog.justoneplanet.info/2012/01/09/android%e3%81%a7activity%e3%81%8c%e5%88%87%e3%82%8a%e6%9b%bf%e3%82%8f%e3%82%8b%e3%81%a8%e3%81%8d%e3%81%ae%e3%82%a2%e3%83%8b%e3%83%a1%e3%83%bc%e3%82%b7%e3%83%a7%e3%83%b3%e3%82%92%e5%a4%89%e3%81%88/</link>
		<comments>http://blog.justoneplanet.info/2012/01/09/android%e3%81%a7activity%e3%81%8c%e5%88%87%e3%82%8a%e6%9b%bf%e3%82%8f%e3%82%8b%e3%81%a8%e3%81%8d%e3%81%ae%e3%82%a2%e3%83%8b%e3%83%a1%e3%83%bc%e3%82%b7%e3%83%a7%e3%83%b3%e3%82%92%e5%a4%89%e3%81%88/#comments</comments>
		<pubDate>Sun, 08 Jan 2012 15:36:18 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[android]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://blog.justoneplanet.info/?p=4914</guid>
		<description><![CDATA[activityが切り替わるときにアニメーションをさせたくなくなった。 ■実装 res/values/style.xml 以下のようにテーマを定義する。 &#60;resource&#62; &#60;style name=&#038; [...]]]></description>
			<content:encoded><![CDATA[<p>activityが切り替わるときにアニメーションをさせたくなくなった。</p>
<h3>■実装</h3>
<h4>res/values/style.xml</h4>
<p>以下のようにテーマを定義する。</p>
<pre class="brush: xml;">
&lt;resource&gt;
    &lt;style name=&quot;NoAnimationTheme&quot; parent=&quot;android:Theme&quot;&gt;
        &lt;item name=&quot;android:windowAnimationStyle&quot;&gt;@style/Animation.Activity&lt;/item&gt;
    &lt;/style&gt;
    &lt;style name=&quot;Animation.Activity&quot; parent=&quot;android:Animation.Activity&quot;&gt;
        &lt;item name=&quot;android:activityOpenEnterAnimation&quot;&gt;@anim/activity_open_enter&lt;/item&gt;
        &lt;item name=&quot;android:activityOpenExitAnimation&quot;&gt;@anim/activity_open_exit&lt;/item&gt;
        &lt;item name=&quot;android:activityCloseEnterAnimation&quot;&gt;@anim/activity_close_enter&lt;/item&gt;
        &lt;item name=&quot;android:activityCloseExitAnimation&quot;&gt;@anim/activity_close_exit&lt;/item&gt;
    &lt;/style&gt;
&lt;/resource&gt;
</pre>
<section class="kakomi">
<h4>anim/activity_open_enter.xml</h4>
<p>startActivityで開くActivityのanimation。</p>
<pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;set xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
    android:interpolator=&quot;@android:anim/accelerate_interpolator&quot;&gt;
    &lt;translate
        android:fromXDelta=&quot;100%&quot;
        android:toXDelta=&quot;0%&quot;
        android:duration=&quot;0&quot;
        android:fillAfter=&quot;true&quot;
        android:fillEnabled=&quot;true&quot;/&gt;
&lt;/set&gt;
</pre>
<h4>anim/activity_open_exit.xml</h4>
<p>startActivityで閉じるActivityのanimation。</p>
<pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;set xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
    android:interpolator=&quot;@android:anim/accelerate_interpolator&quot;&gt;
    &lt;translate
        android:fromXDelta=&quot;0%&quot;
        android:toXDelta=&quot;-100%&quot;
        android:duration=&quot;0&quot;
        android:fillAfter=&quot;true&quot;
        android:fillEnabled=&quot;true&quot;/&gt;
&lt;/set&gt;
</pre>
<h4>anim/activity_close_exit.xml</h4>
<p>finishで閉じるActivityのanimation。</p>
<pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;set xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
    android:interpolator=&quot;@android:anim/accelerate_interpolator&quot;&gt;
    &lt;translate
        android:fromXDelta=&quot;0%&quot;
        android:toXDelta=&quot;100%&quot;
        android:duration=&quot;0&quot;
        android:fillAfter=&quot;true&quot;
        android:fillEnabled=&quot;true&quot;/&gt;
&lt;/set&gt;
</pre>
<h4>anim/activity_close_open.xml</h4>
<p>finishで開くActivityのanimation。</p>
<pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;set xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
    android:interpolator=&quot;@android:anim/accelerate_interpolator&quot;&gt;
    &lt;translate
        android:fromXDelta=&quot;-100%&quot;
        android:toXDelta=&quot;0%&quot;
        android:duration=&quot;0&quot;
        android:fillAfter=&quot;true&quot;
        android:fillEnabled=&quot;true&quot;/&gt;
&lt;/set&gt;
</pre>
<h5>参考</h5>
<p>上述の内容などは以下のような参考サイトに情報がある。</p>
<ul>
<li><a href="http://www.adamrocker.com/blog/289/activity_open_close_animation.html">ActivityのOpenとCloseをアニメーションさせる</a></li>
<li><a href="http://www.atmarkit.co.jp/fsmart/articles/android21/02.html">アニメーションでAndroidに独創的な画面エフェクトを</a></li>
<li><a href="http://stackoverflow.com/questions/7997753/is-it-possible-to-do-this-android-screen-animation-with-a-viewpager">Is it possible to do this Android screen animation with a ViewPager?</a></li>
<li><a href="http://stackoverflow.com/questions/3925355/android-fadeout-animation-for-splash-screen">Android &#8211; Fadeout animation for splash screen</a></li>
</ul>
</section>
<h4>AndroidManifest.xml</h4>
<h5>アプリケーション全体に適用する</h5>
<p>以下のようにapplicationタグに記述することでアプリケーション全体に変更したアニメーションを適用できる。</p>
<pre class="brush: xml;">
&lt;application
    android:icon=&quot;@drawable/icon&quot;
    android:label=&quot;@string/app_name&quot;
    android:theme=&quot;@style/NoAnimationTheme&quot;&gt;
</pre>
<h5>アクティビティに適用する</h5>
<p>以下のようにactivityタグに記述することで単一のアクティビティにのみ変更したアニメーションを適用できる。</p>
<pre class="brush: xml;">
&lt;activity
    android:label=&quot;@string/app_name&quot;
    android:name=&quot;.MainActivity&quot;&gt;
&lt;/activity&gt;
</pre>
<h3>■応用</h3>
<p>上述の方法だと特定の条件下でのみアニメーションを変えるといったことができない。条件によってanimationを変えたい場合は、以下のようにすることで対応できる。</p>
<pre class="brush: java;">
public class MainActivity extends Activity {
    /**
     * 起動時に実行される
     */
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        setTheme(R.style.NoAnimationTheme);// super.onCreateの前に実行する必要がある
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.justoneplanet.info/2012/01/09/android%e3%81%a7activity%e3%81%8c%e5%88%87%e3%82%8a%e6%9b%bf%e3%82%8f%e3%82%8b%e3%81%a8%e3%81%8d%e3%81%ae%e3%82%a2%e3%83%8b%e3%83%a1%e3%83%bc%e3%82%b7%e3%83%a7%e3%83%b3%e3%82%92%e5%a4%89%e3%81%88/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>androidでギャラリーと連携する</title>
		<link>http://blog.justoneplanet.info/2012/01/08/android%e3%81%a7%e3%82%ae%e3%83%a3%e3%83%a9%e3%83%aa%e3%83%bc%e3%81%a8%e9%80%a3%e6%90%ba%e3%81%99%e3%82%8b/</link>
		<comments>http://blog.justoneplanet.info/2012/01/08/android%e3%81%a7%e3%82%ae%e3%83%a3%e3%83%a9%e3%83%aa%e3%83%bc%e3%81%a8%e9%80%a3%e6%90%ba%e3%81%99%e3%82%8b/#comments</comments>
		<pubDate>Sun, 08 Jan 2012 11:38:40 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[android]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[インテント]]></category>

		<guid isPermaLink="false">http://blog.justoneplanet.info/?p=4912</guid>
		<description><![CDATA[■実装 ギャラリーの起動 以下のようにすることで（画像データに選択肢を絞って）ギャラリーアプリを起動することができる。 Intent intent = new Intent(); intent.setType(&#038;quot [...]]]></description>
			<content:encoded><![CDATA[<h3>■実装</h3>
<h4>ギャラリーの起動</h4>
<p>以下のようにすることで（画像データに選択肢を絞って）ギャラリーアプリを起動することができる。</p>
<pre class="brush: java;">
Intent intent = new Intent();
intent.setType(&quot;image/*&quot;);
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(intent, REQUESTCODE);
</pre>
<h4>ギャラリーからデータを受け取る</h4>
<pre class="brush: java;">
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUESTCODE &amp;&amp; resultCode == RESULT_OK) {
        //data.getData();//ギャラリーで選択したファイルのuriが格納されている
    }
}
</pre>
<section class="kakomi">
<h4>uriからpathの文字列を取得</h4>
<p>以下のようにすることでuriからpathの文字列を取得することができる。</p>
<pre class="brush: java;">
private final String getPathFromUri(Uri uri) {
    String[] projection = { MediaStore.Images.Media.DATA };
    Cursor cursor = managedQuery(uri, projection, null, null, null);
    int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
    cursor.moveToFirst();
    return cursor.getString(column_index);
}
</pre>
<h5>参考</h5>
<ul>
<li><a href="http://stackoverflow.com/questions/3401579/get-filename-and-path-from-uri-from-mediastore">Get filename and path from uri from mediastore</a></li>
</ul>
</section>
]]></content:encoded>
			<wfw:commentRss>http://blog.justoneplanet.info/2012/01/08/android%e3%81%a7%e3%82%ae%e3%83%a3%e3%83%a9%e3%83%aa%e3%83%bc%e3%81%a8%e9%80%a3%e6%90%ba%e3%81%99%e3%82%8b/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>androidで顔検出する</title>
		<link>http://blog.justoneplanet.info/2011/12/29/android%e3%81%a7%e9%a1%94%e6%a4%9c%e5%87%ba%e3%81%99%e3%82%8b/</link>
		<comments>http://blog.justoneplanet.info/2011/12/29/android%e3%81%a7%e9%a1%94%e6%a4%9c%e5%87%ba%e3%81%99%e3%82%8b/#comments</comments>
		<pubDate>Thu, 29 Dec 2011 14:19:28 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[android]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://blog.justoneplanet.info/?p=4887</guid>
		<description><![CDATA[int maxFaces = 10;// 検出する顔の最大数 FaceDetector detector = new FaceDetector(bitmap.getWidth(), bitmap.getHeight(), [...]]]></description>
			<content:encoded><![CDATA[<pre class="brush: java;">
int maxFaces = 10;// 検出する顔の最大数
FaceDetector detector = new FaceDetector(bitmap.getWidth(), bitmap.getHeight(), maxFaces);
FaceDetector.Face[] faces = new FaceDetector.Face[maxFaces];
ArrayList&lt;Bitmap&gt; recognized = new ArrayList&lt;Bitmap&gt;();

// bitmapの中から顔を検出してfacesに格納する
int num = detector.findFaces(bitmap, faces);

// facesに格納されたデータから座標情報を取り出してbitmapを切り出す
for (int i = 0; i &lt; num; i++) {
    FaceDetector.Face face = faces[i];
    PointF point = new PointF(0.0f, 0.0f);
    face.getMidPoint(point);

    int x = (int) (point.x - 1.5f * face.eyesDistance());
    int y = (int) (point.y - 2 * face.eyesDistance());
    int width  = (int) (face.eyesDistance() * 3);
    int height = (int) (face.eyesDistance() * 4);
    x = (x &lt; 0)? 0 : x;
    y = (y &lt; 0)? 0 : y;
    width = (width &gt; bitmap.getWidth())? bitmap.getWidth() : width;
    height = (height &gt; bitmap.getHeight())? bitmap.getHeight() : height;
    recognized.add(Bitmap.createBitmap(bitmap, x, y, width, height));
}
return recognized;
</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.justoneplanet.info/2011/12/29/android%e3%81%a7%e9%a1%94%e6%a4%9c%e5%87%ba%e3%81%99%e3%82%8b/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>androidでprivateメソッドのテストをする</title>
		<link>http://blog.justoneplanet.info/2011/12/25/android%e3%81%a7private%e3%83%a1%e3%82%bd%e3%83%83%e3%83%89%e3%81%ae%e3%83%86%e3%82%b9%e3%83%88%e3%82%92%e3%81%99%e3%82%8b/</link>
		<comments>http://blog.justoneplanet.info/2011/12/25/android%e3%81%a7private%e3%83%a1%e3%82%bd%e3%83%83%e3%83%89%e3%81%ae%e3%83%86%e3%82%b9%e3%83%88%e3%82%92%e3%81%99%e3%82%8b/#comments</comments>
		<pubDate>Sat, 24 Dec 2011 16:53:46 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[android]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://blog.justoneplanet.info/?p=4882</guid>
		<description><![CDATA[そういえば書いてなかったのでメモ。 /** * Hogeクラスのprivateメソッドadd(int a, int b)をテストする * @throws SecurityException * @throws Illeg [...]]]></description>
			<content:encoded><![CDATA[<p>そういえば書いてなかったのでメモ。</p>
<pre class="brush: java;">
    /**
     * Hogeクラスのprivateメソッドadd(int a, int b)をテストする
     * @throws SecurityException
     * @throws IllegalArgumentException
     * @throws NoSuchMethodException
     * @throws IllegalAccessException
     * @throws InvocationTargetException
     */
    public void testAdd() throws SecurityException, IllegalArgumentException, NoSuchMethodException, IllegalAccessException, InvocationTargetException {
        Hoge hoge = new Hoge();
        Class&lt;Hoge&gt; clz = Hoge.class;
        Method method = clz.getDeclaredMethod(&quot;add&quot;, Integer.class, Integer.class);
        method.setAccessible(true);
        int result = (int) method.invoke(hoge, 5, 3);
        asserTrue(result == 8);
    }
</pre>
<p>staticメソッドの場合は以下のようになる。</p>
<pre class="brush: java;">
    /**
     * Hogeクラスのprivate staticメソッドadd(int a, int b)をテストする
     * @throws SecurityException
     * @throws IllegalArgumentException
     * @throws NoSuchMethodException
     * @throws IllegalAccessException
     * @throws InvocationTargetException
     */
    public void testAdd() throws SecurityException, IllegalArgumentException, NoSuchMethodException, IllegalAccessException, InvocationTargetException {
        Class&lt;Hoge&gt; clz = Hoge.class;
        Method method = clz.getDeclaredMethod(&quot;add&quot;, Integer.class, Integer.class);
        method.setAccessible(true);
        int result = (int) method.invoke(clz, 5, 3);
        asserTrue(result == 8);
    }
</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.justoneplanet.info/2011/12/25/android%e3%81%a7private%e3%83%a1%e3%82%bd%e3%83%83%e3%83%89%e3%81%ae%e3%83%86%e3%82%b9%e3%83%88%e3%82%92%e3%81%99%e3%82%8b/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>androidでArrayAdapterを使う</title>
		<link>http://blog.justoneplanet.info/2011/12/24/android%e3%81%a7arrayadapter%e3%82%92%e4%bd%bf%e3%81%86/</link>
		<comments>http://blog.justoneplanet.info/2011/12/24/android%e3%81%a7arrayadapter%e3%82%92%e4%bd%bf%e3%81%86/#comments</comments>
		<pubDate>Sat, 24 Dec 2011 11:05:58 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[android]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://blog.justoneplanet.info/?p=4876</guid>
		<description><![CDATA[■実装 mListView = (ListView) findViewById(R.id.list); mListView.setAdapter(mOriginalArrayAdapter); mOriginalArra [...]]]></description>
			<content:encoded><![CDATA[<h3>■実装</h3>
<pre class="brush: java;">
mListView = (ListView) findViewById(R.id.list);
mListView.setAdapter(mOriginalArrayAdapter);
</pre>
<p>mOriginalArrayAdapterを生成するとする。</p>
<pre class="brush: java;">
public class OriginalArrayAdapter extends ArrayAdapter&lt;OriginalDataRow&gt; {
    private LayoutInflater inflater;

    /**
     * セル内における可変要素
     */
    public static class ViewHolder {
        public TextView text;
    }

    public OriginalArrayAdapter(Context context, int textViewResourceId, ArrayList&lt;OriginalDataRow&gt; data) {
        super(context, textViewResourceId, data);
        inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        final OriginalDataRow data = getItem(position);// フィールドなどから取得してはいけない...(a)

        // viewのセットアップ
        ViewHolder holder = null;
        if (convertView == null){
            holder = new ViewHolder();
            convertView = inflater.inflate(R.layout.cell_original_data, null);
            holder.text = (TextView) convertView.findViewById(R.id.text);
            convertView.setTag(holder);
        }
        else {
            holder = (ViewHolder) convertView.getTag();
        }

        // dataをviewに書き出す
        holder.text.setText(data.text);
        return convertView;
    }
}
</pre>
<h4>filterを使用する</h4>
<pre class="brush: java;">
    @Override
    public void onTextChanged(CharSequence s, int start, int count, int after) {
        String query = mEditText.getText().toString();
        if (query.equals(&quot;&quot;)) {
            mListView.clearTextFilter();
        }
        else {
            mListView.setFilterText(query);
        }
    }
</pre>
<p>(a)の部分でsuperクラスのgetItemを使用しないとフィルタリングが上手く適用されない。また、filterを使用する場合は、リストアイテムのtoString値が使用されるため、以下のように必要に応じてOverrideする必要がある。</p>
<pre class="brush: java;">
public class OriginalDataRow {
    public String name;
    @Override
    public String toString() {
        return name;// filterに使用する文字列
    }
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.justoneplanet.info/2011/12/24/android%e3%81%a7arrayadapter%e3%82%92%e4%bd%bf%e3%81%86/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>androidのSQLiteでAUTOINCREMENT値を取得する</title>
		<link>http://blog.justoneplanet.info/2011/11/11/android%e3%81%aesqlite%e3%81%a7autoincrement%e5%80%a4%e3%82%92%e5%8f%96%e5%be%97%e3%81%99%e3%82%8b/</link>
		<comments>http://blog.justoneplanet.info/2011/11/11/android%e3%81%aesqlite%e3%81%a7autoincrement%e5%80%a4%e3%82%92%e5%8f%96%e5%be%97%e3%81%99%e3%82%8b/#comments</comments>
		<pubDate>Fri, 11 Nov 2011 05:59:39 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[android]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[SQLite]]></category>

		<guid isPermaLink="false">http://blog.justoneplanet.info/?p=4760</guid>
		<description><![CDATA[SELECT `seq` FROM sqlite_sequence WHERE `name` = 'TABLENAME'; 上述を踏まえて以下のようにすることで取得できる。 /** * auto_incrementで代入 [...]]]></description>
			<content:encoded><![CDATA[<pre class="brush: sql;">
SELECT `seq` FROM sqlite_sequence WHERE `name` = 'TABLENAME';
</pre>
<p>上述を踏まえて以下のようにすることで取得できる。</p>
<pre class="brush: java;">
    /**
     * auto_incrementで代入した最大値
     * @return
     */
    public long getLastInsertId() {
        long index = 0;
        SQLiteDatabase sdb = getReadableDatabase();
        Cursor cursor = sdb.query(
                &quot;sqlite_sequence&quot;,
                new String[]{&quot;seq&quot;},
                &quot;name = ?&quot;,
                new String[]{TABLENAME},
                null,
                null,
                null,
                null
        );
        if (cursor.moveToFirst()) {
            index = cursor.getLong(cursor.getColumnIndex(&quot;seq&quot;));
        }
        cursor.close();
        return index;
    }
</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.justoneplanet.info/2011/11/11/android%e3%81%aesqlite%e3%81%a7autoincrement%e5%80%a4%e3%82%92%e5%8f%96%e5%be%97%e3%81%99%e3%82%8b/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>robotiumを使ってみる</title>
		<link>http://blog.justoneplanet.info/2011/11/05/robotium%e3%82%92%e4%bd%bf%e3%81%a3%e3%81%a6%e3%81%bf%e3%82%8b/</link>
		<comments>http://blog.justoneplanet.info/2011/11/05/robotium%e3%82%92%e4%bd%bf%e3%81%a3%e3%81%a6%e3%81%bf%e3%82%8b/#comments</comments>
		<pubDate>Fri, 04 Nov 2011 21:25:27 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[android]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[テスト]]></category>

		<guid isPermaLink="false">http://blog.justoneplanet.info/?p=4709</guid>
		<description><![CDATA[@ayunyanさんに教えていただいたので使ってみる。 ■シナリオ 以下のようにandroid版顔文字辞典を操作するとする。 メニューを開く カテゴリ追加をタップする カテゴリ名を入力し登録する(a) 登録したカテゴリ( [...]]]></description>
			<content:encoded><![CDATA[<p>@ayunyanさんに教えていただいたので使ってみる。</p>
<h3>■シナリオ</h3>
<p>以下のようにandroid版顔文字辞典を操作するとする。</p>
<ol>
<li>メニューを開く</li>
<li>カテゴリ追加をタップする</li>
<li>カテゴリ名を入力し登録する(a)</li>
<li>登録したカテゴリ(a)をロングタップする</li>
<li>編集を選択する</li>
<li>カテゴリ名を変更して登録する(b)</li>
<li>編集したカテゴリ(b)をロングタップする</li>
<li>削除をタップする</li>
</ol>
<h3>■テストコード</h3>
<p>以下のようにして「みんなの顔文字辞典」のカテゴリー追加・編集・削除のダイアログのテストを行う。</p>
<pre class="brush: java;">
package info.justoneplanet.android.kaomoji.test.dialog;

import com.jayway.android.robotium.solo.Solo;

import info.justoneplanet.android.kaomoji.KaomojiFavorite;
import info.justoneplanet.android.kaomoji.R;
//import android.app.Instrumentation;
import android.test.ActivityInstrumentationTestCase2;

/**
 * カテゴリを追加するダイアログのテストケース
 * @author justoneplanet
 * カテゴリの登録・編集・削除は決まった順番で行われる必要があるためメソッド名で順序を指定した
 */
public class CategoryDialogBuilderTest extends ActivityInstrumentationTestCase2&lt;KaomojiFavorite&gt; {

    private KaomojiFavorite mActivity;
    //private Instrumentation mInstrumentation;
    private Solo solo;

    private static final String OLD_CATEGORY_NAME = &quot;新しいカテゴリ&quot;;
    private static final String NEW_CATEGORY_NAME = &quot;新カテゴリ&quot;;

    public CategoryDialogBuilderTest() {
        super(&quot;info.justoneplanet.android.kaomojifavorite&quot;, KaomojiFavorite.class);
    }

    @Override
    public void setUp() throws Exception {
        super.setUp();
        mActivity = getActivity();
        //mInstrumentation = getInstrumentation();
        solo = new Solo(getInstrumentation(), getActivity());
    }

    @Override
    public void tearDown() throws Exception {
        super.tearDown();
        mActivity = null;
        //mInstrumentation = null;
    }

    /**
     * カテゴリを正しく追加できるか
     */
    public void testCategory1Add() {
        // メニュー &gt; カテゴリを追加
        solo.clickOnMenuItem(mActivity.getString(R.string.menu_category_add));
        solo.enterText(0, OLD_CATEGORY_NAME);// 新しいカテゴリ名を入力
        // 登録するボタン
        solo.clickOnButton(mActivity.getString(R.string.function_register_category));
    }

    /**
     * カテゴリを正しく追加できるか
     */
    public void testCategory2Edit() {
        // リストの最後の要素がわからないのでテキストで探索
        solo.clickLongOnText(OLD_CATEGORY_NAME);
        // カテゴリの編集をクリック
        solo.clickOnText(mActivity.getString(R.string.function_edit_category));
        solo.clearEditText(0);// テキストを消す
        solo.enterText(0, NEW_CATEGORY_NAME);// 新カテゴリ名を入力
        // 登録するボタン
        solo.clickOnButton(mActivity.getString(R.string.function_register_category));
    }

    /**
     * カテゴリを削除できるか
     * @throws InterruptedException
     */
    public void testCategory3Delete() {
        // リストの最後の要素がわからないのでテキストで探索
        solo.clickLongOnText(NEW_CATEGORY_NAME);
        // カテゴリの削除をクリック
        solo.clickOnText(mActivity.getString(R.string.function_delete_category));
        // すぐに終了してしまうと削除クエリが実行されないみたい（Thread.sleepよりもこっち）
        solo.waitForDialogToClose(1000);
    }
}
</pre>
<p>操作する要素がテキストで指定できる探索が非常にテストを行いやすい！感謝！</p>
<section class="kakomi">
<h4>clickInListについて</h4>
<p>以下のようにして使用した。おそらく表示しているlistアイテムの配列の中でのpositionを指定していると思われる。また、表示されていないlistアイテムを上からの位置で指定することはできなかった。</p>
<pre class="brush: java;">
private String tapEmoticonAfterCategory(String category, int position) {
    solo.clickOnText(category);
    solo.waitForDialogToClose(1000);// 作用するまでwait
    ArrayList&lt;TextView&gt; list = solo.clickInList(position);// 表示されているlistの要素配列のposition
    solo.waitForDialogToClose(1000);// 作用するまでwait
    Log.e(&quot;tapped&quot;, String.valueOf(list.get(0).getText()));
    return String.valueOf(list.get(0).getText());
}
</pre>
</section>
<h3>■参考</h3>
<ul>
<li><a href="http://code.google.com/p/robotium/">robotium</a></li>
</ul>
<section>
<h4>おまけ</h4>
<p>当初は以下のようにThread.sleepを使用していたが、ProgressDialogを表示し通信結果を待つような場合に期待した動作にならなかった。</p>
<pre class="brush: java;">
    /**
     * カテゴリを削除できるかテストする
     * @throws InterruptedException
     */
    public void testCategory3Delete() throws InterruptedException {
        // リストの最後の要素がわからないのでテキストで探索
        solo.clickLongOnText(NEW_CATEGORY_NAME);
        // カテゴリの削除をクリック
        solo.clickOnText(mActivity.getString(R.string.function_delete_category));
        Thread.sleep(1000);// 期待の動作とならない
    }
</pre>
</section>
<p>テキスト（半角カナ？）によってはいまいち探索できないときがある。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.justoneplanet.info/2011/11/05/robotium%e3%82%92%e4%bd%bf%e3%81%a3%e3%81%a6%e3%81%bf%e3%82%8b/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>AsyncTaskのテストをする</title>
		<link>http://blog.justoneplanet.info/2011/11/04/asynctask%e3%81%ae%e3%83%86%e3%82%b9%e3%83%88%e3%82%92%e3%81%99%e3%82%8b/</link>
		<comments>http://blog.justoneplanet.info/2011/11/04/asynctask%e3%81%ae%e3%83%86%e3%82%b9%e3%83%88%e3%82%92%e3%81%99%e3%82%8b/#comments</comments>
		<pubDate>Fri, 04 Nov 2011 05:18:52 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[android]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[テスト]]></category>

		<guid isPermaLink="false">http://blog.justoneplanet.info/?p=4700</guid>
		<description><![CDATA[■コード 以下のようにUIスレッドでAsyncTaskをインスタンス化する必要がある。 public class EveryoneTaskTest extends ActivityInstrumentationTestC [...]]]></description>
			<content:encoded><![CDATA[<h3>■コード</h3>
<p>以下のようにUIスレッドでAsyncTaskをインスタンス化する必要がある。</p>
<pre class="brush: java;">
public class EveryoneTaskTest extends ActivityInstrumentationTestCase2&lt;Kaomoji&gt; {
    private Kaomoji mActivity;
    private Instrumentation mInstrumentation;
    private EveryoneTask everyoneHttp;
    private CountDownLatch countDownLatch;
    private String mResult;

    public EveryoneTaskTest() {
        super(&quot;info.justoneplanet.android.kaomoji&quot;, Kaomoji.class);
    }

    @Override
    protected void setUp() throws Exception {
        super.setUp();
        mActivity = getActivity();
        mInstrumentation = getInstrumentation();
        countDownLatch = new CountDownLatch(1);
    }
    @Override
    protected void tearDown() throws Exception {
        super.tearDown();
        mActivity = null;
        mInstrumentation = null;
    }

    public void testExecute() throws InterruptedException, JSONException {
        mActivity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                everyoneHttp = new EveryoneTask(new EveryoneTask.Observer(){
                    @Override
                    public void onHttpUpdate(String result, MODE mode) {
                        mResult = result;
                        countDownLatch.countDown();// カウントを0にする
                    }
                });
                everyoneHttp.execute(null);
            }
        });
        countDownLatch.await();// countが0になるまで処理を待機

        // 要素の検証
        JSONObject elm;
        JSONArray ary = new JSONArray(mResult);
        assertTrue(ary.length() == 150);
    }
}
</pre>
<section class="kakomi">
<h4>失敗例</h4>
<p>以下のようにアプリのメインスレッド以外でAsyncTaskのインスタンス化を行なってはならない。挙動が不安定になりonPostExecuteが実行されない。</p>
<pre class="brush: java;">
/**
 * みんなな顔文字を通信して取得するクラスのテストケース
 * @author justoneplanet
 */
public class EveryoneHttpTest extends AndroidTestCase implements EveryoneHttp.Observer {
    CountDownLatch countDownLatch;
    private EveryoneHttp everyoneHttp;
    private String mResult;

    @Override
    protected void setUp() throws Exception {
        super.setUp();
        countDownLatch = new CountDownLatch(1);
    }

    public void testDoInBackground() throws InterruptedException, JSONException {
        everyoneHttp = new EveryoneHttp(this);// get everyone's emoticons from transfer
        everyoneHttp.execute();
        countDownLatch.await();// countが0になるまで処理を待機

        JSONArray ary = new JSONArray(mResult);
        assertTrue(ary.length() == 150);// 要素数の検証

        // 要素の検証
        JSONObject elm = ary.getJSONObject(0);
        Log.e(&quot;elm&quot;, elm.toString());
        assertFalse(elm.getString(&quot;face&quot;).equals(null));
        assertFalse(elm.getString(&quot;tag&quot;).equals(null));
    }

    /**
     * 通信完了後に実行される
     */
    @Override
    public void onHttpUpdate(String result) {
        mResult = result;
        countDownLatch.countDown();// カウントを0にする
    }
}
</pre>
</section>
<p>非同期処理自体はAsyncTaskをwrapしたクラスで行なっている。Observerを使ったのでテストコードもすっきり。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.justoneplanet.info/2011/11/04/asynctask%e3%81%ae%e3%83%86%e3%82%b9%e3%83%88%e3%82%92%e3%81%99%e3%82%8b/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>androidでAndroidWebDriverを使ってみる</title>
		<link>http://blog.justoneplanet.info/2011/11/01/android%e3%81%a7androidwebdriver%e3%82%92%e4%bd%bf%e3%81%a3%e3%81%a6%e3%81%bf%e3%82%8b/</link>
		<comments>http://blog.justoneplanet.info/2011/11/01/android%e3%81%a7androidwebdriver%e3%82%92%e4%bd%bf%e3%81%a3%e3%81%a6%e3%81%bf%e3%82%8b/#comments</comments>
		<pubDate>Mon, 31 Oct 2011 15:34:08 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[android]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[テスト]]></category>

		<guid isPermaLink="false">http://blog.justoneplanet.info/?p=4687</guid>
		<description><![CDATA[元ネタはTim BrayのIntroducing Android WebDriverという記事。 ■準備 テストプロジェクトで右クリックし「propaties＞ Java Build Path ＞ Libraries ＞ [...]]]></description>
			<content:encoded><![CDATA[<p>元ネタはTim Brayの<a href="http://android-developers.blogspot.com/2011/10/introducing-android-webdriver.html?utm_source=feedburner&#038;utm_medium=feed&#038;utm_campaign=Feed%3A+blogspot%2FhsDu+%28Android+Developers+Blog%29&#038;utm_content=Google+Reader">Introducing Android WebDriver</a>という記事。</p>
<h3>■準備</h3>
<p>テストプロジェクトで右クリックし「propaties＞ Java Build Path ＞ Libraries ＞ Add External JARs」で以下のjarをインポートする。</p>
<ul>
<li>android_webdriver_library-srcs.jar</li>
<li>android_webdriver_library.jar</li>
<li><a href="http://code.google.com/p/guava-libraries/">guava-10.0.1.jar</a></li>
</ul>
<h3>■コード</h3>
<p>Tim様の記事ではgoogle.comが使用されているが以下のような理由によってテストにパスしない。</p>
<ul>
<li>ロケールが違うので日本語表示される</li>
<li>結果がリッチすぎて上手くdomを抽出できない</li>
</ul>
<p>テストコード内でgoogle.comのリンクをクリックするようにできると思うが、html構造を把握するのが大変なので以下のようなコードでmozillaのサイトでテストすることにした。</p>
<pre class="brush: java;">
package bootcamp2011.android.test;

import java.util.List;

import bootcamp2011.android.Bootcamp2011Activity;
import android.test.ActivityInstrumentationTestCase2;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.android.AndroidWebDriver;;

public class Bootcamp2011ActivityTest extends
        ActivityInstrumentationTestCase2&lt;Bootcamp2011Activity&gt; {

    private AndroidWebDriver driver;

    public Bootcamp2011ActivityTest() {
        super(&quot;bootcamp2011.android.bootcamp2011activity&quot;, Bootcamp2011Activity.class);
    }

    @Override
    protected void setUp() throws Exception {
      driver = new AndroidWebDriver(getActivity());
    }

    @Override
    protected void tearDown() {
       driver.quit();
    }

    public void testGoogleShouldWork() {
        // mozillaのサイトを訪問
        driver.get(&quot;https://developer.mozilla.org/ja/JavaScript&quot;);

        // 検索boxを抽出して文字入力し送信
        WebElement searchBox = driver.findElement(By.id(&quot;q&quot;));
        searchBox.sendKeys(&quot;querySelector&quot;);
        searchBox.submit();

        // 検索結果にquerySelectorという文字列が含まれているかテスト（仮）
        WebElement resultSection = driver.findElement(By.id(&quot;search-results&quot;));
        List&lt;WebElement&gt; searchResults = resultSection.findElements(By.tagName(&quot;table&quot;));
        WebElement result = searchResults.get(0);
        assertTrue(result.getText().contains(&quot;querySelector&quot;));
    }
}
</pre>
<p>By.cssSelector()というメソッドがあるのだが上手く働かない&#8230;一応、動作するサンプルが「android-sdk-mac_x86/extras/google/webdriver/TestAnAndroidWebApp/src/simple/app/test/SimpleGoogleTest.java」にある。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.justoneplanet.info/2011/11/01/android%e3%81%a7androidwebdriver%e3%82%92%e4%bd%bf%e3%81%a3%e3%81%a6%e3%81%bf%e3%82%8b/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SimpleCursorTreeAdapterのgetChildrenCursorがアプリ起動時にも実行される</title>
		<link>http://blog.justoneplanet.info/2011/10/27/simplecursortreeadapter%e3%81%aegetchildrencursor%e3%81%8c%e3%82%a2%e3%83%97%e3%83%aa%e8%b5%b7%e5%8b%95%e6%99%82%e3%81%ab%e3%82%82%e5%ae%9f%e8%a1%8c%e3%81%95%e3%82%8c%e3%82%8b/</link>
		<comments>http://blog.justoneplanet.info/2011/10/27/simplecursortreeadapter%e3%81%aegetchildrencursor%e3%81%8c%e3%82%a2%e3%83%97%e3%83%aa%e8%b5%b7%e5%8b%95%e6%99%82%e3%81%ab%e3%82%82%e5%ae%9f%e8%a1%8c%e3%81%95%e3%82%8c%e3%82%8b/#comments</comments>
		<pubDate>Wed, 26 Oct 2011 15:33:05 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[android]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://blog.justoneplanet.info/?p=4653</guid>
		<description><![CDATA[android 2.3未満で起こった挙動のメモ。android 2.3以降では起こらない。 メモ 以下のようにして開閉可能なListActivityを定義する。 public class KaomojiFavorite  [...]]]></description>
			<content:encoded><![CDATA[<p>android 2.3未満で起こった挙動のメモ。android 2.3以降では起こらない。</p>
<section class="kakomi">
<h4>メモ</h4>
<p>以下のようにして開閉可能なListActivityを定義する。</p>
<pre class="brush: java;">
public class KaomojiFavorite extends ExpandableListActivity implements FavoriteHelper.Listener {
    private FavoriteHelper favoriteHelper;
    private CategoryHelper categoryHelper;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getExpandableListView().setCacheColorHint(0);// scroll時の背景

        // カテゴリを取得
        categoryHelper = new CategoryHelper(getApplicationContext(), null);
        Cursor categoryCursor = categoryHelper.getCursor();
        startManagingCursor(categoryCursor);

        // お気に入りを取得してlistにセット
        favoriteHelper = new FavoriteHelper(getApplicationContext(), null);
        ExpandableListAdapter adapter = favoriteHelper.getSimpleAdapter(this, categoryCursor);
        setListAdapter(adapter);

    }
</pre>
<p>カテゴリ毎にお気に入りを表示する仕組みだ。FavoriteHelperクラスの実装は以下のようになっている。</p>
<pre class="brush: java;">
    public ExpandableListAdapter getSimpleAdapter(Listener listener, Cursor categoryCursor)
    {
        mListener = listener;
        ExpandableListAdapter adapter = new ExpandableListAdapter(
                mContext,
                categoryCursor,
                R.layout.category,
                new String []{&quot;_id&quot;, &quot;name&quot;},
                new int []{R.id.list_id, R.id.list_category},
                R.layout.list,
                new String []{&quot;item&quot;, &quot;_id&quot;},
                new int []{R.id.list_item, R.id.list_id}
        );
        return adapter;
    }

    /**
     * categoryデータ（Cursor）を元にしてExpandableListActivity用のAdapterを生成する
     * @author justoneplanet
     */
    public class ExpandableListAdapter extends SimpleCursorTreeAdapter {

        public ExpandableListAdapter(Context context, Cursor groupCursor,
                int groupLayout, String[] groupFrom, int[] groupTo,
                int childLayout, String[] childFrom, int[] childTo) {
            super(context, groupCursor, groupLayout, groupFrom, groupTo, childLayout, childFrom, childTo);
        }

        /**
         * カテゴリ用のCursorからIDを取得して子データを検索取得する
         * android 2.2以前ではアプリ起動時にも実行される
         */
        @Override
        protected Cursor getChildrenCursor(Cursor groupCursor) {
            final long idCategory = groupCursor.getLong(groupCursor.getColumnIndex(&quot;_id&quot;));
            SQLiteDatabase sdb = getReadableDatabase();
            Cursor cursor = sdb.query(
                    &quot;favorite&quot;,
                    new String[]{&quot;_id&quot;, &quot;id_category&quot;, &quot;item&quot;},
                    &quot;id_category = ?&quot;,
                    new String[]{String.valueOf(idCategory)},
                    null,
                    null,
                    null,
                    null
            );
            mListener.onGetChildrenCursor(cursor);
            return cursor;
        }
    }
</pre>
</section>
<p>以上。めも。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.justoneplanet.info/2011/10/27/simplecursortreeadapter%e3%81%aegetchildrencursor%e3%81%8c%e3%82%a2%e3%83%97%e3%83%aa%e8%b5%b7%e5%8b%95%e6%99%82%e3%81%ab%e3%82%82%e5%ae%9f%e8%a1%8c%e3%81%95%e3%82%8c%e3%82%8b/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

