2016-01-18 30 views
0

我不知道在哪裏/如何運行此服務在後臺工作。 我開發使用CountDownTimer的應用程序。 我發現我應該在Service.class中創建一個CountDownTimer並在MainActivity.class中運行一個Service.class。如何設置服務/ StartForeground正常工作CountDownTimer

  1. 爲什麼TextView不顯示在我的屏幕上?我把它放在OnCreate和onStartCommand中。接下來我嘗試在MainActivity中運行它,但沒有成功。

  2. 我仍然嘗試實現我的代碼,以正確地在後臺工作這個CountDownTimer。在官方Android網站上,我看到他們使用「Log.i」命令來運行此Foreground方法。我如何在我的代碼中使用它?我應該在Service.class中添加這個嗎?

下面是我的代碼:

MainActivity:

Button btnStart, btnStop; 
TextView textViewTime; 


@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
} 

public void startService(View view) 
{ 
    Intent intent = new Intent(this,MyService.class); 
    startService(intent); 
} 

public void stopService(View view) 
{ 
    Intent intent = new Intent(this,MyService.class); 
    stopService(intent); 
} 

爲MyService:

Button btnStart, btnStop; 
TextView textViewTime; 
public String hms; 

@Override 
public void onCreate() { 

    btnStart = (Button) btnStart.findViewById(R.id.btnStart); 
    btnStop = (Button) btnStop.findViewById(R.id.btnStop); 
    textViewTime = (TextView) textViewTime.findViewById(R.id.textViewTime); 

    textViewTime.setText("00:01:30"); 

    final CounterClass timer = new CounterClass(90000, 1000); 


    btnStart.setOnClickListener(new View.OnClickListener() { 
       @Override 
      public void onClick(View v) { 
       //startService(v); 
       timer.start(); 
             } 
                  }); 

    super.onCreate(); 
} 


@Override 
public int onStartCommand(Intent intent, int flags, int startId) { // create start a service 

    textViewTime.setText("00:01:30"); 

    Toast.makeText(this, "Service Started...", Toast.LENGTH_LONG).show(); 
    // timer.start(); 




    //return START_STICKY; // return integer value 
    return super.onStartCommand(intent, flags, startId); 
} 

@Override 
public void onDestroy() { // stop a service 

    Toast.makeText(this, "Service Destroyed...", Toast.LENGTH_LONG).show(); 

    super.onDestroy(); 
} 

@Nullable 
@Override 
public IBinder onBind(Intent intent) { // it's not needed but we must override this method 
    return null; 
} 


public class CounterClass extends CountDownTimer { 

    public CounterClass(long millisInFuture, long countDownInterval) { 
     super(millisInFuture, countDownInterval); 
    } 

    @Override 
    public void onTick(long millisUntilFinished) { 
     long millis = millisUntilFinished; 
     hms = String.format("%02d:%02d:%02d", TimeUnit.MILLISECONDS.toHours(millis), 
       TimeUnit.MILLISECONDS.toMinutes(millis) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis)), 
       TimeUnit.MILLISECONDS.toSeconds(millis) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis))); 
     System.out.println(hms); 
     textViewTime.setText(hms); 

    } 

    @Override 
    public void onFinish() { 
     textViewTime.setText("Completed."); 
    } 
} 

回答

0

這裏是您的解決方案很簡單,雖然:)

活動XML

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="vertical" 
    tools:context="in.ashish29agre.stackoverflow.sample.servicetimer.ServiceTimerActivity"> 

    <TextView 
     android:id="@+id/status_tv" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:padding="16dp" 
     android:text="TImer will start here" /> 

    <Button 
     android:id="@+id/start_btn" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:onClick="startService" 
     android:text="Start" /> 

    <Button 
     android:id="@+id/stop_btn" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:onClick="stopService" 
     android:text="Stop" /> 
</LinearLayout> 

Java代碼

import android.content.BroadcastReceiver; 
import android.content.Context; 
import android.content.Intent; 
import android.content.IntentFilter; 
import android.os.Bundle; 
import android.support.v4.content.LocalBroadcastManager; 
import android.support.v7.app.AppCompatActivity; 
import android.view.View; 
import android.widget.TextView; 

import in.ashish29agre.stackoverflow.R; 

public class ServiceTimerActivity extends AppCompatActivity { 

    TextView textViewTime; 
    private TimerStatusReceiver receiver; 


    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_service_timer); 
     textViewTime = (TextView) findViewById(R.id.status_tv); 
     receiver = new TimerStatusReceiver(); 
    } 


    @Override 
    protected void onResume() { 
     super.onResume(); 
     LocalBroadcastManager.getInstance(this).registerReceiver(receiver, new IntentFilter(CountdownTimerService.TIME_INFO)); 
    } 

    @Override 
    protected void onPause() { 
     super.onPause(); 
     LocalBroadcastManager.getInstance(this).unregisterReceiver(receiver); 
    } 

    public void startService(View view) { 
     Intent intent = new Intent(this, CountdownTimerService.class); 
     startService(intent); 
    } 

    public void stopService(View view) { 
     Intent intent = new Intent(this, CountdownTimerService.class); 
     stopService(intent); 
    } 


    private class TimerStatusReceiver extends BroadcastReceiver { 

     @Override 
     public void onReceive(Context context, Intent intent) { 
      if (intent != null && intent.getAction().equals(CountdownTimerService.TIME_INFO)) { 
       if (intent.hasExtra("VALUE")) { 
        textViewTime.setText(intent.getStringExtra("VALUE")); 
       } 
      } 
     } 
    } 
} 

服務代碼

import android.app.Notification; 
import android.app.PendingIntent; 
import android.app.Service; 
import android.content.Intent; 
import android.os.CountDownTimer; 
import android.os.IBinder; 
import android.support.annotation.Nullable; 
import android.support.v4.content.LocalBroadcastManager; 
import android.support.v7.app.NotificationCompat; 

import java.util.concurrent.TimeUnit; 

import in.ashish29agre.stackoverflow.R; 

public class CountdownTimerService extends Service { 
    public static final String TIME_INFO = "time_info"; 

    private CounterClass timer; 

    @Override 
    public void onCreate() { 
     super.onCreate(); 

    } 

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

    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 
     timer = new CounterClass(90000, 1000); 
     timer.start(); 
     Intent notificationIntent = new Intent(this, ServiceTimerActivity.class); 
     PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, 
       notificationIntent, Intent.FLAG_ACTIVITY_NEW_TASK); 

     Notification notification = new NotificationCompat.Builder(this) 
       .setSmallIcon(R.drawable.ic_launcher) 
       .setContentText("Counter down service") 
       .setContentIntent(pendingIntent).build(); 

     startForeground(101, notification); 

     return START_NOT_STICKY; 
    } 

    @Override 
    public void onDestroy() { 
     timer.cancel(); 
     super.onDestroy(); 
     Intent timerInfoIntent = new Intent(TIME_INFO); 
     timerInfoIntent.putExtra("VALUE", "Stopped"); 
     LocalBroadcastManager.getInstance(CountdownTimerService.this).sendBroadcast(timerInfoIntent); 
    } 

    public class CounterClass extends CountDownTimer { 

     public CounterClass(long millisInFuture, long countDownInterval) { 
      super(millisInFuture, countDownInterval); 
     } 

     @Override 
     public void onTick(long millisUntilFinished) { 
      long millis = millisUntilFinished; 
      String hms = String.format("%02d:%02d:%02d", TimeUnit.MILLISECONDS.toHours(millis), 
        TimeUnit.MILLISECONDS.toMinutes(millis) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis)), 
        TimeUnit.MILLISECONDS.toSeconds(millis) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis))); 
      System.out.println(hms); 
      Intent timerInfoIntent = new Intent(TIME_INFO); 
      timerInfoIntent.putExtra("VALUE", hms); 
      LocalBroadcastManager.getInstance(CountdownTimerService.this).sendBroadcast(timerInfoIntent); 
     } 

     @Override 
     public void onFinish() { 
      Intent timerInfoIntent = new Intent(TIME_INFO); 
      timerInfoIntent.putExtra("VALUE", "Completed"); 
      LocalBroadcastManager.getInstance(CountdownTimerService.this).sendBroadcast(timerInfoIntent); 
     } 
    } 
} 

忘記提及需要在清單

<application 
     android:allowBackup="true" 
     android:icon="@mipmap/ic_launcher" 
     android:label="@string/app_name" 
     android:supportsRtl="true" 
     android:theme="@style/AppTheme"> 


     <service android:name=".sample.servicetimer.CountdownTimerService" /> 
    </application> 
+0

謝謝,@ sector11 但與AppCompatActivity一個問題 - 在我的Android工作室它不顯示,所以我有一個標準的命令ActionBarActivity 。 在CountDownTimerService中我有2個錯誤:「ic.launcher - 無法解析符號」 - 我更改。撤消到mipmap,它已修復。接下來是Intent.FLAG_ACTIVITY_NEW_TASK - 「必須是一個或多個..PendingIntent或Intent ..」。我怎樣才能解決這個問題? – gryzek

+0

添加任何drawable並更改其引用,或者您可以完全評論前景代碼 – sector11

+0

我不知道,但 - 它與Intent.FLAG_ACTIVITY中的一個錯誤一起工作.. - 您對此有何看法?通過這種溝通,我應該再添加一個PendingIntent或Intent。爲什麼? 儘管如此,感謝您的解決方案。有用! :) – gryzek

0

首先

你必須寫廣播接收器在MainActivity.java和registeroncreate()unregisteronDetstroy()

其次

在服務中onTick()方法,你必須sendbroadcast()將在MainActivity.java調用onReceive(),然後就可以活動的chage text of Textview的onReceive方法。

+0

這就是真正的答案添加服務:d – sector11