【AndroidでSkobblerを使う】地図上に自分の位置を表示する

このエントリーを Google ブックマーク に追加
Pocket
[`yahoo` not found]

今回は地図上に自分の位置を表示します。
実装した機能は下記の通りです。

  • 自位置を取得する。
  • 自位置を表示する。
  • 自位置アニメーションの追加
  • 自位置をタップした時の処理
  • 向いている方向を表示する。
public class MainActivity extends AppCompatActivity {
    private SKMapSurfaceView skMapSurfaceView;
    private SKMapViewHolder mapHolder;
    String mapResourcesDirPath;
    private SKCurrentPositionProvider currentPositionProvider;
    private Bitmap currentIconBitmap;

    SKPrepareMapTextureListener skPrepareMapTextureListener = new SKPrepareMapTextureListener() {
        @Override
        public void onMapTexturesPrepared(boolean b) {
            if (b) {
                initMapSetting();
            }
        }
    };

    SKMapSurfaceListener skMapSurfaceListener = new SKMapSurfaceListener() {
        @Override
        public void onActionPan() {
        }

        @Override
        public void onActionZoom() {
        }

        @Override
        public void onSurfaceCreated(SKMapViewHolder skMapViewHolder) {
            mapHolder = skMapViewHolder;
            skMapSurfaceView = skMapViewHolder.getMapSurfaceView();
            currentIconBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);
            initCurrentPosition();
            skMapSurfaceView.centerMapOnPosition(new SKCoordinate(139.766084, 35.681382));
        }

        @Override
        public void onMapRegionChanged(SKCoordinateRegion skCoordinateRegion) {
        }

        @Override
        public void onMapRegionChangeStarted(SKCoordinateRegion skCoordinateRegion) {
        }

        @Override
        public void onMapRegionChangeEnded(SKCoordinateRegion skCoordinateRegion) {
        }

        @Override
        public void onDoubleTap(SKScreenPoint skScreenPoint) {
        }

        @Override
        public void onSingleTap(SKScreenPoint skScreenPoint) {
        }

        @Override
        public void onRotateMap() {
        }

        @Override
        public void onLongPress(SKScreenPoint skScreenPoint) {
        }

        @Override
        public void onInternetConnectionNeeded() {
        }

        @Override
        public void onMapActionDown(SKScreenPoint skScreenPoint) {
        }

        @Override
        public void onMapActionUp(SKScreenPoint skScreenPoint) {
        }

        @Override
        public void onPOIClusterSelected(SKPOICluster skpoiCluster) {
        }

        @Override
        public void onMapPOISelected(SKMapPOI skMapPOI) {
        }

        @Override
        public void onAnnotationSelected(SKAnnotation skAnnotation) {
        }

        @Override
        public void onCustomPOISelected(SKMapCustomPOI skMapCustomPOI) {
        }

        @Override
        public void onCompassSelected() {
        }

        @Override
        public void onCurrentPositionSelected() {
            //自位置をタップしたときに呼ばれる
            //アニメーションを停止する。
            skMapSurfaceView.stopCurrentPositionIconPulseAnimation();
        }

        @Override
        public void onObjectSelected(int i) {
        }

        @Override
        public void onInternationalisationCalled(int i) {
        }

        @Override
        public void onBoundingBoxImageRendered(int i) {
        }

        @Override
        public void onGLInitializationError(String s) {
        }

        @Override
        public void onScreenshotReady(Bitmap bitmap) {
        }
    };
    SensorEventListener sensorEventListener = new SensorEventListener() {
        @Override
        public void onSensorChanged(SensorEvent event) {
            //mapView.reportNewHeading(t.values[0]);
            switch (event.sensor.getType()) {
                case Sensor.TYPE_ORIENTATION:
                    if (event.values.length > 0) {
                        float value = event.values[0];
                        if (value != 0) {
                            //方位を設定する。ヘディングだけが変わりアイコンはそのままなことに注意する。
                            skMapSurfaceView.reportNewHeading(value);
                            //自位置アイコンの角度を変更する。詳細は割愛
                            ImageView imageView = new ImageView(getApplicationContext());
                            Matrix matrix = new Matrix();
                            matrix.postRotate(value);
                            Bitmap bitmap = Bitmap.createBitmap(currentIconBitmap, 0, 0, currentIconBitmap.getWidth(), currentIconBitmap.getHeight(), matrix, true);
                            imageView.setImageBitmap(bitmap);
                            skMapSurfaceView.setCurrentPositionIconFromView(imageView);
                        }
                    }
                break;
            }
        }

        @Override
        public void onAccuracyChanged(Sensor sensor, int accuracy) {
        }
    };

    private void initCurrentPosition() {
        //方位を取得を開始する。SkobblerSDKではなくAndroidSDKを使うので説明は割愛
        SensorManager sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
        Sensor orientationSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);
        sensorManager.registerListener(sensorEventListener, orientationSensor, SensorManager.SENSOR_DELAY_UI);
        //位置情報を取得するためのプロバイダーをインスタンス化
        currentPositionProvider = new SKCurrentPositionProvider(MainActivity.this);
        //位置情報を取得したときのコールバック(SKCurrentPositionListener)を設定
        currentPositionProvider.setCurrentPositionListener(skCurrentPositionListener);
        // 位置情報取得方法を設定する。
        // 第一引数:GPS
        // 第二引数:A-GPS
        // 第三引数:GPSとA-GPSの両方
        currentPositionProvider.requestLocationUpdates(true, true, true);
        //地図上に自位置を表示する
        skMapSurfaceView.getMapSettings().setCurrentPositionShown(true);
        //自位置アイコンを変更する。Viewを引数にするので内容はどのようなものでも表示することが可能
        ImageView imageView = new ImageView(getApplicationContext());
        imageView.setImageBitmap(currentIconBitmap);
        skMapSurfaceView.setCurrentPositionIconFromView(imageView);
        //アニメーションを設定する。
        SKPulseAnimationSettings skPulseAnimationSettings = new SKPulseAnimationSettings();
        //指定できるアニメーションはPULSE_CCPだけのようです。円が膨張→縮小を繰り返すアニメーションになります。
        skPulseAnimationSettings.setAnimationType(SKAnimationSettings.SKAnimationType.PULSE_CCP);
        // 円の色を指定します。RGBのfloat配列で指定します。
        skPulseAnimationSettings.setColor(new float[]{1f, 0f, 0f});
        // アニメーションの持続性を指定する。true:無限/false:一回のみ
        skPulseAnimationSettings.setContinuous(true);
        // 膨張時間をミリ秒指定する。
        skPulseAnimationSettings.setDuration(10000);
        // 縮小時間をミリ秒指定する。
        skPulseAnimationSettings.setDurationOut(1000);
        // 膨張する大きさを指定。
        skPulseAnimationSettings.setSpan(5);
        // イージングを指定。
        skPulseAnimationSettings.setAnimationEasingType(SKAnimationSettings.SKEasingType.EASE_IN_CUBIC);
        // アニメーションを開始する。
        skMapSurfaceView.setCurrentPositionIconPulseAnimation(skPulseAnimationSettings);
    }

    SKCurrentPositionListener skCurrentPositionListener = new SKCurrentPositionListener() {
        @Override
        public void onCurrentPositionUpdate(SKPosition skPosition) {
            SKPositionerManager.getInstance().reportNewGPSPosition(skPosition);
            skMapSurfaceView.centerMapOnPosition(skPosition.getCoordinate());
        }
    };

    /**
    * Deactivates the orientation sensor
    */
    private void stopOrientationSensor() {
        SensorManager sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
        sensorManager.unregisterListener(sensorEventListener);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mapResourcesDirPath = getFilesDir().getPath() + "/" + "SKMaps/";
        if (!new File(mapResourcesDirPath).exists()) {
            new SKPrepareMapTextureThread(this, mapResourcesDirPath, "SKMaps.zip", skPrepareMapTextureListener).start();
        } else {
            initMapSetting();
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        if (mapHolder != null) {
          mapHolder.onPause();
        }
        stopOrientationSensor();
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (mapHolder != null) {
            mapHolder.onResume();
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (currentPositionProvider != null) {
            currentPositionProvider.stopLocationUpdates();
        }
    }

    private void initMapSetting() {
        SKMapsInitSettings initMapSettings = new SKMapsInitSettings();
        initMapSettings.setMapResourcesPaths(mapResourcesDirPath,
        new SKMapViewStyle(mapResourcesDirPath + "daystyle/", "daystyle.json"));
        final SKAdvisorSettings advisorSettings = initMapSettings.getAdvisorSettings();
        advisorSettings.setAdvisorConfigPath(mapResourcesDirPath + "Advisor");
        advisorSettings.setResourcePath(mapResourcesDirPath + "Advisor/Languages");
        advisorSettings.setLanguage(SKAdvisorSettings.SKAdvisorLanguage.LANGUAGE_EN);
        advisorSettings.setAdvisorVoice("en");
        initMapSettings.setAdvisorSettings(advisorSettings);
        SKMaps.getInstance().initializeSKMaps(this, initMapSettings);
        SKMapFragment mapFragment = new SKMapFragment();
        mapFragment.setMapSurfaceListener(skMapSurfaceListener);
        FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
        fragmentTransaction.add(R.id.container, mapFragment).commit();
    }
}

Androidゲームプログラミング A to Z

新品価格
¥4,968から
(2017/2/27 22:58時点)


AndroidエンジニアのためのモダンJava

新品価格
¥3,456から
(2017/2/27 23:01時点)


AndroidNDKネイティブプログラミング第2版

中古価格
¥1,893から
(2017/2/28 00:04時点)


Androidアプリ開発逆引きレシピ (PROGRAMMER’S RECiPE)

新品価格
¥3,024から
(2017/2/28 00:06時点)


Android Studio ではじめる Android プログラミング入門 第3版 Android Studio 2対応

新品価格
¥3,240から
(2017/2/28 00:11時点)


アプリを作ろう! Android入門 Android Studio版 Android5対応

新品価格
¥2,160から
(2017/2/28 00:31時点)


コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

*

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)