【问题标题】:How to set Service/StartForeground to work CountDownTimer properly如何设置 Service/StartForeground 以正常工作 CountDownTimer
【发布时间】:2016-01-18 11:09:44
【问题描述】:

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

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

我的服务:

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

【问题讨论】:

    标签: java android android-studio service countdowntimer


    【解决方案1】:

    虽然你的解决方案很简单 :)

    活动 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);
            }
        }
    }
    

    忘了说需要在 manifest 中添加服务

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

    【讨论】:

    • 谢谢,@sector11 但 AppCompatActivity 存在问题 - 在我的 android studio 中它没有显示,所以我有一个标准命令 ActionBarActivity。在 CountDownTimerService 我有 2 个错误:“ic.launcher - 无法解析符号” - 我将 .drawable 更改为 mipmap 并且它已修复。下一个是 Intent.FLAG_ACTIVITY_NEW_TASK -“必须是一个或多个..PendingIntent 或 Intent..”。我该如何解决这个问题?
    • 添加任何可绘制对象并更改其引用,否则您可以完全注释该前台代码
    • 我不知道,但是 - 它适用于符合 Intent.FLAG_ACTIVITY 的一个错误.. - 您对此有何看法?通过这种交流,我应该再添加一个 PendingIntent 或 Intent。为什么?不过,感谢您提供此解决方案。有用! :)
    • @gryzek 你可以更改待处理的意图标志,为了快速解决我使用它你可以研究更多:)
    • @sector11。你能回答这个问题吗?我不知道我应该如何为通知的意图和文本视图编写服务代码。
    【解决方案2】:

    首先

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

    其次

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

    【讨论】:

    • 这是正确的答案:D
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-07-28
    • 2022-08-04
    • 2021-04-06
    • 2022-12-21
    • 1970-01-01
    • 2017-08-13
    • 1970-01-01
    相关资源
    最近更新 更多