如何将服务中onLocationChanged的值绑定到Fragemnt

时间:2017-03-08 08:53:16

标签: android service location broadcastreceiver bind

大家好我在Myservice中有一个不断变化的值,即我在服务中onLocationChanged计算的速度和距离,我想在TextView中显示更改的值片段,我已经尝试使用broadcastReceiver进行广播并接收它,但它不适用于KitKat(API 19), 所以我试图绑定它,但它给了我错误的价值,请给我任何帮助 这是Service Class中的locationListener

 public class MyLocationListener implements LocationListener {

        public void onLocationChanged(final Location loc) {
             Location lastLocation;
            if (loc != null) {
                Double d1;
                Long t1;
                 speed = 0.0;
                d1 = 0.0;
                t1 = 0l;
                currentLocation = loc;
                lastLocation = currentLocation;

                // two arrays for position and time.
                positions = new Double[data_points][2];
                times = new Long[data_points];

                positions[counter][0] = loc.getLatitude();
                positions[counter][1] = loc.getLongitude();
                times[counter] = loc.getTime();

                try {
                    // get the distance and time between the current position, and the previous position.
                    // using (counter - 1) % data_points doesn't wrap properly
                    d1 = distance(positions[counter][0], positions[counter][1], positions[(counter + (data_points - 1)) % data_points][0], positions[(counter + (data_points - 1)) % data_points][1]);
                    t1 = times[counter] - times[(counter + (data_points - 1)) % data_points];
                } catch (NullPointerException e) {
                }

                if (loc.hasSpeed()) {
                    speed = loc.getSpeed() * 1.0; // need to * 1.0 to get into a double for some reason...
                } else {
                    speed = d1 / t1; // m/s
                }
                counter = (counter + 1) % data_points;
                speed = speed * 3.6d;
                distanceList = new ArrayList<>();
                Log.i("**********", "Location changed");
                myLocation = new LatLng(loc.getLatitude(), loc.getLongitude());
                if (isBetterLocation(loc, previousBestLocation)) {
                    loc.getLatitude();
                    loc.getLongitude();
                    for (LatLng location : cameraLocation) {
//                        closestCamera = location;
//                        smallestDistance = distance;
//                        Log.e("distanceTest", distance + "");
//                        Log.d("closestCamera" , location+"" );
//                        distanceList.add(CalculationByDistance(myLocation, location));
//                        distance = Collections.min(distanceList);
                        double distanceFromLastLocation = CalculationByDistance(new LatLng(lastLocation.getLatitude(), lastLocation.getLongitude()), location);
                        double distanceFromCurrentLocation = CalculationByDistance(new LatLng(lastLocation.getLatitude(), lastLocation.getLongitude()), location);
                        if (distanceFromCurrentLocation < distanceFromLastLocation) {
                            continue; // User is going away from location i.e location is behind user. No need to calculate distance between user and cameraLocation.
                        }
                        distanceList.add(CalculationByDistance(myLocation, location));
                        if (Collections.min(distanceList) == distanceFromCurrentLocation) {
                            // this location is nearest amongst all the cameraLocations.
                            smallestDistance = distanceFromCurrentLocation;
                            closestCamera = location;
                        }

                    }

                    DecimalFormat df = new DecimalFormat("###.##");
                    String distanceString = df.format(smallestDistance);
                    intent.setAction(MY_ACTION);
                    speedInt = speed.intValue();
                    intent.putExtra("speed", speed.intValue());
                    intent.putExtra("Latitude", loc.getLatitude());
                    intent.putExtra("Longitude", loc.getLongitude());
                    intent.putExtra("distance", distanceString);
                    intent.putExtra("Provider", loc.getProvider());
                    sendBroadcast(intent);
                    if (speed > 25) {
                        // createNotification(R.raw.camera_alert , String.valueOf(R.string.cameraAlertString));
                    }
                    sendNotification();

                }



            }
        }
//*******************************************************************************************************

        public void onProviderDisabled(String provider) {
            Toast.makeText(getApplicationContext(), "Gps Disabled", Toast.LENGTH_SHORT).show();
        }


        public void onProviderEnabled(String provider) {
            Toast.makeText(getApplicationContext(), "Gps Enabled", Toast.LENGTH_SHORT).show();
        }


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

        }

    }

我想将smallestDistance和speed.intValue()绑定到Fragment,这是一个binder类。

  private final IBinder binder = new TaskBinder();


    public class TaskBinder extends Binder {
        public GPSService getService() {
            return GPSService.this;
        }
    }

这里是我尝试绑定的方法

 public  String  getDestance(){
        DecimalFormat df = new DecimalFormat("###.##");
        String distanceString = df.format(smallestDistance);
        return distanceString ;
    }
    public  int getSpeed(){
        return speedInt ;
    }

以及如何将服务连接到片段

  private ServiceConnection connection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName className, IBinder service) {
            binder = (GPSService.TaskBinder) service;
            localService = binder.getService();
            isBound = true;
            Log.d("connect", "onServiceConnected");
            String nearestCamera = localService.getDestance();
            int speed = localService.getSpeed();
            Log.e("w speedd" , speed+"");
            Log.e("w nearestCamera" , nearestCamera+"");
            nearestCameraTxt.setText( nearestCamera+" Km/m");
            carSpeedTxt.setText(speed+"\n Km/h");

        }
        @Override
        public void onServiceDisconnected(ComponentName arg0) {
            isBound = false;
            Log.d("notConnect", "onServiceNotConnected");

        }
    };

2 个答案:

答案 0 :(得分:0)

在你的片段中试试这个:

GPSTracker mService;  //define service class;
 boolean mBound = false;

现在调用Bind服务方法:

/**
 * Defines callbacks for service binding, passed to bindService()
 */
private ServiceConnection mConnection = new ServiceConnection() {

    @Override
    public void onServiceConnected(ComponentName className,
                                   IBinder service) {
        // We've bound to LocalService, cast the IBinder and get LocalService instance
        GPSTracker.MyBinder binder = (GPSTracker.MyBinder) service;
        mService = binder.getService();
        mBound = true;
    }

    @Override
    public void onServiceDisconnected(ComponentName arg0) {
        mBound = false;
    }
};

使用以下方式获取价值:

if (mBound) {
        // Call a method from the LocalService.
        // However, if this call were something that might hang, then this request should
        // occur in a separate thread to avoid slowing down the activity performance.
         Double latitude = mService.getLatitude();
        Double longitude = mService.getLongitude();
        Toast.makeText(getActivity(), "Received", Toast.LENGTH_LONG).show();
    }

在您的服务类中重写此方法:

 @Override
public IBinder onBind(Intent arg0) {
    return mBinder;
}

public class MyBinder extends Binder {
    GPSTracker getService() {   //GPSTracker is the service class name
        return GPSTracker.this; 
    }
}

public Double getLatitude_s() {
    return latitude;
}

public Double getLongitude_s() {
    return longitude;
}

您还需要使用以下命令从Fragment类启动服务:

getActivity().startService(new Intent(getActivity(), GPSTracker.class));

答案 1 :(得分:0)

您可以使用EventBus在ServiceFragment之间进行通信。

在Gradle中添加依赖项:

compile 'org.greenrobot:eventbus:3.0.0'

创建将保存您的位置值的事件对象:

public class LocationUpdateEvent {
  public final Location location;

  public LocationUpdateEvent(final Location location) {
    this.location = location;
  }

  public Location getLocation() {
    return location;
  }
}

从服务onLocationChanged()发送事件:

EventBus.getDefault().post(new LocationUpdateEvent(latLng));

订阅Fragment中的活动:

@Subscribe
public void onLocationUpdateEvent(LocationUpdateEvent event) {
    int speed = event.getLocation().getSpeed()
    // set speed variable to TextView as you do now in your code
    };

@Override
public void onStart() {
    super.onStart();
    EventBus.getDefault().register(this); // it's important to register the bus
}

@Override
public void onStop() {
    super.onStop();
    EventBus.getDefault().unregister(this); // unregister is nessesary
}