package com.igo.user.utils.google import android.Manifest import android.annotation.SuppressLint import android.content.Context import android.content.pm.PackageManager import android.graphics.Bitmap import android.graphics.Color import android.location.LocationManager import android.os.Handler import android.os.Looper import android.text.TextUtils import android.util.Log import android.view.View import android.widget.Toast import androidx.core.content.ContextCompat import cn.sinata.xldutils.utils.SPUtils import com.google.android.gms.common.api.ApiException import com.google.android.gms.common.util.CollectionUtils.listOf import com.google.android.gms.maps.* import com.google.android.gms.maps.model.* import com.google.android.libraries.places.api.Places import com.google.android.libraries.places.api.model.* import com.google.android.libraries.places.api.net.FetchPlaceRequest import com.google.android.libraries.places.api.net.FindAutocompletePredictionsRequest import com.google.android.libraries.places.api.net.FindCurrentPlaceRequest import com.google.gson.Gson import com.igo.user.IGoApplication import com.igo.user.R import com.igo.user.utils.Const import okhttp3.* import java.util.* import java.util.Collections.emptyList object AMapKit { val TAG = "GoogleMap" @SuppressLint("MissingPermission") fun initLocation(context: Context, success: (Place) -> Unit, error: () -> Unit) { val placesClient = Places.createClient(context) val placeFields: List = listOf(Place.Field.LAT_LNG,Place.Field.NAME,Place.Field.ADDRESS) // Use the builder to create a FindCurrentPlaceRequest. val request: FindCurrentPlaceRequest = FindCurrentPlaceRequest.newInstance(placeFields) // Call findCurrentPlace and handle the response (first check that the user has granted permission). if (ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) { val placeResponse = placesClient.findCurrentPlace(request) placeResponse.addOnCompleteListener { task -> if (task.isSuccessful) { val response = task.result for (placeLikelihood: PlaceLikelihood in response?.placeLikelihoods ?: emptyList()) { Log.i(TAG, "Place '${placeLikelihood.place.name}' has likelihood: ${placeLikelihood.likelihood}") } if (response?.placeLikelihoods?.isEmpty() != true){ success(response.placeLikelihoods[0].place) } } else { val exception = task.exception if (exception is ApiException) { Log.e(TAG, "Place not found: ${exception.message}") } error() } } } else { // A local method to request required permissions; // See https://developer.android.com/training/permissions/requesting Toast.makeText(context, context.getString(R.string.没有权限), Toast.LENGTH_SHORT).show() // getLocationPermission() error() } } fun initMap(mapView: SupportMapFragment,function: (GoogleMap) -> Unit) { mapView.getMapAsync { p0 -> val mMyLocationStyle = GoogleMapOptions() // mMyLocationStyle.interval(5000) // mMyLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE_NO_CENTER) // mMyLocationStyle.myLocationIcon(BitmapDescriptorFactory.fromResource(R.mipmap.gps_point)) // p0.setLocationSource() = mMyLocationStyle // p0.isMyLocationEnabled = false // p0.animateCamera(CameraUpdateFactory.zoomTo(aMap.maxZoomLevel - 3)) // 设置定位的类型为定位模式,有定位、跟随或地图根据面向方向旋转几种 // p0.setMyLocationType(GoogleMap.LOCATION_TYPE_LOCATE) // val uiSettings: UiSettings = aMap.uiSettings // uiSettings.isZoomControlsEnabled = false function(p0) } } fun drawLine(context: Context, aMap: GoogleMap, start: LatLng, end: LatLng): Polyline? { val latLngs: MutableList = ArrayList() latLngs.add(start) latLngs.add(end) return aMap.addPolyline( PolylineOptions().addAll(latLngs).width(10f).color( ContextCompat.getColor(context, R.color.quantum_yellow900) ) ) } /*** * 监听地图的移动 */ fun addMapMoveListener(aMap: GoogleMap, marker: Marker, finishPosition: (LatLng) -> Unit) { aMap.setOnCameraMoveListener { marker.position = aMap.cameraPosition.target } aMap.setOnCameraIdleListener { finishPosition(aMap.cameraPosition.target) } } fun drawLineAndMove(context: Context, aMap: GoogleMap, start: LatLng, end: LatLng, padd: Int) { drawLine(context, aMap, start, end) moveCamera(aMap, start, end, padd) } fun drawLine(context: Context, aMap: GoogleMap, latLngs: List?): Polyline? { val options = PolylineOptions().addAll(latLngs!!).width(20f) .color(ContextCompat.getColor(context, R.color.quantum_googgreen)) return aMap.addPolyline(options) } fun drawLine(context: Context, aMap: GoogleMap, latLngs: List?,color:Int): Polyline? { val options = PolylineOptions().addAll(latLngs!!).width(20f) .color(ContextCompat.getColor(context, color)) return aMap.addPolyline(options) } fun moveCamera(aMap: GoogleMap, latlng: LatLng?) { val mCameraUpdate = CameraUpdateFactory.newCameraPosition( CameraPosition(latlng!!, 16f, 0f, 0f) ) aMap.animateCamera(mCameraUpdate) } fun moveCamera(aMap: GoogleMap, latlng: LatLng?,zoom:Float) { val mCameraUpdate = CameraUpdateFactory.newCameraPosition( CameraPosition(latlng!!, zoom, 0f, 0f) ) aMap.animateCamera(mCameraUpdate) } fun moveCamera(aMap: GoogleMap, start: LatLng?, end: LatLng?) { var bounds: LatLngBounds? = null if (start!!.latitude < end!!.latitude) bounds = LatLngBounds(start, end) else bounds = LatLngBounds(end, start) val mCameraUpdate = CameraUpdateFactory.newLatLngBounds(bounds, 150) aMap.animateCamera(mCameraUpdate, object : GoogleMap.CancelableCallback { override fun onFinish() { } override fun onCancel() { } }) } fun moveCamera(aMap: GoogleMap, start: LatLng?, end: LatLng?, padd: Int) { val bounds = LatLngBounds(start!!, end!!) val mCameraUpdate = CameraUpdateFactory.newLatLngBounds(bounds, padd) aMap.animateCamera(mCameraUpdate) } fun getOption( latLng: LatLng, view: View ): MarkerOptions { return MarkerOptions().anchor(0.5f, 1f) .position(latLng) .icon(BitmapDescriptorFactory.fromBitmap(convertViewToBitmap(view)!!)) .draggable(true).flat(true) } /*** * 修改marker的view */ fun getIcon(view: View): BitmapDescriptor { return BitmapDescriptorFactory.fromBitmap(convertViewToBitmap(view)!!) } /** * 吧iew转化为bitmap * * @param view * @return */ fun convertViewToBitmap(view: View): Bitmap? { view.isDrawingCacheEnabled = true view.measure( View.MeasureSpec.makeMeasureSpec( 0, View.MeasureSpec.UNSPECIFIED ), View.MeasureSpec.makeMeasureSpec( 0, View.MeasureSpec.UNSPECIFIED ) ) view.layout(0, 0, view.measuredWidth, view.measuredHeight) view.buildDrawingCache() val mCacheBitmap = view.drawingCache return Bitmap.createBitmap(mCacheBitmap) } /** * 添加marker点 */ fun addMarker( aMap: GoogleMap, mLat: Double, mLng: Double, view: View, peopleId: String ): Marker? { val options: MarkerOptions = getOption(LatLng(mLat, mLng), view) val marker: Marker = aMap.addMarker(options)!! if (!TextUtils.isEmpty(peopleId)) { marker.tag = peopleId } return marker } fun getTance(tance: Float): String { if (tance == 0f) { return IGoApplication.appContext!!.getString(R.string.zero_tance) } return if (tance > 1000) { String.format("%.1f"+IGoApplication.appContext!!.getString(R.string.公里), (tance / 1000f)) } else { String.format("%.1f"+IGoApplication.appContext!!.getString(R.string.米), tance) } } // fun drawFenceByCity(context: Context, city: String, va1: GeoFenceListener) { // val mGeoFenceClient = GeoFenceClient(context) // mGeoFenceClient.setActivateAction(GeoFenceClient.GEOFENCE_IN) // mGeoFenceClient.addGeoFence(city, ""); // mGeoFenceClient.setGeoFenceListener(va1); // // } fun drawFace(context: Context, aMap: GoogleMap, latLngs: List?): Polygon? { var po = PolygonOptions().addAll(latLngs!!) .fillColor(ContextCompat.getColor(context, R.color.l_transparent_10)).strokeColor( Color.RED ).strokeWidth(1f) return aMap.addPolygon(po) } fun drawCricle(context: Context, aMap: GoogleMap, latLng: LatLng,bg:Double): Circle? { return aMap.addCircle(CircleOptions(). center(latLng). radius(bg). fillColor(ContextCompat.getColor(context, R.color.l_transparent_10)). strokeColor( Color.RED). strokeWidth(1f)); } fun getTimeType(num: Int): String { if (num in 0..60) { return num.toString() + "s" } if (num in 60..60 * 60) { return (num / 60).toString() + ":" + (num % 60).toString() + "s" } if (num in 60..60 * 60 * 24) { return (num / 3600).toString() + ":" + ((num % 3600) / 60).toString() + ":" + (((num % 3600) % 60) % 60).toString() + "s" } return "" } fun initRouteLine( context: Context, start: LatLng, end: LatLng, onClick: (latLngs: MutableList, lineTance: Float, lineTime: Long) -> Unit ) { initRouteLine(context, start, end, null, onClick) } fun initRouteLine( context: Context, start: LatLng, end: LatLng, centerPoint: List?, onClick: (latLngs: MutableList, lineTance: Float, lineTime: Long) -> Unit ) { //https://maps.googleapis.com/maps/api/directions/json?origin=39.99709957757345,116.31184045225382&destination=39.949158391497214,116.4154639095068&sensor=false&mode=driving var language = SPUtils.instance().getString("language") if (language.isEmpty()){ language = "en" } val client: OkHttpClient = OkHttpClient().newBuilder() .build() val mediaType: MediaType = MediaType.parse("text/plain")!! val body: RequestBody = RequestBody.create(mediaType, "") var centerStr = getPointStr(centerPoint?: arrayListOf()) val request: Request = Request.Builder() .url("https://maps.googleapis.com/maps/api/directions/json" + "?origin=" + start.latitude.toString()+","+start.longitude.toString() + "&destination="+end.latitude.toString()+","+end.longitude.toString() + "&waypoints="+ centerStr + "®ion="+language+ "&key="+ Const.google_key ) .method("GET", body) .build() val response: Response = client.newCall(request).execute() var resurse = response.body()!!.string() var googleBean = Gson().fromJson(resurse, GoogleRouteBean::class.java) var time = 0 //秒 var tance = 0 //米 var allPoint = arrayListOf() for (routes in googleBean.routes?: arrayListOf()){ if (routes.legs.isNullOrEmpty()){ Log.i(TAG, "initRouteLine: 无路线") return } time = routes.legs[0].duration?.value?:0 tance= routes.legs[0].distance?.value?:0 if (routes.legs.isNullOrEmpty()){ Log.i(TAG, "initRouteLine: 无途径点") return } for (item in routes.legs[0].steps?: arrayListOf()){ allPoint.add(LatLng(item.end_location?.lat?:0.0, item.end_location?.lng?:0.0)) } } onClick(allPoint, tance.toFloat(), time.toLong()/60) } private fun getPointStr(centerPoint: List): String { var s = "" for (item in centerPoint){ if (s.isEmpty()){ s+=item.latitude.toString()+","+item.longitude.toString() }else{ s+="|"+item.latitude.toString()+","+item.longitude.toString() } } return s } /*** * 是否开启gps */ public fun isLocServiceEnable(context: Context): Boolean { val locationManager = context.getSystemService(Context.LOCATION_SERVICE) as LocationManager var gps = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) var network = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER) if (gps || network) { return true } return false } fun getClient(url:String,function: (String) -> Unit){ val client = OkHttpClient().newBuilder().build() val mediaType = MediaType.parse("text/plain") val body = RequestBody.create(mediaType, "") val request: Request = Request.Builder() .url(url) .method("GET",null) .build() Thread{ try { val response = client.newCall(request).execute() Handler(Looper.getMainLooper()).post { function(response.body()?.string()?:"") } }catch (e:Exception){ e.printStackTrace() } }.start() } /*** * 周边检索 * @param lat * @param lng */ fun searchPoint( context: Context, lat: Double, lng: Double, function: ( List) -> Unit ) { var language = SPUtils.instance().getString("language") if (language.isEmpty()){ language = "en" } var url = "https://maps.googleapis.com/maps/api/place/nearbysearch/json" + "?location="+ lat.toString()+","+lng.toString() + "&radius=1500" + // "&type=restaurant" + "&language="+language + "&key="+Const.google_key getClient(url){ var near = Gson().fromJson(it,GoogleNearBean2::class.java) if (near.results!!.isNotEmpty() && near.results!!.size > 1){ function(near.results?: arrayListOf()) } } } /*** * 输入内容自动提示 * @param str * @param var1 */ fun searchSite(context: Context, content: String?, cityName: String, function: (List) -> Unit) { val placesClient = Places.createClient(context) var language = SPUtils.instance().getString("language") if (language.isEmpty()){ language = "en" } val token = AutocompleteSessionToken.newInstance() // val bounds = RectangularBounds.newInstance( // LatLng(-33.880490, 151.184363), LatLng(-33.858754, 151.229596)) val request = FindAutocompletePredictionsRequest.builder() // Call either setLocationBias() OR setLocationRestriction(). // .setLocationBias(bounds) .setOrigin(LatLng(IGoApplication.lat, IGoApplication.lon)) .setCountries(language) .setTypeFilter(TypeFilter.ADDRESS) .setSessionToken(token) .setQuery(content) .build() placesClient.findAutocompletePredictions(request).addOnSuccessListener { response -> function(response.autocompletePredictions) }.addOnFailureListener { exception -> if (exception is ApiException) { Log.e(TAG, "Place not found: " + exception.statusCode) } } } fun getPlanceIdDetail(context: Context,id:String,function: (Place) -> Unit){ val placesClient = Places.createClient(context) val placeFields = Arrays.asList(Place.Field.ID, Place.Field.NAME) val request = FetchPlaceRequest.newInstance(id, placeFields) placesClient.fetchPlace(request).addOnSuccessListener { response -> val place: Place = response.getPlace() function(place) }.addOnFailureListener { exception -> if (exception is ApiException) { Log.e(TAG, "Place not found: " + exception.message) val statusCode = exception.statusCode } } } /*** * 逆地址编码 */ fun getAddress(context: Context,lat:Double,lon:Double,function:(String)->Unit) { var language = SPUtils.instance().getString("language") if (language.isEmpty()){ language = "en" } var url = "https://maps.googleapis.com/maps/api/geocode/json" + "?latlng="+ lat.toString() +","+lon.toString() + "&language="+language+ "&result_type=postal_code"+ "&key="+Const.google_key getClient(url){ var bean = Gson().fromJson(it,GoogleBackBean::class.java) if (!bean.results.isNullOrEmpty() && bean.results!![0].types.isNotEmpty()) function(bean.results!![0].address_components!![0].short_name!!) } } fun getAddressName(context: Context,lat:Double,lon:Double,function:(String)->Unit) { var language = SPUtils.instance().getString("language") if (language.isEmpty()){ language = "en" } var url = "https://maps.googleapis.com/maps/api/geocode/json" + "?latlng="+ lat.toString() +","+lon.toString() + "&language="+language+ "&result_type=street_address"+ "&key="+Const.google_key getClient(url){ var bean = Gson().fromJson(it,GoogleBackBean::class.java) if (!bean.results.isNullOrEmpty() && bean.results!![0].types.isNotEmpty()) function(bean.results!![0].address_components!![3].short_name!!) } } // fun startNavi(startLat:Double,startLon:Double,endLat:Double,endLon:Double){ // if (ApkUtils.isAvilible(DeviceConfigInternal.context, "com.google.android.apps.maps")) { // val gmmIntentUri: Uri = Uri.parse("google.navigation:q=$endLat,$endLon, + Sydney +Australia") // val mapIntent = Intent(Intent.ACTION_VIEW, gmmIntentUri) // mapIntent.setPackage("com.google.android.apps.maps") // DeviceConfigInternal.context.startActivity(mapIntent) // } else { // ToastUtils.showShortToast(IGoApplication.appContext, "您尚未安装谷歌地图") // val uri: Uri = Uri.parse("market://details?id=com.google.android.apps.maps") // var intent = Intent(Intent.ACTION_VIEW, uri) // DeviceConfigInternal.context.startActivity(intent) // } // } }