从远程设备获取位置数据

时间:2019-10-10 06:42:27

标签: android

有很多教程可以帮助您了解 用户的设备,我要在构建应用程序时从驾驶员的设备获取此信息 出租车公司的想法是传递此位置数据 到客户应用程序,以便客户可以跟踪驾驶员的 位置。 我该如何解决?

3 个答案:

答案 0 :(得分:0)

您有2个选择,也许更多...

op1: 创建后台服务并使用位置侦听器,在位置更改中调用一个api并更新驱动程序的最后一个位置,并使用计时器(例如:每30秒调用一次驱动程序的最后一个api)在后台服务中调用客户应用程序api

op2: 创建通知服务,每次您要向驱动程序发送推送时,在收到此类通知时在notif服务中,调用api并更新最后一个位置 然后在每个最新的位置更新中,将推送发送给客户

这是我的方式:(我正在使用音频和其他东西,请删除您不会使用的任何东西

public class LocationService extends Service {

private static final String TAG = "LocationService";
private DBHelper DBConnection;
private Context context;
public LocationManager locationManager;
public MyLocationListener listener;
public static boolean gpsEnable = true;
private NotificationManager notificationManager;
private int lastVolume;
private AudioManager audioManager;
private boolean sendingListInProgress = false;
public static MediaPlayer mediaPlayer;
//private BroadcastReceiver broadcastReceiver = new BroadcastReceiver(); 

@Override
public void onCreate() {
    super.onCreate();
    context = this;
    DBConnection = new DBHelper(context);
    DBConnection.DBCreate(context);
    IntentFilter i = new IntentFilter();
    i.addAction("android.intent.action.update_map");
    //registerReceiver(broadcastReceiver, new IntentFilter(LocationManager.PROVIDERS_CHANGED_ACTION));
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    super.onStartCommand(intent, flags, startId);

    try {
        FirebaseCrash.log("Activity created");
        locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        listener = new MyLocationListener();
        int minDistance = 10;
        int time = 8000;
        if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
                ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED)
            return START_NOT_STICKY;
        else
            locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, time, minDistance, listener);

        notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);

        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
            NotificationChannel channel = new NotificationChannel(CHANNEL_ID, "N", NotificationManager.IMPORTANCE_DEFAULT);
            channel.enableLights(true);
            channel.setSound(null, null);
            channel.setDescription(String.valueOf(getText(R.string.app_name2)));
            notificationManager.createNotificationChannel(channel);
        }

        NotificationCompat.Builder builder = new NotificationCompat.Builder(context, CHANNEL_ID);
        builder.setAutoCancel(false);
        builder.setContentTitle(getText(R.string.app_name2));
        builder.setSmallIcon(R.drawable.ic_launcher_small);
        builder.setLargeIcon(BitmapFactory.decodeResource(this.getResources(), R.mipmap.ic_launcher));
        builder.setOngoing(true);
        builder.setContentIntent(PendingIntent.getActivity(context, 479, new Intent(context, SplashActivity.class)
                .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK), 0));

        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
            startForeground(13, builder.build());
        } else {
            notificationManager.notify(13, builder.build());
        }
        audioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
        lastVolume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
    } catch (Exception ex) {
        //FirebaseCrash.logcat(Log.ERROR, TAG, "NPE caught");
        //FirebaseCrash.report(ex);
    }
    return START_STICKY;
}

@Override
public IBinder onBind(Intent intent) {
    return null;
}

@Override
public void onDestroy() {
    //unregisterReceiver(broadcastReceiver);
    if (Cache.getInt(Cache.status) == 1) {
        startService(new Intent(context, LocationService.class));
    } else {
        if (locationManager != null && listener != null)
            locationManager.removeUpdates(listener);
        listener = null;
        locationManager = null;
        if (notificationManager != null)
            notificationManager.cancel(13);
        super.onDestroy();
    }
}

private void playAlarmSound() { //play alarm when gps turn off
    if (mediaPlayer != null)
        mediaPlayer.stop();
    mediaPlayer = new MediaPlayer();
    audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC), 0);
    try {
        AssetFileDescriptor afd = this.getAssets().openFd("analog_alarm.mp3");
        mediaPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
        mediaPlayer.prepare();
    } catch (Exception ignored) {
    }
    mediaPlayer.start();
    checkGPS();
}

private void checkSound() {
    if (gpsEnable || Cache.getInt(Cache.status) == 0) {
        if (mediaPlayer != null)
            mediaPlayer.stop();
        audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, lastVolume, 0);
    } else {
        new Handler().postDelayed(this::checkSound, 1500);
        playAlarmSound();
    }
}

public class MyLocationListener implements LocationListener {

    public void onLocationChanged(final Location locations) {
        if (locations.getLatitude() > 20 && locations.getLongitude() > 20) {
            App.lastLat = locations.getLatitude(); //save last location some where
            App.lastLng = locations.getLongitude();//save last location some where
            Cache.set(Cache.lat, locations.getLatitude());//save last location some where
            Cache.set(Cache.lng, locations.getLongitude());//save last location some where
        }
        SendLocation(locations, isNetworkEnable());//api call
    }

    public void onProviderDisabled(String provider) {
        gpsEnable = false;
        if (Cache.getInt(Cache.status) == 1) { // true means active
            DBConnection.saveReport(context, new OfficialDriverEvents(0));
            checkSound();
            checkGPS();
        }
    }

    public void onProviderEnabled(String provider) {
        gpsEnable = true;
        DBConnection.saveReport(context, new OfficialDriverEvents(1));
        checkSound();
        checkGPS();
    }

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

private void reportChangeToServer(List<OfficialDriverEvents> list) {
    ApiService apiService = ApiClient.getClient().create(ApiService.class);
    Call<Integer> call = apiService.officialDriverEvents(list);
    call.enqueue(new Callback<Integer>() {
        @Override
        public void onResponse(@NonNull Call<Integer> call, @NonNull Response<Integer> response) {
            if (response.code() == 200)
                try {
                    if (response.body() != null && response.body() == 1) {
                        DBHelper.database.execSQL("DELETE FROM 'event'");
                    }

                } catch (Exception ignored) {
                }
        }

        @Override
        public void onFailure(@NonNull Call<Integer> call, @NonNull Throwable t) {
        }
    });
}

private void SendLocation(Location getLocation, boolean isNetworkEnable) {
    if (!gpsEnable) {
        checkGPS();
    }
    if (isNetworkEnable) {
        checkDatabaseReportList();
        if (!sendingListInProgress) {
            checkDatabaseLocationList();
        }
    }
    if (getLocation.getLatitude() > 20 && getLocation.getLongitude() > 20) {
        Locations location = new Locations();
        location.setStrIMEI(Cache.getString(Cache.imei));
        location.setStrUnitId(Cache.getString(Cache.id));
        location.setLat(getLocation.getLatitude());
        location.setLon(getLocation.getLongitude());
        location.setDistance(0);
        location.setLogDate(Time.getNowPersianDate());
        location.setLogTime(Time.getNowTime());
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            location.setViSpeed(String.valueOf((int) (getLocation.getSpeedAccuracyMetersPerSecond() * 3.6)));
            location.setAccurecy(String.valueOf(getLocation.getVerticalAccuracyMeters()));
            location.setSteps(String.valueOf(getLocation.getBearingAccuracyDegrees()));
        } else {
            location.setViSpeed(String.valueOf((int) (getLocation.getSpeed() * 3.6)));
            location.setAccurecy(String.valueOf(getLocation.getAccuracy()));
            location.setSteps(String.valueOf(getLocation.getBearing()));
        }
        if (isNetworkEnable) {
            SendRequest(location);
        } else {
            DBConnection.saveData(context, location);//request failed save in db for send this later
        }
    }
}

private void checkDatabaseLocationList() {
    List<Locations> lstLocations = DBConnection.openData(context);
    if (lstLocations != null && lstLocations.size() > 0) {
        sendingListInProgress = true;
        SendRequestList(lstLocations);
    } else {
        sendingListInProgress = false;
    }
}

private void checkDatabaseReportList() { // send all failed requests
    List<OfficialDriverEvents> list = DBConnection.getReport(context);
    if (list != null && list.size() > 0)
        reportChangeToServer(list);
}

private void SendRequestList(List<Locations> lstLocations) {
    ApiService apiService = ApiClient.getClient().create(ApiService.class);

    Call<Integer> call = apiService.saveMobileMovementList(lstLocations);
    call.enqueue(new Callback<Integer>() {
        @Override
        public void onResponse(@NonNull Call<Integer> call, @NonNull Response<Integer> response) {
            if (response.code() == 200 && response.body() != null && response.body() == 1) {
                try {
                    DBHelper.database.execSQL("DELETE FROM 'gps' WHERE id IN (SELECT id FROM 'gps' LIMIT 1000)");
                    Log.d("peyloc", "list removed");
                } catch (Exception e) {
                    Log.d("peyloc", "list 200 catch: " + e.getMessage());
                } finally {
                    new Handler().postDelayed(() -> checkDatabaseLocationList(), 20000);
                    Log.d("peyloc", "finally check for offline list");
                }
            } else {
                new Handler().postDelayed(() -> checkDatabaseLocationList(), 20000);
                sendingListInProgress = false;
                Log.d("peyloc", "list not 200");
            }
        }

        @Override
        public void onFailure(@NonNull Call<Integer> call, @NonNull Throwable t) {
            sendingListInProgress = false;
            Log.d("peyloc", "list onFailure");
        }
    });
}

private void checkGPS() { //check gps
    if (!gpsEnable) {
        if (!TurnOnLocationActivity.isRun && !TripAcceptActivity.isRun && !HomeFragment.isRun && !com.rayanandisheh.peysepar.helper.Location.isShowing)
            context.startActivity(new Intent(context, TurnOnLocationActivity.class).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
//            checkSound();
    }
}

private boolean isNetworkEnable() { //check network
    NetworkInfo netInfo = ((ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE)).getActiveNetworkInfo();
    return netInfo != null && netInfo.isConnectedOrConnecting();
}

private void SendRequest(final Locations location) {
    ApiService apiService = ApiClient.getClient().create(ApiService.class);
    Call<Integer> call = apiService.saveMobileMovement(location);
    call.enqueue(new Callback<Integer>() {
        @Override
        public void onResponse(@NonNull Call<Integer> call, @NonNull Response<Integer> response) {
            if (response.code() == 200 && response.body() != null && response.body() == 1)
                Log.d("peyloc", "200 ok");
            else {
                Log.d("peyloc", "200 not ok");
                DBConnection.saveData(context, location);//request failed save in db for send this later
            }
        }

        @Override
        public void onFailure(@NonNull Call<Integer> call, @NonNull Throwable t) {
            Log.d("peyloc", "onFailure");
            DBConnection.saveData(context, location);//request failed save in db for send this later
        }
    });
}
}

答案 1 :(得分:0)

https://codelabs.developers.google.com/codelabs/realtime-asset-tracking/index.html?index=..%2F..index#1

尝试使用Firebase实施它。这是跟踪人员并进行实时跟踪的最佳方法。

答案 2 :(得分:0)

您可以使用融合的位置提供程序和任何实时数据库来提高可靠性。

融合位置提供程序是一种高级Google Play服务API,用于包装诸如GPS之类的基础位置传感器。您可以完成以下任务: 1.注册位置连接事件 2.连接到位置传感器 3.注册更新或准确性更改 4.获取最后的位置 有关更简单的位置更新,请查看此smart-location-lib位置API包装器。

Android official document

Retrieving Location with LocationServices API elaborated

Firebase实时数据库 Firebase Realtime Database是一个云托管数据库,支持多个平台的Android,iOS和Web。所有数据均以JSON格式存储,并且通过在所有平台和设备之间执行同步,数据中的任何更改都会立即反映出来。这使我们能够以最小的努力轻松构建更灵活的实时应用。

Firebase Realtime Database

供参考,请通过 Real-time Asset Tracking sample code labs