You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Android Studio中用Java实现向Nominatim发送GET请求

解决方案

要向Nominatim发送GET请求,需注意Android禁止在主线程执行网络操作,必须通过异步任务实现。以下提供两种简单可行的方案:

方案一:原生HttpURLConnection + AsyncTask

无需额外依赖,使用Android原生API实现。

  1. 添加网络权限
    在AndroidManifest.xml中添加互联网权限:
<uses-permission android:name="android.permission.INTERNET" />
  1. 实现异步任务类
    在Player类内部添加用于执行网络请求的异步任务:
private class FetchLocationDetailsTask extends AsyncTask<String, Void, String> {
    @Override
    protected String doInBackground(String... urls) {
        String response = "";
        HttpURLConnection urlConnection = null;
        try {
            URL url = new URL(urls[0]);
            urlConnection = (HttpURLConnection) url.openConnection();
            urlConnection.setRequestMethod("GET");
            urlConnection.setConnectTimeout(5000);
            urlConnection.setReadTimeout(5000);

            // 读取响应内容
            InputStream in = new BufferedInputStream(urlConnection.getInputStream());
            response = convertStreamToString(in);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (urlConnection != null) {
                urlConnection.disconnect();
            }
        }
        return response;
    }

    @Override
    protected void onPostExecute(String result) {
        super.onPostExecute(result);
        // 在主线程处理返回结果
        if (!TextUtils.isEmpty(result)) {
            Log.d("Nominatim Response", result);
            // 此处可添加JSON解析逻辑,提取城市、地址等信息
        }
    }

    // 将输入流转换为字符串工具方法
    private String convertStreamToString(InputStream is) {
        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
        StringBuilder sb = new StringBuilder();
        String line;
        try {
            while ((line = reader.readLine()) != null) {
                sb.append(line).append('\n');
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return sb.toString();
    }
}
  1. 启动异步请求
    在onLocationChanged方法中调用异步任务发送请求:
@Override
public void onLocationChanged(@NonNull Location location) {
    double lat = location.getLatitude();
    Log.d("lat: ", ""+lat);
    double lng = location.getLongitude();
    Log.d("lng: ", ""+lng);

    String path = "https://nominatim.openstreetmap.org/reverse?lat=" + lat +
            "&lon=" + lng + "&format=json&extratags=1";

    // 启动异步任务
    new FetchLocationDetailsTask().execute(path);
}

方案二:OkHttp(更简洁)

使用第三方OkHttp库简化网络请求代码。

  1. 添加依赖
    在模块级build.gradle的dependencies中添加OkHttp依赖:
implementation 'com.squareup.okhttp3:okhttp:4.12.0'
  1. 实现请求方法
    添加异步请求方法:
private void fetchLocationDetails(String url) {
    OkHttpClient client = new OkHttpClient.Builder()
            .connectTimeout(5, TimeUnit.SECONDS)
            .readTimeout(5, TimeUnit.SECONDS)
            .build();

    Request request = new Request.Builder()
            .url(url)
            .get()
            .build();

    client.newCall(request).enqueue(new Callback() {
        @Override
        public void onFailure(@NonNull Call call, @NonNull IOException e) {
            e.printStackTrace();
        }

        @Override
        public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
            if (response.isSuccessful() && response.body() != null) {
                final String responseData = response.body().string();
                // 切换到主线程处理结果
                runOnUiThread(() -> {
                    Log.d("Nominatim Response", responseData);
                    // 解析JSON数据
                });
            }
        }
    });
}
  1. 调用请求方法
    在onLocationChanged中调用该方法:
@Override
public void onLocationChanged(@NonNull Location location) {
    // ... 原有纬度、经度获取代码
    String path = "https://nominatim.openstreetmap.org/reverse?lat=" + lat +
            "&lon=" + lng + "&format=json&extratags=1";
    fetchLocationDetails(path);
}

完整修改后的代码(方案一)

import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.ImageButton;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;

import com.google.android.gms.maps.SupportMapFragment;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

public class Player extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle bundle) {
        super.onCreate(bundle);
        setContentView(R.layout.activity_client);
        Background_DoWork();

    }


    private void Background_DoWork() {
        ImageButton imgbtnBack = findViewById(R.id.BackActivity);
        imgbtnBack.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });


        SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
                .findFragmentById(R.id.map);


        ActivityResultLauncher<String[]> locationPermissionRequest =
                registerForActivityResult(new ActivityResultContracts
                        .RequestMultiplePermissions(), result -> {
                    Boolean fineLocationGranted = result.getOrDefault(
                            Manifest.permission.ACCESS_FINE_LOCATION, false);
                    Boolean coarseLocationGranted = result.getOrDefault(
                            Manifest.permission.ACCESS_COARSE_LOCATION, false);
                    if ((fineLocationGranted != null && fineLocationGranted) || (coarseLocationGranted != null && coarseLocationGranted)) {

                        LocationManager lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);


                        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                            return;
                        }

                        lm.requestSingleUpdate(LocationManager.GPS_PROVIDER, new LocationListener() {
                            @Override
                            public void onLocationChanged(@NonNull Location location) {
                                double lat = location.getLatitude();
                                Log.d("lat: ", ""+lat);
                                double lng = location.getLongitude();
                                Log.d("lng: ", ""+lng);

                                String path = "https://nominatim.openstreetmap.org/reverse?lat=" + lat +
                                        "&lon=" + lng + "&format=json&extratags=1";

                                new FetchLocationDetailsTask().execute(path);

                            }
                        }, null);

                    }
                });

        locationPermissionRequest.launch(new String[] {
                Manifest.permission.ACCESS_FINE_LOCATION,
                Manifest.permission.ACCESS_COARSE_LOCATION
        });
    }

    private class FetchLocationDetailsTask extends AsyncTask<String, Void, String> {
        @Override
        protected String doInBackground(String... urls) {
            String response = "";
            HttpURLConnection urlConnection = null;
            try {
                URL url = new URL(urls[0]);
                urlConnection = (HttpURLConnection) url.openConnection();
                urlConnection.setRequestMethod("GET");
                urlConnection.setConnectTimeout(5000);
                urlConnection.setReadTimeout(5000);

                InputStream in = new BufferedInputStream(urlConnection.getInputStream());
                response = convertStreamToString(in);
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (urlConnection != null) {
                    urlConnection.disconnect();
                }
            }
            return response;
        }

        @Override
        protected void onPostExecute(String result) {
            super.onPostExecute(result);
            if (!TextUtils.isEmpty(result)) {
                Log.d("Nominatim Response", result);
                // 可在此添加JSON解析逻辑
            }
        }

        private String convertStreamToString(InputStream is) {
            BufferedReader reader = new BufferedReader(new InputStreamReader(is));
            StringBuilder sb = new StringBuilder();
            String line;
            try {
                while ((line = reader.readLine()) != null) {
                    sb.append(line).append('\n');
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return sb.toString();
        }
    }
}

注意事项

  • 必须添加互联网权限才能正常发送网络请求
  • Nominatim有请求频率限制,避免短时间内重复发送请求,建议添加缓存机制
  • 可使用Gson等库解析返回的JSON数据,快速提取城市、地址等目标信息

内容的提问来源于stack exchange,提问作者Carl

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 07:06:21