2012-07-02 7 views
11

通知バーに自分のアプリを追加して、Google Playストアの一部のアプリのように常に表示するようにしたいとします。通知バーに常にサービスを表示する

私はそれが、このスクリーンショットのようになりたい:

enter image description here

私は私の通知がクリアされ、通知がクリックされたときに私のアプリを開口するためにされないようにしたいです。

は、ここで私のサービスクラスのコードです:

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

そして私は私のプロジェクトのマニフェストファイルで私のサービスを宣言します。

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

ここでサービスの起動と停止のための私のクラスです

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

私のレイアウトコードは次のとおりです。

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

答えて

9

、あなたのアプリケーションが常にステータスバー上に存在になりたい場合は、サービスを作成し、onStart(...)onStartCommand(...)方法でstartForeground(id, notification)を呼び出し、それぞれのonDestroy()方法でstopForeground()メソッドを呼び出す必要がありますサービス。

idは通知に割り当てることができる整数で、通知はNotificationオブジェクトです(詳しくはhttp://developer.android.com/guide/topics/ui/notifiers/notifications.htmlを参照してください)。

サービスが実行されている限り、ステータスバーの通知が表示されます。

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

あなたは、サービスのonStart(...)onStartCommand(...)方法でこのコードを置くことができます。

また、あなたがここにサービスの詳細を読むことができます:あなたのサービスを設定しながらということ

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

注:これら二つのフラグを設定することをお勧めします、あなたの通知が常に存在持つためにhttp://developer.android.com/reference/android/app/Service.html

+0

適切 –

+0

をフォーマットしてください。ステータスバーに通知を残す場合は、サービスを実装する必要があります。サービスからアクティビティを呼び出すことはできません。 – Dinesh

+0

startForeground(...)メソッドは、サービスクラスのメンバーで定義されていない方法startForeground(int型、通知)エラー言う@paradxあなたの答え –

18

フォアグラウンドで実行する必要がある場合を除いて、フォアグラウンドにすることは、あなたに継続的なイベントをもたらします。これは、非常に不適切なことです。音楽プレーヤーは、それを行うべきアプリの良い例です。ユーザーは、デバイスで他の多くのことをしているときでも、音楽が途切れることなく再生されることを期待しています。

ほとんどのサービスは、メモリが不足しているときにシステムによって一時的に停止される可能性があり、メモリが再び利用可能になると自動的に再起動されます。だから、正しい考え方は2つのアイデアを分けることです。

  1. 通知を常に表示したい場合は、私が言及した2つのフラグを使用します。
  2. フォアグラウンドでサービスを実行する必要がある場合は、Service.startForeground()に電話する必要がありますが、これは継続的な通知を受け取る方法ではありません。
+2

@HeroVsZero大歓迎です。あなたはこれを受け入れられた答えとして選択することを検討するかもしれません、なぜなら、それは正しい答えですから。私が説明したように、彼が本物で思いやりのある答えを担当するためにparadxが好きなのは、彼が示唆しているのは実際は悪いアドバイスです。将来の訪問者を最も正しい答えに導くことが、どの回答を選択するかを決定する最も重要な要素であると私は考えている。 –

+3

私は怒らないでください:) –

0

NotificationCompact.Builderクラス(通知をビルドするための最新バージョン)を使用した例です。

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

通知バーを常に表示するには、以下のコードを使用してください。

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