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

Android测速仪开发:如何将LocationListener计算的距离传至MainActivity更新UI

安卓测速仪:如何将LocationListener计算的距离传递到MainActivity更新UI

提前说明:我对自己写的这段代码并不满意,但只求它能正常运行,请勿严苛评判。

我正在开发一款Android测速仪应用,遇到了一个基础问题。我需要使用Android Location Service计算两个GPS坐标间的距离(我知道Fused Location Provider更优,但请先忽略这点)。

位置监听器类位于CurrentLocationListener.java文件中。目前我已能在该文件中获取两个坐标并计算出更新后的坐标与旧坐标间的距离,但需要找到一种方式将该距离传递到MainActivity.java中,以此更新UI上的相关数值(比如里程表读数)。以下是两个Java文件的代码:

MainActivity.java

package com.example.speedometer;

import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import android.Manifest;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.pm.PackageManager;
import android.location.Location;
import android.location.LocationManager;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import java.lang.Thread;

public class MainActivity extends AppCompatActivity {

    CurrentLocationListener currentLocationListener;
    LocationManager locationManager;
    TextView textCurrentSpeed, textOdometer, textAvgSpeed;
//    MainActivity mainActivity;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
//        mainActivity = this;

        currentLocationListener = new CurrentLocationListener();
        textCurrentSpeed = findViewById(R.id.dispCurrentSpeed);
        textOdometer = findViewById(R.id.dispOdometer);
        textAvgSpeed = findViewById(R.id.dispAvgSpeed);

        locationManager = (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)
        {
            Toast.makeText(this, "Location permission not granted. Please grant permission.", Toast.LENGTH_LONG).show();
            alertbox();
        }
        locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 2000, 5, currentLocationListener);
    }

    protected void alertbox()
    {
        if (ContextCompat.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, Manifest.permission.ACCESS_COARSE_LOCATION}, 1);
        }
    }

    public void updateLocation() {
        Location location = null;
        double[] coords = new double[2];

        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            Toast.makeText(this, "Permission to gps not granted. Grant permissions and try again or restart the application.", Toast.LENGTH_LONG).show();
            alertbox();
        }
        else {
            location = locationManager.getLastKnownLocation(Context.LOCATION_SERVICE);
        }

        locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 5000, 5, currentLocationListener);

        if (location == null)
        {
            location = currentLocationListener.getLocation();
        }
        else {
            Toast.makeText(this, "unknown location", Toast.LENGTH_LONG).show();
        }

    }

    @SuppressLint("SetTextI18n")
    protected void main()
    {
        double oldlat, newlat, oldlong, newlong;
        double[] coords;
        double odometer = 0, timeElapsed = 0, distanceTravelled, currentSpeed, avgSpeed;
        double startTime, endTime;

//        coords = updateLocation();
//        oldlong = coords[0];
//        oldlat = coords[1];



//        while(true)
//        {
//            startTime = System.nanoTime();
//            try
//            {
//                Thread.sleep(10000);
//            } catch (InterruptedException e)
//            {
//                e.printStackTrace();
//            }
//
//            coords = updateLocation();
//
//            newlong = coords[0];
//            newlat = coords[1];
//            System.out.println(newlat + " " + newlong);
//
//            distanceTravelled = earthDistance(oldlat, oldlong, newlat, newlong);
//
//            odometer += distanceTravelled;
//
//            endTime = System.nanoTime();
//
//            timeElapsed += (endTime - startTime);
//            currentSpeed = (distanceTravelled)/((endTime-startTime)/1e9); // m/s to km/hr
//            avgSpeed = (odometer/1000)/(timeElapsed/1e9);
//
////            System.out.println("odo: " + odometer);
////            System.out.println("currspeed: " + currentSpeed);
//            System.out.println("dist: " + distanceTravelled);
//
//            textCurrentSpeed.setText(currentSpeed + " m/s");
//            textOdometer.setText((odometer) + " m");
//            textAvgSpeed.setText(avgSpeed + " km/hr");
//
//            oldlat = newlat;
//            oldlong = newlong;
//        }
    }


    protected double earthDistance(double lat1, double lon1, double lon2, double lat2)
    {

        final double R = 6371e3; // Radius of the earth

        double latDistance = Math.toRadians(lat2 - lat1);
        double lonDistance = Math.toRadians(lon2 - lon1);
        double a = Math.sin(latDistance / 2) * Math.sin(latDistance / 2)
                + Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2))
                * Math.sin(lonDistance / 2) * Math.sin(lonDistance / 2);
        double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));

        return R * c;
    }

    public void setTextFields(double distance)
    {
        System.out.println(distance);
    }

    public void buttonStart(View MainActivity)
    {
//        main();
        updateLocation();
    }
}

CurrentLocationListener.java

package com.example.speedometer;

import android.location.Location;
import android.location.LocationListener;
import android.os.Bundle;
import android.os.Message;
import android.widget.TextView;
import android.view.View;
import android.content.Context;

public class CurrentLocationListener implements LocationListener {
    Location myLocation;
    double templat = 404, templong = 404;
    double odometer = 0, totalTime = 0, currentDist, currentSpeed, avgSpeed;
    TextView textCurrentSpeed, textOdometer, textAvgSpeed;
    MainActivity mainActivity;


    public Location getLocation()
    {
        return myLocation;
    }

    @Override
    public void onLocationChanged(Location location)
    {
//        textCurrentSpeed = mainActivity.findViewById(R.id.dispCurrentSpeed);
//        textOdometer = mainActivity.findViewById(R.id.dispOdometer);
//        textAvgSpeed = mainActivity.findViewById(R.id.dispAvgSpeed);
        double startTime, endTime;
        myLocation = location;
        if (templat == 404 && templong == 404)
        {
            templat = location.getLatitude();
            templong = location.getLongitude();
        }
        else
        {
            currentDist = earthDistance(location.getLatitude(), location.getLongitude(), templong, templat);
            templat = location.getLatitude();
            templong = location.getLongitude();
            System.out.println("dist: " + currentDist);
            odometer += currentDist;
            totalTime += 10;
            currentSpeed = currentDist/10;
            avgSpeed = odometer/totalTime;

            mainActivity.setTextFields(odometer);
//            textCurrentSpeed.setText(currentSpeed + " m/s");
        }
//        System.out.println("update");
//        System.out.println(location.getLatitude() + " " + location.getLongitude());
    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {

    }

    @Override
    public void onProviderEnabled(String provider) {

    }

    @Override
    public void onProviderDisabled(String provider) {

    }

    protected double earthDistance(double lat1, double lon1, double lon2, double lat2)
    {

        final double R = 6371e3; // Radius of the earth

        double latDistance = Math.toRadians(lat2 - lat1);
        double lonDistance = Math.toRadians(lon2 - lon1);
        double a = Math.sin(latDistance / 2) * Math.sin(latDistance / 2)
                + Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2))
                * Math.sin(lonDistance / 2) * Math.sin(lonDistance / 2);
        double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));

        return R * c;
    }
}

我的核心需求是用计算出的数值更新TextView控件,比如里程表读数。我知道代码中有很多重复和注释,但我确实毫无头绪,急需帮助。若需更多信息,请告知。提前感谢。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 22:50:36