Creating an application that runs in the background

9

Some famous applications, among them Facebook, WhatsApp, Hangouts, use a service running in the background that does not end even with the device's power off.

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

    
asked by anonymous 21.05.2014 / 18:04

2 answers

12

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

  • Create a new File New project and name the project for BackgroundAppExample .
  • Type the following in 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" />
    

  • Type the following into 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>
    

  • 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;
     }
    }
    
  • Run!

  • Now follow these steps:

  • 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
    

  • OpentheBackgroundAppExample.javafileandtypethefollowingcodethere:

    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; } }
  • Compile and execute.

  • Result:

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

        
    21.05.2014 / 18:17
    1

    I was having the same problem and after a long time searching for the answer and testing I got 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 to see if it has new messages and notifying the user .

    My 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% 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 if the alarm is already created, I assign the onCreate that will be executed referring to my Intent , I assign a time to start and set the BroadcastReceiver alarm to execute even with the device blogged, done in the % with_% start a Task , since I need to post a page on the web, using recursion to continue running.

    My RTC_WAKEUP

    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);
        }
    }
    

    }

    Result

    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 cell phone has worked properly and with little delay to display notifications with the application closed and open, you can also call a Service or < in> IntetService in BroadcastReceiver .

        
    08.06.2018 / 18:35