ウェブ、ショウジン

Android APIのWebViewを使って超簡易ブラウザを試してみる【その3】

2011-10-11
Category
スマートフォン・アプリ

前回追加したオプション・メニューに新しく「Go」というアイテムを作成し、URL入力欄を設け、ここから他のWebページをアプリのホーム画面で表示するようにする。

オプション・メニューにアイテムを追加する

MyWebView/src/com/example/mywebview/MyWebView.java

の既存のコード

@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);

の後に以下を追加。

// URL入力フォームを表示するメニュー・アイテム
MenuItem gotoItem = menu.add(0, GO_MENU_ID, 0 ,R.string.menu_item_name_go);
gotoItem.setIcon(android.R.drawable.ic_menu_search);

すると、電球に赤いバッテンアイコンがつくので

MyWebView3-1

アイコンをクリックして出てくるダイアログから「型 ‘string’ のフィールド ‘menu_item_name_go’ を作成します」を選んでReturn。

MyWebView3-2

すると、「R.java」ファイルが開いて「publicstatic CharSequence menu_item_name_go;」が挿入されているので、これを保存。まだ電球に赤いバッテンアイコンはあるので、再度アイコンをクリックし、出てくるダイアログで「定数 ‘GO_MENU_ID’ を作成します」を選択してReturn。これでアイコンは消えた。

MyWebView3-3

続いて、Aboutメニューのときと同じようにメニュー・アイテム名をリソース(string.xml)に追加する。

MyWebView/res/values/strings.xmlに
Go」を追加。

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="hello">Hello World, MyWebView!</string>
    <string name="app_name">MyWebView</string>
    <!-- オプション・メニュー用文字列 -->
    <string name="menu_item_name_about">About</string>
    <string name="menu_item_name_go">Go</string>
    <string name="about_appname">MyWebView Version.1.0.0</string>
</resources>

MyWebViewプロジェクトを右クリックして「プロジェクトのビルド」を実行してから「実行>2 Androidアプリケーション」を選んでエミュレーターで確認。(「プロジェクトのビルド」を実行してからでないと、今回追加した部分がアプリケーションに反映されない)

MENUボタンをタップすると、追加した「Go」アイテムも表示されるようになった。

MyWebView3-4

「Go」アイテム用のActivityを追加する

URLの入力ができて、その結果を親画面(アプリのホーム画面)のWebView画面に返すための新しいActivityを作成する。

そのための新しいJavaクラス「GoActivity」を作成する。

既存のsrc/com.example.mywebview/AboutActivity.javaをコピーして、com.example.mywebviewを選んだところで「貼り付け」。名前を「GoActivity」に。

中のコードは以下の内容に変更。

▼MyWebView/src/com.example.mywebview/GoActivity.java

package com.example.mywebview;

import android.app.Activity;

public class GoActivity extends Activity {

}

作成されたActivity(GoActivity)にURL入力フォームをレイアウトする処理を追加する。

▼MyWebView/src/com.example.mywebview/GoActivity.java

package com.example.mywebview;

import android.app.Activity;

public class GoActivity extends Activity {
     @Override
     public void onCreate(Bundle savedInstanceState){
          super.onCreate(savedInstanceState);
          setContentView(R.layout.go_activity);
     }
}

いつものように電球に赤いバッテンアイコンが点くので、これをEclipseの機能を使って解消する。

続いて、「Go」の画面を定義する。

MyWebView/res/layout配下に「go_activity.xml」を作成。(新規に作ってもいいし、既存のmain.xmlやabout_activity.xmlをコピー&貼り付けしてもいい)

以下はチュートリアル記事にあったレイアウト例そのまんま。

*画面上のUI部品に対する識別子(@+id/url_edit_text)を変更した場合はjava側からUIにアクセスする部分も同様に変更する必要があるので注意すること。

▼MyWebView/res/layout/go_activity.xml

<?xml version="1.0" encoding="utf-8"?>
<linearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:gravity="center_horizontal"
>

     <!-- スペーサー -->
     <linearLayout
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:minHeight="50dip"
     </linearLayout>
     <!-- // スペーサー -->

     <!-- エディット・コントロールのタイトル -->
     <editText
          android:text="http://"
          android:id="@+id/url_edit_text"
          android:hint="URL"
          android:layout_width="fill_parent"
          android:layout_height="wrap_content"
          android:layout_marginLeft="5dip"
          android:layout_marginRight="5dip"
          android:layout_marginBottom="20dip"
          >
     </editText>
     <!-- // エディット・コントロールのタイトル -->

     <!--  Goボタン -->
     <button
          android:id="@+id/button_ok"
          style="?android:attr/textAppearanceMedium"
          android:layout_height="wrap_content""
          android:layout_width="wrap_content"
          android:text="OK"
     />
     <!-- // Goボタン -->

</linearLayout>

go_activity.xmlの内容について。

LinearLayout形式を使って画面を作成している。

「EditText」がユーザーが入力したURL文字列を受け取るためのエディット・コントロールとなっている。このエディット・コントロールに入力された文字列をWebView(本アプリのホーム画面)に引き渡すために(アクセスできるように)IDをつけておく。(識別子:@+id/url_edit_textのurl_edit_text部分)

続いて、画面に表示する文字列をリソース(string.xml)に追加する。

<string name="go_edit_title">あなたは今日はどちらに行かれますか?</string

▼MyWebView/res/values/strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="hello">Hello World, MyWebView!</string>
    <string name="app_name">MyWebView</string>
    <!-- オプション・メニュー用文字列 -->
    <string name="menu_item_name_about">About</string>
    <string name="menu_item_name_go">Go</string>
    <string name="about_appname">MyWebView Version.1.0.0</string>
    <string name="go_edit_title">あなたは今日はどちらに行かれますか?</string>
</resources>

最後にマニフェスト・ファイル「AndroidManifest.xml」に以下の一文を追加。

<!-- Goアイテム用のActivityを追加 -->
<activity android:name=".GoActivity"></activity>

▼MyWebView/AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="me.showjin.mywebview"
      android:versionCode="1"
      android:versionName="1.0">
    <uses-sdk android:minSdkVersion="4" />

    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".MyWebView"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <!-- Aboutアイテム用のActivityを追加 -->
        <activity android:name=".AboutActivity"></activity>
          <!-- Goアイテム用のActivityを追加 -->
          <activity android:name=".GoActivity"></activity>

    </application>
        <uses-permission android:name="android.permission.INTERNET"></uses-permission>
</manifest>

オプション・メニューから呼び出せるようにする

URL入力フォームをGoメニューの画面にレイアウトできたので、これをアプリのオプション・メニューから呼び出せるようにする。

親画面(この例でいうとアプリを立ち上げた際にWebページを表示するWebView画面)のonMenuItemSelectedに処理を追加する。

MyWebView.javaに以下のコードを追加。

// オプション・メニューをタップしたらGoアイテムを呼び出せるように
case GO_MENU_ID:
          // Intentの作成
          Intent intentGotoActivity = new Intent(this, GoActivity.class);
          startActivityForResult(intentGoActivity, GO_MENU_ID);
          return true;

▼MyWebView/src/com.example.mywebview/MyWebView.java
*ここからWebViewに表示するloadUrlの値をYahoo!Japanに変更(とくに意味はなし)

package com.example.mywebview;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.webkit.WebView;
import android.webkit.WebViewClient;

public class MyWebView extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        WebView  webView = (WebView)findViewById(R.id.main_webview);
        webView.setWebViewClient(new WebViewClient());
        webView.loadUrl("http://yahoo.co.jp/");
    }

    // オプションメニューを作成
    private static final int ABOUT_MENU_ID = Menu.FIRST;
     private static final int GO_MENU_ID = 0;

    @Override
    public boolean onCreateOptionsMenu(Menu menu){
         super.onCreateOptionsMenu(menu);

         // URL入力フォームを表示するメニュー・アイテム
         MenuItem gotoItem = menu.add(0, GO_MENU_ID, 0, R.string.menu_item_name_go);
         gotoItem.setIcon(android.R.drawable.ic_menu_search);

         // Aboutダイアログ表示メニュー・アイテム
         MenuItem aboutItem = menu.add(0, ABOUT_MENU_ID, 0, R.string.menu_item_name_about);
         aboutItem.setIcon(android.R.drawable.ic_menu_info_details);
         return true;
    }

    // About画面を呼び出す処理を追加
    public boolean onMenuItemSelected(int featureId, MenuItem item){
         switch(item.getItemId()){
         case ABOUT_MENU_ID:
              // Intentを作成する
              Intent intentAboutActivity = new Intent(this, AboutActivity.class);
              startActivity(intentAboutActivity);
              return true;

          // オプション・メニューをタップしたらGoアイテムを呼び出せるように
         case GO_MENU_ID:
                   // Intentの作成
                   Intent intentGotoActivity = new Intent(this, GoActivity.class);
                   startActivityForResult(intentGotoActivity, GO_MENU_ID);
                   return true;

              default:
               break;
         }
          return super.onMenuItemSelected(featureId, item);
    }
}

Activityを開始する際にstartActivityではなく「startActivityForResult」を使用している点に注意。startActivityForResultは、開始したActivityから何らかの情報を受け取りたい場合に使用するらしい。

今回は入力されたURL文字列をWebView側で受け取ってURLで指定されたWebページをロード(読み込む)処理になるので、このstartActivityForResultを使用している。

エミュレーターで確認するためにプロジェクトを右クリックして「プロジェクトのビルド」を実行。その上でエミュレーターを起動してアプリも起動(WebView画面にYahoo!JAPANがロードされる)を確認したら、MENUボタンをタップ。

MyWebView3-5

「Go」アイテムをタップすると

MyWebView3-6

URL入力フォームとOKボタンがレイアウトされたActivityが表示されるようになった。

でも、この段階ではまだレイアウト(URL入力フォームとOKボタン)以外の処理を実装していないので、URL入力欄に文字列を入力することはできるけれど、OKボタンを押しても反応はしない。元の画面にもどるには、端末エミュレーターの戻るボタン(横になったUターンボタン)をタップ。

入力データの受け渡し

URL入力フォームに入力された文字列を取得してWebページを呼び出し、親画面であるWebView画面に返す処理を追加していく。

▼MyWebView/src/com.example.mywebview/GoActivity.java

package com.example.mywebview;

import android.app.Activity;
import android.os.Bundle;

public class GoActivity extends Activity {
     @Override
     public void onCreate(Bundle savedInstanceState){
          super.onCreate(savedInstanceState);
          setContentView(R.layout.go_activity);
     }
}

上記の既存のコードを以下の内容に変更。

package me.showjin.mywebview;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

public class GoActivity extends Activity {

     // 追加部分その1ここから
     public static final String THE_URL = "THE_URL";
     // 追加部分その1ここまで

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

          // OKボタン(追加部分その2ここから)
          Button okButton = (Button)findViewById(R.id.button_ok);
          okButton.setOnClickListener(new View.OnClickListener(){
               public void onClick(View view){
                    // エディット・コントロール(URL入力フォーム部分)から文字列を取得
                    EditText edit = (EditText)findViewById(R.id.url_edit_text);
                    // 入力値をIntentの拡張項目に登録
                    Intent intent = new Intent();
                    intent.putExtra(THE_URL, edit.getText().toString());
                    // 閉じる
                    setResult(RESULT_OK, intent);
                    finish();

               }
          });
          // OKボタン(追加部分その2ここまで)
     }
}

ここでまた電球に赤いバッテンアイコンが三つでたのでEclipseの力を借りてゴニョゴニョ解消していく。

MyWebView3-7

一行目は「’View’ をインポートします」で解消。一緒に二行目も解消できた。

MyWebView3-8

残り(三行目)は「’EditText’ をインポートします」で解消できた。

MyWebView3-9

GoActivity.javaに追加した部分について。

ボタンにアクセスするためにidを使用してボタンのクラス(インスタンス)を取得している。
(Button okButton = (Button)findViewById(R.id.button_ok);)

そして、setOnClickListenerを使用し、ボタンがタップされた際の処理をボタンに対して設定している。

onClickの中では以下のような処理を行っている。

  1. idを使用してエディット・コントロール(URL入力フォーム部分)にアクセスできるように。
  2. Intentを作成。親画面(WebView画面)に値を返すためにIntentを作成している。IntentはActivity間でやりとりされるデータ。
  3. putExtraを使用して、作成したIntentの拡張項目にエディット・コントロールから取得した文字列を格納。文字列は「THE_URL」というキー(親側から使用出来るよう、Staticで宣言)とともに格納。このキーは親画面が値を取得する際に使用。
  4. setResultを使用し、Activityの実行結果と親画面に返すIntentを設定。
  5. finishを呼び出すことでActivityが終了。

最後に、呼び出した側(この例ではWebView画面)で入力されたURLを取得する部分を記述していく。

▼MyWebView/src/com.example.mywebview/MyWebView.java
(追加した部分はコメント)

package me.showjin.mywebview;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.webkit.WebView;
import android.webkit.WebViewClient;

public class MyWebView extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        WebView  webView = (WebView)findViewById(R.id.main_webview);
        webView.setWebViewClient(new WebViewClient());
        webView.loadUrl("http://yahoo.co.jp/");
    }

    // オプションメニューを作成
    private static final int ABOUT_MENU_ID = Menu.FIRST;
     private static final int GO_MENU_ID = 0;

    @Override
    public boolean onCreateOptionsMenu(Menu menu){
         super.onCreateOptionsMenu(menu);

         // URL入力フォームを表示するメニュー・アイテム
         MenuItem gotoItem = menu.add(0, GO_MENU_ID, 0, R.string.menu_item_name_go);
         gotoItem.setIcon(android.R.drawable.ic_menu_search);

         // Aboutダイアログ表示メニュー・アイテム
         MenuItem aboutItem = menu.add(0, ABOUT_MENU_ID, 0, R.string.menu_item_name_about);
         aboutItem.setIcon(android.R.drawable.ic_menu_info_details);
         return true;
    }

    // About画面を呼び出す処理を追加
    public boolean onMenuItemSelected(int featureId, MenuItem item){
         switch(item.getItemId()){
         case ABOUT_MENU_ID:
              // Intentを作成する
              Intent intentAboutActivity = new Intent(this, AboutActivity.class);
              startActivity(intentAboutActivity);
              return true;

          // オプション・メニューをタップしたらGoアイテムを呼び出せるように
         case GO_MENU_ID:
              // Intentを作成する
              Intent intentGotoActivity = new Intent(this, GoActivity.class);
               startActivityForResult(intentGotoActivity, GO_MENU_ID);
              return true;

              default:
               break;
         }
          return super.onMenuItemSelected(featureId, item);
    }

    // 追加ここから
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data){
         // ハンドリング対象外のリクエストは無視する
         if(requestCode != GO_MENU_ID){
              return;
         }
         // OK以外で戻ってきたら何もしない
         if(resultCode != RESULT_OK){
              return;
         }
         // URLが入力されたと判断してWebページをロードする
         WebView webView = (WebView)findViewById(R.id.main_webview);
         webView.loadUrl(data.getStringExtra(GoActivity.THE_URL));
    }
    // ここまで
}

onActivityResultはMyWebViewが呼び出したActivityから戻り値がある場合に呼び出されるハンドラというものらしい。startActivityforResultで起動されるすべてのActivityの終了時にこのメソッドが呼び出されるらしい。そして、以下の三つの値を使ってこのメソッド内で全てのActivityの戻り値を判断するらしい。

  1. どのActivityの戻り値なのか:requestCode
  2. 実行結果はどうだったか:resultCode
  3. Activityが返してきたデータ:data

GO_MENU_ID(URL入力画面)からの戻り値かどうかを確認。また、resultCodeも「戻る」ボタンがタップされた際にはRESULT_CANCELが返るので、これを判定する必要がある。

resultCodeを確認後、Activityが返してきたIntentから入力されたURL文字列を取り出してWebView(本アプリのホーム画面)に渡し、リロードしている。

プロジェクトをビルドしてここまでの変更を反映させてからエミュレーターを起動して確認してみる。

アプリが起動したらMENUボタンをタップしてオプション・メニューの「About」と「Go」を表示させ、「Go」をタップして表示される画面のURL入力欄に適当なWebページのURLを入力して「OK」ボタンをタップ。

入力したWebページが表示されたら成功。(成功しました、、ううう、感無量)

第5回 簡易ブラウザの作成(その3)のとおりにやっただけですが、とてもわかりやすくて勉強になりました。ありがとうございます。

Categories

Tag Cloud

AdMob Android Apache centos CodeIgniter EC-CUBE facebookアプリ facebookページ feed Firefox Flash google googleanalytics htaccess iPad iPhone JavaScript lamp mobile nginx ogp pear php plugin rollover rss sendmail setting smarty ssh Titanium Mobile Titanium Studio tutorial ubuntu vim VirtualBox vmware vps Windows WordPress xampp youtube さくらインターネット アクセス解析 カスタム投稿