素人のアンドロイドアプリ開発日記

mapのコンテンツ

MapViewに付加できるいろいろな機能

2011.04.25

前回地図の表示を作成しましたが、地図に付加できるいろいろな機能を紹介したいと思います。

まず、地図をつかんだりできるようにする為の関数

mapview.setEnabled(true);
mapview.setClickable(true);

次に拡大縮小を行う為のデフォルトのコントローラーは下記です。

mapview.setBuiltInZoomControls(true);

次にmapviewのコントローラーを作成します。(見えるものでなく、関数です。)

MapController mc=mapview.getController();

GPSで場所の指定ができます。

mc.setCenter(new GeoPoint(35609127,140113235));

またズームレベルの変更ができます。

mc.setZoom(16);

ともに値の取得に際しては、コントローラーの方ではなく、mapviewの方を利用します。

mapview.getMapCenter();
mapview.getZoomLevel();

以上で地図を作成するとほぼグーグルマップと同じ機能で地図を利用できると思います。しかし、次の機能がついてません。

・ダブルクリック
・長押し

この機能の追加に関してdispatchEventを利用する方法と、layerにイベントを追加する方法があります。

最終的にはlayerの方に追加をしたのですが、dispatchEventの方も不毛な勉強ではなかったので、ついでに記載をさせていただきます。

 

前提としては「MapViewではイベントを取得ができない」と言う問題がおこります。

OnDoubleTapListener,OnGestureListenerで取得をしたいのですが、どうやってもイベントがわたされません。

参照::Android: MapActivityでダブルタップする

dispatchEventを利用します。

 

dispatchEventは発行されるイベントを全て取得します。クリックも移動も全て取得をします。

なので、dispatchEventで取得したイベントはGestureDetectorを作成して、タッチイベントにイベントを渡す形で受け渡します。

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
 super.dispatchTouchEvent(ev);
 gestureDetector.onTouchEvent(ev);
 return onTouchEvent(ev);
}

このようにしてOnDoubleTapListener,OnGestureListenerをimplementsした関数に値を引き渡すとダブルクリックの動作も取得してくれます。

@Override
public boolean onDoubleTap(MotionEvent e) {
 return false;
}

@Override
public boolean onDoubleTapEvent(MotionEvent e) {
 return false;
}

のどちらかで実行をすればよいのだけど、このイベントの差って何だろうか。割と曖昧にしている片が多かったのですが、

参照::タッチパネルのダブルタップや長押しを検出する

onDoubleTapはダブルタップで、onDoubleTapEventはダブルタップ中のイベントらしいです。なぜか、onDoubleTapEventの中に動作を書こうとしている方が多かった印象なのですが、

@Override
public boolean onDoubleTap(MotionEvent e) {
 mc.zoomIn();
 return false;
}

などで、拡大ができる形がよいかと思います。

ソース一式

package in.andante.mapView;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import android.os.Bundle;
import android.view.GestureDetector;
import android.view.View;
import android.view.GestureDetector.OnDoubleTapListener;
import android.view.GestureDetector.OnGestureListener;
import android.view.MotionEvent;
import android.view.View.OnTouchListener;

public class MapVVV extends MapActivity  implements OnGestureListener,OnDoubleTapListener, OnTouchListener{
 
 private GestureDetector gestureDetector;
 
 @Override
 public void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 MapView map = new MapView(this, "APIキー");
 
 map.setEnabled(true);
 map.setClickable(true);
 map.setBuiltInZoomControls(true);
 mc=map.getController();
 mc.setCenter(new GeoPoint(35609127,140113235));
 mc.setZoom(16);
 gestureDetector = new GestureDetector(this,this);
 setContentView(map);
 }
 MapController mc;
 @Override
 public boolean dispatchTouchEvent(MotionEvent ev) {
 super.dispatchTouchEvent(ev);
 gestureDetector.onTouchEvent(ev);
 return onTouchEvent(ev);
 }
 
 @Override
 public boolean onTouch(View v, MotionEvent event) {
 return false;
 }
 
 @Override
 protected boolean isRouteDisplayed() {
 return false;
 }
 
 @Override
 public void onLongPress(MotionEvent e) {
 }
 
 @Override
 public boolean onDoubleTap(MotionEvent e) {
 mc.zoomIn();
 return false;
 }

 @Override
 public boolean onDoubleTapEvent(MotionEvent e) {
 return false;
 }

 @Override
 public boolean onDown(MotionEvent arg0) {
 return false;
 }

 @Override
 public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
 return false;
 }

 @Override
 public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
 return false;
 }

 @Override
 public void onShowPress(MotionEvent e) {
 }

 @Override
 public boolean onSingleTapUp(MotionEvent e) {
 return false;
 }

 @Override
 public boolean onSingleTapConfirmed(MotionEvent e) {
 return false;
 }
}

同様にしてonLongPress(長押し)の動作も設定ができるのですが、問題がひとつあって、zoomボタンの上などで、ダブルクリックをしても動作をしてしまいます

dispatchTouchEventが全てのイベントを取得してしまうが故にview上にさまざまな要素が増えれば増えただけ、修正が必要になります。

なので、次にレイヤーを利用して、ダブルクリックを取得してみましょう。

レイヤーとは、mapViewにはもともと上にレイヤーを重ねる事ができて、そこに矢印を配置したりできるのですが、そのレイヤーにイベントを持たせてあげるという方法です。

参照::特定のタップイベント時にMapViewから座標を取得する

レイヤーのクラスは下記の形になります。

class MyOverlay extends Overlay implements OnDoubleTapListener,OnGestureListener{
 
 private GestureDetector gesture = new GestureDetector(this);
 private MapView parent;

 MyOverlay(MapView mapView){
 parent = mapView;
 }
 
 @Override
 public boolean onTouchEvent(MotionEvent e, MapView mapView) {
 gesture.onTouchEvent(e);
 return super.onTouchEvent(e, mapView);
 }
 
 public void onLongPress(MotionEvent e) {

 }

 @Override
 public boolean onDown(MotionEvent e) {
 return false;
 }

 @Override
 public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,float velocityY) {
 return false;
 }

 @Override
 public boolean onScroll(MotionEvent e1, MotionEvent e2,float distanceX, float distanceY) {
 return false;
 }

 @Override
 public void onShowPress(MotionEvent e) {
 
 }

 @Override
 public boolean onSingleTapUp(MotionEvent e) {
 return false;
 }

 @Override
 public boolean onDoubleTap(MotionEvent e) {
 
 return false;
 }

 @Override
 public boolean onDoubleTapEvent(MotionEvent e) {
 mc.zoomIn();
 return false;
 }

 @Override
 public boolean onSingleTapConfirmed(MotionEvent e) {
 return false;
 }
 
}

上記のレイヤーをMapViewに追加をします。

map.getOverlays().add( new MyOverlay(map));

mapviewに重ねたレイヤー上にイベントを付加する事ができました。こちらの方法だと、今のところ、特に大きな問題もなく動作できると思います。

以上です。

カテゴリー:map

地図を表示させる設定

2011.04.25

googlemapの呼び出しを行う時にマニフェストの設定などいくつか必要な項目があります。

最初に簡単に表示を行うだけの、サンプルを作成してみたいと思います。

mapview

最初に作成を行う時にはエミュレーターでtargetをGoogle APIsにしましょう。一応、api levelは7のものを選んでおきます。

public class MapVVV extends MapActivity {
 @Override
 public void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 }
 @Override
 protected boolean isRouteDisplayed() {
 // TODO Auto-generated method stub
 return false;
 }
}

次に地図の表示部分ですが、MapViewを作成する時にcontextとAPIキーを引数にいれて作成をします。

MapView map = new MapView(this, "APIキー");
setContentView(map);

以上でクラス側の作成が完了しました。次にマニフェストの修正を行います。

外部への通信の使用が必要なので、

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

を追加します。

また、mapのクラスを使用しているので、

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

を記載します。この記述はapplicationタグの内部にいれて利用をします。

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

以上で、地図の表示ができました。

カテゴリー:map

MapViewを利用する為のキーを取得する。

2011.04.24

google mapを表示する為にもっとも敷居が高いのが、キーの取得です。

簡単にキーの取得方法を記載します。

最初にフィンガープリントを取得します。

決まりきった動作なので、誰かパッチを作ってくれてる人がいたら素敵だったのですが、、なかったので、コマンドプロンプトを利用します。

コマンドプロンプトの使い方はほぼ分かりません。

とりあえず、

cd [directry名]

で好きなディレクトリに移動ができるのと、

cd ..

で現在いるディレクトリから上に階層に移動をすることができます。

で、コマンドプロンプトの中を移動するのですが、最初にJavaのフォルダの位置を確認しましょう。

C:\Program Files\Java

人によって位置は異なるかもしれませんが、確認したら、そこまでコマンドプロンプトで移動をします。

ここかたjdk1.6.***と自分のインストールしているjavaのフォルダの中のbinフォルダまで移動します。

C:\Program Files\Java\jdk1.6.**\bin

移動が完了したら、フィンガープリントを発行します。

>keytool -list -keystore C:\Users\%USERNAME%\.android\debug.keystore

ですが、これもフォルダで目視ができるかと思います。上記がフィンガープリントの発行のコマンドです。

このコマンドを入力すると、パスワードを入力してくれと書いてあるので、

androidと入れたら、出力されました。(何もいれなくてもよいようです。。)

以上で取得が完了したら、googleのページへ移動をします。

Maps API Key Signup

ここで、取得ができます。取得ができたら作成を開始しましょう。

尚、取得したキーとフィンガープリントはどこかに保持しておくとよいでしょう。

次回からMapViewを利用する勉強をしていきたいと思います。

カテゴリー:map

公開中のアプリ、是非ダウンロードしてみてください

2chまとめのたね

RSSを利用してさまざまなブログの情報をキュレーションしてくれるアプリ

インストールする

ひらがな戦記

OPENGL ES2 を利用したカルタのソーシャルゲーム

インストールする