Java
Android
初心者向け
QA

【Android】QAを楽にしたい...そうだ!デバッグメニューを作ろう!

デバッグメニューとは?

ソフトウェア開発者向けの隠された機能。
あくまでも開発者向けの機能なので一般的なユーザーには操作は出来ないようになっているのが標準である。

必要なの?

マストじゃないです。
あくまでもデバッグを楽にするためなので、まずはデバッグを行う人にヒアリングから始めてみましょう。
ただ、あると嬉しいなぁって声が出たり、デバッグにエンジニアの工数がかかっているなら作ったほうがいいです。

実装した機能例

表示&コピー

  • Build Ver.
  • HOSTNAME(サーバーホストの切り替え)
  • AdID etc...

アクション

  • IMAGE CACHE削除(Glide)
  • データ全削除
  • 日付の変更(リセット)
  • 外部連携用テストユーザー
  • 外部アクセスからの認証
  • 退会 etc...

実装例

アイテムセルサンプルです。
親でScrollViewなりで囲ってあげて増殖させてもいいかと思います。

activity_debug_menu.xml
<!-- 省略 -->

                <!--Item Parent Name 表示&コピー -->
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="@dimen/listview_height"
                android:background="@color/debug_item_parent_color"
                android:orientation="horizontal">

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    android:layout_marginLeft="@dimen/listview_margin_left"
                    android:gravity="left"
                    android:text="表示&コピー"
                    android:textColor="@color/debug_text_color"
                    android:textSize="14sp"/>

            </LinearLayout>

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="@android:color/white"
                android:orientation="vertical">

                <!-- Item Child Name Build Ver. -->
                <LinearLayout
                    android:id="@+id/build_info_area"
                    android:layout_width="match_parent"
                    android:layout_height="@dimen/listview_height"
                    android:layout_gravity="center"
                    android:background="@drawable/default_selector"
                    android:clickable="true"
                    android:orientation="horizontal"
                    android:paddingLeft="@dimen/listview_margin_left">

                    <LinearLayout
                        android:layout_width="wrap_content"
                        android:layout_height="match_parent">

                        <ImageView
                            android:layout_width="@dimen/listview_icon_width"
                            android:layout_height="@dimen/listview_icon_height"
                            android:layout_gravity="center"
                            android:layout_marginRight="@dimen/listview_icon_margin_right"
                            android:background="@drawable/ic_build_36dp"/>

                    </LinearLayout>

                    <LinearLayout
                        android:layout_width="125dp"
                        android:layout_height="match_parent">

                        <TextView
                            android:layout_width="wrap_content"
                            android:layout_height="match_parent"
                            android:layout_gravity="center"
                            android:layout_marginRight="10dp"
                            android:gravity="center"
                            android:text="BUILD Ver."
                            android:textSize="@dimen/listview_item_text_size"/>

                    </LinearLayout>

                <!-- 取得Ver -->
                    <TextView
                        android:id="@+id/build_info_txt"
                        android:layout_width="match_parent"
                        android:layout_height="match_parent"
                        android:gravity="left|center"
                        android:text="Ver.X.XX.X"
                        android:textColor="@color/debug_text_color"
                        android:textSize="@dimen/listview_item_text_size"/>

                </LinearLayout>

                <!-- 区切り線 -->
                <include layout="@layout/component_divider_wrap"/>

<!-- 省略 -->

ただの区切り線です。

component_divider_wrap.xml
<merge xmlns:android="http://schemas.android.com/apk/res/android"
       android:layout_width="match_parent"
       android:layout_height="match_parent">

    <LinearLayout
        android:id="@+id/div"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="72dp"
        android:layout_weight="1">

        <View style="@style/divider_horizontal"/>

    </LinearLayout>
</merge>

サンプルとして一例をonCreateに記述してますが、アイテム数が増えると読みにくくなるので、Butter KnifeなりでアイテムをBindしてあげるといいかもしれません。

DebugMenuActivity.java
public class DebugMenuActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_debug_menu);

        // Build Ver. Text
        TextView buildInfoTxt = (TextView)findViewById(R.id.build_info_txt);

        buildInfoTxt.setText("Ver. " + BuildConfig.VERSION_NAME + " " + BuildConfig.BUILD_TIMESTAMP + " " + BuildConfig.BUILD_HASH + " (" + BuildConfig.BUILD_MACHINE + ")");
        // Build Ver. Area
    LinearLayout buildInfoArea =(LinearLayout)findViewById(R.id.build_info_area);

        buildInfoArea.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                copyClipBoard((String)buildInfoTxt.getText());
            }
        });
    }

   // クリップボードにコピー
   private void copyClipBoard(String copySource) {
        if (copySource.equals("")) {
            return;
        }

        //クリップボードに格納するItemを作成
        ClipData.Item item = new ClipData.Item(copySource);

        //MIMETYPEの作成
        String[] mimeType = new String[1];
        mimeType[0] = ClipDescription.MIMETYPE_TEXT_URILIST;

        //クリップボードに格納するClipDataオブジェクトの作成
        ClipData cd = new ClipData(new ClipDescription("text_data", mimeType), item);

        //クリップボードにデータを格納
        ClipboardManager cm = (ClipboardManager) getActivity().getSystemService(Context.CLIPBOARD_SERVICE);
        cm.setPrimaryClip(cd);
    }
}

後述

自己満足でHostName変更する際にアイコンをタップするとサジェストが出る機能を入れたら意外と好評だったり、外部アクセス認証もできたほうがいいよねってことで実装してたらPlが焼肉を奢ってくれました
焼肉好きの体育会系エンジニアのみなさん!ぜひ作ってみましょう:sunglasses:

12月23日は @yuzu_afro さんのターンです!