0

奇妙に聞こえるかもしれませんが、 と を使用して単純なタイマーを作成しましactivityservice(開始およびバインド)。

アクティビティでは、メッセージを実装onStartonStopてログに記録するだけです (Log.d(TAG,"activity started/stopped")。

実際には、電話が PC に接続されていれば、すべてが機能しているように見えます。タイマーを開始、一時停止、変更、再起動できます。他のアプリを開くと、バックグラウンドで動作し続けます。私はそれを思い出すことができ、実際のカウントダウンがダウンしているのが見えます. 終了したら、通知からアクティビティを呼び出して、呼び出し音を止めることができます。などなど

電話がPCから切り離されている場合、サービスがまったくないように機能します。そのため、アクティビティが実行され、ホームボタンを押すとバック​​グラウンドになり、停止するまで数分間動作し続けます。

実行中のアプリケーションでプロセスを確認できます。アクティビティを思い出すと、一時停止した時点から再開されます。つまり、10分に設定し、開始をクリックしてからホームボタンをクリックします。2〜3分後に動作が停止し、アクティビティを思い出すと、8〜7分からカウントダウンが続きます...

何か案が?

アクティビティ:

package com.sleone.cookingtimer;

import com.sleone.cookingtimer.TimerService.LocalBinder;

import android.os.Bundle;
import android.os.IBinder;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.view.Menu;
import android.view.View;
import android.widget.Button;

import kankan.wheel.widget.WheelView;
import kankan.wheel.widget.adapters.NumericWheelAdapter;
import android.util.Log;

public class TimerMainActivity extends Activity {
    // private CookingTimer timer;
    // suppressWarnings because is initialized binding to the service

    private TimerService timerService;
    private Intent timerServiceIntent;
    private final String TAG = "TimerMainActivity";

    private WheelView hoursWheel ;
    private WheelView minutesWheel;
    private WheelView secondsWheel;

    /*
     * Initialize the activity
     */
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_timer_main);

        timerServiceIntent = new Intent(this, TimerService.class);
        startTimerService();

        // init the gui
        hoursWheel = (WheelView) findViewById(R.id.hoursWheelView);
        minutesWheel = (WheelView) findViewById(R.id.minutesWheelView);
        secondsWheel = (WheelView) findViewById(R.id.secondsWheelView);
        hoursWheel.setViewAdapter(new NumericWheelAdapter(this, 0, 6));
        minutesWheel.setViewAdapter(new NumericWheelAdapter(this, 0, 59));
        secondsWheel.setViewAdapter(new NumericWheelAdapter(this, 0, 59));
    }

    @Override
    protected void onStop(){
        super.onStop();
        Log.d(TAG, "TimerMainActivity stopped");
    }

    @Override
    protected void onStart(){
        super.onStart();
        Log.d(TAG, "TimerMainActivity started");
    }

    private void startTimerService() {
        // connect to the service
        // leave the service in background
        Log.d(TAG, "Starting the TimerService");
        startService(timerServiceIntent);
        // interact with the service
        Log.d(TAG, "Binding to the TimerService");
        bindService(timerServiceIntent, mConnection, Context.BIND_AUTO_CREATE);
    }

    private void stopTimerService() {
        unbindService(mConnection);
        stopService(timerServiceIntent);
    }

    /*
     * Disconnect from the service
     */
    @Override
    protected void onDestroy() {
        Log.d(TAG, "Stopping TimerService");
        super.onStop();
        stopTimerService();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.timer_main, menu);
        return true;
    }

    public void controlTimer(View view) {
        Button controlButton = (Button) findViewById(R.id.controlTimerButton);

        if (controlButton.getText().equals(
                getResources().getText(R.string.startTimer))) {
            if ((hoursWheel.getCurrentItem() == 0)
                    && (minutesWheel.getCurrentItem() == 0)
                    && (secondsWheel.getCurrentItem() == 0)) {
                return;
            }
            controlButton.setText(R.string.stopTimer);
            timerService.startTimer();
        } else {
            controlButton.setText(R.string.startTimer);
            timerService.stopTimer();
        }

    }

    /* Defines callbacks for service binding, passed to bindService() */
    private ServiceConnection mConnection = new ServiceConnection() {

        @Override
        public void onServiceConnected(ComponentName className, IBinder service) {
            // We've bound to LocalService, cast the IBinder and get
            // LocalService instance
            LocalBinder binder = (LocalBinder) service;
            timerService = binder.getService();
            binder.createCookingTimer(TimerMainActivity.this);

            Log.d(TAG, "onServiceConnected() finished");
        }

        @Override
        public void onServiceDisconnected(ComponentName arg0) {
            Log.e(TAG, "TimerService unexpectedly disconnected!!");
        }
    };
}

サービス:

package com.sleone.cookingtimer;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;

public class TimerService extends Service{
    // Binder given to clients
    private final IBinder mBinder = new LocalBinder();
    private CookingTimer timer;
    //private int timerServiceId;

    public class LocalBinder extends Binder {
        public TimerService getService() {
            // Return this instance of LocalService so clients can call public methods

            return TimerService.this;
        }

        // when the client connects to the service  instantiate the CookingImer
        public void createCookingTimer(TimerMainActivity timerMainActivity){
            timer = new CookingTimer(timerMainActivity);    
        }  
    }

    public void startTimer(){
        timer.startTimer();
    }

    public void stopTimer(){
        timer.stopTimer();
    }

    @Override
    public IBinder onBind(Intent arg0) {
        // TODO Auto-generated method stub
        return mBinder;
    }
}

タイマー自体は必要ないと思います。時分秒ホイールを更新して音を鳴らして音を出すCountDownTimerだけです。onTickonFinishnotification

4

2 に答える 2

0

PCに接続すると実行が少し遅くなりますが、接続しないとタイミングが少し異なり、実行の順序が変わるという、ある種の競合状態が発生する可能性があります。コードなしで見分けるのは難しいです。

于 2013-03-12T14:26:15.597 に答える
0

わかりました、私はそれを理解したと思います。

基本的に、CPUがスリープ状態になるとサービスが一時停止される可能性があることを正確に理解していませんでした。

したがって、エミュレーター上またはケーブルが接続されている間は、バッテリーの消費がないため、CPUがスリープ状態になることはないと思います。

CPU スリープからでもアプリケーションをウェイクアップするには、AlarmManager.RTC_WAKEUP フラグを指定して AlarmManger を使用しました。

于 2013-03-18T09:33:34.213 に答える