Pergunta

Como posso verificar se um serviço de fundo está funcionando?

Eu quero uma atividade Android que alterna o estado do serviço -. Ela me permite ligá-lo se ele está desligado e fora se ele estiver em

Foi útil?

Solução

Eu tive o mesmo problema há pouco tempo. Desde o meu serviço foi local, acabei simplesmente usando um campo estático na classe de serviço para o estado de alternância, como descrito por hackbod aqui

Editar (para o registro):

Aqui está a solução proposta pela hackbod:

Se o seu cliente e código do servidor é parte do mesmo .apk e você está ligação para o serviço com uma concreto Intenção (um que especifica a classe de serviço exato), então você pode simplesmente ter o seu serviço conjunto um variável global quando se está em execução que o seu cliente pode verificar.

Nós deliberadamente não tem uma API para verificar se um serviço é correr, porque, quase sem falhar, quando você quer fazer algo assim você acaba com as condições de corrida em seu código.

Outras dicas

Eu uso o seguinte a partir de dentro de uma atividade:

private boolean isMyServiceRunning(Class<?> serviceClass) {
    ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
    for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
        if (serviceClass.getName().equals(service.service.getClassName())) {
            return true;
        }
    }
    return false;
}

E eu chamá-lo usando:

isMyServiceRunning(MyService.class)

Isso funciona de forma confiável, porque se baseia nas informações sobre a execução de serviços prestados pelo sistema operacional Android através de ActivityManager # getRunningServices .

Todas as abordagens utilizando onDestroy ou eventos onSometing ou aglutinantes ou variáveis ??estáticas não irá funcionar de forma confiável porque, como um desenvolvedor, você nunca sabe, quando Android decide matar seu processo ou qual dos retornos de chamada mencionados são chamados ou não. Por favor, note a coluna "killable" no ciclo de vida tabela de eventos na documentação do Android.

Entendi!

Você deve chamada startService() para o seu serviço a ser devidamente registrados e passando BIND_AUTO_CREATE não será suficiente.

Intent bindIntent = new Intent(this,ServiceTask.class);
startService(bindIntent);
bindService(bindIntent,mConnection,0);

E agora a classe ServiceTools:

public class ServiceTools {
    private static String LOG_TAG = ServiceTools.class.getName();

    public static boolean isServiceRunning(String serviceClassName){
        final ActivityManager activityManager = (ActivityManager)Application.getContext().getSystemService(Context.ACTIVITY_SERVICE);
        final List<RunningServiceInfo> services = activityManager.getRunningServices(Integer.MAX_VALUE);

        for (RunningServiceInfo runningServiceInfo : services) {
            if (runningServiceInfo.service.getClassName().equals(serviceClassName)){
                return true;
            }
        }
        return false;
     }
}

Um pequeno complemento é:

Meu objetivo é conhecer wether um serviço está sendo executado sem executá-lo actualy se ele não estiver em execução.

Chamando bindService ou chamar uma intenção que pode ser capturado pelo serviço não é uma boa idéia, em seguida, uma vez que irá iniciar o serviço se ele não está em execução.

Assim, como miracle2k sugerido, o melhor é ter um campo estático na classe de serviço para saber se o serviço foi iniciado ou não.

Para torná-lo ainda mais limpo, sugiro para transformar o serviço em um singleton com um atraente muito, muito preguiçoso: isto é, não há nenhuma instanciação em todo o Singleton exemplo, através de métodos estáticos. O método estático getInstance do seu serviço / singleton apenas retorna a instância do singleton se ele foi criado. Mas não actualy iniciar ou instanciar o próprio singleton. O serviço só é iniciado através de métodos de início de serviço normais.

Seria, então, ainda mais limpa para modificar o padrão de design singleton para renomear o método getInstance confundindo em algo parecido com o método isInstanceCreated() : boolean.

O código será semelhante a:

public class MyService extends Service
{
   private static MyService instance = null;

   public static boolean isInstanceCreated() {
      return instance != null;
   }//met

   @Override
   public void onCreate()
   {
      instance = this;
      ....
   }//met

   @Override
   public void onDestroy()
   {
      instance = null;
      ...
   }//met
}//class

Esta solução é elegante, mas é relevante apenas se você tiver acesso à classe de serviço e somente para as classes Iside o app / pacote do serviço. Se suas classes estão fora do aplicativo de serviço / pacote, então você pode consultar o ActivityManager com limitações sublinhada por Pieter-Jan Van Robays.

Você pode usar isso (eu não tentei isso ainda, mas eu espero que isso funcione):

if(startService(someIntent) != null) {
    Toast.makeText(getBaseContext(), "Service is already running", Toast.LENGTH_SHORT).show();
}
else {
    Toast.makeText(getBaseContext(), "There is no service running, starting service..", Toast.LENGTH_SHORT).show();
}

O método StartService retorna um objeto ComponentName se houver um serviço já está em execução. Se não, null será retornado.

Veja abstrato pública ComponentName StartService (Intenção de serviço) .

Isto não é como a verificação eu acho, porque ele está começando o serviço, para que possa adicionar stopService(someIntent); sob o código.

    public boolean checkServiceRunning(){
         ActivityManager manager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
        for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) 
                {
                    if ("com.example.yourpackagename.YourServiceName"
                            .equals(service.service.getClassName())) 
                    {
                        return true;
                    }
                }
             return false;
    }

Eu ligeiramente modificada uma das soluções apresentadas acima, mas passando a classe em vez de um nome de cadeia genérica, a fim de ter a certeza de comparar strings que sai do mesmo método class.getName()

public class ServiceTools {
    private static String LOG_TAG = ServiceTools.class.getName();

    public static boolean isServiceRunning(Context context,Class<?> serviceClass){
        final ActivityManager activityManager = (ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE);
        final List<RunningServiceInfo> services = activityManager.getRunningServices(Integer.MAX_VALUE);

        for (RunningServiceInfo runningServiceInfo : services) {
            Log.d(Constants.TAG, String.format("Service:%s", runningServiceInfo.service.getClassName()));
            if (runningServiceInfo.service.getClassName().equals(serviceClass.getName())){
                return true;
            }
        }
        return false;
    }
}

e

Boolean isServiceRunning = ServiceTools.isServiceRunning(
                    MainActivity.this.getApplicationContext(),
                    BackgroundIntentService.class);

Um extrato de Android docs:

Como sendBroadcast (Intenção ) , mas se houver qualquer receptores para a Intenção esta função irá bloquear e imediatamente enviá-los antes de retornar.

Pense este hack como "ping" o Service , uma vez que pode transmitir de forma síncrona que pode transmitir e obter um resultado - sincronicamente -. No segmento interface do usuário

Service

@Override
public void onCreate() {
   LocalBroadcastManager
     .getInstance(this)
     .registerReceiver(new ServiceEchoReceiver(), new IntentFilter("ping"));
}

private class ServiceEchoReceiver extends BroadcastReceiver {
    public void onReceive (Context context, Intent intent) {
      LocalBroadcastManager
         .getInstance(this)
         .sendBroadcastSync(new Intent("pong"));
    }
}

Activity

    bool serviceRunning = false;

    protected void onCreate (Bundle savedInstanceState){
        LocalBroadcastManager.getInstance(this).registerReceiver(pong, new IntentFilter("pong"));
        LocalBroadcastManager.getInstance(this).sendBroadcastSync(new Intent("ping"));
        if(!serviceRunning){
           //run the service
        }
    }

    private BroadcastReceiver pong = new BroadcastReceiver(){
        public void onReceive (Context context, Intent intent) {
          serviceRunning = true;   
        }
    }

Eu só quero acrescentar uma nota para a resposta por @Snicolas. Os seguintes passos podem ser utilizados para verificar serviço parada com / sem chamar onDestroy().

  1. onDestroy() chamado:. Vá para Configurações -> Aplicações -> Executar Serviços -> Selecionar e parar o serviço

  2. onDestroy() não Chamado: Vá para Configurações -> Aplicações -> Gerenciar Aplicativos -> Selecionar e "Stop Force" a sua aplicação em que o serviço está sendo executado. No entanto, como o aplicativo é parado aqui, então definitivamente as instâncias de serviço também será interrompido.

Finalmente, eu gostaria de mencionar que a abordagem mencionado lá usando uma variável estática na classe singleton está funcionando para mim.

onDestroy nem sempre é chamado no serviço de modo que este é inútil!

Por exemplo: Basta executar o aplicativo novamente com uma mudança de Eclipse. A aplicação é vigorosamente saiu usando SIG: 9.

A maneira correta para verificar se um serviço está sendo executado é simplesmente perguntar isso. Implementar um BroadcastReceiver em seu serviço que responde a pings de suas atividades. Registre o BroadcastReceiver quando o serviço é iniciado, e cancelar o registro quando o serviço é destruído. Da sua actividade (ou qualquer componente), enviar um broadcast local intenção do serviço e se ele responde, você sabe que está em execução. Note a diferença sutil entre ACTION_PING e ACTION_PONG no código abaixo.

public class PingableService extends Service
{
    public static final String ACTION_PING = PingableService.class.getName() + ".PING";
    public static final String ACTION_PONG = PingableService.class.getName() + ".PONG";

    public int onStartCommand (Intent intent, int flags, int startId)
    {
        LocalBroadcastManager.getInstance(this).registerReceiver(mReceiver, new IntentFilter(ACTION_PING));
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy ()
    {
        LocalBroadcastManager.getInstance(this).unregisterReceiver(mReceiver);
        super.onDestroy();
    }

    private BroadcastReceiver mReceiver = new BroadcastReceiver()
    {
        @Override
        public void onReceive (Context context, Intent intent)
        {
            if (intent.getAction().equals(ACTION_PING))
            {
                LocalBroadcastManager manager = LocalBroadcastManager.getInstance(getApplicationContext());
                manager.sendBroadcast(new Intent(ACTION_PONG));
            }
        }
    };
}


public class MyActivity extends Activity
{
    private boolean isSvcRunning = false;

    @Override
    protected void onStart()
    {
        LocalBroadcastManager manager = LocalBroadcastManager.getInstance(getApplicationContext());
        manager.registerReceiver(mReceiver, new IntentFilter(PingableService.ACTION_PONG));
        // the service will respond to this broadcast only if it's running
        manager.sendBroadcast(new Intent(PingableService.ACTION_PING));
        super.onStart();
    }

    @Override
    protected void onStop()
    {
        LocalBroadcastManager.getInstance(this).unregisterReceiver(mReceiver);
        super.onStop();
    }

    protected BroadcastReceiver mReceiver = new BroadcastReceiver()
    {
        @Override
        public void onReceive (Context context, Intent intent)
        {
            // here you receive the response from the service
            if (intent.getAction().equals(PingableService.ACTION_PONG))
            {
                isSvcRunning = true;
            }
        }
    };
}

Primeiro de tudo você não devo tentar alcançar o serviço usando o ActivityManager. (Discutido aqui )

Os serviços podem executar por conta própria, estar vinculado a uma atividade ou ambos. O caminho para o check-in uma Atividade Se o serviço está sendo executado ou não é fazendo uma interface (que se estende Binder), onde você declarar métodos que tanto a atividade e o Serviço, compreender. Você pode fazer isso através de sua própria interface, onde você declarar por exemplo "isServiceRunning ()". Você pode então vincular sua atividade para o seu serviço, executar o método isServiceRunning (), o Serviço irá verificar por si mesmo se ele estiver em execução ou não e retorna um booleano para a sua actividade.

Você também pode usar esse método para parar o seu serviço ou interagir com ele de outra maneira.

Eu usei esse tutorial para aprender a implementar este cenário em meu aplicativo.

Xamarin C # versão:

private bool isMyServiceRunning(System.Type cls)
{
    ActivityManager manager = (ActivityManager)GetSystemService(Context.ActivityService);

    foreach (var service in manager.GetRunningServices(int.MaxValue)) {
        if (service.Service.ClassName.Equals(Java.Lang.Class.FromType(cls).CanonicalName)) {
            return true;
        }
    }
    return false;
}

Para o caso de uso dado aqui podemos simplesmente fazer uso do valor de retorno do método stopService(). Ele retorna true se existe o serviço especificado e é morto. Senão ele retorna false. Assim, você pode reiniciar o serviço se o resultado é false outra coisa é a certeza de que o serviço atual foi interrompido. :) Seria melhor se você tiver uma olhada em este .

Mais uma vez, outra alternativa que as pessoas podem encontrar mais limpo se eles usam intenções pendentes (por exemplo, com o AlarmManager:

public static boolean isRunning(Class<? extends Service> serviceClass) {
    final Intent intent = new Intent(context, serviceClass);
    return (PendingIntent.getService(context, CODE, intent, PendingIntent.FLAG_NO_CREATE) != null);
}

Onde CODE é uma constante que você define em particular na sua classe para identificar as intenções pendentes associadas ao seu serviço.

A seguir é um elegante hack que abrange todos os Ifs. Este é apenas para serviços locais.

    public final class AService extends Service {

        private static AService mInstance = null;

        public static boolean isServiceCreated() {
            try {
                // If instance was not cleared but the service was destroyed an Exception will be thrown
                return mInstance != null && mInstance.ping();
            } catch (NullPointerException e) {
                // destroyed/not-started
                return false;
            }
        }

        /**
         * Simply returns true. If the service is still active, this method will be accessible.
         * @return
         */
        private boolean ping() {
            return true;
        }

        @Override
        public void onCreate() {
            mInstance = this;
        }

        @Override
        public void onDestroy() {
            mInstance = null;
        }
    }

E mais tarde:

    if(AService.isServiceCreated()){
        ...
    }else{
        startService(...);
    }

A resposta do geekQ mas na classe Kotlin. Graças geekQ

fun isMyServiceRunning(serviceClass : Class<*> ) : Boolean{
    var manager = getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
    for (service in manager.getRunningServices(Integer.MAX_VALUE)) {
        if (serviceClass.name.equals(service.service.className)) {
            return true
        }
    }
    return false
}

A chamada

isMyServiceRunning(NewService::class.java)

Pode haver vários serviços com o mesmo nome da classe.

Acabei de criar dois aplicativos. O nome do pacote do primeiro aplicativo é com.example.mock. Eu criei um subpacote chamado lorem no aplicativo e um serviço chamado Mock2Service. Assim seu nome completo é com.example.mock.lorem.Mock2Service.

Então eu criei o segundo aplicativo e um serviço chamado Mock2Service. O nome do pacote do segundo aplicativo é com.example.mock.lorem. O nome completo do serviço é com.example.mock.lorem.Mock2Service também.

Aqui está a minha saída logcat.

03-27 12:02:19.985: D/TAG(32155): Mock-01: com.example.mock.lorem.Mock2Service
03-27 12:02:33.755: D/TAG(32277): Mock-02: com.example.mock.lorem.Mock2Service

A melhor idéia é comparar casos ComponentName porque equals() de ComponentName compara ambos os nomes de pacotes e nomes de classe. E não pode haver dois aplicativos com o mesmo nome do pacote instalado em um dispositivo.

Os equals () método de ComponentName.

@Override
public boolean equals(Object obj) {
    try {
        if (obj != null) {
            ComponentName other = (ComponentName)obj;
            // Note: no null checks, because mPackage and mClass can
            // never be null.
            return mPackage.equals(other.mPackage)
                    && mClass.equals(other.mClass);
        }
    } catch (ClassCastException e) {
    }
    return false;
}

ComponentName

Isto aplica-se mais para a depuração Serviço Intenção uma vez que gerar um segmento, mas podem trabalhar para os serviços regulares também. Eu encontrei este fio graças a Binging

No meu caso, eu brinquei com o depurador e encontrou a exibição de thread. É o tipo de olhares como o ícone de ponto de bala no MS Word. De qualquer forma, você não tem que estar no modo depurador para usá-lo. Clique sobre o processo e clique sobre esse botão. Qualquer intenção Serviços vai aparecer, enquanto eles estão funcionando, pelo menos no emulador.

Se o serviço pertence a outro processo ou APK usar a solução baseada na ActivityManager.

Se você tem acesso à sua fonte, é só usar a solução baseada em um campo estático. Mas em vez de usar um booleano, sugiro usar um objeto Date. Enquanto o serviço está em execução, apenas atualizar o seu valor para 'agora' e quando ele termina de defini-lo como nulo. A partir da atividade que você pode verificar se o seu nulo ou a data é muito antiga que significa que ele não está em execução.

Você também pode enviar notificação de transmissão de seu serviço, indicando que está em execução ao longo Mais informações sobre como progresso.

Dentro TheServiceClass definir:

 public static Boolean serviceRunning = false;

Então, em onStartCommand (...)

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

    serviceRunning = true;
    ...
}

 @Override
public void onDestroy()
{
    serviceRunning = false;

} 

Em seguida, chamada if(TheServiceClass.serviceRunning == true) de qualquer classe.

ligamento uso simples com não criar auto - veja ps. e atualização ...

public abstract class Context {

 ... 

  /*
  * @return {true} If you have successfully bound to the service, 
  *  {false} is returned if the connection is not made 
  *  so you will not receive the service object.
  */
  public abstract boolean bindService(@RequiresPermission Intent service,
        @NonNull ServiceConnection conn, @BindServiceFlags int flags);

exemplo:

    Intent bindIntent = new Intent(context, Class<Service>);
    boolean bindResult = context.bindService(bindIntent, ServiceConnection, 0);

Por que não usar? getRunningServices ()

List<ActivityManager.RunningServiceInfo> getRunningServices (int maxNum)
Return a list of the services that are currently running.

Nota:. Este método destina-se apenas para a depuração ou a implementação de interfaces de usuário do tipo de gerenciamento de serviços


ps. android documentação é enganador i ter aberto um problema no Google rastreador para eliminar quaisquer dúvidas:

https://issuetracker.google.com/issues/68908332

como podemos ver serviço ligam realmente invoca uma transação via ActivityManager aglutinante através do serviço de pastas de cache - i mossa controlar qual serviço é responsável pela ligação, mas como podemos ver o resultado para o bind é:

int res = ActivityManagerNative.getDefault().bindService(...);
return res != 0;

transação é feita através de pasta:

ServiceManager.getService("activity");

a seguir:

  public static IBinder getService(String name) {
    try {
        IBinder service = sCache.get(name);
        if (service != null) {
            return service;
        } else {
            return getIServiceManager().getService(name);

este é definido em ActivityThread via:

 public final void bindApplication(...) {

        if (services != null) {
            // Setup the service cache in the ServiceManager
            ServiceManager.initServiceCache(services);
        }

isso é chamado em ActivityManagerService no método:

 private final boolean attachApplicationLocked(IApplicationThread thread,
            int pid) {
    ...
    thread.bindApplication(... , getCommonServicesLocked(),...)

então:

 private HashMap<String, IBinder> getCommonServicesLocked() {

mas não há nenhuma "atividade" único pacote janela e alarme ..

Por isso, precisamos voltar a chamada:

 return getIServiceManager().getService(name);

    sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());

isso faz chamada através de:

    mRemote.transact(GET_SERVICE_TRANSACTION, data, reply, 0);

o que leva a:

BinderInternal.getContextObject()

e este é nativo método ....

  /**
     * Return the global "context object" of the system.  This is usually
     * an implementation of IServiceManager, which you can use to find
     * other services.
     */
    public static final native IBinder getContextObject();

Eu não tenho tempo agora para cavado no c assim até eu dissecar descansar chamada i suspender a minha resposta.

, mas o melhor caminho para verificação se o serviço está sendo executado é criar bind (se ligam não é criada serviço não existem) - e consulta o serviço sobre seu estado através do bind (usando armazenados bandeira interna sobre -lo estado).

atualização 2018/06/23

i descobriu que aqueles interessante:

/**
 * Provide a binder to an already-bound service.  This method is synchronous
 * and will not start the target service if it is not present, so it is safe
 * to call from {@link #onReceive}.
 *
 * For peekService() to return a non null {@link android.os.IBinder} interface
 * the service must have published it before. In other words some component
 * must have called {@link android.content.Context#bindService(Intent, ServiceConnection, int)} on it.
 *
 * @param myContext The Context that had been passed to {@link #onReceive(Context, Intent)}
 * @param service Identifies the already-bound service you wish to use. See
 * {@link android.content.Context#bindService(Intent, ServiceConnection, int)}
 * for more information.
 */
public IBinder peekService(Context myContext, Intent service) {
    IActivityManager am = ActivityManager.getService();
    IBinder binder = null;
    try {
        service.prepareToLeaveProcess(myContext);
        binder = am.peekService(service, service.resolveTypeIfNeeded(
                myContext.getContentResolver()), myContext.getOpPackageName());
    } catch (RemoteException e) {
    }
    return binder;
}

Em suma :)

"Fornecer um ligante para um serviço já-bound. Este método é síncrono e não será iniciado o serviço de destino se ele não está presente."

pública IBinder peekService (Intenção serviço, resolvedType String, Cordas callingPackage) lança RemoteException;

*

public static IBinder peekService(IBinder remote, Intent service, String resolvedType)
             throws RemoteException {
    Parcel data = Parcel.obtain();
    Parcel reply = Parcel.obtain();
    data.writeInterfaceToken("android.app.IActivityManager");
    service.writeToParcel(data, 0);
    data.writeString(resolvedType);
    remote.transact(android.os.IBinder.FIRST_CALL_TRANSACTION+84, data, reply, 0);
    reply.readException();
    IBinder binder = reply.readStrongBinder();
    reply.recycle();
    data.recycle();
    return binder;
}

*

Em seu Serviço Sub-Class Use um booleano estático para obter o estado do Serviço conforme demonstrado abaixo.

MyService.kt

class MyService : Service() {
    override fun onCreate() {
        super.onCreate()
        isServiceStarted = true
    }
    override fun onDestroy() {
        super.onDestroy()
        isServiceStarted = false
    }
    companion object {
        var isServiceStarted = false
    }
}

MainActivity.kt

class MainActivity : AppCompatActivity(){
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val serviceStarted = FileObserverService.isServiceStarted
        if (!serviceStarted) {
            val startFileObserverService = Intent(this, FileObserverService::class.java)
            ContextCompat.startForegroundService(this, startFileObserverService)
        }
    }
}

A minha conversão Kotlin das respostas ActivityManager::getRunningServices base. Coloque esta função em uma atividade -

private fun isMyServiceRunning(serviceClass: Class<out Service>) =
    (getSystemService(ACTIVITY_SERVICE) as ActivityManager)
        .getRunningServices(Int.MAX_VALUE)
        ?.map { it.service.className }
        ?.contains(serviceClass.name) ?: false

Utilize este código.

if (isMyServiceRunning(MainActivity.this, xyzService.class)) { // Service class name
    // Service running
} else {
    // Service Stop
}


public static boolean isMyServiceRunning(Activity activity, Class<?> serviceClass) {
        ActivityManager manager = (ActivityManager) activity.getSystemService(Context.ACTIVITY_SERVICE);
        for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
            if (serviceClass.getName().equals(service.service.getClassName())) {
                return true;
            }
        }
        return false;
    }

Tome-caras fáceis ...:)

Eu acho que a solução mais adequada está segurando um par de valor-chave em SharedPreferences sobre se o serviço está sendo executado ou não.

A lógica é muito simples; em qualquer posição desejada na sua classe de serviço; colocar um valor booleano que funcionará como uma bandeira para você sobre se o serviço está sendo executado ou não. Então leia este valor onde quer que você quer na sua aplicação.

Um código de exemplo que estou usando no meu aplicativo está abaixo:

Na minha classe de serviço (Um serviço para Audio Stream), eu executar o código a seguir quando o serviço é para cima;

private void updatePlayerStatus(boolean isRadioPlaying)
{
        SharedPreferences sharedPref = this.getSharedPreferences(getString(R.string.str_shared_file_name), Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sharedPref.edit();
        editor.putBoolean(getString(R.string.str_shared_file_radio_status_key), isRadioPlaying);
        editor.commit();
}

Então, em qualquer atividade da minha candidatura, estou verificando o status do serviço com a ajuda da seguinte código;

private boolean isRadioRunning() {
        SharedPreferences sharedPref = this.getSharedPreferences(getString(R.string.str_shared_file_name), Context.MODE_PRIVATE);

        return sharedPref.getBoolean(getString(R.string.str_shared_file_radio_status_key), false);
}

Não há permissões especiais, sem loops ... maneira fácil e solução limpa:)

Se precisar de informações adicionais, consulte o href="http://developer.android.com/training/basics/data-storage/shared-preferences.html" rel="nofollow"> ligação

Espero que isso ajude.

scroll top