如何设置Service / StartForeground正确工作CountDownTimer

时间:2016-01-18 11:09:45

标签: java android android-studio service countdowntimer

我不确定在何处/如何运行此服务以在后台工作。 我开发了使用CountDownTimer的应用程序。 我发现我应该在Service.class中创建一个CountDownTimer并在MainActivity.class中运行一个Service.class。

  1. 为什么TextView不会在我的屏幕上显示?我把它放在OnCreate和onStartCommand中。接下来我尝试在MainActivity中运行它,但没有成功。

  2. 我仍然尝试实现我的代码,以便在后台正确使用此CountDownTimer。在官方Android网站上,我看到他们使用“Log.i”命令来运行此Foreground方法。我如何在我的代码中使用它?我应该在Service.class中添加它吗?

  3. 以下是我的代码:

    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.");
        }
    }
    

2 个答案:

答案 0 :(得分:0)

<强>首先

您必须在MainActivity.java中编写广播接收器,在QEventregisteroncreate()unregister编写onDetstroy()

其次

onTick()方法的服务中,您必须sendbroadcast()将在MainActivity.java中调用onReceive(),然后在onReceive方法中,您可以chage text of Textview个活动。

答案 1 :(得分: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>