Marketへのキーワード検索直通アプリSearch Marketリリース - ReDo

2010年12月17日

Marketへのキーワード検索直通アプリSearch Marketリリース

searchmarket01.jpg searchmarket02.jpg searchmarket_01.png

新UIのMarketのトップページの読み込みに少々時間がかかるのが気になった(電波状態が悪いとちょっとイラッ☆とする)ので、Marketのキーワード検索への直通アプリSearch Marketをリリースしました。

以下、解説らしきものとコード等。

【参考サイト】
突然消失するかもしれないブログ:AndroidMarketのアプリにリンクを張る方法
http://typex2.wordpress.com/2010/01/09/android-market%E3%81%AE%E3%82%A2%E3%83%97%E3%83%AA%E3%81%AB%E3%83%AA%E3%83%B3%E3%82%AF%E3%82%92%E5%BC%B5%E3%82%8B%E6%96%B9%E6%B3%95/

  • 本当はマーケットのインクリメンタル検索欄へのIntentショトカだけにしたかったのですが、うまくいかなかったのでUI作りました。
  • Theme.Translucent.NoTitleBarの透明テーマをベースに、背景を半透明の黒で塗りつぶして小スペースUIにしてます。
  • EditTextのEnterを拾って検索を実行してます。
  • 初期状態で強制IME起動はrequesetFocusタグとonWindowFocusChangedハンドラのセットで実現してます。もっと賢い方法があるのかな?

main.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="#80000000"
    >
    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal|bottom">
        <Button
            android:id="@+id/marketButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="0dip"
            android:drawableLeft="@drawable/market"
            android:drawablePadding="0dip"
            />
        <EditText
            android:id="@+id/searchEdit"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:hint="@string/keyword"
            android:singleLine="true"
            >
            <!-- focus set -->
            <requestFocus />
            </EditText>
        <Button
            android:id="@+id/searchButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="0dip"
            android:drawableLeft="@android:drawable/ic_menu_search"
            android:drawablePadding="0dip"
            />
    </LinearLayout>
</FrameLayout>

SearchMarket.java

package youten.redo.searchmarket;

import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnKeyListener;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;

/**
 * SearchMarket
 */
public class SearchMarket extends Activity {
    /** 検索URI */
    private static final String SEARCH_URI_PREFIX = "market://search?q=";
    /** 検索EditText */
    private static EditText searchEdit = null;
    /** ハンドラ */
    private static Handler handler = new Handler();

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        // 検索EditText
        searchEdit = (EditText) findViewById(R.id.searchEdit);

        // 左のボタンはMarket直接呼び出し
        findViewById(R.id.marketButton).setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                startMarket();
            }
        });

        // Enter時には検索呼び出し。
        searchEdit.setOnKeyListener(new OnKeyListener() {
            public boolean onKey(View v, int keyCode, KeyEvent event) {
                // Enterを離した際に
                if (event.getAction() == KeyEvent.ACTION_UP) {
                    if (keyCode == KeyEvent.KEYCODE_ENTER) {
                        startSearch();
                    }
                }
                return false;
            }
        });

        // 右のボタンは検索呼び出し
        findViewById(R.id.searchButton).setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                startSearch();
            }
        });

    }

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);

        // 検索EditTextがフォーカスを持ったらIMEを有効にする
        if (hasFocus && searchEdit == getCurrentFocus()) {
            handler.post(new Runnable(){
                public void run(){
                    // IME on
                    InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
                    imm.showSoftInput(searchEdit, InputMethodManager.SHOW_IMPLICIT);
                }
            });
        }
    }

    /**
     * 検索呼び出し
     */
    private void startSearch() {
        String keyword = searchEdit.getText().toString();
        if (keyword != null) {
            if (keyword.length() > 0) {
                // キーワードでMarket検索。
                Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse(SEARCH_URI_PREFIX + keyword));
                try {
                    startActivity(i);
                } catch (ActivityNotFoundException e) {
                    // Activityが見つからなかった場合はそのまま終了。
                }
                finish();
            } else {
                // キーワードが空の場合はMarketを直接呼び出す。
                startMarket();
            }

        }
    }

    /**
     * Marketを直接呼ぶ
     */
    private void startMarket() {
        Intent i = new Intent(Intent.ACTION_MAIN);
        i.setClassName("com.android.vending", "com.android.vending.AssetBrowserActivity");
        i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        try {
            startActivity(i);
        } catch (ActivityNotFoundException e) {
            // Activityが見つからなかった場合はそのまま終了。
        }
        finish();
    }
}

コメント(2)

追記:マイアプリ直行ショトカを作ろうとしましたが、
com.android.vending.MyDownloadsActivityへの明示的Intenetは
java.lang.SecurityException: Permission Denial:
というオチでした。

なんかミスってるだけな気もするんですがどうやるんだろう・・・。

メモ:@8796nさんに教えてもらた結果、現Marketでは以下のIntentでマイアプリ直行が可能。

マイアプリへの直結Intentはactionをcom.google.android.finsky.VIEW_MY_DOWNLOADSにしてcom.android.vending.AssetBrowserActivityを呼ぶとおk。

コメントする