2014年3月20日木曜日

Android - 自動でソフトキーボードが出るのを防ぐ

アプリを起動して、最初にEditTextにフォーカスが当たってしまうと、ソフトキーボードが自動で出てしまいます。これが嫌だったので、対策メモ。

この自動でソフトキーボードが出てしまうのを防ぐには、
public class TestActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
        setContentView(R.layout.activity_main);
    }

}
setSoftInputMode()で、WindowManager.LayoutParamsを設定します。

「SOFT_INPUT_STATE_ALWAYS_HIDDEN」

を設定すると、見事にアプリ起動時にEditTextにフォーカスがあたってもソフトキーボードがでなくなりました。対象のEditTextをクリックすると、ちゃんとソフトキーボードが出ます。

これで、一件落着。

ちなみに、

「SOFT_INPUT_STATE_HIDDEN」

を設定しても、同じ効果が得られます。

さて、何が違うんだろう。


参考:
WindowManager.LayoutParams | Android Developers
Y.A.M の 雑記帳: Android 自動でソフトキーボードが出るのを防ぐ

2014年3月16日日曜日

Android - Theme.Holo.Light.DarkActionBarだとOverflowメニューのフォントカラーが変わらない

Overflowメニューのフォントカラーを変えるために、「textAppearanceLargePopupMenu」を使用したのですが、parentが「Theme.Holo」や「Theme.Holo.Light」だと変更されるのですが、「Theme.Holo.Light.DarkActionBar」だと変更されなかったので、対策メモ。
<style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar">
    <item name="android:itemTextAppearance">@style/itemTextAppearance</item>
</style>

<style name="itemTextAppearance">
    <item name="android:textColor">@android:color/holo_blue_bright</item>
</style>
「itemTextAppearance」を使用すると、フォントカラーを変更することができます。

あと、「itemBackground」を使用すると、Overflowメニューの背景を変えることができます。


こんなところで。

2014年3月10日月曜日

Android Studio - Espressoを使えるようにする

Android StudioでのテストでEspressoを導入したので、導入メモ。
Android Studioのバージョンは、0.5.1を使用しています。


1. 開発者向けオプションの設定

「設定」-「開発者向けオプション」の以下の設定をオフにします。
・ウィンドウアニメスケール
・トランジションアニメスケール
・Animator再生時間スケール


2. ライブラリーを追加する

ライブラリーには、依存ライブラリーを含めたstandaloneと依存ライブラリーが別々になっているdependenciesがあります。
今回は、standaloneを使用します。

standaloneからzipファイルをダウンロードします。
「bin」-「espresso-standalone」に「espresso-1.1-bundled.jar」がありますので、プロジェクトの「libs」フォルダーへコピーします。


3. AndroidManifest.xmlを編集する

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="パッケージ名" >

    <application>
        <uses-library android:name="android.test.runner" />
    </application>

    <instrumentation
        android:name="com.google.android.apps.common.testing.testrunner.GoogleInstrumentationTestRunner"
        android:targetPackage="ターゲットパッケージ名" />
</manifest>
この段階では、「android:name」が赤い文字になっていますが、「build.gradle」ファイルを編集し、同期させると正常に認識されます。

「android:targetPackage」も赤い文字になっていますが、原因はまだわかっていません。とりあえず問題はないので、そのままで大丈夫です。


4. build.gradleを編集する

android {
    defaultConfig {
        testInstrumentationRunner "com.google.android.apps.common.testing.testrunner.GoogleInstrumentationTestRunner"
    }
}
dependencies {
    androidTestCompile files('libs/espresso-1.1-bundled.jar')
}

入力が終わったら、同期をさせます。


5. Run/Debug Configurationを編集する

「Run」-「Edit Configurations…」を開き、「+」ボタンを押して、「Android Test」を選択します。
「Name」に適宜名前を入力し、「Specific instrumentation runner (optional)」に以下を入力します。

com.google.android.apps.common.testing.testrunner.GoogleInstrumentationTestRunner

入力したら、「OK」ボタンを押します。


これで、Android StudioでEspressoを使用することができます。


6. サンプル
import static com.google.android.apps.common.testing.ui.espresso.Espresso.onView;
import static com.google.android.apps.common.testing.ui.espresso.action.ViewActions.click;
import static com.google.android.apps.common.testing.ui.espresso.matcher.ViewMatchers.withId;

import android.test.ActivityInstrumentationTestCase2;

public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActivity> {

    public MainActivityTest() {
        super(MainActivity.class);
    }

    public void setUp() throws Exception {
        super.setUp();
        getActivity();
    }

    public void testMethod() {
        onView(withId(R.id.button1)).perform(click());
    }
}


こんなかんじです。


参考:
Espresso
EspressoSamples
Y.A.M の 雑記帳: Android UI Testing framework の Espresso を使う

Android - ActivityInstrumentationTestCase2でtestSuiteConstructionFailed

ActivityInstrumentationTestCase2を使ってユニットテストをした際、

java.lang.RuntimeException: Exception during suite construction
at android.test.suitebuilder.TestSuiteBuilder$FailedToCreateTests.testSuiteConstructionFailed


で、落ちる現象でハマったので、メモ。

原因は、
public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActivity> {

    public MainActivityTest(Class<MainActivity> activityClass) {
        super(activityClass);
    }
}
自動で作成されるコンストラクタの引数にあります。
コンストラクタに引数があると、上記のエラーで落ちてしまいます。
エラーを取り除くには、引数なしのコンストラクタにする必要があります。
public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActivity> {

    public MainActivityTest() {
        super(MainActivity.class);
    }
}
これで、エラーが出なくなります。


こんなところで。

2014年3月7日金曜日

Android Studio - Version 0.5.0 でGradle plug-inエラー

Android Studioのバージョンが、0.5.0になったので、バージョンアップしたら、

The project is using an unsupported version of the Android Gradle plug-in (0.8.3).
Version 0.9.0 introduced incompatible changes in the build language.

のエラーが出て、ビルド出来なくなってしまったので、対策メモ。

プロジェクトルート直下にある「build.gradle」を開き、
dependencies {
    classpath 'com.android.tools.build:gradle:0.8.+'
}
のところを、
dependencies {
    classpath 'com.android.tools.build:gradle:0.9.+'
}
に変更します。

変更後、「Sync Project with Gradle Files」ボタンを押すと、新しいバージョンのGradle plug-in がダウンロードされて、正常にビルドができるようになります。

参考:
Getting Started with Android Studio | Android Developers
Android Studio 0.5.0 Released


こんなところで。

Android - ClickableSpanのアンダーラインを消す

特定の文字列にClickableSpanを適用させると、デフォルトではリンクにアンダーラインがつくのですが、このアンダーラインを消したかったので、消し方をメモ。
public class TestFragment extends Fragment {
    public static class NonUnderlinedClickableSpan extends ClickableSpan
    {
        @Override
        public void updateDrawState(TextPaint ds) {
            ds.setColor(Color.BLUE);
            ds.setUnderlineText(false);
        }

        @Override
        public void onClick(View widget) {
        }
    }
}
ClickableSpanを継承したクラスを作成し、updateDrawState()をオーバーライドします。updateDrawState()の中で、setUnderlineText(false)にしてあげるとアンダーラインが消えます。

このupdateDrawState()の中でsetColor()を使うと、文字の色も変えることが出来ます。

あと、URLSpan()でも同じ方法で、アンダーラインを消したり、文字と色を変えることが出来ます。
public class TestFragment extends Fragment {
    public static class NonUnderlinedURLSpan extends URLSpan {
        public NonUnderlinedURLSpan(String url) {
            super(url);
        }

        @Override
        public void updateDrawState(TextPaint ds) {
            ds.setColor(Color.BLUE);
            ds.setUnderlineText(false);
        }
    }
}
 
 
こんなところで。

2014年3月2日日曜日

Android Studio - assetsフォルダーの設定

Android Studioの「assets」フォルダーが、ADTと違っていたので、メモ。


Android Studioで、「assets」フォルダーを使用する場合は、「main」フォルダーの下に作成します。設定は、特に必要ありません。「assets」フォルダーを作成するだけで認識します。

ちなみに、この設定は、「main」フォルダーと同じ階層にある、「プロジェクト名.iml」というファイルの中に記述されています。


こんなところかな。

Android Studio - Volleyを使えるようにする

Android StudioでVolleyを使ってみたので、その際の設定メモ。


1. Gitリポジトリをクローンする。

Volleyは、Jar形式での配布は行われていないので、Volleyライブラリを使うためにソースコードを取得します。ソースコードは、Gitリポジトリで公開されています。

Gitリポジトリで公開されているソースコードなのですが、どうもADT用らしいので、まずEclipsの「Git Repository Exploring」を起動させます。

「Git Repository Exploring」の「Clone a Git repository」からリポジトリをクローンします。

「Location」-「URI」に、

 https://android.googlesource.com/platform/frameworks/volley/

と入力。「Host」と「Repository path」は、自動補完されます。

入力したら、「Next」をクリック。

「Branch Selection」で、たくさん出てきますが、「master」だけ選択して、「Next」をクリック。

「Destination」-「Directory」に、保存先を入力します。
「Projects」-「Import all existing projects after clone finishes」にチェックをつけて、「finish」をクリック。

リポジトリのクローンが終わると、Volleyライブラリが表示されます。

Git Repository Exploringでの作業は、これで終わりです。
次に、「Java」パースペクティブに戻ります。


2. volley.jarを作成する。

「Java」パースペクティブに戻って、「Package Explorer」を見ると、

「Volley」
「VplleyTests」

プロジェクトが作成されています。

その、「Volley」プロジェクトを選択して、右クリックし、「Properties」を選択します。

プロパティが開いたら、

「Android」-「Is Library」

にチェックを入れて、ライブラリとして扱えるようにします。
チェックを入れたら、「OK」をクリック。

「Package Explorer」に戻ると、「volley」-「bin」の中に、「volley.jar」が作成されています。

この「volley.jar」をAndroid Studioの「libs」フォルダーにコピーして使用します。


3. Android Studioでの作業

「libs」フォルダーに「volley.jar」をコピーしたら、ツールバーにある「Sync Project with Gradle Files」ボタンを押すだけです。


これで、Android StudioでVolleyが使えるようになります。


こんなところかな。


参考:
Effective Android

2014年3月1日土曜日

Android - バックキー操作で、メニューが開かなくなる

バックキーを検知して、処理を記入したら、メニューボタンを押してもメニューが開かなくなってしまったので、対策メモ。
public class TestActivity extends Activity {
    @Override
    public boolean dispatchKeyEvent(KeyEvent event) {
        if (event.getAction() == KeyEvent.ACTION_DOWN) {
            switch (event.getKeyCode()) {
                case KeyEvent.KEYCODE_BACK:
                    // 処理を記入
                    return false;
                case KeyEvent.KEYCODE_MENU:
                    openOptionsMenu();
                    return false;
            }
        }
        return super.dispatchKeyEvent(event);
    }
}
たんに、openOptionsMenu()を呼び出しているだけですが、このopenOptionsMenu()にたどり着くまでに、結構時間がかかってしまった。


こんなところで。

Android - ギャラリーにある画像のパスを取得する

Intent使用してギャラリーを起動させ、ギャラリーにある画像を選択し、パスを取得する機会があったので、メモ。
public class TestFragment extends Fragment {
    private static final int REQUEST_CODE = 0;

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        Intent intent = new Intent(Intent.ACTION_PICK);
        intent.setType("image/*");
        startActivityForResult(intent, REQUEST_CODE);
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == REQUEST_CODE) {
            switch (resultCode) {
                case Activity.RESULT_OK:
                    String[] projection = {MediaStore.MediaColumns.DATA};
                    String selection = null;
                    String[] selectionArgs = null;
                    String sortOrder = null;
                    Cursor cursor = getActivity().getContentResolver().query(data.getData(), projection, selection, selectionArgs, sortOrder);
                    if (cursor.getCount() == 1) {
                        cursor.moveToNext();
                        String filePath = cursor.getString(0);
                        Toast.makeText(getActivity(), filePath, Toast.LENGTH_LONG).show();
                    }
            }
        }
    }
}
startActivityForResult()でギャラリーを起動させ、画像を選択すると、onActivityResult()で、結果が受け取れます。

onActivityResult()の「data」にファイルのパス情報がURIとして格納されていますので、getContentResolver().query()の第一引数として「data.getData()」で渡してあげれば、ファイルのパス情報が取得できます。


こんなところかな。