羅針盤アプリを起動するAndroidアプリを作成する

Googleマップを使用し、HT-03Aにプリインストールされている「羅針盤」アプリ内の星空機能使用するAndroidアプリを作成します。

■AndroidSDKリファレンス(サイト)
http://developer.android.com/reference/packages.html

■AndroidSDKリファレンス
android-sdk-windows-1.5_r2.zip
解凍後のフォルダ内
docs/reference/packages.html

■GoogleAPIリファレンス
android-sdk-windows-1.5_r2.zip
解凍後のフォルダ内
add-ons/google_apis-3/docs/reference/index.html

羅針盤アプリ

羅針盤アプリのランドマーク機能と星空機能は他アプリからの起動が可能です。
各機能の起動条件(API)は以下になります。

ランドマーク起動・登録API

引数に指定した緯度、経度を元にマイランドマークに情報を登録することができます。
また、起点緯度、経度を仮想現在地として呼び出すことができます。

クラス名:com.nttdocomo.android.compass.land.LandPanoramaActivity

ランドマーク起動API

起点緯度、経度を仮想現在地として呼び出すことができます。

クラス名:com.nttdocomo.android.compass.land.LandPanoramaActivity

星空起動API

起点緯度、経度を仮想現在地とし、仮想現在地の星空を表示することができます。
また、任意の日時を入力することにより、入力時間の星空を表示することができます。

クラス名:com.nttdocomo.android.compass.star.StarMain

Androidアプリを作成する

「ファイル」→「新規」→「Androidプロジェクト」 プロジェクト名、アプリケーション名、パッケージ名を入力、ターゲット名を選択する。Googleマップを使用するため、ターゲット名は「Google APIs」を選択。
今回は「Create Activity」のチェックをはずします。


完了ボタンをクリック。

Googleマップを表示するクラスを作成する

MapAndRashinban/src/sndroid/sample
にフォーカスをあて、右クリックし、
「新規」→「クラス」を選択します。
名前にクラス名を入力、スーパークラスにcom.google.android.maps.MapActivityを入力(もしくは参照から入力)します。


完了ボタンをクリック。

Googleマップを表示する

まず、Googleマップを表示できるようにします。

MainActivity.java

package android.sample;

import android.os.Bundle;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapView;

public class MainActivity extends MapActivity {

    private MapView mView;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        mView = new MapView(this, getString(R.string.api_key));
        mView.setEnabled(true);
        mView.setClickable(true);
        setContentView(mView);
    }
    
    @Override
    protected boolean isRouteDisplayed() {
        return false;
    }
}

今回はmain.xmlではなく、com.google.android.maps.MapViewを使用してGoogleマップを表示します。

        mView = new MapView(this, getString(R.string.api_key));
        mView.setEnabled(true);
        mView.setClickable(true);
        setContentView(mView);

「Googleマップを使用するAndroidアプリを作成する」の回でmain.xmlに設定したように、enabled、clickable、APIキーを設定しています。

strings.xml

strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="hello">Hello World, MainActivity!</string>
    <string name="app_name">HelloMap</string>
    <string name="api_key">【APIキー】</string>
</resources>

strings.xmlにAPIキーを記述します。

AndroidManifest.xml

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="android.sample"
      android:versionCode="1"
      android:versionName="1.0">
    
    <uses-permission android:name="android.permission.INTERNET"/>
    
    <application 
        android:icon="@drawable/icon" android:label="@string/app_name">
        <uses-library android:name="com.google.android.maps"/>
        
        <activity android:name=".MainActivity"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category 
                    android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
    <uses-sdk android:minSdkVersion="3" />
</manifest>

activity(MainActivity)を追加します。

mapを使用するため、

<uses-library android:name="com.google.android.maps"/>

を追加し、
mapでインターネットを使用するため

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

を追加します。

Android Virtual Devices Manager

Android Virtual Devices Managerの設定が必要です。

アイコンをクリックし、AVDを作成します。
作成方法は「Googleマップを使用するAndroidアプリを作成する」の回と同じですので、すでにリストに「ターゲット:Google APIs - 1.5」で作成されたAVDがあれば作成する必要はありません。

アプリを実行する


MAP上に画像を表示する

画面中央の緯度、経度を取得するため、その場所が分かりやすいように画面中央に画像を表示させます。

画像を配置する


star.png

MapAndRashinban/res/drawable
に配置し、
MapAndRashinban
にフォーカスをあて、右クリックし「リフレッシュ」を選択します。

MAP上に画像を表示するクラスを作成する

MapAndRashinban/src/sndroid/sample
にフォーカスをあて、右クリックし、
「新規」→「クラス」を選択します。
名前にクラス名を入力、スーパークラスにcom.google.android.maps.Overlayを入力(もしくは参照から入力)します。

完了ボタンをクリック。

MapOverlay.java

MapOverlay.java

package android.sample;

import android.graphics.Bitmap;
import android.graphics.Canvas;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;

public class MapOverlay extends Overlay {
    private Bitmap mBitmap;
    
    public MapOverlay(Bitmap bitmap) {
        this.mBitmap = bitmap;
    }

    public void draw(Canvas canvas, MapView mapView, boolean shadow){
         canvas.drawBitmap(mBitmap, 
                 mapView.getWidth() / 2 - mBitmap.getWidth() / 2, 
                 mapView.getHeight() / 2 - mBitmap.getHeight() / 2, 
                 null);
    }
}

com.google.android.maps.Overlayを継承したクラスです。

    public void draw(Canvas canvas, MapView mapView, boolean shadow){
         canvas.drawBitmap(mBitmap, 
                 mapView.getWidth() / 2 - mBitmap.getWidth() / 2, 
                 mapView.getHeight() / 2 - mBitmap.getHeight() / 2, 
                 null);
    }

draw(Canvas canvas, MapView mapView, boolean shadow) で画像やテキストなどの表示を行います。
ここで記述された画像やテキストなどは、Googleマップの上に表示されます。

画面の中央に画像が表示されるように
mapView.getWidth() / 2 - mBitmap.getWidth() / 2
mapView.getHeight() / 2 - mBitmap.getHeight() / 2
と指定しています。

MainActivity.java

MainActivity.java

package android.sample;

import java.util.List;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;

public class MainActivity extends MapActivity {

    private MapView mView;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        mView = new MapView(this, getString(R.string.api_key));
        mView.setEnabled(true);
        mView.setClickable(true);
        setContentView(mView);
        
        // 画面中央に表示する画像
        Bitmap mBitmap = BitmapFactory.decodeResource(getResources(), 
                R.drawable.star);
        
        MapOverlay overlay = new MapOverlay(mBitmap);
        List list = mView.getOverlays();
        list.add(overlay);
    }
        
    @Override
    protected boolean isRouteDisplayed() {
        return false;
    }
}

        Bitmap mBitmap = BitmapFactory.decodeResource(getResources(), 
                R.drawable.star);

で画面中央に表示する画像を設定しています。

        MapOverlay overlay = new MapOverlay(mBitmap);
        List list = mView.getOverlays();
        list.add(overlay);

でMapViewのOverlayリストを取得し、そのリストにMapOverlayを追加しています。

アプリを実行する


画面をフリックするとGoogleマップが動き、画像は常に画面中央に表示されることが確認できます。

Mapアプリから羅針盤アプリを起動する

星空起動APIから、必須である緯度と経度をGoogleマップから取得し、羅針盤アプリの星空画面を表示させます。

strings.xml

strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="hello">Hello World, MainActivity!</string>
    <string name="app_name">HelloMap</string>
    <string name="api_key">【APIキー】</string>
    <string name="menu_Rashinban">羅針盤アプリ起動</string>
    <string name="msg_Latitude">緯度:</string>
    <string name="msg_Longitude">経度:</string>
    <string name="msg_confirmation">確認</string>
    <string name="msg_yes">はい</string>
    <string name="msg_cancel">キャンセル</string>
    <string name="msg_rashinban_start">羅針盤アプリを起動しますか?</string>
</resources>

strings.xmlにテキストを設定します。

MainActivity.java

MainActivity.java

package android.sample;

import java.util.List;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;

public class MainActivity extends MapActivity {
    /** 羅針盤アプリパッケージ名 */
    private final String editTextPackageStr = "com.nttdocomo.android.compass";
    /** 羅針盤アプリクラス名(星空) */
    private final String editTextClassStr = "com.nttdocomo.android.compass.star.StarMain";
    /** メニューID   */
    private final int MENU_ID1 = Menu.FIRST;

    private MapView mView;
    //緯度
    private float latitude = 0f;
    //経度
    private float longitude = 0f;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        mView = new MapView(this, getString(R.string.api_key));
        mView.setEnabled(true);
        mView.setClickable(true);
        setContentView(mView);
        
        // 画面中央に表示する画像
        Bitmap mBitmap = BitmapFactory.decodeResource(getResources(), 
                R.drawable.star);
        
        MapOverlay overlay = new MapOverlay(mBitmap);
        List list = mView.getOverlays();
        list.add(overlay);
    }
        
    @Override
    protected boolean isRouteDisplayed() {
        return false;
    }
    

     /**
     * メニューを作成する
     */
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);
        
        menu.add(0, 
                MENU_ID1, 
                0, 
                getString(R.string.menu_Rashinban))
.setIcon(android.R.drawable.ic_menu_compass);
        return true;
    }
    
    /**
     * メニューボタン押下時の処理
     */
    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        super.onPrepareOptionsMenu(menu);
        return true;
    }
    
    /**
     * メニューを選択時の処理
     */
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case MENU_ID1:


            GeoPoint gPoint = mView.getMapCenter();
            //緯度
            latitude = Float.parseFloat(String.valueOf(gPoint.getLatitudeE6() / 1E6));
            //経度
            longitude = Float.parseFloat(String.valueOf(gPoint.getLongitudeE6() / 1E6));
            
            //ダイアログ設定
            AlertDialog.Builder aDialogBuilder = new AlertDialog.Builder(this);
            aDialogBuilder.setTitle(getString(R.string.msg_confirmation));
            aDialogBuilder.setMessage(
                    getString(R.string.msg_Latitude) + latitude + 
                    "\n" + 
                    getString(R.string.msg_Longitude) + longitude + 
                    "\n" + 
                    getString(R.string.msg_rashinban_start));
            aDialogBuilder.setPositiveButton(getString(R.string.msg_yes),
 new DialogInterface.OnClickListener(){
                public void onClick(DialogInterface dialog,int whichButton) {
                    Intent intent = new Intent();
                    //緯度(必須)
                    intent.putExtra("lat", latitude);
                    //経度(必須)
                    intent.putExtra("lon", longitude);
                    intent.setClassName(editTextPackageStr, editTextClassStr);
                    //羅針盤アプリへ
                    startActivity(intent);
                }
            });
            aDialogBuilder.setNegativeButton(getString(R.string.msg_cancel), new DialogInterface.OnClickListener(){
                public void onClick(DialogInterface dialog,int whichButton) {
                }
            });

            
            //ダイアログ作成
            aDialogBuilder.create();
            //ダイアログ表示
            aDialogBuilder.show();
            
            return true;
        default:
            break;
        }
        return super.onOptionsItemSelected(item);
    }
}

メニューから「羅針盤アプリ起動」を選択すると、確認ダイアログが表示され、「はい」ボタンの押下すると羅針盤アプリが起動するように作成しています。

GeoPoint gPoint = mView.getMapCenter();

で現在表示されているマップの中央の位置を取得しています。

//緯度
latitude = Float.parseFloat(String.valueOf(gPoint.getLatitudeE6() / 1E6));
//経度
longitude = Float.parseFloat(String.valueOf(gPoint.getLongitudeE6() / 1E6));

gPoint.getLatitudeE6()
gPoint.getLongitudeE6()
でそれぞれ緯度、経度が取得できますが、その値は×1E6されており、
羅針盤アプリの緯度、経度の範囲と合わせるため、÷1E6をしています。
また、取得される値の型はdouble型であるため、羅針盤アプリの型であるfloatに変えています。

GeoPoint gPoint = mView.getMapCenter();
AlertDialog.Builder aDialogBuilder = new AlertDialog.Builder(this);
aDialogBuilder.setTitle(getString(R.string.msg_confirmation));
aDialogBuilder.setMessage(
    getString(R.string.msg_Latitude) + latitude + 
        "\n" + 
        getString(R.string.msg_Longitude) + longitude + 
        "\n" + 
        getString(R.string.msg_rashinban_start));
aDialogBuilder.setPositiveButton(getString(R.string.msg_yes),
     new DialogInterface.OnClickListener(){
    public void onClick(DialogInterface dialog,int whichButton) {
        【略】
    }
});
aDialogBuilder.setNegativeButton(getString(R.string.msg_cancel),
new DialogInterface.OnClickListener(){
    public void onClick(DialogInterface dialog,int whichButton) {
    }
});

//ダイアログ作成
aDialogBuilder.create();
//ダイアログ表示
aDialogBuilder.show();

この部分がダイアログ表示部分になります。
setTitleでタイトルを、
setMessageでメッセージを、
setPositiveButtonで「はい」ボタンを、
setNegativeButtonで「キャンセル」ボタンを設定した後、
作成、表示を行っています。

Intent intent = new Intent();
//緯度(必須)
intent.putExtra("lat", latitude);
//経度(必須)
intent.putExtra("lon", longitude);
intent.setClassName(editTextPackageStr, editTextClassStr);
//羅針盤アプリへ
startActivity(intent);

この部分で羅針盤アプリの起動を行っています。

Intent#putExtra (String name, float value)
を使用して、渡すデータの名前と値を設定し、
Intent#setClassName (String packageName, String className)
を使用して、起動するアプリのパッケージ名、クラス名を設定し、
Activityを起動しています。

アプリを転送する

端末とPCをUSBケーブルで接続することでアプリをインストールすることができます。
ドライバーは
android-sdk-windows-1.5_r2.zip
解凍後のusb_driverフォルダ内にあります。
接続後にウインドウが表示されたら、「いいえ」→ driverのある場所をフルパスで指定 → 完了
とすることで転送が可能になります。

●Eclipse
Eclipseからエミュレータで実行する方法と同じように、実行を行います。

Android Device Chooserウィンドウが表示されるので、
「Choose a running Android device」を選択し、OKボタンを押下します。

●コマンドプロンプト
コマンドプロンプトから転送をするには、
android-sdk-windows-1.5_r2.zip
解凍後のtoolsにディレクトリの移動をし、

adb install 【作成したアプリのディレクトリ】\MapAndRashinban\bin\MapAndRashinban.apk

を実行します。

アプリを実行する

アプリを実行し、画面をフリックしてGoogleマップを動かし、メニューボタンを押下します。

※画像はエミュレータ画像です

※画像はエミュレータ画像です

確認ダイアログが表示されるので、「はい」ボタンを押下します。

※画像はエミュレータ画像です

MapAndRashinbanのActivityは終了していないため、戻るボタンを押下するとMapAndRashinbanの画面が表示されます。

このページ「星空を見る」の上へ