2012-07-02 1 views
11

Quiero agregar mi aplicación a la barra de notificaciones para que siempre se muestre, como algunas aplicaciones en la tienda de Google Play.Mostrar siempre el servicio en la barra de notificación

Quiero que sea como esta captura de pantalla:

enter image description here

Quiero que mi notificación no se borrará, y para mi aplicación para ser abierta cuando se hace clic en la notificación.

Aquí está mi código de clase de servicio:

package com.demo; 

import java.util.Random; 

import android.app.Notification; 
import android.app.NotificationManager; 
import android.app.PendingIntent; 
import android.app.Service; 
import android.content.Intent; 
import android.os.Handler; 
import android.os.IBinder; 
import android.os.Message; 
import android.widget.Toast; 

public class ServiceExample extends Service { 

    @Override 
    public IBinder onBind(Intent intent) { 
     return null; 
    } 

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

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

    @Override 
    public void onLowMemory() { 
     super.onLowMemory(); 
     Toast.makeText(this,"Service LowMemory",300).show(); 
    } 

    @Override 
    public void onStart(Intent intent, int startId) { 
     super.onStart(intent, startId); 
     Toast.makeText(this,"Service start",300).show(); 
     Notification notification = new Notification(R.drawable.ic_launcher, 
       "Rolling text on statusbar", System.currentTimeMillis()); 

     PendingIntent contentIntent = PendingIntent.getActivity(this, 0, 
       new Intent(this, ServiceDemoActivity.class), PendingIntent.FLAG_UPDATE_CURRENT); 

     notification.setLatestEventInfo(this, 
       "Notification title", "Notification description", contentIntent); 

     startForeground(1, notification); 
    } 

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

     Toast.makeText(this,"task perform in service",300).show(); 
     /*ThreadDemo td=new ThreadDemo(); 
     td.start();*/ 
     Notification notification = new Notification(R.drawable.ic_launcher, 
       "Rolling text on statusbar", System.currentTimeMillis()); 

     PendingIntent contentIntent = PendingIntent.getActivity(this, 0, 
       new Intent(this, ServiceDemoActivity.class), PendingIntent.FLAG_UPDATE_CURRENT); 

     notification.setLatestEventInfo(this, 
       "Notification title", "Notification description", contentIntent); 

     startForeground(1, notification); 

     return super.onStartCommand(intent, flags, startId); 
    } 

    private class ThreadDemo extends Thread{ 
     @Override 
     public void run() { 
      super.run(); 
      try{ 
      sleep(70*1000); 
      handler.sendEmptyMessage(0); 
      }catch(Exception e){ 
       e.getMessage(); 
      } 
     } 
    } 
    private Handler handler=new Handler(){ 
    @Override 
    public void handleMessage(Message msg) { 
     super.handleMessage(msg); 
     showAppNotification(); 
    } 
    }; 

    void showAppNotification() { 
     try{ 
     NotificationManager nm = (NotificationManager)getSystemService(NOTIFICATION_SERVICE); 
     // The PendingIntent to launch our activity if the user selects this 
     // notification. Note the use of FLAG_CANCEL_CURRENT so that, if there 
     // is already an active matching pending intent, cancel it and replace 
     // it with the new array of Intents. 
//  PendingIntent contentIntent = PendingIntent.getActivities(this, 0, 
//    "My service completed", PendingIntent.FLAG_CANCEL_CURRENT); 

     // The ticker text, this uses a formatted string so our message could be localized 
     String tickerText ="djdjsdjkd"; 

     // construct the Notification object. 
     Notification notif = new Notification(R.drawable.ic_launcher, tickerText, 
       System.currentTimeMillis()); 

     // Set the info for the views that show in the notification panel. 
//  notif.setLatestEventInfo(this, from, message, contentIntent); 

     // We'll have this notification do the default sound, vibration, and led. 
     // Note that if you want any of these behaviors, you should always have 
     // a preference for the user to turn them off. 
     notif.defaults = Notification.DEFAULT_ALL; 

     // Note that we use R.layout.incoming_message_panel as the ID for 
     // the notification. It could be any integer you want, but we use 
     // the convention of using a resource id for a string related to 
     // the notification. It will always be a unique number within your 
     // application. 
     nm.notify(0, notif); 
     }catch(Exception e){ 
      e.getMessage(); 
     } 
    } 
} 

y declaro mi servicio en mi proyecto de archivo de manifiesto:

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="com.demo" 
    android:versionCode="1" 
    android:versionName="1.0" > 

    <uses-sdk android:minSdkVersion="8" /> 
    <application 
     android:icon="@drawable/ic_launcher" 
     android:label="@string/app_name" > 
     <activity 
      android:name=".ServiceDemoActivity" 
      android:label="@string/app_name" > 
      <intent-filter> 
       <action android:name="android.intent.action.MAIN" /> 
       <category android:name="android.intent.category.LAUNCHER" /> 
      </intent-filter> 
     </activity> 
     <service android:name=".ServiceExample"></service> 
    </application> 

</manifest> 

Ésta es mi clase para iniciar y detener el servicio:

package com.demo; 

import android.app.Activity; 
import android.content.Intent; 
import android.content.IntentFilter; 
import android.content.ReceiverCallNotAllowedException; 
import android.os.Bundle; 
import android.view.View; 
import android.view.View.OnClickListener; 

public class ServiceDemoActivity extends Activity implements OnClickListener { 
    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 
     findViewById(R.id.start).setOnClickListener(this); 
     findViewById(R.id.stop).setOnClickListener(this); 
    } 

    private Intent inetnt; 
    @Override 
    public void onClick(View v) { 
     switch (v.getId()) { 
     case R.id.start: 

      inetnt=new Intent(this,ServiceExample.class); 
      startService(inetnt); 
      break; 
     case R.id.stop: 

      inetnt=new Intent(this,ServiceExample.class); 
      stopService(inetnt); 
      break; 
     } 
    } 

    @Override 
    protected void onResume() { 
     super.onResume(); 
    } 

    @Override 
    protected void onDestroy() { 
     super.onDestroy(); 
//  
    } 
} 

Aquí está mi código de diseño:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:orientation="vertical" > 

    <Button 
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content" 
     android:text="StartService" 
     android:id="@+id/start"/> 

     <Button 
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content" 
     android:text="StopService" 
     android:id="@+id/stop" /> 

</LinearLayout> 

Respuesta

9

Si desea que la aplicación esté presente en la barra de estado en todo momento, usted tiene que escribir un servicio y llamar startForeground(id, notification) en los métodos onStart(...) y onStartCommand(...) y respectivamente llamar al método stopForeground() en el método de la onDestroy() Servicio.

La identificación es un número entero que puede asignar a la notificación y la notificación es un objeto Notification (puede leer más sobre esto aquí: http://developer.android.com/guide/topics/ui/notifiers/notifications.html).

De esta forma, siempre que se ejecute su servicio, se mostrará la notificación de la barra de estado.

Notification notification = new Notification(R.drawable.statusbar_icon, 
     "Rolling text on statusbar", System.currentTimeMillis()); 

PendingIntent contentIntent = PendingIntent.getActivity(this, 0, 
     new Intent(this, YourActivity.class), PendingIntent.FLAG_UPDATE_CURRENT); 

notification.setLatestEventInfo(this, 
     "Notification title", "Notification description", contentIntent); 

startForeground(1, notification); 

Usted puede poner este código en onStart(...) y onStartCommand(...) métodos del servicio.

También se puede leer más sobre los servicios aquí: http://developer.android.com/reference/android/app/Service.html

+0

favor formatear correctamente su respuesta –

+0

@paradx dice error El método está definido – Dinesh

+0

El método startForeground (...) es un miembro de la clase de servicio startForeground (int, de notificación). Si desea mantener una notificación en la barra de estado, debe implementar un servicio, no puede llamarlo desde una actividad. –

18

Con el fin de tener su notificación siempre está presente, tendrá que establecer estas dos banderas:

notification.flags |= Notification.FLAG_ONGOING_EVENT | Notification.FLAG_NO_CLEAR; 

Tenga en cuenta que al configurar su Servicio Estar en primer plano también le proporcionará un evento continuo, que es algo muy inapropiado de hacer a menos que realmente necesite que su Servicio se ejecute en primer plano. Un reproductor de música es un buen ejemplo de una aplicación que debería hacer eso: el usuario tiene la expectativa de que su música se reproducirá sin interrupción, incluso cuando hace muchas otras cosas con el dispositivo.

La mayoría de los servicios, sin embargo, pueden permitirse ser detenidos temporalmente por el sistema cuando la memoria es baja, y luego reiniciarse automáticamente cuando la memoria esté disponible nuevamente. Entonces, la forma correcta de pensar es separar las dos ideas.

  1. Si desea que su notificación esté siempre visible, use las dos banderas que mencioné.
  2. Si también necesita que su Servicio se ejecute en primer plano, puede y debe llamar al Service.startForeground(), pero no piense en esto como una forma de recibir una notificación en curso.
+2

@HeroVsZero Eres bienvenido. Puede considerar seleccionar esto como la respuesta aceptada, porque, bueno, es la respuesta correcta. Por mucho que me gustaría que paradx mantuviera al representante por su respuesta genuina y considerada, lo que sugiere es en realidad un mal consejo, como ya expliqué. Creo que dirigir a los futuros visitantes a la respuesta más correcta es el factor más importante para decidir qué respuesta seleccionar. –

+3

No me ofenderé :) –

0

Aquí está el ejemplo utilizando la clase NotificationCompact.Builder, que es la versión más reciente para generar notificaciones.

private void startNotification() { 

    //Sets an ID for the notification 

    int mNotificationId = 001; 

    // Build Notification , setOngoing keeps the notification always in status bar 
    NotificationCompat.Builder mBuilder = 
      new NotificationCompat.Builder(this) 
        .setSmallIcon(R.drawable.ldb) 
        .setContentTitle("Stop LDB") 
        .setContentText("Click to stop LDB") 
        .setOngoing(true); 




    // Gets an instance of the NotificationManager service 
    NotificationManager mNotifyMgr = 
      (NotificationManager) getSystemService(NOTIFICATION_SERVICE); 

    // Build the notification and issues it. 
    mNotifyMgr.notify(mNotificationId, mBuilder.build()); 


} 
0

Simplemente use el código de abajo para mostrar siempre la barra de notificaciones.

Notification.Builder builder = new Notification.Builder(MainActivity.this); 
    builder.setSmallIcon(R.mipmap.ic_launcher) 
      .setContentText("Call Recorder") 
      .setAutoCancel(false); 
    Notification notification = builder.getNotification(); 

    notification.flags |= Notification.FLAG_NO_CLEAR 
      | Notification.FLAG_ONGOING_EVENT; 

    NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); 
    notificationManager.notify(1, notification); 
Cuestiones relacionadas