Creating app that runs in the background

Asked

Viewed 9,432 times

9

Some famous apps, among them Facebook, Whatsapp, Hangouts, use a service running in the background that does not end even with the disconnection/ connection of the device.

My question is how to develop an application with this feature? Can someone create a basic example that demonstrates this concept?

  • The guy asks a question and does not come back to mark as solved and abandons the stackoverflow....

  • http://www.thiengo.com.br/service-android-understandingand using. In your case see this material, it teaches to resume the service using broadcast... now if you want to save values or something of the kind after the reboot, have to use Sqlite storing there everything you need for when to run the application again

2 answers

12

This example shows how you can minimize your activity and start a service and resume your activity whenever needed.

  1. Create a new project File » New and name the project to Backgroundappexample.
  2. Write the following at main.xml:

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:padding="@dimen/padding_medium"
        android:text="@string/hello_world"
        tools:context=".BackgroundAppExample" />
    
    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_alignRight="@+id/textView1"
        android:layout_marginRight="49dp"
        android:layout_marginTop="74dp"
        android:text="Start Service" />
    

  3. Write next in the manifest file:

    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.backgroundappexample"
    android:versionCode="1"
    android:versionName="1.0" >
    
    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="15" />
    
    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".BackgroundAppExample"
            android:label="@string/title_activity_background_app_example" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
    
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <service android:enabled="true" android:name=".BackgroundService" />
    </application>
    

  4. Create and write the following in src/Backgroundservice.java:

    package com.example.backgroundappexample;
    
    import android.app.Notification;
    import android.app.NotificationManager;
    import android.app.PendingIntent;
    import android.app.Service;
    import android.content.Intent;
    import android.os.Binder;
    import android.os.Bundle;
    import android.os.IBinder;
    
    public class BackgroundService extends Service {
        private NotificationManager mNM;
    Bundle b;
    Intent notificationIntent;
    private final IBinder mBinder = new LocalBinder();
    private String newtext;
    
    public class LocalBinder extends Binder {
        BackgroundService getService() {
            return BackgroundService.this;
        }
    }
    
    @Override
    public void onCreate() {
        mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
    
        newtext = "BackGroundApp Service Running";
    
        Notification notification = new Notification(R.drawable.ic_launcher, newtext,System.currentTimeMillis());
        PendingIntent contentIntent = PendingIntent.getActivity(BackgroundService.this, 0, new Intent(BackgroundService.this,   BackgroundAppExample.class), 0);
        notification.setLatestEventInfo(BackgroundService.this,"BackgroundAppExample", newtext, contentIntent);
        mNM.notify(R.string.local_service_started, notification);
        notificationIntent = new Intent(this, BackgroundAppExample.class);
        showNotification();     
    }
    
    public int onStartCommand(Intent intent, int flags, int startId) {
        return START_STICKY;
    }
    public void onDestroy() {
        mNM.cancel(R.string.local_service_started);
        stopSelf();
    }
    private void showNotification() {
        CharSequence text = getText(R.string.local_service_started);
    
        Notification notification = new Notification(R.drawable.ic_launcher, text, System.currentTimeMillis());
        PendingIntent contentIntent = PendingIntent.getActivity(this, 0,new Intent(this, BackgroundAppExample.class), 0);
        notification.setLatestEventInfo(this, "BackgroundAppExample",newtext, contentIntent);
        notification.flags = Notification.FLAG_ONGOING_EVENT | Notification.FLAG_NO_CLEAR;     
        notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
    
        mNM.notify(R.string.local_service_started, notification);
    }
    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
     }
    }
    
  5. Execute!


Now follow the following steps:

  1. Create a project called Backgroundappexample and set the information as indicated in the image.

     Build Target: Android 4.0
     Application Name: BackgroundAppExample
     Package Name: com. example. BackgroundAppExample
     Activity Name: BackgroundAppExample
     Min SDK Version: 8
    

    inserir a descrição da imagem aqui

  2. Open the file Backgroundappexample.java and write following code there:

    package com.example.backgroundappexample;
    
    import android.app.Activity;
    import android.content.Intent;
    import android.os.Bundle;
    import android.view.Menu;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.Button;
    import android.widget.TextView;
    
    public class BackgroundAppExample extends Activity {
    
    public static boolean isService = false; 
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    
        Button startserviceButton = (Button) findViewById(R.id.button1);
        startserviceButton.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                startService(new Intent(BackgroundAppExample.this,BackgroundService.class));
                Intent startMain = new Intent(Intent.ACTION_MAIN);
                startMain.addCategory(Intent.CATEGORY_HOME);
                startMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                startActivity(startMain);
                isService = true;
            }
        });
    }
    
    @Override
    protected void onResume() {
        super.onResume();
        stopService(new Intent(BackgroundAppExample.this,
                BackgroundService.class));
        if(isService)
        {
            TextView tv = (TextView) findViewById(R.id.textView1);
            tv.setText("Service Resumed");
            isService = false;
        }
    }
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
     }
    }
    
  3. Compile and run.

Upshot:

inserir a descrição da imagem aqui inserir a descrição da imagem aqui inserir a descrição da imagem aqui inserir a descrição da imagem aqui

That response was an adaptation of this tutorial(written in English).

  • 1

    Your example gives a good idea of the use of services on Android, but is not exactly what I want. I want something like an uninterrupted process that is not finalized in the restart of the operating system, because you will be listening to some change in a remote database to warn the user. It is similar to a messenger. A message has arrived.

  • 3

    Uninterrupted service does not exist of course. But I believe that you can configure it to start at the end of the cell phone boot. Take a look at this OS question http://stackoverflow.com/questions/2784441/trying-to-start-a-service-on-boot-on-android. Warning: Perhaps using a service to spend resources is bad behavior. Take a look at google’s GCM.

1

I was having the same problem and after a long time looking for the answer and testing I managed using AlarmManager and BroadcastReceiver, what I needed:

I have a web system where someone registers notifications in the database, and an API that returns a json with the requests, I needed something to run with the app open or closed checking for new messages and notifying the user.

Man AndroidManifest.xml

<receiver
        android:name=".Servico.BootReciever"
        android:enabled="true"
        android:exported="true">
        <intent-filter>
            <action android:name="ALARME_DISPARADO2"/>
            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
    </receiver>

In my onCreate of Activity

boolean alarmeativo = (PendingIntent.getBroadcast( this, 0, new Intent( "ALARME_DISPARADO2" ), PendingIntent.FLAG_NO_CREATE ) == null);

        if(alarmeativo) {
            Intent intent = new Intent( "ALARME_DISPARADO2" );
            PendingIntent p = PendingIntent.getBroadcast( this, 0, intent, 0 );
            Calendar c = Calendar.getInstance();
            c.setTimeInMillis( System.currentTimeMillis() );
            c.add( Calendar.SECOND, 3 );

            AlarmManager alarm = (AlarmManager) getSystemService( ALARM_SERVICE );
            alarm.set( AlarmManager.RTC_WAKEUP, c.getTimeInMillis(), p );
        }

I check that the alarm is already created, assign the Intent which will be executed referencing my BroadcastReceiver, set a time to start and set the alarm RTC_WAKEUP to perform even with the blogged device, done in BroadcastReceiver beginning a Task, because I need to post on a web page, using recursiveness to continue running.

Man BootReciever.java

public class BootReciever extends BroadcastReceiver {
public static Usuario us;
public static Notifi not;
public static NotifiSetor notSet;
public static Agenda notAg;

public static boolean Iniciar = true;
public static boolean saida;

int x = 0;

@Override
public void onReceive(Context context, Intent intent) {

        Iniciar = false;
        Usuario u = new Usuario( context );
        u.Select();
        us = u;

        Notifi n = new Notifi( context );
        not = n;

        NotifiSetor ns = new NotifiSetor(context );
        notSet = ns;

        Agenda ag = new Agenda( context );
        notAg = ag;

        NotificationTask us = new NotificationTask();
        us.execute(context);
}

public boolean isOnline(Context context) {
    boolean conectado;
    try {
        ConnectivityManager conectivtyManager = (ConnectivityManager) context.getSystemService( Context.CONNECTIVITY_SERVICE );
        if (conectivtyManager.getActiveNetworkInfo() != null
                && conectivtyManager.getActiveNetworkInfo().isAvailable()
                && conectivtyManager.getActiveNetworkInfo().isConnected()) {
            conectado = true;
        } else {
            conectado = false;
        }
    } catch (Exception e) {
        conectado = false;
    }
    return conectado;
}

private class NotificationTask extends AsyncTask<Context, Void, Context> {
    @Override
    protected Context doInBackground(Context... ct) {


        saida = false;
        try {
            Agenda a = new Agenda(notAg.getCt());
            List<Agenda> list = a.SelectExibir();
            if(list != null) {
                for (int x = 0; x < list.size(); x++) {
                    long date1 = System.currentTimeMillis();
                    SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
                    String dateString = sdf.format(date1);
                    if(list.get(x).getExibir().equals(dateString)) {
                        Calendar cal = Calendar.getInstance( TimeZone.getTimeZone("GMT"));
                        Date currentLocalTime = cal.getTime();
                        DateFormat date = new SimpleDateFormat("dd-MM-yyyy");
                        date.setTimeZone(TimeZone.getTimeZone("GMT"));
                        String localTime = date.format(currentLocalTime);

                        NewMessageNotification.notify(ct[0], list.get(x).getTitulo(), list.get(x).getMensagem(), list.get(x).getID());
                        a.setID(list.get(x).getID());
                        a.setUltimo_Exib(localTime);
                        a.UpdateExibir();
                    }
                }
            }
        } catch (Exception e) {
        }

        if(isOnline(ct[0])) {
            //Log.d("",String.valueOf( x++ ));
            // notificaçoes agendadas
            try {
                //buscar na api
                // buscar no webservice
                String json = "json a ser enviando para API";
                HttpService servi = new HttpService();
                String retorno = servi.post(json);

                try {
                    JSONObject jsonObj = new JSONObject(retorno);
                    JSONArray array = jsonObj.getJSONArray("Res");
                    if (jsonObj.getBoolean("Response")) {

                        for (int i = 0; i < array.length(); i++) {
                            // notificacao
                            notAg.setID(array.getJSONObject(i).getInt("ID"));
                            if (!notAg.ValidaId()) {
                                Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
                                //cal.add(Calendar.DAY_OF_MONTH, -1);
                                Date currentLocalTime = cal.getTime();
                                DateFormat date = new SimpleDateFormat("dd-MM-yyyy");
                                date.setTimeZone(TimeZone.getTimeZone("GMT"));
                                String localTime = date.format(currentLocalTime);

                                notAg.setTitulo(array.getJSONObject(i).getString("TITULO"));
                                notAg.setMensagem(array.getJSONObject(i).getString("MENSAGEM"));
                                notAg.setCadastro(array.getJSONObject(i).getString("DATA_CAD"));
                                notAg.setExibir(array.getJSONObject(i).getString("REPETIR"));
                                notAg.setUltimo_Exib(localTime);
                                notAg.setStatus(array.getJSONObject(i).getInt("STATUS"));
                                notAg.Insert();
                            } else {
                                notAg.setTitulo(array.getJSONObject(i).getString("TITULO"));
                                notAg.setMensagem(array.getJSONObject(i).getString("MENSAGEM"));
                                notAg.setCadastro(array.getJSONObject(i).getString("DATA_CAD"));
                                notAg.setExibir(array.getJSONObject(i).getString("REPETIR"));
                                notAg.setStatus(array.getJSONObject(i).getInt("STATUS"));
                                notAg.Update();
                            }
                        }
                    }
                } catch (Exception e) {
                }
            } catch (Exception e) {
                // Restore interrupt status.
                //Thread.currentThread().interrupt();
            }

            // notificaçoes geral equipe
            try {
                //buscar na api
                // buscar no webservice
                String json = "json a ser enviando para API";
                HttpService servi = new HttpService();
                String retorno = servi.post(json);

                try {
                    JSONObject jsonObj = new JSONObject(retorno);
                    JSONArray array = jsonObj.getJSONArray("Res");
                    if (jsonObj.getBoolean("Response")) {

                        for (int i = 0; i < array.length(); i++) {
                            // notificacao
                            not.setID(array.getJSONObject(i).getInt("ID"));
                            if (!not.ValidaId()) {
                                not.setTitulo(array.getJSONObject(i).getString("TITULO"));
                                not.setMensagem(array.getJSONObject(i).getString("MENSAGEM"));
                                not.setData(array.getJSONObject(i).getString("DATA_CAD"));
                                not.setStatus(array.getJSONObject(i).getInt("STATUS"));
                                not.Insert();
                                NewMessageNotification.notify(ct[0], not.getTitulo(), not.getMensagem(), not.getID());
                            }
                        }
                    }
                } catch (Exception e) {
                }
            } catch (Exception e) {
                // Restore interrupt status.
                //Thread.currentThread().interrupt();
            }

            // notificaçoes geral setor
            try {
                //buscar na api
                // buscar no webservice
                String json = "json a ser enviando para API";
                HttpService servi = new HttpService();
                String retorno = servi.post(json);

                try {
                    JSONObject jsonObj = new JSONObject(retorno);
                    JSONArray array = jsonObj.getJSONArray("Res");
                    if (jsonObj.getBoolean("Response")) {

                        for (int i = 0; i < array.length(); i++) {
                            // notificacao
                            notSet.setID(array.getJSONObject(i).getInt("ID"));
                            if (!notSet.ValidaId()) {
                                notSet.setTitulo(array.getJSONObject(i).getString("TITULO"));
                                notSet.setMensagem(array.getJSONObject(i).getString("MENSAGEM"));
                                notSet.setData(array.getJSONObject(i).getString("DATA_CAD"));
                                notSet.setStatus(array.getJSONObject(i).getInt("STATUS"));
                                notSet.Insert();
                                NewMessageNotification.notify(ct[0], notSet.getTitulo(), notSet.getMensagem(), notSet.getID());
                            }
                        }
                    }
                } catch (Exception e) {
                }
                // exibir
            } catch (Exception e) {
                // Restore interrupt status.
                //Thread.currentThread().interrupt();
            }
        }
        try { 
            // recursividade para continuar executando
            doInBackground( ct[0] );
        } catch(Exception e) {

        }
        return ct[0];
    }

    @Override
    protected void onPostExecute(Context result) {
        // Após a inserção da nota, vamos mostrar um Toast ao usuário
        saida = true;
        Iniciar = true;
        doInBackground(result);
    }
}

}

Upshot

I/art: Increasing code cache capacity to 128KB
D/14:46:36: -> Iniciado
D/14:46:41: -> Iniciado
D/14:46:42: -> Iniciado
D/14:46:44: -> Iniciado
D/14:46:45: -> Iniciado
D/14:46:46: -> Iniciado
D/14:46:48: -> Iniciado
D/14:46:49: -> Iniciado
D/14:46:50: -> Iniciado
D/14:46:52: -> Iniciado
D/14:46:53: -> Iniciado
D/14:46:54: -> Iniciado
D/14:46:56: -> Iniciado
D/14:46:56: -> Iniciado
D/14:46:57: -> Iniciado
D/14:46:58: -> Iniciado
D/14:46:59: -> Iniciado
D/14:47:00: -> Iniciado
D/14:47:01: -> Iniciado
D/14:47:03: -> Iniciado
D/14:47:04: -> Iniciado
D/14:47:07: -> Iniciado
D/14:47:09: -> Iniciado
D/14:47:11: -> Iniciado
D/14:47:12: -> Iniciado
D/14:47:15: -> Iniciado
D/14:47:16: -> Iniciado
D/14:47:17: -> Iniciado
D/14:47:18: -> Iniciado
D/14:47:19: -> Iniciado
D/14:47:20: -> Iniciado
D/14:47:21: -> Iniciado
D/14:47:22: -> Iniciado
D/14:47:23: -> Iniciado
D/14:47:24: -> Iniciado
D/14:47:25: -> Iniciado
D/14:47:26: -> Iniciado
D/14:47:27: -> Iniciado
D/14:47:28: -> Iniciado
D/14:47:30: -> Iniciado
D/14:47:32: -> Iniciado
D/14:47:33: -> Iniciado
D/14:47:34: -> Iniciado
D/14:47:35: -> Iniciado
D/14:47:36: -> Iniciado
D/14:47:37: -> Iniciado
D/14:47:38: -> Iniciado
D/14:47:38: -> Iniciado
D/14:47:39: -> Iniciado
D/14:47:40: -> Iniciado
D/14:47:41: -> Iniciado
D/14:47:42: -> Iniciado
D/14:47:43: -> Iniciado
D/14:47:43: -> Iniciado
D/14:47:44: -> Iniciado
D/14:47:45: -> Iniciado
D/14:47:46: -> Iniciado
D/14:47:46: -> Iniciado
D/14:47:47: -> Iniciado
D/14:47:48: -> Iniciado
D/14:47:49: -> Iniciado
D/14:47:50: -> Iniciado
I/art: Background sticky concurrent mark sweep GC freed 3085(212KB) AllocSpace objects, 2(40KB) LOS objects, 1% free, 28MB/28MB, paused 5.805ms total 16.525ms
D/14:47:50: -> Iniciado
D/14:47:51: -> Iniciado
D/14:47:52: -> Iniciado
D/14:47:53: -> Iniciado
D/14:47:54: -> Iniciado
D/14:47:55: -> Iniciado
D/14:47:56: -> Iniciado
D/14:47:57: -> Iniciado
D/14:47:58: -> Iniciado
D/14:47:58: -> Iniciado
D/14:47:59: -> Iniciado
D/14:48:00: -> Iniciado
D/14:48:01: -> Iniciado
D/14:48:02: -> Iniciado
D/14:48:02: -> Iniciado
D/14:48:03: -> Iniciado
D/14:48:04: -> Iniciado
D/14:48:05: -> Iniciado
D/14:48:06: -> Iniciado
D/14:48:07: -> Iniciado
D/14:48:09: -> Iniciado
D/14:48:10: -> Iniciado
D/14:48:11: -> Iniciado
D/14:48:12: -> Iniciado
D/14:48:13: -> Iniciado
D/14:48:13: -> Iniciado
D/14:48:14: -> Iniciado
D/14:48:15: -> Iniciado
D/14:48:16: -> Iniciado
D/14:48:17: -> Iniciado
D/14:48:18: -> Iniciado
D/14:48:19: -> Iniciado
D/14:48:20: -> Iniciado
D/14:48:21: -> Iniciado
D/14:48:22: -> Iniciado
D/14:48:22: -> Iniciado
Application terminated.

And testing on my phone worked properly and with little time delay to view notifications with the app closed and open, you can also call a Service or a Intetservice in the onReceive.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.