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.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; public class MainActivity extends FragmentActivity implements OnMapReadyCallback,LocationListener { Nemophila nemophila; private GoogleMap mMap; private ActivityMainBinding binding; private LatLng currentLatlng = null; private LatLng testLatlng; private LatLng testLatlng2; private LatLng initialLatlng; private LatLng shopLatlng; private GroundOverlay currentOverlay; LocationManager locationManager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); binding = ActivityMainBinding.inflate(getLayoutInflater()); setContentView(binding.getRoot()); nemophila = (Nemophila) this.getApplication(); //現在地ボタン ImageButton button1 = findViewById(R.id.currentButton); // lambda式 button1.setOnClickListener( v -> { Log.d("debug", "currentbutton, 現在地にカメラを移動"); //現在地にカメラを移動 zoomMap(currentLatlng.latitude, currentLatlng.longitude); }); 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 shopsViewModel = new ViewModelProvider(this).get(ShopsViewModel.class); //ダミーショップaとcが返される座標にしておく //画面スクロールに応じて以下の1行を実行するようにする shopsViewModel.setViewArea(20.0, 40.0, 10.0, 30.0); // 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); //初期画面の座標(現在地をロードするまで) // initialLatlng = new LatLng(39,138); //店Cの座標にカメラ移動 initialLatlng = new LatLng(34.5,12.3); //初期画面に移動 // mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(initialLatlng, 5f)); mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(initialLatlng, 15f)); //標準のマーカー(店用のピン) setMarker(latitude, longitude); //アイコン画像をマーカーに設定 //画像関連がわかっていないのでパス //setIcon(latitude, longitude); /* //多分使わない // タップした時のリスナーをセット mMap.setOnMapClickListener(tapLocation -> { // map(ピン以外)をtapされた位置の緯度経度 latlng = new LatLng(tapLocation.latitude, tapLocation.longitude); String str = String.format(Locale.US, "%f, %f", tapLocation.latitude, tapLocation.longitude); mMap.addMarker(new MarkerOptions().position(location).title(str)); mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latlng, 18)); }); */ //長押し時に店を作成し、その座標にピンを立てる //長押し時にその座標を保存し、投稿画面に移り、Shop作成完了時にはピンを立て、Shop画面に移行 mMap.setOnMapLongClickListener(longpushLocation -> { // Nemophila nemophila = (Nemophila) this.getApplication(); //長押しされた位置の緯度経度を取得 //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); //遷移先でShopの作成中... // //Shopの作成が完了した場合。if~ // //作成した店の座標を受け取る // LatLng newlocation = new LatLng(nemophila.getCurrentLatitude(), nemophila.getCurrentLongitude()); // //ピンをその座標に立て、緯度経度をタイトルに設定 // //タイトルはnullにする予定 // //↓返り値でMarkerを返すので、Nemophilaに渡す予定 // Marker createMaker = mMap.addMarker(new MarkerOptions().position(newlocation).title(""+nemophila.getCurrentLatitude()+" :"+ nemophila.getCurrentLongitude())); // //ピンを立てた位置にカメラを移動 // mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(newlocation, 15)); }); // ピンをクリックした場合 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()); 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); // ズーム //zoomMap(latitude, longitude); } 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, 15f)); } //現在地の表示 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); // カメラを移動 //zoomMap(latitude, longitude); // 透明度 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); } //現在地が変更されるたびに現在地アイコンを移動 //LatLng型で受け取っておく currentLatlng = new LatLng(location.getLatitude(), location.getLongitude()); /* テスト用。現在座標を画面に表示 */ // // 緯度の表示 // TextView textView1 = findViewById(R.id.text_view1); // String str1 = "Latitude:"+location.getLatitude(); // textView1.setText(str1); // // // 経度の表示 // TextView textView2 = findViewById(R.id.text_view2); // String str2 = "Longitude:"+location.getLongitude(); // textView2.setText(str2); //現在地アイコンを表示.このsetIcon内にzoomMap処理もあるので注意 setIcon(location.getLatitude(),location.getLongitude()); } @Override public void onProviderEnabled(String provider) { } @Override public void onProviderDisabled(String provider) { } }