android 國內外通用的google定位程式碼 (國內只需要開啟vpn即可,不需要google服務之類的東西)
阿新 • • 發佈:2019-02-06
原本用的網上搜到的CLocation,但是發現好多機型不能定到位,想突破機型的限制,也就只有通過網路定位了,下面上程式碼 最好別亂改 (雖然定位用不到google map 但是最好別刪除某些程式碼,注意!) 。
首先呼叫這個getLocationPermission();獲取到許可權程式碼如下:
private void getLocationPermission(){ Log.e("e", "getLocationPermission: 獲取位置許可權"); String[] permissions = {Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}; if(ContextCompat.checkSelfPermission(this.getApplicationContext(), FINE_LOCATION) == PackageManager.PERMISSION_GRANTED){ if(ContextCompat.checkSelfPermission(this.getApplicationContext(), COURSE_LOCATION) == PackageManager.PERMISSION_GRANTED){ mLocationPermissionsGranted = true; initMap(); //獲取到許可權後執行的定位關鍵方法!!! }else{ ActivityCompat.requestPermissions(this, permissions, LOCATION_PERMISSION_REQUEST_CODE); } }else{ ActivityCompat.requestPermissions(this, permissions, LOCATION_PERMISSION_REQUEST_CODE); //沒有許可權,請求許可權在onRequestPermissionsResult記得寫initMap方法 } }
下面就是關鍵的initMap方法//必須初始化一個地圖物件才能定到位 我也不知道為什麼 我是給了個高度為1dp的地圖物件...
private void initMap() {
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
mapFragment.getMapAsync(FastActivity.this); //地圖的監聽 }
initMap時最好用isServiceOK判斷下保險:
if(isServicesOK()){ initMap(); }else{ }
public boolean isServicesOK(){ int available = GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(FastActivity.this); if(available == ConnectionResult.SUCCESS){ return true; } if(GoogleApiAvailability.getInstance().isUserResolvableError(available)){ android.app.Dialog dialog = GoogleApiAvailability.getInstance().getErrorDialog(FastActivity.this, available, ERROR_DIALOG_REQUEST); dialog.show(); }else{ } return false; }
然後在監聽的回撥onMapReady中如下:
@Override public void onMapReady(GoogleMap googleMap) { // Toast.makeText(this, "地圖已準備就緒", Toast.LENGTH_SHORT).show(); if (mLocationPermissionsGranted) { getDeviceLocation(); //獲取位置的方法 if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { return; } } }
獲取位置的方法詳情如下:
private void getDeviceLocation(){ mFusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this); try{ if(mLocationPermissionsGranted){ final Task location = mFusedLocationProviderClient.getLastLocation(); location.addOnCompleteListener(new OnCompleteListener() { @Override public void onComplete(@NonNull Task task) { if(task.isSuccessful()){ Location currentLocation = (Location) task.getResult(); // Toast.makeText(FastActivity.this,task.getResult().toString(),Toast.LENGTH_LONG).show(); if(null == currentLocation){ Intent intent = new Intent(FastActivity.this, AddressErrorActivity.class); startActivity(intent); finish(); }else{ if(mfApplication.getLan() == 2){ //系統語言的判斷 因為要做國際化 漢語不做國際化可以去掉此段if。。。else。。。 getAddressNew(currentLocation.getLatitude(),currentLocation.getLongitude(),"zh-CN"); }else{//系統語言的判斷 因為要做國際化 英語 不做國際化可以去掉此段if。。。else。。。 getAddressNew(currentLocation.getLatitude(),currentLocation.getLongitude(),"EN"); } } }else{ Toast.makeText(FastActivity.this, getResources().getString(R.string.address_error), Toast.LENGTH_SHORT).show(); } } }); } }catch (SecurityException e){ Log.e("e", "getDeviceLocation: SecurityException: " + e.getMessage() ); } }
上面已經在getAddressNew方法中傳入獲取到經緯度了:
public void getAddressNew(Double latitude, Double longitude,String langeType){ mfApplication.setLot(String.valueOf(latitude)); //設定全域性變數 獲取的經度 mfApplication.setLon(String.valueOf(longitude)); //設定全域性變數 獲取的緯度 OkHttpClient okHttpClient=new OkHttpClient(); Request.Builder builder=new Request.Builder(); Request request=builder.get().url("https://maps.google.com/maps/api/geocode/json?latlng="+latitude+","+longitude+"&language="+langeType+"&sensor=true").build(); //okhttp請求google介面返回的//address Call call=okHttpClient.newCall(request); call.enqueue(new okhttp3.Callback() { @Override public void onFailure(Call call, IOException e) { //介面異常 Log.e("MainActivity", "onFailure: " ); } @Override public void onResponse(Call call, final Response response) throws IOException { //介面呼叫成功 //成功呼叫 Log.e("MainActivity", "onResponse: " ); String s = response.body().string(); Gson g = new Gson(); Map map = g.fromJson(s,HashMap.class); ArrayList l = (ArrayList) map.get("results"); LinkedTreeMap m2 = (LinkedTreeMap) l.get(0); //據我觀察第0位的formatted_address定位是最準確的 String addre = m2.get("formatted_address")+""; } }); }
這裡說一下為什麼要用網路get拼接url獲得到的位置,而不用
Geocoder
我也想用啊- 。- 之前一直用的Geocoder 但是今天一直報異常 rep.failed 貌似是這個。。。 無奈 只能換網路拼接的了。
對了,說下前提是你的配置定位的appkey
<meta-data android:name="GOOGLE_LOCATION_API_KEY" android:value="XXXXXXXXXXXXXXX" /> <meta-data android:name="com.google.android.geo.API_KEY" android:value="@string/google_maps_key" />
我的這二個key用的同一個,這個就需要你們去google map的開發者平臺申請了。。。。。。。 over