Фоновой службе необходимо отправить местоположение GPS на сервер

#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. укажите в своем вопросе свой класс обслуживания