2012-07-02 11 views
11

Chcę dodać moją aplikację do paska powiadomień, aby zawsze była wyświetlana, podobnie jak niektóre aplikacje w sklepie Google Play.Zawsze wyświetlaj usługę na pasku powiadomień

chcę być jak ten zrzut ekranu:

enter image description here

Chcę moje zgłoszenie nie może zostać wyczyszczone, a dla mojego app, które zostaną otwarte, gdy zgłoszenie zostanie kliknięty.

Oto mój kod Class Service:

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

i deklaruję moją służbę w moim projekcie pliku manifestu:

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

oto moja klasa do uruchamiania i zatrzymywania usługi:

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

Oto mój kod układu:

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

Odpowiedz

9

Jeśli chcesz, aby Twoja aplikacja będzie obecny na pasku stanu, w każdym czasie, trzeba napisać usługę i wywołać startForeground(id, notification) w metodach onStart(...) i onStartCommand(...) i odpowiednio wywołać metodę stopForeground() w sposobie onDestroy() usługa.

Identyfikator jest liczbą całkowitą, którą można przypisać do powiadomienia, a powiadomienie to obiekt Notification (więcej informacji można znaleźć tutaj: http://developer.android.com/guide/topics/ui/notifiers/notifications.html).

W ten sposób, dopóki usługa jest uruchomiona, zostanie wyświetlone powiadomienie paska stanu.

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

Możesz umieścić ten kod w onStart(...) i onStartCommand(...) metod usługi.

Ponadto można przeczytać więcej na temat usług tutaj: http://developer.android.com/reference/android/app/Service.html

+0

należy prawidłowo sformatować swoją odpowiedź –

+0

@paradx mówi błędu metoda startForeground (int, zgłoszenia) jest niezdefiniowane – Dinesh

+0

startForeground (...) Metoda jest członkiem klasy usługi. Jeśli chcesz zachować powiadomienie na pasku stanu, musisz wdrożyć usługę, nie możesz jej wywołać z działania. –

18

Aby mieć swoje zgłoszenie zawsze obecny, będziemy chcieli, aby ustawić te dwie flagi:

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

Należy pamiętać, że podczas ustawiania swoje usługi bycie na pierwszym planie spowoduje również ciągłe wydarzenie, które jest bardzo niewłaściwe, chyba że naprawdę potrzebujesz, aby Twoja usługa działała na pierwszym planie. Odtwarzacz muzyczny jest dobrym przykładem aplikacji, która powinna to zrobić - użytkownik oczekuje, że ich muzyka będzie odtwarzana bez przerwy, nawet gdy wykona wiele innych czynności z urządzeniem.

Większość usług może jednak zostać tymczasowo zatrzymana przez system, gdy pamięć jest niska, a następnie ponownie uruchomiona automatycznie po ponownym udostępnieniu pamięci. Więc właściwym sposobem na przemyślenie tego jest oddzielenie obu pomysłów.

  1. Jeśli chcesz, aby twoje powiadomienie było zawsze widoczne, użyj dwóch flag, o których wspomniałem.
  2. Jeśli zdarzy się też potrzebny do uruchomienia usługi na pierwszym planie, można i należy zadzwonić Service.startForeground(), ale nie myślę o tym jako sposób, aby uzyskać bieżące powiadomienie.
+2

@HeroVsZero Proszę bardzo. Możesz rozważyć wybór jako zaakceptowanej odpowiedzi, ponieważ, cóż, jest to właściwa odpowiedź. Chociaż bardzo chciałbym, aby paradoks zachował przedstawiciela za jego szczerą i przemyślaną odpowiedź, sugeruje to, jak wyjaśniłem, złym rady. Myślę, że sterowanie przyszłymi odwiedzającymi najbardziej poprawną odpowiedzią jest najważniejszym czynnikiem decydującym o wyborze odpowiedzi. –

+3

Nie będę się obraził :) –

0

Oto przykład użycia klasy NotificationCompact.Builder, która jest najnowszą wersją do tworzenia powiadomień.

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

Wystarczy użyć poniższego kodu, aby zawsze wyświetlać pasek powiadomień.

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); 
Powiązane problemy