Как настроить Service/StartForeground для правильной работы CountDownTimer

Я не уверен, где/как я могу запустить эту службу для работы в фоновом режиме. Я разрабатываю приложение, которое использует CountDownTimer. Я обнаружил, что должен создать CountDownTimer в Service.class и запустить Service.class в MainActivity.class.

  1. Почему TextView не отображается на моем экране? Я поместил это в OnCreate и onStartCommand. Затем я пытаюсь запустить это в MainActivity, но безуспешно.

  2. Я все еще пытаюсь реализовать свой код для правильной работы этого CountDownTimer в фоновом режиме. На официальном веб-сайте Android я вижу, что они используют команду «Log.i» для запуска этого метода переднего плана. Как я могу использовать это в своем коде? Должен ли я добавить это в Service.class?

Ниже мой код:

Основная активность:

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

person gryzek    schedule 18.01.2016    source источник


Ответы (2)


Вот ваше решение было простым, хотя :)

активность 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>
person silentsudo    schedule 18.01.2016
comment
Спасибо, @sector11 Но есть проблема с AppCompatActivity - в моей андроид-студии он не отображается, поэтому у меня есть стандартная команда ActionBarActivity. В CountDownTimerService у меня есть 2 ошибки: ic.launcher - не удается разрешить символ - я меняю .drawable на mipmap, и это исправлено. Следующий с Intent.FLAG_ACTIVITY_NEW_TASK — должен быть один или несколько из..PendingIntent или Intent... Как я могу это исправить? - person gryzek; 18.01.2016
comment
добавьте любой рисуемый объект и измените его ссылку или нет, вы можете полностью прокомментировать этот код переднего плана - person silentsudo; 18.01.2016
comment
Я не знаю, но - Он работает с одной ошибкой в ​​​​соответствии с Intent.FLAG_ACTIVITY.. - что вы думаете об этом? С этим общением я должен добавить еще один PendingIntent или Intent. Почему? Тем не менее, спасибо за это решение. Оно работает! :) - person gryzek; 18.01.2016
comment
@gryzek, вы можете изменить флаги ожидающих намерений, для быстрого решения, которое я использовал, вы можете изучить это подробнее :) - person silentsudo; 18.01.2016
comment
@ сектор11. не могли бы вы ответить на этот вопрос? я не знаю, как мне написать служебный код для намерения уведомления и текстового просмотра. - person Mina Dahesh; 13.12.2016
comment
@MinaDahesh, с какой проблемой ты столкнулся? - person silentsudo; 13.12.2016
comment
@ сектор11. извините, я забыл вставить ссылку! stackoverflow.com/q/41045576/7268725 - person Mina Dahesh; 13.12.2016
comment
@MinaDahesh, где там принимается prblme ответ? - person silentsudo; 13.12.2016
comment
@ сектор11. как я пишу там, я не знаю, как восстановить BTN, который tv.setText (timeString) - person Mina Dahesh; 13.12.2016
comment
@ сектор11. пожалуйста, ответьте на мой. Пожалуйста, ответьте на него с самого начала. мне это нужно. - person Mina Dahesh; 13.12.2016
comment
@moderator Пожалуйста, изучите эти проблемы. Просто потому, что я не ответил ей, она понизила мои ответы. мина-дахеш stackoverflow.com/users/7268725/migitanar - person silentsudo; 20.12.2016

Во-первых:

Вы должны написать Broadcast Receiver в MainActivity.java и register в oncreate() и unregister в onDetstroy().

Во-вторых

В методе Service in onTick() вы должны sendbroadcast() вызвать onReceive() в MainActivity.java, а затем в методе onReceive вы можете chage text of Textview активности.

person Sachin salunkhe    schedule 18.01.2016
comment
Это верный ответ :D - person silentsudo; 18.01.2016