Форум программистов, компьютерный форум, киберфорум
Наши страницы
Программирование Android
Войти
Регистрация
Восстановить пароль
 
 
SkyL1ne_tm
2 / 2 / 0
Регистрация: 06.07.2013
Сообщений: 97
#1

GPSTracker как Service - Программирование Android

24.05.2015, 21:00. Просмотров 919. Ответов 20
Метки нет (Все метки)

Написал приложение, которое определяет местоположение по GPS/WiFi(мобильным сетям), показывает на карте в виде метки, записывает координаты в базу данных SQLite, а затем можно просматривать треки перемещений за день. Но, приложение работает только когда экран активен.
Возникла потребность сделать так, чтобы определение координат и запись их в БД работало в фоне(экран не активен, приложение свернуто и т.п.)

В MainActivity оставил инициализацию карты, рисование треков и прочее, типа определения переменных и т.п.
http://www.cyberforum.ru/android-dev/thread1755769.html
В Service перенес запрос на определение местоположение через LocationManager, получение самих координат и запись их в БД. Вот примерный код:
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
public class TrackerService extends Service implements LocationListener {
 
    final String myLog = "my_Logs";
    LocationManager locationManager;
    double latitude, longitude;
    LatLng myPosition;
    Calendar addTimeCalendar;
    String addDate;
    Cursor c = null;
 
    public void onCreate() {
        super.onCreate();
        locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
    }
 
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d(myLog, "onStartCommand");
        locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,1000 * 60, 25, this);
        Log.d(myLog, "GPS_Provider request location updates");
        locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 1000 * 60, 25, this);
        Log.d(myLog, "Network_Provider request location updates");
        //getLocation(location);
        return super.onStartCommand(intent, flags, startId);
    }
 
    @Override
    public void onLocationChanged(Location location) {
        getLocation(location);
    }
 
    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {
 
    }
 
    @Override
    public void onProviderEnabled(String provider) {
        getLocation(locationManager.getLastKnownLocation(provider));
    }
 
    @Override
    public void onProviderDisabled(String provider) {
        checkEnabled();
    }
 
    public void getLocation(final Location location) {
        new Thread(new Runnable() {
            public void run() {
                if (location == null)
                    return;
                if (location.getProvider().equals(LocationManager.GPS_PROVIDER)) {
                    Log.d(myLog, "GPS Provider Enabled");
                    latitude = location.getLatitude();
                    longitude = location.getLongitude();
                    myPosition = new LatLng(latitude,longitude);
                    addCoordinates();
                    Log.d(myLog, "---GPS Координаты добавлены---");
                } else if (location.getProvider().equals(LocationManager.NETWORK_PROVIDER)) {
                    Log.d(myLog, "NETWORK PROVIDER Enabled");
                    latitude = location.getLatitude();
                    longitude = location.getLongitude();
                    myPosition = new LatLng(latitude,longitude);
                    addCoordinates();
                    Log.d(myLog, "---Network Координаты добавлены---");
                }
            }
        }).start();
    }
 
    public void addCoordinates() {
        addTimeCalendar = Calendar.getInstance();
        SimpleDateFormat addDayFormat = new SimpleDateFormat("yyyy-MM-dd");
        addDate = addDayFormat.format(addTimeCalendar.getTime());
        SQL sqlHelper = new SQL(this);
        SQLiteDatabase db = sqlHelper.getWritableDatabase();
        ContentValues cv = new ContentValues();
        Log.d(myLog, "--- Insert in coordinates: ---");
        cv.put("Latitude", latitude);
        cv.put("Longitude", longitude);
        cv.put("Time", addDate);
        long rowID = db.insert("coordinates", null, cv);
        Log.d(myLog, "row inserted, ID = " + rowID);
        db.close();
        sqlHelper.close();
    }
 
    public void onDestroy() {
        super.onDestroy();
        Log.d(myLog, "onDestroy");
    }
 
    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }
 
}
Собственно вопрос:
1. Как передать myPostition, т.е. latitude и longitude, из метода getLocation сервиса в MainActivity, чтобы потом их можно было поместить на карту в виде маркера?
2. Правильно ли я сделал, что поместил запрос на обновление локации(местоположения) в onStartCommand? Или это нужно было сделать в onCreate() сервиса?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
24.05.2015, 21:00
Я подобрал для вас темы с готовыми решениями и ответами на вопрос GPSTracker как Service (Программирование Android):

Как передать intent данные в Service?
Здравствуйте! как передать intent данные в класс с расширением Service?...

Как получить context MainActivity в Service?
В MainActivity создаю сервис и startService( SER );, как получить context...

Как отследить принудительную остановку service системой?
Как отследить остановку service когда Android его останавливает из- за нехватки...

Как запустить service при входящем вызове?
Есть ли такая возможность разбудить мой сервис при входящем вызове типа...

Как сохранить состояние Service после перезагрузки телефона?
Как сохранить состояние Service после перезагрузки телефона??? т.е мне нужно...

20
Rube
911 / 559 / 88
Регистрация: 13.02.2014
Сообщений: 2,072
25.05.2015, 07:19 #2
1. Лучше записывать и читать из БД.
2. Лучше в отдельный метод.
0
SkyL1ne_tm
2 / 2 / 0
Регистрация: 06.07.2013
Сообщений: 97
25.05.2015, 08:04  [ТС] #3
И так их записываю, чтобы можно было смотреть треки за день.
Все-таки как передать myPosition в MainActivity, чтобы можно было сразу поместить маркер на карту, как экран будет активен?

Этот метод все равно нужно будет поместить либо в onCreate(), либо в onStartCommand() сервиса?
0
Armagedo
209 / 209 / 60
Регистрация: 22.08.2014
Сообщений: 644
25.05.2015, 08:11 #4
1. Через интент, например.
BroadcastReceiver + LocalBroadcastManager
0
SkyL1ne_tm
2 / 2 / 0
Регистрация: 06.07.2013
Сообщений: 97
25.05.2015, 08:18  [ТС] #5
можно пример?
0
Armagedo
209 / 209 / 60
Регистрация: 22.08.2014
Сообщений: 644
25.05.2015, 08:47 #6
В MainActivity заводишь зверя, например
Java
1
2
3
4
5
6
7
8
9
10
11
12
private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            Toast.makeText(getBaseContext(), 
            "Got command to update. Updating...",
            Toast.LENGTH_LONG).show();
            
                        //выцарапываешь данные из интента через get[...]Extra("latitude"), get[...]Extra("longitude");
                        //ну и пользуешь их. 
                        
        }
    };
В onCreate регистрируешь его
Java
1
2
3
4
5
// Register to receive messages.
            // Register an observer (mMessageReceiver) to receive Intents
            // with actions named "update-map".
            LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver,
                      new IntentFilter("update-map"));
В onDestroy его того
Java
1
2
3
4
5
6
@Override
    protected void onDestroy() {
      // Unregister since the activity is about to be closed.
      LocalBroadcastManager.getInstance(this).unregisterReceiver(mMessageReceiver);
      super.onDestroy();
    }
Ну, и теперь там, где тебе надо

Java
1
2
3
4
5
Intent updateMapIntent = new Intent("update-map");
updateMapIntent.putExtra("longitude", ...);
updateMapIntent.putExtra("latitude", ....);
 
LocalBroadcastManager.getInstance(context).sendBroadcast(updateMapIntent);
Вообщем, где-то так
0
SkyL1ne_tm
2 / 2 / 0
Регистрация: 06.07.2013
Сообщений: 97
25.05.2015, 09:19  [ТС] #7
Цитата Сообщение от Armagedo Посмотреть сообщение
updateMapIntent.putExtra("longitude", ...);
updateMapIntent.putExtra("latitude", ....);
вместо "...." должны быть какие-то параметры?
0
Armagedo
209 / 209 / 60
Регистрация: 22.08.2014
Сообщений: 644
25.05.2015, 09:37 #8
Откройте справку по Intent.putExtra
0
Rube
911 / 559 / 88
Регистрация: 13.02.2014
Сообщений: 2,072
25.05.2015, 09:44 #9
Цитата Сообщение от SkyL1ne_tm Посмотреть сообщение
Как передать myPostition, т.е. latitude и longitude, из метода getLocation сервиса в MainActivity, чтобы потом их можно было поместить на карту в виде маркера?
Цитата Сообщение от SkyL1ne_tm Посмотреть сообщение
Все-таки как передать myPosition в MainActivity, чтобы можно было сразу поместить маркер на карту, как экран будет активен?
Так определись сначала, сразу или потом!
0
SkyL1ne_tm
2 / 2 / 0
Регистрация: 06.07.2013
Сообщений: 97
25.05.2015, 09:55  [ТС] #10
Цитата Сообщение от Armagedo Посмотреть сообщение
Intent updateMapIntent = new Intent("update-map");
updateMapIntent.putExtra("longitude", ...);
updateMapIntent.putExtra("latitude", ....);
LocalBroadcastManager.getInstance(context).sendBroadcast(updateMapIntent);
Я запутался уже..это должно быть в Service или в MainActivity?

Добавлено через 5 минут
Цитата Сообщение от Rube Посмотреть сообщение
Так определись сначала, сразу или потом!
Как только экран станет активным, так и помещать маркер с текущими координатами на карту
0
Rube
911 / 559 / 88
Регистрация: 13.02.2014
Сообщений: 2,072
25.05.2015, 10:43 #11
Цитата Сообщение от SkyL1ne_tm Посмотреть сообщение
Как только экран станет активным, так и помещать маркер с текущими координатами на карту
Так в чем проблема, считывай в OnCreate последние значения координат из БД и все дела.
0
SkyL1ne_tm
2 / 2 / 0
Регистрация: 06.07.2013
Сообщений: 97
25.05.2015, 17:20  [ТС] #12
я так и делаю, если не использовать Service(т.е. все методы в MainActivity)
0
Rube
911 / 559 / 88
Регистрация: 13.02.2014
Сообщений: 2,072
25.05.2015, 18:36 #13
Цитата Сообщение от SkyL1ne_tm Посмотреть сообщение
я так и делаю
Ну и? В чем вопрос?
0
SkyL1ne_tm
2 / 2 / 0
Регистрация: 06.07.2013
Сообщений: 97
25.05.2015, 18:48  [ТС] #14
В этом:

Цитата Сообщение от SkyL1ne_tm Посмотреть сообщение
1. Как передать myPostition, т.е. latitude и longitude, из метода getLocation сервиса в MainActivity, чтобы потом их можно было поместить на карту в виде маркера?
2. Правильно ли я сделал, что поместил запрос на обновление локации(местоположения) в onStartCommand? Или это нужно было сделать в onCreate() сервиса?
0
Rube
911 / 559 / 88
Регистрация: 13.02.2014
Сообщений: 2,072
25.05.2015, 19:26 #15
1. Сделать getLocation статическим?
2. Отвечал уже выше.
0
SkyL1ne_tm
2 / 2 / 0
Регистрация: 06.07.2013
Сообщений: 97
26.05.2015, 12:44  [ТС] #16
Возник вопрос: пытаюсь передать из сервиса в активити 2 параметра: latitude и longitude, затем получить их в активити и поместить на карту в виде маркера. Маркер появляется, но с координатами (0;0), хотя должен быть с текущими координатами, полученными от LocationManager-a. Почему?

Сервис:
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
public class TrackerService extends Service implements LocationListener {
 
    final String myLog = "my_Logs";
    LocationManager locationManager;
    double latitude, longitude;
    LatLng myPosition;
    Calendar addTimeCalendar;
    String addDate;
    Cursor c = null;
    Location location;
 
    public void onCreate() {
        super.onCreate();
        locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
    }
 
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d(myLog, "onStartCommand");
        locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,1000 * 60, 25, this);
        Log.d(myLog, "GPS_Provider request location updates");
        locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 1000 * 60, 25, this);
        Log.d(myLog, "Network_Provider request location updates");
        getLocation(location);
        run();
        return super.onStartCommand(intent, flags, startId);
    }
 
    public void run() {
        Intent intent = new Intent(MainActivity.BROADCAST_ACTION);
        intent.putExtra("latitude", latitude);
        intent.putExtra("longitude", longitude);
        Log.d(myLog, "lat = " + latitude + " lng = " + longitude);
        sendBroadcast(intent);
    }
 
    @Override
    public void onLocationChanged(Location location) {
        getLocation(location);
    }
 
    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {
    }
 
    @Override
    public void onProviderEnabled(String provider) {
        getLocation(locationManager.getLastKnownLocation(provider));
    }
 
    @Override
    public void onProviderDisabled(String provider) {
    }
 
    public void getLocation(Location location) {
                if (location == null)
                    return;
                if (location.getProvider().equals(LocationManager.GPS_PROVIDER)) {
                    Log.d(myLog, "GPS Provider Enabled");
                    latitude = location.getLatitude();
                    longitude = location.getLongitude();
                    myPosition = new LatLng(latitude,longitude);
                    addCoordinates();
                    Log.d(myLog, "---GPS Координаты добавлены---");
                } else if (location.getProvider().equals(LocationManager.NETWORK_PROVIDER)) {
                    Log.d(myLog, "NETWORK PROVIDER Enabled");
                    latitude = location.getLatitude();
                    longitude = location.getLongitude();
                    myPosition = new LatLng(latitude,longitude);
                    addCoordinates();
                    Log.d(myLog, "---Network Координаты добавлены---");
                }
    }
 
    public void addCoordinates() {
        addTimeCalendar = Calendar.getInstance();
        SimpleDateFormat addDayFormat = new SimpleDateFormat("yyyy-MM-dd");
        addDate = addDayFormat.format(addTimeCalendar.getTime());
        SQL sqlHelper = new SQL(this);
        SQLiteDatabase db = sqlHelper.getWritableDatabase();
        ContentValues cv = new ContentValues();
        Log.d(myLog, "--- Insert in coordinates: ---");
        cv.put("Latitude", latitude);
        cv.put("Longitude", longitude);
        cv.put("Time", addDate);
        long rowID = db.insert("coordinates", null, cv);
        Log.d(myLog, "row inserted, ID = " + rowID);
        db.close();
        sqlHelper.close();
    }
 
    public void onDestroy() {
        super.onDestroy();
        stopSelf();
        Log.d(myLog, "onDestroy");
    }
 
    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }
 
}
В MainActivity:

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
protected void onCreate(Bundle savedInstanceState){
startService(new Intent(this, TrackerService.class));
        mMessageReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                Log.d(LOG_TAG, "Got command to update. Updating...");
                latitude = intent.getDoubleExtra("latitude", latitude);
                longitude = intent.getDoubleExtra("longitude", longitude);
                Log.d(LOG_TAG, "lat = " + latitude + " long = " + longitude);
            }
        };
        IntentFilter intFilt = new IntentFilter(BROADCAST_ACTION);
        registerReceiver(mMessageReceiver, intFilt);
}
 
protected void onResume() {
        super.onResume();
        showLocation();
}
В методе showLocation:
Java
1
2
3
4
myPosition = new LatLng(latitude, longitude);
clearMap();
marker = map.addMarker(new MarkerOptions().icon(BitmapDescriptorFactory.fromResource(R.drawable.marker_pink)).position(myPosition).title("GPS"));
marker.showInfoWindow();
Добавлено через 3 минуты
Координаты в базу записываются, когда приложение свернуто(экран не активен). (Посмотрел по треку на карте)
0
Rube
911 / 559 / 88
Регистрация: 13.02.2014
Сообщений: 2,072
26.05.2015, 14:37 #17
Цитата Сообщение от SkyL1ne_tm Посмотреть сообщение
Почему?
Ну видимо потому что они пустые вестимо. Сервис то обновляет карту после получения координат.
Включите логи в методы и смотрите порядок выполнения.
0
SkyL1ne_tm
2 / 2 / 0
Регистрация: 06.07.2013
Сообщений: 97
28.05.2015, 15:32  [ТС] #18
Разобрался с передачей данных через Intent.
Как теперь вызывать сервис, чтобы он регулярно запрашивал местоположение и выполнял другие действия?

Код сервиса:

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
public class TrackerService extends Service implements LocationListener {
 
    final String LOG_TAG = "myLogs";
    LocationManager locationManager;
    double latitude, longitude;
    LatLng myPosition;
    Calendar addTimeCalendar;
    String addDate;
    Cursor c = null;
    Location location;
 
    public void onCreate() {
        super.onCreate();
        locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
 
    }
 
    void locationUpdates () {
        locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,1000 * 45, 25, this);
        Log.d(LOG_TAG, "GPS_Provider request location updates");
        locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 1000 * 45, 25, this);
        Log.d(LOG_TAG, "Network_Provider request location updates");
    }
 
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d(LOG_TAG, "onStartCommand");
        locationUpdates();
        getLocation(location);
        return super.onStartCommand(intent, flags, startId);
    }
 
    @Override
    public void onLocationChanged(Location location) {
        getLocation(location);
    }
 
    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {
    }
 
    @Override
    public void onProviderEnabled(String provider) {
        getLocation(locationManager.getLastKnownLocation(provider));
    }
 
    @Override
    public void onProviderDisabled(String provider) {
    }
 
    public void getLocation(Location location) {
                if (location == null)
                    return;
                if (location.getProvider().equals(LocationManager.GPS_PROVIDER)) {
                    Log.d(LOG_TAG, "GPS Provider Enabled");
                    latitude = location.getLatitude();
                    longitude = location.getLongitude();
                    myPosition = new LatLng(latitude,longitude);
                    Log.d(LOG_TAG, "______in getLocation______");
                    Log.d(LOG_TAG, "GPS lat = " + latitude + " GPS lng = " + longitude);
                    addCoordinates();
                    Log.d(LOG_TAG, "---GPS Координаты добавлены---");
 
                    Intent intent = new Intent(MainActivity.BROADCAST_ACTION);
                    intent.putExtra("latitude", latitude);
                    intent.putExtra("longitude", longitude);
                    Log.d(LOG_TAG, "lat = " + latitude + " lng = " + longitude);
                    sendBroadcast(intent);
 
                } else if (location.getProvider().equals(LocationManager.NETWORK_PROVIDER)) {
                    Log.d(LOG_TAG, "NETWORK PROVIDER Enabled");
                    latitude = location.getLatitude();
                    longitude = location.getLongitude();
                    myPosition = new LatLng(latitude,longitude);
                    Log.d(LOG_TAG, "______in getLocation______");
                    Log.d(LOG_TAG, "WIFI lat = " + latitude + " WIFI lng = " + longitude);
                    addCoordinates();
                    Log.d(LOG_TAG, "---Network Координаты добавлены---");
                    Log.d(LOG_TAG, "______before intent______");
 
                    Intent intent = new Intent(MainActivity.BROADCAST_ACTION);
                    intent.putExtra("latitude", latitude);
                    intent.putExtra("longitude", longitude);
                    Log.d(LOG_TAG, "lat = " + latitude + " lng = " + longitude);
                    sendBroadcast(intent);
                }
    }
 
    public void addCoordinates() {
        addTimeCalendar = Calendar.getInstance();
        SimpleDateFormat addDayFormat = new SimpleDateFormat("yyyy-MM-dd");
        addDate = addDayFormat.format(addTimeCalendar.getTime());
        SQL sqlHelper = new SQL(this);
        SQLiteDatabase db = sqlHelper.getWritableDatabase();
        ContentValues cv = new ContentValues();
        Log.d(LOG_TAG, "--- Insert in coordinates: ---");
        cv.put("Latitude", latitude);
        cv.put("Longitude", longitude);
        cv.put("Time", addDate);
        long rowID = db.insert("coordinates", null, cv);
        Log.d(LOG_TAG, "row inserted, ID = " + rowID);
        db.close();
        sqlHelper.close();
    }
 
    public void onDestroy() {
        super.onDestroy();
        stopSelf();
        Log.d(LOG_TAG, "onDestroy");
    }
 
    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }
 
}
0
Rube
911 / 559 / 88
Регистрация: 13.02.2014
Сообщений: 2,072
28.05.2015, 16:36 #19
AlarmManager поможет.
0
SkyL1ne_tm
2 / 2 / 0
Регистрация: 06.07.2013
Сообщений: 97
28.05.2015, 16:45  [ТС] #20
т.е. с помощью него с заданным интервалом времени стартовать сервис, выполнять действие и убивать сервис?
а потом по новой и так далее.. ?
0
28.05.2015, 16:45
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
28.05.2015, 16:45
Привет! Вот еще темы с решениями:

Как защитится от повторного запуска Service (защита от дурака)?
На вся кий случай хочу проставить защиту. Работает одновременно 4 сервиса и...

Как сделать так, чтобы Service работал после закрытия программы
Здравствуйте! Никак не могу разобраться, как сделать так, чтобы Service...

Как сделать чтобы приложение работало только тогда когда работает Service
Как сделать чтобы приложение работала только тогда когда работает public...

Service
Как создать приложение как Service?


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru