引言
最近了不起这边有个项目需求,我们需要知道设备所在的位置,进而进行未来5天的天气预估,做这个就是为了看天气有没有太阳。
我们是预估一个设备的发电量,外面接了太阳能板,所以需要看天气,看天气就一定要知道设备所在位置。
所在位置和发电量都是需要后端完成的,不放在客户端。
今天就和了不起一起来看看怎么实现定位吧。
一、分析设备环境
我们这个设备在国外,可能有时候有网,可能有时候没有网。
你想嘛,没有网络怎么预测天气呢?
由于在国外,我们可以使用国外的第三方定位系统,可以支持网络IP地址查询。
所以我们就限定这个功能使用的前提就是要有网络。
二、实现方式有哪些
1. 使用Android的蓝牙和GPS定位:
对于Android设备,您可以使用Android的定位服务来获取设备的位置信息。以下是一个示例代码,演示如何获取设备的GPS定位信息:
代码语言:javascript复制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.Bundle;
import androidx.core.app.ActivityCompat;
public class GPSLocator {
private LocationManager locationManager;
private LocationListener locationListener;
public void startGPSLocating(Context context) {
locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
locationListener = new LocationListener() {
@Override
public void onLocationChanged(Location location) {
// 处理定位信息
double latitude = location.getLatitude();
double longitude = location.getLongitude();
// ...
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {}
@Override
public void onProviderEnabled(String provider) {}
@Override
public void onProviderDisabled(String provider) {}
};
// 检查是否有定位权限
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) !=
PackageManager.PERMISSION_GRANTED &&
ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) !=
PackageManager.PERMISSION_GRANTED) {
// 如果没有权限,则请求权限
return;
}
// 请求GPS定位更新
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
}
public void stopGPSLocating() {
if (locationManager != null && locationListener != null) {
locationManager.removeUpdates(locationListener);
}
}
}
```
注意,要在AndroidManifest.xml文件中声明适当的权限(ACCESS_FINE_LOCATION和ACCESS_COARSE_LOCATION)。
我们这里的设备有Android有Ios,所以不太适合我们的初衷。
2. 使用第三方API进行经纬度查询:
当使用第三方API进行经纬度查询时,我们使用Spring Boot框架来构建应用程序,并使用HTTP客户端库(例如Apache HttpClient或OkHttpClient)来发送HTTP请求和接收响应。
下面是一个基于Spring Boot的示例代码,使用Google Maps Geocoding API进行经纬度查询:
2.1 在Spring Boot项目中,首先需要在 pom.xml
文件中添加以下依赖:
代码语言:javascript复制<dependencies>
<!-- Spring Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Apache HttpClient -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<!-- JSON Processing -->
<dependency>
<groupId>javax.json</groupId>
<artifactId>javax.json-api</artifactId>
<version>1.1.4</version>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.json</artifactId>
<version>1.1.4</version>
</dependency>
</dependencies>
2.2 创建一个名为 GeocodingService
的服务类,用于发送请求并解析响应:
代码语言:javascript复制import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import javax.json.Json;
import javax.json.JsonObject;
import javax.json.JsonReader;
import java.io.IOException;
import java.io.StringReader;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
public class GeocodingService {
private static final String API_KEY = "YOUR_API_KEY";
public String queryLocationByCoordinates(double latitude, double longitude) throws IOException {
String url = "https://maps.googleapis.com/maps/api/geocode/json?latlng="
URLEncoder.encode(latitude "," longitude, StandardCharsets.UTF_8)
"&key=" API_KEY;
HttpClient httpClient = HttpClients.createDefault();
HttpGet request = new HttpGet(url);
HttpResponse response = httpClient.execute(request);
HttpEntity entity = response.getEntity();
if (entity != null) {
String result = EntityUtils.toString(entity);
JsonReader jsonReader = Json.createReader(new StringReader(result));
JsonObject jsonObject = jsonReader.readObject();
// 解析JSON响应并获取位置信息
String formattedAddress = jsonObject.getJsonArray("results")
.getJsonObject(0)
.getString("formatted_address");
return formattedAddress;
}
return null;
}
}
2.3 在Spring Boot应用程序的入口类中,创建一个REST控制器来处理请求:
代码语言:javascript复制import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.io.IOException;
@SpringBootApplication
@RestController
public class Application {
private final GeocodingService geocodingService;
public Application(GeocodingService geocodingService) {
this.geocodingService = geocodingService;
}
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@GetMapping("/geocode")
public String geocode(@RequestParam("latitude") double latitude,
@RequestParam("longitude") double longitude) {
try {
return geocodingService.queryLocationByCoordinates(latitude, longitude);
} catch (IOException e) {
e.printStackTrace();
return "Error occurred while retrieving location.";
}
}
}
2.4 在 application.yml
文件中,添加Google Maps Geocoding API的密钥:
代码语言:javascript复制api:
key:
YOUR_API_KEY
2.5 运行Spring Boot应用程序,并通过以下URL发送GET请求来查询经纬度的位置信息:
代码语言:javascript复制http://localhost:8080/geocode?latitude=37.7749&longitude=-122.4194
3. 使用第三方API进行网络IP查询:
例如IP-API或淘宝IP地址库,通过设备的IP地址查询相关位置信息。
以下是一个示例代码,演示如何使用IP-API进行IP地址查询:
代码语言:javascript复制import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
public class IPLocationAPI {
public static void queryLocationByIP(String ipAddress) {
String urlString = "http://ip-api.com/json/" ipAddress;
try {
URL url = new URL(urlString);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
int responseCode = connection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String line;
StringBuilder response = new StringBuilder();
while ((line = reader.readLine()) != null) {
response.append(line);
}
reader.close();
// 解析JSON响应,获取位置信息
// ...
} else {
// 处理错误响应
// ...
}
connection.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
}
}
第三方的API很多,基本上都是商用的,需要花钱购买的,我这边也不多罗列了。
了不起这边也是花钱购买的第三方服务,当然只需要上传IP就可以查询了。
由于我们这个设备是需要联网的,所以解析设备的IP地址就不用我们来做了,我们就直接让设备定期来上报它的IP地址,我们云端就存一下这个IP。
三、总结
定位在Java中可以通过多种方式实现,包括使用Android的蓝牙和GPS功能,以及通过第三方API进行经纬度和IP地址的查询。
今天你和了不起一起探讨了简单实现定位的方式,相信你也掌握了。
当具体需要做定位的时候,还是需要根据公司预算,项目位置,项目计划等等综合考虑选用哪种方案实现。
没有绝对的技术,只有为了业务的技术,但不要因为技术而技术。