Newer
Older
NemophilaClient / app / src / main / java / com / example / nemophila / MainActivity.java
package com.example.nemophila;

import androidx.fragment.app.FragmentActivity;

import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.lifecycle.ViewModelProvider;

import android.app.ProgressDialog;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageButton;
import android.widget.Toast;
import android.annotation.SuppressLint;
import android.content.pm.PackageManager;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.content.Intent;
import android.provider.Settings;
import android.util.Log;
import android.Manifest;

import com.example.nemophila.entities.Shop;
import com.example.nemophila.viewmodels.ShopsViewModel;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptor;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.CameraPosition;
import com.google.android.gms.maps.model.GroundOverlay;
import com.google.android.gms.maps.model.GroundOverlayOptions;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.LatLngBounds;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import com.example.nemophila.databinding.ActivityMainBinding;

import java.util.Locale;

public class MainActivity extends FragmentActivity implements OnMapReadyCallback,LocationListener  {
    ShopsViewModel shopsViewModel;

    Nemophila nemophila;
    private GoogleMap mMap;
    private ActivityMainBinding binding;
    private LatLng currentLatlng = null;
    private LatLng initialLatlng;
    private LatLng shopLatlng;
    private LatLng testLatlng;
    private LatLng testLatlng2;
    private LatLng tapLatlng;
    private CameraPosition nowCamera;
    private LatLng nowLatlng;

    private GroundOverlay currentOverlay;
    LocationManager locationManager;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        shopsViewModel = new ViewModelProvider(this).get(ShopsViewModel.class);

        binding = ActivityMainBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());
//
//        nemophila = (Nemophila) this.getApplication();
//
//        ImageButton myPageButton = findViewById(R.id.myPageButton);
//        // lambda式
//        myPageButton.setOnClickListener( v -> {
//            Log.d("debug", "myPageButton, マイページに画面遷移");
//            Intent intent = new Intent(MainActivity.this, MyPageActivity.class);
//            startActivity(intent);
//        });


        if (ActivityCompat.checkSelfPermission(this,
                Manifest.permission.ACCESS_FINE_LOCATION)
                != PackageManager.PERMISSION_GRANTED) {

            requestPermissionLauncher.launch(
                    Manifest.permission.ACCESS_FINE_LOCATION);
        }
        else{
            locationStart();
        }

        // Obtain the SupportMapFragment and get notified when the map is ready to be used.
        SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
                .findFragmentById(R.id.map);
        assert mapFragment != null;
        mapFragment.getMapAsync(this);

    }

    @Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;

        //ViewModelへのアクセス
        shopsViewModel = new ViewModelProvider(this).get(ShopsViewModel.class);

        // LiveDataへの購読
        shopsViewModel.getShopsLiveData().observe(this, shops -> {
            //受け取ったshopsに対してMarkerが立っているかを確認
            //対応するMarkerがなければMarkerを立てる
            for(Shop shop:shops) {
                if(shopsViewModel.getMarker(shop)==null){

                    shopLatlng = new LatLng(shop.getLatitude(), shop.getLongitude());
                    System.out.println(shopLatlng);
                    Marker createMaker = mMap.addMarker(new MarkerOptions().position(shopLatlng).title(""));
                    //マーカーに店情報を持たせる
                    createMaker.setTag(shop);
                    //ShopToMarkerに紐づけ
                    shopsViewModel.setShopAndMarker(shop,createMaker);
                }
            }

        });

/*
        //研究室周辺の緯度経度
        double latitude = 34.7308032;
        double longitude = 135.2630272;

        //テスト用,仮ピン立て
        testLatlng = new LatLng(latitude, longitude);
        testLatlng2 = new LatLng(34.74, 135.26);

        //店Cの座標にカメラ移動
        //initialLatlng = new LatLng(34.5,12.3);

        //標準のマーカー(店用のピン)
        //setMarker(latitude, longitude);

        //アイコン画像をマーカーに設定
        //画像関連がわかっていないのでパス
        //setIcon(latitude, longitude);
 */

        //初期画面の座標(現在地をロードするまで表示)
        //initialLatlng = new LatLng(39,138);
        initialLatlng = new LatLng(nemophila.getCameraLatitude(),nemophila.getCameraLongitude());
        //初期画面に移動
        //mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(initialLatlng, 15f));
        mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(initialLatlng, nemophila.getZoom()));


        //画面が動いたとき
        mMap.setOnCameraIdleListener(() -> {
            //カメラの座標とZOOM倍率を保存
            //nowCamera = mMap.getCameraPosition();
            nemophila.setCameraLatitude(mMap.getCameraPosition().target.latitude);
            nemophila.setCameraLongitude(mMap.getCameraPosition().target.longitude);
            nemophila.setZoom(mMap.getCameraPosition().zoom);

            //nowLatlng = new LatLng(nowCamera.target.latitude, nowCamera.target.longitude);
            //nowZoom = nowCamera.zoom;
            //Shopの描画範囲を指定
            shopsViewModel.setViewArea(nemophila.getCameraLongitude()+1, nemophila.getCameraLatitude()+1, nemophila.getCameraLongitude()-1, nemophila.getCameraLatitude()-1);
        });

        /*
        //多分使わない
        // タップした時のリスナーをセット
        mMap.setOnMapClickListener(tapLocation -> {
            // map(ピン以外)をtapされた位置の緯度経度
            tapLatlng = new LatLng(tapLocation.latitude, tapLocation.longitude);
            mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(tapLatlng, nowZoom));
            shopsViewModel.setViewArea(tapLatlng.longitude+1, tapLatlng.latitude+1, tapLatlng.longitude-1, tapLatlng.latitude-1);
        });
        */

        //長押し時に店を作成し、その座標にピンを立てる
        //長押し時にその座標を保存し、投稿画面に移り、Shop作成完了時にはピンを立て、Shop画面に移行
        mMap.setOnMapLongClickListener(longpushLocation -> {
            //長押しされた位置の緯度経度を取得
            //LatLng newlocation = new LatLng(longpushLocation.latitude, longpushLocation.longitude);
            //Nemophilaに座標を保存
            nemophila.setCurrentLatitude(longpushLocation.latitude);
            nemophila.setCurrentLongitude(longpushLocation.longitude);
            //長押しした場合は今からShopを作成するので、CurrentShopをnullで登録しておく
            nemophila.setCurrentShop(null);
            //ShopCreate画面に遷移
            Intent intent = new Intent(MainActivity.this, ShopCreateActivity.class);
            startActivity(intent);
        });

        // ピンをクリックした場合
        mMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
            @Override
            public boolean onMarkerClick(Marker marker) {
                //店の詳細と投稿一覧を表示
                //ここでshopActivityを呼び出す

                //下からクリックしたことを通知
                Toast.makeText(MainActivity.this, "ピンクリック", Toast.LENGTH_SHORT).show();
                //選んだ店をsetする(現状はnullになっているが後で直す)
                nemophila.setCurrentShop((Shop)marker.getTag());
                System.out.println(nemophila.getCurrentShop().getName());

                //ShopActivity画面に遷移
                Intent intent = new Intent(MainActivity.this, ShopActivity.class);
                startActivity(intent);

                return false;
            }
        });

    }

    //起動時から立っているピンの設定。完成時不要
    private void setMarker(double latitude, double longitude){
        MarkerOptions markerOptions = new MarkerOptions();
        MarkerOptions markerOptions2 = new MarkerOptions();

        markerOptions.position(testLatlng);
        markerOptions.title("ntlab");
        mMap.addMarker(markerOptions);

        //テスト用
        markerOptions2.position(testLatlng2);
        markerOptions2.title(null);
        mMap.addMarker(markerOptions2);

    }

    private void zoomMap(double latitude, double longitude){
        // 表示する東西南北の緯度経度を設定
        double south = latitude * (1-0.00005);
        double west = longitude * (1-0.00005);
        double north = latitude * (1+0.00005);
        double east = longitude * (1+0.00005);

        LatLng latlng = new LatLng(latitude,longitude);

        // LatLngBounds (LatLng southwest, LatLng northeast)
        //左下、右上
        LatLngBounds bounds = LatLngBounds.builder()
                .include(new LatLng(south , west))
                .include(new LatLng(north, east))
                .build();

        int width = getResources().getDisplayMetrics().widthPixels;
        int height = getResources().getDisplayMetrics().heightPixels;

        // static CameraUpdate.newLatLngBounds(LatLngBounds bounds, int width, int height, int padding)
        mMap.moveCamera(CameraUpdateFactory.
                newLatLngBounds(bounds, width, height, 0));

        //ズーム処理
        mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latlng, nemophila.getZoom()));
    }

    //現在地の表示
    private void setIcon(double latitude, double longitude){
        //Drawable ic_current = ResourcesCompat.getDrawable(getResources(),R.drawable.icon_current,null);
        //更新前の現在地アイコンを消去
        if(currentOverlay != null) {
            currentOverlay.remove();
        }

        LatLng current_location = new LatLng(latitude,longitude);

        // マップに貼り付ける BitmapDescriptor生成
        BitmapDescriptor descriptor = BitmapDescriptorFactory.fromResource(R.drawable.icon_current);
        //Drawable ic_current = ResourcesCompat.getDrawable(getResources(),R.drawable.ic_current_location,null);

        // 貼り付設定
        GroundOverlayOptions overlayOptions = new GroundOverlayOptions();
        overlayOptions.image(descriptor);

        //public GroundOverlayOptions anchor (float u, float v)
        // (0,0):top-left, (0,1):bottom-left, (1,0):top-right, (1,1):bottom-right
        overlayOptions.anchor(0.5f, 0.5f);

        // 張り付け画像の大きさ メートル単位
        // public GroundOverlayOptions	position(LatLng location, float width, float height)
        overlayOptions.position(current_location, 200f, 200f);

        // マップに貼り付け・アルファを設定
        currentOverlay = mMap.addGroundOverlay(overlayOptions);

        // 透明度
        assert currentOverlay != null;
        currentOverlay.setTransparency(0.8F);
    }


    private final ActivityResultLauncher<String>
            requestPermissionLauncher = registerForActivityResult(
            new ActivityResultContracts.RequestPermission(),
            isGranted -> {
                if (isGranted) {
                    locationStart();
                }
                else {
                    Toast toast = Toast.makeText(this,
                            "これ以上なにもできません", Toast.LENGTH_SHORT);
                    toast.show();
                }
            });

    //現在地の取得
    @SuppressLint("MissingPermission")
    private void locationStart(){
        Log.d("debug","locationStart()");

        // LocationManager インスタンス生成
        locationManager =
                (LocationManager) getSystemService(LOCATION_SERVICE);

        if (locationManager != null && locationManager.isProviderEnabled(
                LocationManager.GPS_PROVIDER)) {

            Log.d("debug", "location manager Enabled");
        } else {
            // GPSを設定するように促す
            Intent settingsIntent =
                    new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
            startActivity(settingsIntent);
            Log.d("debug", "not gpsEnable, startActivity");
        }

        if (ContextCompat.checkSelfPermission(this,
                Manifest.permission.ACCESS_FINE_LOCATION) !=
                PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this,
                    new String[]{Manifest.permission.ACCESS_FINE_LOCATION,}, 1000);

            Log.d("debug", "checkSelfPermission false");
            return;
        }

        locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
                1000, 50, this);

    }

    @Override
    public void onLocationChanged(Location location) {
        //初期画面は現在地を中心にするため...
        if (currentLatlng == null){
            //↓現在地ロード後画面中心を現在地にする場合
            //zoomMap(location.getLatitude(), location.getLongitude());
            //ロード画面の終了
            findViewById(R.id.LL_Load).setVisibility(View.GONE);

            //現在地ボタンを表示
            findViewById(R.id.currentButton).setVisibility(View.VISIBLE);
            ImageButton button1 = findViewById(R.id.currentButton);

            button1.setOnClickListener( v -> {
                Log.d("debug", "currentbutton, 現在地にカメラを移動");
                System.out.println(shopsViewModel.getShopsLiveData().getValue());
                //現在地にカメラを移動
                zoomMap(currentLatlng.latitude, currentLatlng.longitude);
            });
        }

        //現在地が変更されるたびに現在地アイコンを移動
        //LatLng型で受け取っておく
        currentLatlng = new LatLng(location.getLatitude(), location.getLongitude());

        //現在地アイコンを表示.このsetIcon内にzoomMap処理もあるので注意
        setIcon(location.getLatitude(),location.getLongitude());
    }



    @Override
    public void onProviderEnabled(String provider) {

    }

    @Override
    public void onProviderDisabled(String provider) {

    }

}