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

Android天气APP改造:基于GPS定位调用OpenWeatherMap显示天气

改造天气APP以使用GPS获取当前位置

Hey there! Let's get your weather app updated to use GPS for the current location instead of those fixed coordinates. Here's a step-by-step guide to make that happen:

1. 添加必要权限到AndroidManifest.xml

首先,我们需要声明访问位置数据和互联网的权限(因为要调用OpenWeatherMap接口)。在你的manifest标签内添加这些代码:

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />

2. 在MainActivity.java中实现GPS位置逻辑

我们将使用谷歌推荐的FusedLocationProviderClient来获取用户的当前坐标。下面是修改你的Activity代码的具体步骤:

2.1 添加必要的导入

在MainActivity.java顶部添加这些导入语句:

import android.Manifest;
import android.content.pm.PackageManager;
import android.location.Location;
import androidx.core.app.ActivityCompat;
import com.google.android.gms.location.FusedLocationProviderClient;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.tasks.OnSuccessListener;

2.2 添加成员变量

在MainActivity类内部添加这些变量:

private FusedLocationProviderClient fusedLocationClient;
private static final int LOCATION_PERMISSION_REQUEST_CODE = 100;

2.3 初始化位置客户端并检查权限

更新你的onCreate方法,设置位置客户端并检查权限:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    getSupportActionBar().hide();
    setContentView(R.layout.activity_main);
    
    // 初始化位置客户端
    fusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
    
    // 你原有的字体和视图绑定代码
    weatherFont = Typeface.createFromAsset(getApplicationContext().getAssets(), "fonts/weathericons-regular-webfont.ttf");
    cityField = findViewById(R.id.city_field);
    updatedField = findViewById(R.id.updated_field);
    detailsField = findViewById(R.id.details_field);
    currentTemperatureField = findViewById(R.id.current_temperature_field);
    humidity_field = findViewById(R.id.humidity_field);
    pressure_field = findViewById(R.id.pressure_field);
    weatherIcon = findViewById(R.id.weather_icon);
    weatherIcon.setTypeface(weatherFont);
    
    // 检查是否拥有位置权限
    checkLocationPermission();
}

2.4 实现权限检查和请求方法

添加这些方法来处理权限请求:

private void checkLocationPermission() {
    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
            && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        // 向用户请求位置权限
        ActivityCompat.requestPermissions(this,
                new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                LOCATION_PERMISSION_REQUEST_CODE);
        return;
    }
    // 权限已授予,获取当前位置
    getCurrentLocation();
}

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if (requestCode == LOCATION_PERMISSION_REQUEST_CODE) {
        if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            // 用户允许权限,获取位置
            getCurrentLocation();
        } else {
            // 用户拒绝权限,使用原固定坐标作为备选方案
            executeWeatherTask("23.8315", "91.2868");
        }
    }
}

2.5 获取当前位置并触发天气API调用

添加这个方法来获取用户位置,并将坐标传递给你已有的AsyncTask:

private void getCurrentLocation() {
    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
            && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        return;
    }
    // 获取最后已知的位置
    fusedLocationClient.getLastLocation()
            .addOnSuccessListener(this, new OnSuccessListener<Location>() {
                @Override
                public void onSuccess(Location location) {
                    if (location != null) {
                        // 将坐标转换为字符串并传递给天气任务
                        String latitude = String.valueOf(location.getLatitude());
                        String longitude = String.valueOf(location.getLongitude());
                        executeWeatherTask(latitude, longitude);
                    } else {
                        // 无法获取位置,使用备选坐标
                        executeWeatherTask("23.8315", "91.2868");
                    }
                }
            });
}

// 封装方法来运行你的天气AsyncTask
private void executeWeatherTask(String lat, String lon) {
    Function.placeIdTask asyncTask = new Function.placeIdTask(new Function.AsyncResponse() {
        @Override
        public void processFinish(String weather_city, String weather_description, String weather_temperature, String weather_humidity, String weather_pressure, String weather_iconText, String updatedOn) {
            // 更新UI显示天气数据
            cityField.setText(weather_city);
            updatedField.setText(updatedOn);
            detailsField.setText(weather_description);
            currentTemperatureField.setText(weather_temperature);
            humidity_field.setText("Humidity: " + weather_humidity);
            pressure_field.setText("Pressure: " + weather_pressure);
            weatherIcon.setText(Html.fromHtml(weather_iconText));
        }
    });
    asyncTask.execute(lat, lon);
}

3. 最终配置:添加谷歌Play服务依赖

确保你的项目包含位置服务依赖。在**模块级build.gradle**的dependencies块中添加这行代码:

implementation 'com.google.android.gms:play-services-location:21.0.1'

关键注意事项

  • 备选方案:如果用户拒绝权限或设备无法获取位置,我们会回退到你原来的固定坐标——你也可以添加一个Toast提示用户。
  • 实时更新:如果需要持续更新位置(比如用户移动时),可以使用fusedLocationClient.requestLocationUpdates()代替getLastLocation()。
  • 位置精度:ACCESS_FINE_LOCATION使用GPS获取精确坐标,ACCESS_COARSE_LOCATION使用Wi-Fi/基站获取大致位置——我们同时添加两者以提升兼容性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 04:03:32