#android #service #timer #gps
#Android #Обслуживание #таймер #gps
Вопрос:
У меня проблема с моим приложением для Android. Мне нужно приложение, которое будет отправлять местоположение GPS в фоновом режиме каждые 10 минут на сервер (здесь у меня есть служба WCF, которая работает). Приложению необходимо отправлять данные, даже если оно закрыто. Итак, я создал службу (для целей тестирования), которая отправляет мне время на сервере. Но когда я вставляю свой код для получения местоположения GPS в свой сервис, все выходит из строя (неожиданно останавливается).
Я понял, что вам нужно установить какой-нибудь приемник или что-то в этом роде, но пока ничего не работает. Поэтому я буду очень рад, если кто-нибудь сможет мне помочь.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.biromatik.GPS"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="4" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<activity
android:label="@string/app_name"
android:name=".ETMGPSServiceActivity" >
<intent-filter >
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:name=".MyApplication" >
<service
android:enabled="true"
android:name=".MonitorService" >
</service>
<receiver
android:enabled="true"
android:name=".LocationReceiver" >
<intent-filter >
<action android:name="com.biromatik.intent.action.LOCATION" />
</intent-filter>
</receiver>
</application>
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.SEND_SMS"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
</manifest>
Комментарии:
1. «сбой всего моего сервиса (неожиданно остановлен)» -> какую ошибку вы получаете?
2. В CatLog я получаю это: 11-11 15: 25: 49.541: E / AndroidRuntime (229): обработчик Uncaught: основной поток завершается из-за неперехваченного исключения
Ответ №1:
Я сделал это в своем приложении, чтобы сделать то же самое, что вы просили.
В моем сервисе я добавил это:
@Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
addLocationListener();
}
private void addLocationListener()
{
triggerService = new Thread(new Runnable(){
public void run(){
try{
Looper.prepare();//Initialise the current thread as a looper.
lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
Criteria c = new Criteria();
c.setAccuracy(Criteria.ACCURACY_COARSE);
final String PROVIDER = lm.getBestProvider(c, true);
MyLocationListener myLocationListener = new MyLocationListener();
lm.requestLocationUpdates(PROVIDER, 600000, 0, myLocationListener);
Log.d("LOC_SERVICE", "Service RUNNING!");
Looper.loop();
}catch(Exception ex){
ex.printStackTrace();
}
}
}, "LocationThread");
triggerService.start();
}
public static void updateLocation(Location location)
{
Context appCtx = MyApplication.getAppContext();
double latitude, longitude;
latitude = location.getLatitude();
longitude = location.getLongitude();
Intent filterRes = new Intent();
filterRes.setAction("xxx.yyy.intent.action.LOCATION");
filterRes.putExtra("latitude", latitude);
filterRes.putExtra("longitude", longitude);
appCtx.sendBroadcast(filterRes);
}
class MyLocationListener implements LocationListener
{
@Override
public void onLocationChanged(Location location)
{
updateLocation(location);
}
}
ПРИМЕЧАНИЕ: Видите, что я использую MyApplication.getAppContext(); это потому, что я использую свой собственный класс приложения для добавления контекста.
И тогда у меня есть BroadcastReceiver с этим:
public class LocationReceiver extends BroadcastReceiver {
double latitude, longitude;
@Override
public void onReceive(final Context context, final Intent calledIntent)
{
Log.d("LOC_RECEIVER", "Location RECEIVED!");
latitude = calledIntent.getDoubleExtra("latitude", -1);
longitude = calledIntent.getDoubleExtra("longitude", -1);
updateRemote(latitude, longitude);
}
private void updateRemote(final double latitude, final double longitude )
{
//HERE YOU CAN PUT YOUR ASYNCTASK TO UPDATE THE LOCATION ON YOUR SERVER
}
}
класс приложения:
public class MyApplication extends Application {
private static Context context;
/* (non-Javadoc)
* @see android.app.Application#onCreate()
*/
@Override
public void onCreate() {
MyApplication.context=getApplicationContext();
}
public static Context getAppContext() {
return MyApplication.context;
}
}
Также в вашем манифесте вам нужно добавить оба:
<application
android:icon="@drawable/icon"
android:label="@string/app_name"
android:name=".MyApplication" >
//YOUR ACTIVITIES HERE...
<service
android:enabled="true"
android:name=".LocationService" >
</service>
<receiver
android:enabled="true"
android:name=".LocationReceiver" >
<intent-filter >
<action android:name="xxx.yyy.intent.action.LOCATION" />
</intent-filter>
</receiver>
</application>
Способ определить, запущена ли служба, я делаю это при своем первом действии:
/**
* Check location service.
*/
private void checkLocationService()
{
Log.d("CHECK_SERVICE", "Service running: " (settings.getBoolean("locationService", false)?"YES":"NO"));
if(settings.getBoolean("locationService", false))
return;
Intent mServiceIntent = new Intent(this, LocationService.class);
startService(mServiceIntent);
}
Очевидно, вам нужно управлять SharedPreferences (настройки), чтобы установить переменной LocationService значение true / false, запущена служба (OnStart) или нет (onDestroy).
Комментарии:
1. Это выглядит идеально, но у меня все еще есть проблемы: this xxx.yyy.intent… что поставить вместо этого, и у меня также есть проблема с этим MyApplication.getContext (), есть ли какой-либо другой способ?
2. как я уже сказал, вам нужно создать класс, который расширяется из приложения (и добавить его в свой манифест) xxx.yyy.intent.action. МЕСТОПОЛОЖЕНИЕ может быть любым, каким вы хотите.. введите имя вашего пакета и добавьте intent.action. МЕСТОПОЛОЖЕНИЕ, чтобы быть более конкретным об этом .. Я отредактирую свой ответ с помощью класса application
3. ХОРОШО, теперь я получаю: W / ActivityManager (51): Не удается запустить намерение службы {act=com.biromatik.GPS.MonitorService}: не найдено. Можете ли вы сказать мне, как запустить эту службу сейчас?
4. находится ли ваш класс обслуживания в том же пакете, что и ваше приложение?
5. укажите в своем вопросе свой класс обслуживания