Java如何实现定位

2023-12-11 17:30:09 浏览数 (1)

引言

最近了不起这边有个项目需求,我们需要知道设备所在的位置,进而进行未来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地址的查询。

今天你和了不起一起探讨了简单实现定位的方式,相信你也掌握了。

当具体需要做定位的时候,还是需要根据公司预算,项目位置,项目计划等等综合考虑选用哪种方案实现。

没有绝对的技术,只有为了业务的技术,但不要因为技术而技术。

我是了不起
和我一起学习更多精彩知识!!!

0 人点赞