2012-03-29 31 views
7

私はIntentServiceを持っています。私はそれを進行中の通知で固定したいと思っています。問題は通知が表示され、すぐに消えてしまうことです。サービスは継続して実行されます。 IntentServiceでstartForegroundをどのように使うべきですか?IntentServiceのStartForeground

@Override 
public int onStartCommand(Intent intent, int flags, int startId) { 
    super.onStartCommand(intent, flags, startId); 
    Notification notification = new Notification(R.drawable.marker, "Notification service is running", 
      System.currentTimeMillis()); 
    Intent notificationIntent = new Intent(this, DashboardActivity.class); 
    notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP| 
     Intent.FLAG_ACTIVITY_SINGLE_TOP); 
    PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0); 
    notification.setLatestEventInfo(this, "App", 
      "Notification service is running", pendingIntent); 
    notification.flags|=Notification.FLAG_NO_CLEAR; 
    startForeground(1337, notification); 
    return START_STICKY; 
} 

@Override 
protected void onHandleIntent(Intent intent) { 

    String id = intent.getStringExtra(ID); 
    WebSocketConnectConfig config = new WebSocketConnectConfig(); 
    try { 
     config.setUrl(new URI("ws://" + App.NET_ADDRESS 
       + "/App/socket?id="+id)); 
    } catch (URISyntaxException e) { 
     e.printStackTrace(); 
    } 
    ws = SimpleSocketFactory.create(config, this); 
    ws.open(); 
} 

おかげ

+2

すぎ – waqaslam

答えて

9

これはIntentServiceすべきではありません。書かれている通り、IntentServiceは1ミリ秒ほど生きるでしょう。 onHandleIntent()が返されると、サービスは破棄されます。これは通常のServiceでなければなりません。独自のスレッドをフォークし、スレッドとサービスの有効期間を管理します。

あなたのNotificationがすぐに離れる理由は、サービスが直ちに離れるためです。 IntentService状態のdocumentationとして

+1

おかげで、私はサービスにそれを変換し、今では働いているあなたのコードが含まれています。 – Matroska

+2

Downvotedの理由:誤った答えになる可能性があります。 IntentService docsの抜粋:「すべてのリクエストは単一のワーカースレッドで処理されます。*必要な時間がかかるだけで(アプリケーションのメインループをブロックしません)、一度に1つのリクエストしか処理されません。ミリ秒ほど過ぎるとは言いません。 https://developer.android.com/reference/android/app/IntentService。html – GregoryK

+1

書かれているように、この 'IntentService'は、' onHandleIntent() 'のコードが実行するのに数ミリ秒かかりますという単純な理由から、ミリ秒程度の間存続します。 – CommonsWare

1

...サービスは、必要に応じて、開始 ワーカースレッドを使用して順番にそれぞれの意図を処理し、それは仕事がなくなったときに自分自身を停止しています。

したがって、問題は、あなたのサービスがonHandleIntent()が終了した後に仕事を失っていることです。したがって、サービスは停止し、通知は却下されます。だから、IntentServiceのコンセプトはおそらくあなたの仕事のための最良のケースではありません。


質問のタイトルは「IntentServiceためStartForeground」であるとして、私はいくつかのことを明確にしたいと思います:(以下のコードを参照してください)それはあなたのIntentServiceがフォアグラウンドで実行できるようにすることは本当に簡単です

が、あなた確かにいくつかのことを考慮する必要があります。それはほんの数秒かかる場合

  • はフォアグラウンドでサービスを実行しないでください - かもしれないバグがユーザーということ。定期的に短いタスクを実行すると通知が表示され消えてしまうことを想像してみてください* uhhhh *

  • サービスをデバイスのアウェイクを維持できるようにする必要があるかもしれません(しかし、それはスタックオーバーフローでかなりうまくカバーされます)。

  • IntentServiceに複数のインテントをキューイングした場合、以下のコードは通知の表示/非表示を終了します。 (あなたのケースにはもっと良い解決策があるかもしれません - @CommonsWareがサービスを拡張して自分ですべてを行うことを示唆していますが、言及したいのですが - IntentServiceのjavadocには数秒しか働かないということは何もありません。それは何かを持っている。)


public class ForegroundService extends IntentService { 

    private static final String TAG = "FrgrndSrv"; 

    public ForegroundService() { 
     super(TAG); 
    } 

    @Override 
    protected void onHandleIntent(Intent intent) { 

     Notification.Builder builder = new Notification.Builder(getBaseContext()) 
       .setSmallIcon(R.drawable.ic_foreground_service) 
       .setTicker("Your Ticker") // use something from something from R.string 
       .setContentTitle("Your content title") // use something from something from 
       .setContentText("Your content text") // use something from something from 
       .setProgress(0, 0, true); // display indeterminate progress 

     startForeground(1, builder.build()); 
     try { 
      doIntesiveWork(); 
     } finally { 
      stopForeground(true); 
     } 
    } 

    protected void doIntesiveWork() { 
     // Below should be your logic that takes lots of time 
     try { 
      Thread.sleep(10000); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 
} 
+0

コンピュータプログラミングの一般的なルールは、あなたのために何か他のものが取得したリソースについて決して仮定しないことです。あなたは 'IntentService'によって使われたバックグラウンドスレッドを作成しませんでした。したがって、あなたがどれくらい安全にそれを使用することができるかについては、何も仮定してはいけません。私たちは 'AsyncTask'でこの非常に問題に遭遇しました。ここでは、Googleが' execute() 'のルールを変更して、すべてのタスクの中で1つのスレッドに制限しています。短期間以上スレッドを保持したい場合は、独自のスレッドを作成します。恥ずかしいプログラミング方法を推薦するためにダウン投票する。 – CommonsWare

+1

@CommonsWare私はあなたの意見を見て、それを理解しています。それは理にかなっている。実際には、私は、書かれているように、あなたのIntentServiceは1ミリ秒程度の間生き続けるだろうという声明には少し賛成です。 "IntentServiceは、要求に応じて非同期要求(インテントとして表現)を処理するサービスの基本クラスであり、クライアントはstartService(Intent)呼び出しを通じて要求を送信し、必要に応じてサービスが開始され、それぞれのインテントをワーカースレッドを使用して順番に処理し、作業がなくなったときに停止します。 – GregoryK

関連する問題