1. 程式人生 > >android 國內外通用的google定位程式碼 (國內只需要開啟vpn即可,不需要google服務之類的東西)

android 國內外通用的google定位程式碼 (國內只需要開啟vpn即可,不需要google服務之類的東西)

原本用的網上搜到的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