如何使用服务运行后台计时器

时间:2018-01-03 11:09:20

标签: java android service timer

即使应用关闭,如何让计时器运行?我尝试在我的服务类的onstart命令上添加一个倒数计时器,但它没有工作。我还为它添加了一个简单的振动功能,以便我可以检查警报是否正常工作。要正确显示我在这里说的是代码:

mainActivity.java     公共类MainActivity扩展了AppCompatActivity {

    private SectionPageAdapter mSectionPageAdapter;

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

        mSectionPageAdapter = new SectionPageAdapter(getSupportFragmentManager());

        mViewPager = (ViewPager) findViewById(R.id.container);
        setupViewPager(mViewPager);

        TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
        tabLayout.setupWithViewPager(mViewPager);
    }

    private void setupViewPager(ViewPager viewPager){
        SectionPageAdapter adapter = new SectionPageAdapter(getSupportFragmentManager());
        adapter.addFragment(new page1(), "apps");
        adapter.addFragment(new page2(), "timer");
        adapter.addFragment(new page3(), "details");
        viewPager.setAdapter(adapter);
    }

}

page2_fragment(计时器所在的位置,另一个片段目前没有功能)

package com.softeng.applockerproject;

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.Vibrator;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

import java.util.concurrent.TimeUnit;



public class page2 extends Fragment {
    private static final String TAG =   "page2";
private Button btntest;
private TextView timer,tv;
private Spinner spinner, spinner2;
public int hours, mins, duration;
private Vibrator v;

private static int myVariable;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.page2_fragment,container,false);

    btntest = (Button) view.findViewById(R.id.button2);
    timer = (TextView) view.findViewById(R.id.Timer);
    tv = (TextView) view.findViewById(R.id.textView3);

    //setting up spinners
    spinner = (Spinner) view.findViewById(R.id.spinner1);
    String [] values = {"00","01","02","03","04","05","06"};
    ArrayAdapter<String> adapter = new ArrayAdapter<String>(this.getActivity(), android.R.layout.simple_spinner_item, values);
    adapter.setDropDownViewResource(android.R.layout.simple_dropdown_item_1line);
    spinner.setAdapter(adapter);
    spinner2 = (Spinner) view.findViewById(R.id.spinner2);
    String [] values2 = {"00","01","10","20","30","40","50","60"};
    ArrayAdapter<String> adapter2 = new ArrayAdapter<String>(this.getActivity(), android.R.layout.simple_spinner_item, values2);
    adapter2.setDropDownViewResource(android.R.layout.simple_dropdown_item_1line);
    spinner2.setAdapter(adapter2);

    //button start
    btntest.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

            String spin=spinner.getSelectedItem().toString();
            hours = Integer.parseInt(spin);
            hours = hours*3600000;
            String spin2=spinner2.getSelectedItem().toString();
            mins = Integer.parseInt(spin2);
            mins = mins*60000;
            duration = hours+mins;
            setParam(duration);
            myVariable = duration;
            startService(duration);
        }
    });
    return view;
}


//timer part
public void setParam(int param){
     CountDownTimer countDownTimer = new CountDownTimer(param,    1000) {

        @Override
        public void onTick(long param) {
            long millis= param;
            String hms= String.format("%02d:%02d:%02d",

                    TimeUnit.MILLISECONDS.toHours(millis),
                    TimeUnit.MILLISECONDS.toMinutes(millis) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis))
                    //seconds
                    ,TimeUnit.MILLISECONDS.toSeconds(millis) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis))
            );
            timer.setText(hms);
        }

        @Override
        public void onFinish() {
            timer.setText("00:00");
            //setVibrate();
            //stopService();
        }
    };
    countDownTimer.start();
}

//vibrate
/*private void setVibrate(){
    long n[] = {50,1000,500,1000,500,1000,500,1000,500,1000,500,1000,500,1000,500,1000,500,1000};
    v = (Vibrator) getActivity().getSystemService(Context.VIBRATOR_SERVICE);
    v.vibrate(n, -1);
}*/


//services part
public void startService(int duration)
{
    int n = duration;
    Intent intent = new Intent(getActivity(),MyService.class);
    getActivity().startService(intent);
    //Toast.makeText(getActivity(), "starting",Toast.LENGTH_SHORT).show();
}

/*public void stopService( )
{
    getActivity().stopService(new Intent(getActivity(),MyService.class));
    //Toast.makeText(getActivity(), "starting",Toast.LENGTH_SHORT).show();
}*/

public static int getVariable()
{
    return myVariable;
}

}

最后我尝试提供服务。 MyService.java

package com.softeng.applockerproject;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.CountDownTimer;
import android.os.IBinder;
import android.os.Vibrator;
import android.support.annotation.Nullable;
import android.widget.Toast;

import java.util.concurrent.TimeUnit;


public class MyService extends Service {

private Vibrator v;
int i = page2.getVariable();
@Override
public void onCreate() {
    super.onCreate();
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    //setParam(i);
    Toast.makeText(this,"%02d"+i,Toast.LENGTH_LONG).show();
    return START_STICKY;

}

@Override
public void onDestroy() {
    long n[] = {50,1000,500,1000,500,1000,500,1000,500,1000,500,1000,500,1000,500,1000,500,1000};
    v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
    v.vibrate(n, -1);
    Toast.makeText(this,"service stopped!",Toast.LENGTH_LONG).show();
}

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

//private void setVibrate(){

//timer
public void setParam(int param){
    CountDownTimer countDownTimer = new CountDownTimer(param,    1000) {

        @Override
        public void onTick(long param) {
            long millis= param;
            /*String hms= String.format("%02d:%02d:%02d",

                    TimeUnit.MILLISECONDS.toHours(millis),
                    TimeUnit.MILLISECONDS.toMinutes(millis) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis))
                    //seconds
                    ,TimeUnit.MILLISECONDS.toSeconds(millis) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis))
            );*/
            //timer.setText(hms);
        }

        @Override
        public void onFinish() {
            //timer.setText("00:00");
            //setVibrate();
            onDestroy();
        }
    };
    countDownTimer.start();
}

}

有人可以说明如何正确地做到这一点吗?

3 个答案:

答案 0 :(得分:0)

我认为您需要的是AlarmManager,因为即使您的应用未运行,它也会提供计时服务。见:

Will AlarmManager work if my application is not running?

从您的问题来看,这似乎会起作用 - 除非您需要在后台进行处理。只要不被“杀死”,当你的应用程序被“关闭”时,也可以这样做。但这意味着您的服务将继续运行。

答案 1 :(得分:0)

如果在Activity中使用带有静态Runnable的静态Handler对象,即使活动已关闭,也可以创建一个继续工作的计时器,而无需服务。如果你愿意,我可以稍后发布一些代码示例。

<强>更新 在MainActivity类字段中:

   private static Handler handler;
   private static Runnable runnable ;
   private static final TIMER_DELAY = 60000; // 1 minute in milliseconds
on MainActivity onCreate

 if (handler == null) {
            handler = new Handler();
            runnable = new Runnable() {
                @Override
                public void run() {
                  // do some delayed work
                    handler.postDelayed(runnable, TIMER_DELAY); // repeat again
                }
            };
            handler.postDelayed(runnable, TIMER_DELAY);
        }

当然,run()内部的任何方法都必须是静态的。

但如果手机进入睡眠模式,定时器将停止,为避免这种情况,您应尝试以下操作:

  • 获取部分WAKE_LOCK

  • 启动前台服务,即调用startForeground的服务

  • 在状态栏中显示不可忽略的通知。

答案 2 :(得分:0)

我不知道这是否是解决这个问题的最佳方法。我对此有点新意,如果这个答案看起来很愚蠢,那就很抱歉。

我更改了MyService.java中的一些区域:

package com.softeng.applockerproject;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.CountDownTimer;
import android.os.IBinder;
import android.os.Vibrator;
import android.support.annotation.Nullable;
import android.widget.Toast;

import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.TimeUnit;


public class MyService extends Service {

    private Vibrator v;
    long i = page2.getVariable();
    //private static Timer timer = new Timer();

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

    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        CountDownTimer countDownTimer = new CountDownTimer(60000,    1000) {

            @Override
            public void onTick(long param) {

            }

            @Override
            public void onFinish() {
                //timer.setText("00:00");
                //setVibrate();
                //onDestroy();
                long n[] = {1,1000,500,1000,500,1000,500,1000,500,1000,500,1000,500,1000,500,1000,500,1000};
                v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
                v.vibrate(n, -1);
                onDestroy();
            }
        };
        countDownTimer.start();
        return START_STICKY;

    }


    public void onDestroy() {
        stopSelf();
    }

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

}

如果您有任何建议,请在下面发表评论。这对我很有帮助。