2012-07-02 13 views
11

Desidero aggiungere la mia app alla barra delle notifiche in modo che venga sempre visualizzata, come alcune app nel Google Play Store.Mostra sempre il servizio nella barra delle notifiche

voglio che sia come questo screen shot:

enter image description here

voglio che il mio notifica di non essere cancellato, e per la mia app da aprire quando la notifica viene cliccato.

Ecco il mio Codice di servizio Classe:

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

e dichiaro il mio servizio nel mio progetto file manifesto:

<?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> 

Ecco la mia classe per avviare e arrestare il servizio:

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

Ecco il mio codice di layout:

<?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> 

risposta

9

Se si desidera che l'applicazione per essere presenti sulla barra di stato in ogni momento, si deve scrivere un servizio e chiamare startForeground(id, notification) nei metodi onStart(...) e onStartCommand(...) e, rispettivamente, chiamare il metodo stopForeground() nel metodo della onDestroy() servizio.

L'id è un numero intero che è possibile assegnare alla notifica e la notifica è un oggetto Notification (è possibile leggere ulteriori informazioni qui: http://developer.android.com/guide/topics/ui/notifiers/notifications.html).

In questo modo finché il servizio è in esecuzione, verrà visualizzata la notifica della barra di stato.

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

È possibile inserire questo codice in onStart(...) e onStartCommand(...) metodi del servizio.

Inoltre si può leggere di più sui servizi di qui: http://developer.android.com/reference/android/app/Service.html

+0

formattare correttamente la risposta –

+0

@paradx dice error Il metodo startForeground (int, Notification) è undefined – Dinesh

+0

Il metodo startForeground (...) è un membro della classe di servizio. Se si desidera mantenere una notifica sulla barra di stato, è necessario implementare un servizio, non è possibile chiamarlo da un'attività. –

18

Al fine di avere la vostra comunicazione sempre presente, ti consigliamo di impostare questi due bandiere:

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

Si noti che durante l'impostazione il tuo servizio essere in primo piano ti porterà anche un evento in corso, è una cosa molto inappropriata da fare a meno che tu non abbia veramente bisogno che il tuo Servizio funzioni in primo piano. Un lettore musicale è un buon esempio di un'app che dovrebbe farlo: l'utente ha l'aspettativa che la sua musica suonerà senza interruzioni, anche quando si fanno molte altre cose con il dispositivo.

La maggior parte dei servizi, tuttavia, può essere temporaneamente interrotta dal sistema quando la memoria è in esaurimento e quindi riavviata automaticamente quando la memoria è nuovamente disponibile. Quindi il modo corretto di pensarci è separare le due idee.

  1. Se si desidera che la notifica sia sempre visibile, utilizzare le due bandiere che ho citato.
  2. Se vi capita di bisogno anche il vostro servizio per l'esecuzione in primo piano, si può e si deve chiamare Service.startForeground(), ma non pensare a questo come un modo per ottenere una notifica in corso.
+2

@HeroVsZero Sei il benvenuto. Potresti considerare di selezionare questa come risposta accettata, perché, beh, è ​​la risposta giusta. Per quanto mi piacerebbe che il paradosso mantenga il rappresentante per la sua risposta genuina e ponderata, ciò che suggerisce è in realtà un cattivo consiglio, come ho spiegato. Penso che indirizzare i futuri visitatori alla risposta più corretta sia il fattore più importante nel decidere quale risposta selezionare. –

+3

Non mi offenderò :) –

0

Ecco un esempio di utilizzo della classe NotificationCompact.Builder che è la versione più recente per la generazione di notifiche.

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

Basta usare sotto il codice per mostrare sempre la barra di notifica.

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); 
Problemi correlati