Запуск сервиса на платформе Android - PullRequest
3 голосов
/ 20 февраля 2010

Я запускаю службу, используя startService (намерение) . Когда я вызываю эту функцию, она достигает onCreate службы, но не может вызвать onStartCommand . Вот мой код -

@Override
public void onReceive(Context context, Intent intent) {
    // Send a text notification to the screen.
    Log.e("mudit", "Action: " + intent.getAction());

    try {
        ConnectivityManager connManager = (ConnectivityManager) context
                .getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo info = connManager.getActiveNetworkInfo();
        Log.e("mudit", "getType: " + info.getType());
        Log.e("mudit", "isConnected: " + info.isConnected());
        if (info.isConnected()) {

            Intent newinIntent = new Intent(context, service.class);
            context.startService(newinIntent);
        }

    } catch (Exception e) {
        e.printStackTrace();
        Intent newinIntent = new Intent(context, service.class);
        context.stopService(newinIntent);

    }

}

Сервисный код -

package com.android.service;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.widget.Toast;

public class service extends Service {

    @Override
    public IBinder onBind(Intent arg0) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Toast.makeText(this, "Service created...", Toast.LENGTH_LONG).show();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Toast.makeText(this, "Service destroyed ...", Toast.LENGTH_LONG).show();
    }

    public int onStartCommand(Intent intent, int flags, int startId) {

        Toast.makeText(this, "onStartCommand...", Toast.LENGTH_LONG).show();
        return 1;
    }

}  

Manifest.xml -

<receiver class=".AReceiver" android:name=".AReceiver">
        <intent-filter>
            <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
        </intent-filter>
    </receiver>
    <service class=".service" android:name=".service"
        android:enabled="true" android:icon="@drawable/icon">
    </service>

Ответы [ 5 ]

3 голосов
/ 06 ноября 2012
  1. Unbound Service: он работает в фоновом режиме бесконечно, даже если запущена деятельность с завершением службы.
  2. Связанная служба: она будет работать до времени жизни активности.

Деятельность может запустить службу через startService(), и она остановится через stopService(). Если деятельность хочет взаимодействовать с сервисом, она может использовать bindService().

Сначала вызывается onCreate(), после вызова onStartCommand с данными намерения, предоставленными действием.

Источник

2 голосов
/ 21 июля 2012

larsVogel решает эту проблему (и многим другим нравится) в этом прекрасном посте .

вот как я адаптировал его код для создания приемника подключения, который отслеживает, когда пользователь подключается к сети WIFI, для пакетной загрузки данных об использовании:

в файле манифеста, поместите получателя и объявите службу прямо перед конечным тегом для вашего :

    <receiver android:name=".ConnMonitor" android:enabled="true">
        <intent-filter>
            <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
        </intent-filter>
    </receiver>
    <service android:name=".BatchUploadGpsData" ></service>

</application>

создать класс приемника вещания в отдельном файле с именем ConnMonitor.java (пожалуйста, раскомментируйте вызовы журнала, чтобы иметь возможность правильно контролировать поток)

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.util.Log;

public class ConnMonitor extends BroadcastReceiver {
    private String TAG = "TGtracker";

    @Override
    public void onReceive(Context context, Intent intent) {
        //String typeName = "";
        String state = "";
        int type = -1;
        ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService( Context.CONNECTIVITY_SERVICE );
        NetworkInfo test = (NetworkInfo) connectivityManager.getActiveNetworkInfo();
        //Log.v(TAG,"there has been a CONNECTION CHANGE -> "+intent.getExtras().get(ConnectivityManager.EXTRA_NETWORK_INFO));
        try {
            //typeName = test.getTypeName().toString();
            type = test.getType();
            state = test.getState().toString();
            //Log.i(TAG,"type -> '"+typeName +"'  state -> '"+state+"'"   );
        } catch (Exception e) {
            //typeName = "null";
            type = -1;
            state = "DISCONNECTED";
            //Log.i(TAG,"type -> error1 "+e.getMessage()+ "   cause = "+e.getCause()   );
        }

        if ( (type == 1)  &&  (state == "CONNECTED") ) {
            //Log.i(TAG, "I am soooo friggin uploadin on this beautiful WIFI connection ");
            Intent batchUploadDataService = new Intent(context, BatchUploadGpsData.class);
            context.startService(batchUploadDataService);
        } else {
            //Log.e(TAG,"NO FOUND MATCH type -> '"+typeName +"'  state -> '"+state+"'"   );
        }
    }
}

и, наконец, создайте сервис BatchUploadGpsData.java следующим образом:

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;

public class BatchUploadGpsData extends Service {
    final String TAG = "TGtracker";

    @Override
    public void onCreate() {
        Log.e(TAG, "here i am, rockin like a hurricane.   onCreate service");
    // this service tries to upload and terminates itself whether it is successful or not 
    // but it only effectively DOES anything while it is created 
    // (therefore, you can call 1 million times if uploading isnt done, nothing happens)
    // if you comment this next line, you will be able to see that it executes onCreate only the first it is called
    // the reason i do this is that the broadcast receiver is called at least twice every time you have a new change of connectivity state with successful connection to wifi
        this.stopSelf();
    }
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        //Log.i(TAG, "Received start id " + startId + ": " + intent);
        Log.e(TAG, "call me redundant BABY!  onStartCommand service");
        // this service is NOT supposed to execute anything when it is called
        // because it may be called inumerous times in repetition
        // all of its action is in the onCreate - so as to force it to happen ONLY once
        return 1;
    }
    @Override
    public IBinder onBind(Intent intent) {
        // TODO Auto-generated method stub
        return null;
    }

}

это не псевдокод, это реальный код, протестированный и работающий на Android 2.2 и выше.

способ протестировать эту услугу - выключить и перезапустить сервисы WIFI на вашем андроиде (отключение маршрутизатора Wi-Fi также поможет). НО этот код не проверяет, действительно ли вы подключены к сети. для этого я рекомендую вам сделать запрос httpclient и проверить результат вызова. выходит за рамки этого обсуждения.

ПРИМЕЧАНИЕ: поскольку службы работают в том же потоке, что и пользовательский интерфейс, я настоятельно рекомендую реализовать загрузку в отдельном потоке или асинхронной задаче, в зависимости от ваших конкретных потребностей. Вы также можете запустить весь сервис в отдельном потоке, но это опять-таки не является предметом этого обсуждения, несмотря на то, что в этих случаях это стандартная практика.

2 голосов
/ 24 октября 2010

Сначала вы должны добавить @Override перед onStartCommand(..), затем , чтобы убедиться, что цель для проекта Android выше, чем 2,0 .

1 голос
/ 18 апреля 2012

Я считаю, что вы не можете получить доступ к любым компонентам пользовательского интерфейса, таким как Dialog или даже Toast в службе.

попробуйте это.

public int onStartCommand(Intent intent, int flags, int startId) {

/*    Toast.makeText(this, "onStartCommand...", Toast.LENGTH_LONG).show();
    return 1; */

    Log.i("YourService", "Yes this works.");
}
0 голосов
/ 14 октября 2011

Прежде всего, назовите свой класс чем-то другим, это моя рекомендация избегать путаницы в будущем. Во-вторых, вот пример моего явного вызова службы, которая у меня работает. Я использую полные пути при вызове сервисов и т. Д., Поскольку они не находятся в одном пакете с моим приложением.

<service android:name="com.public.service.UploaderService" android:icon="@drawable/vgbio"></service>

Вот суть моего класса обслуживания,

package com.public.service;
....
public class UploaderService extends Service{
....
}

В-третьих, убедитесь, что вы используете @Override для onStartCommand ().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...