我正在开发一个简单的闹钟应用程序。
我创建了一个具有scheduledAtFixedRate
的服务来检查当前小时是否与设定的小时相匹配。如果我多次设置时间,当其中一个时间设置到来时,每隔一个时间设置都会关闭(例如:当前时间是20:00,我将闹钟设置为9:10,9:20和20:01,当它是20:01时,3个“唤醒”活动一起出现)。我无法弄清楚原因。这是代码:
MainActivity:
package com.example.lalarm;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Bundle;
import android.preference.PreferenceActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.TimePicker;
import android.widget.Toast;
public class MainActivity extends PreferenceActivity {
TimePicker timePicker;
protected static int hourSet;
protected static int minuteSet;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.alarm_preferences);
setContentView(R.layout.activity_main);
getActionBar().setDisplayShowTitleEnabled(false);
timePicker = (TimePicker)findViewById(R.id.timePicker1);
timePicker.setIs24HourView(true);
}
@Override
public boolean onCreateOptionsMenu (Menu menu){
super.onCreateOptionsMenu(menu);
CreateMenu(menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item){
return MenuChoice(item);
}
private void CreateMenu (Menu menu){
MenuItem mi1 = menu.add(0, 1, 1, "Stop");
{mi1.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);}
MenuItem mi2 = menu.add(0, 2, 2, "Save");
{mi2.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);}
}
private boolean MenuChoice (MenuItem item){
switch (item.getItemId()){
case 2:
Intent i = new Intent("com.example.AlarmService1");
stopService(i);
hourSet = timePicker.getCurrentHour();
minuteSet = timePicker.getCurrentMinute();
i.putExtra("hourSet", hourSet);
i.putExtra("minuteSet", minuteSet);
startService(i);
Toast.makeText(getBaseContext(), "Alarm set", Toast.LENGTH_LONG).show();
return true;
case 1:
stopService(new Intent("com.example.AlarmService1"));
return true;
}
return false;
}
}
服务:
package com.example.lalarm;
import android.app.Notification;
import java.util.Timer;
import java.util.TimerTask;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.support.v4.app.NotificationCompat;
import android.text.format.Time;
import android.util.Log;
public class AlarmService extends Service {
int counter = 0;
private static int hourSet, minuteSet;
private static int currentHour, currentMinute;
static final int UPDATE_INTERVAL = 6_000;
private Timer timer = new Timer();
Time time = new Time();
@Override
public IBinder onBind(Intent arg0){
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startID){
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
builder.setSmallIcon(R.drawable.alarm_512).setContentTitle("Alarm").setContentText("Alarm is on");
Notification notification = builder.build();
startForeground(1, notification);
hourSet = intent.getIntExtra("hourSet", 0);
minuteSet = intent.getIntExtra("minuteSet", 0);
Log.d("Service", "before checkTime()");
checkTime();
Log.d("Service", "after checkTime()");
return START_STICKY;
}
private void checkTime(){
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
time.setToNow();
currentHour = time.hour;
currentMinute = time.minute;
if(currentHour == hourSet && currentMinute == minuteSet){
Log.d("Service", "inside if statement");
Intent i = new Intent("com.example.AlarmTime1");
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
cancel();
}
}
}, 0, UPDATE_INTERVAL );
}
@Override
public void onDestroy(){
super.onDestroy();
stopForeground(true);
}
}
logcat的:
12-01 21:44:51.501: D/Service(567): ****before checkTime()****
12-01 21:44:51.511: D/Service(567): ****after checkTime()****
12-01 21:44:51.601: I/WindowManager(94): createSurface Window{415c1f20 Toast paused=false}: DRAW NOW PENDING
12-01 21:44:51.662: D/dalvikvm(567): GC_CONCURRENT freed 186K, 3% free 11269K/11591K, paused 4ms+17ms
12-01 21:44:51.871: D/dalvikvm(147): GC_FOR_ALLOC freed 4974K, 32% free 11089K/16199K, paused 262ms
12-01 21:44:51.871: I/dalvikvm-heap(147): Grow heap (frag case) to 11.909MB for 1048592-byte allocation
12-01 21:44:52.341: D/dalvikvm(147): GC_CONCURRENT freed 32K, 26% free 12081K/16199K, paused 5ms+7ms
12-01 21:44:53.390: D/Service(567): ****before checkTime()****
12-01 21:44:53.390: D/Service(567): ****after checkTime()****
12-01 21:44:54.041: D/dalvikvm(147): GC_CONCURRENT freed 408K, 24% free 12330K/16199K, paused 5ms+7ms
12-01 21:44:55.051: I/WindowManager(94): createSurface Window{4169bff8 Toast paused=false}: DRAW NOW PENDING
12-01 21:45:02.281: D/Service(567): ****before checkTime()****
12-01 21:45:02.281: D/Service(567): ****inside if statement****
12-01 21:45:02.281: I/ActivityManager(94): START {act=com.example.AlarmTime1 flg=0x10000000 cmp=com.example.lalarm/.AlarmTime} from pid 567
12-01 21:45:02.291: W/WindowManager(94): Failure taking screenshot for (180x273) to layer 21010
12-01 21:45:02.301: D/Service(567): ****after checkTime()****
12-01 21:45:02.461: I/WindowManager(94): createSurface Window{415e1108 Toast paused=false}: DRAW NOW PENDING
12-01 21:45:03.011: D/dalvikvm(147): GC_CONCURRENT freed 749K, 24% free 12314K/16199K, paused 5ms+8ms
12-01 21:45:03.091: D/AudioSink(38): bufferCount (4) is too small and increased to 12
12-01 21:45:03.440: I/WindowManager(94): createSurface Window{4163a730 com.example.lalarm/com.example.lalarm.AlarmTime paused=false}: DRAW NOW PENDING
12-01 21:45:03.501: D/Service(567): ****inside if statement****
12-01 21:45:03.501: I/ActivityManager(94): START {act=com.example.AlarmTime1 flg=0x10000000 cmp=com.example.lalarm/.AlarmTime} from pid 567
12-01 21:45:03.511: W/WindowManager(94): Failure taking screenshot for (180x273) to layer 21015
12-01 21:45:04.201: D/AudioSink(38): bufferCount (4) is too small and increased to 12
12-01 21:45:04.291: I/WindowManager(94): createSurface Window{414b6ee0 com.example.lalarm/com.example.lalarm.AlarmTime paused=false}: DRAW NOW PENDING
12-01 21:45:04.621: I/ActivityManager(94): Displayed com.example.lalarm/.AlarmTime: +2s225ms
12-01 21:45:04.711: I/ARMAssembler(36): generated scanline__00000077:03010104_00008001_00000000 [ 89 ipp] (110 ins) at [0x41dbd450:0x41dbd608] in 7341190 ns
12-01 21:45:04.881: I/ActivityManager(94): Displayed com.example.lalarm/.AlarmTime: +1s96ms
12-01 21:45:05.351: D/dalvikvm(567): GC_CONCURRENT freed 276K, 4% free 11452K/11847K, paused 4ms+7ms
12-01 21:45:05.392: D/Service(567): ****inside if statement****
12-01 21:45:05.401: I/ActivityManager(94): START {act=com.example.AlarmTime1 flg=0x10000000 cmp=com.example.lalarm/.AlarmTime} from pid 567
12-01 21:45:05.411: W/WindowManager(94): Failure taking screenshot for (180x273) to layer 21020
12-01 21:45:05.801: D/AudioSink(38): bufferCount (4) is too small and increased to 12
12-01 21:45:05.900: I/WindowManager(94): createSurface Window{41649658 com.example.lalarm/com.example.lalarm.AlarmTime paused=false}: DRAW NOW PENDING
12-01 21:45:07.061: I/ActivityManager(94): Displayed com.example.lalarm/.AlarmTime: +1s556ms
12-01 21:45:07.561: W/WindowManager(94): Failure taking screenshot for (180x273) to layer 21025
12-01 21:45:07.661: I/WindowManager(94): createSurface Window{414b6ee0 com.example.lalarm/com.example.lalarm.AlarmTime paused=false}: DRAW NOW PENDING
12-01 21:45:08.400: W/WindowManager(94): Failure taking screenshot for (180x273) to layer 21020
12-01 21:45:08.481: I/WindowManager(94): createSurface Window{4163a730 com.example.lalarm/com.example.lalarm.AlarmTime paused=false}: DRAW NOW PENDING
12-01 21:45:09.070: W/WindowManager(94): Failure taking screenshot for (180x273) to layer 21015
12-01 21:45:09.141: I/WindowManager(94): createSurface Window{41677078 com.example.lalarm/com.example.lalarm.MainActivity paused=false}: DRAW NOW PENDING
12-01 21:46:04.771: W/ThrottleService(94): unable to find stats for iface rmnet0
: E/(): Device disconnected
由于日志inside if statement
重复,我认为scheduleAtFixedRate
出了问题。我试图在活动被触发后放cancel()
但它不起作用。那么如何解决这个问题?