I am rather new to android and I am attempting an alarm clock app. I am starting an activity through an AlarmManager which works fine as long as the phone is awake. When the phone is asleep it appears to run the code properly and then it runs the onStop function closing the activity. I have tried various combinations of WakeLock and Window flags with no avail.
This does however work on an older phone (2.3) if that helps. Any insight is appreciated.
Here is code for the Alarm activity:
package com.myAlarm.android;
import java.text.SimpleDateFormat;
import java.util.Date;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.hardware.Sensor;
import android.hardware.SensorManager;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Vibrator;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.view.View.MeasureSpec;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.Window;
import android.view.WindowManager;
import android.view.animation.Animation;
import android.view.animation.LinearInterpolator;
import android.view.animation.TranslateAnimation;
import android.widget.DigitalClock;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.TextClock;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ImageView;
import com.snoozulooze.android.UtilityFunctions;
@SuppressLint("NewApi")
public class Alarm extends Activity{
private int timerDelay = 4000;
private int id;
private double snoozeInt = 1;
private TextView clockText;
private TextView dateText;
private LinearLayout clockLayout;
private DatabaseHandler db;
public static AlarmRow ALARM_DATA;
private Animation animScroll;
private SensorManager mSensorManager;
private ShakeEventListener mSensorListener;
private Runnable alertLoop;
private Handler handler;
private ImageView snooze;
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
turnOnScreen();
Log.i("ALARM", "on create ran");
AlarmWakeLock.acquireCpuWakeLock(Alarm.this);
setContentView(R.layout.activity_alarm);
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mSensorListener = new ShakeEventListener();
handler = new Handler();
alertLoop = new Runnable() {
@Override
public void run() {
playAlarm();
handler.postDelayed(this, timerDelay);
}
};
//Create the clock for text clock of digital clock
LayoutParams clockParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
clockLayout = (LinearLayout)findViewById(R.id.alarmClockLayout);
dateText = (TextView) findViewById(R.id.alarmClockDateTxt);
try{
TextClock tc = new TextClock(Alarm.this);
tc.setLayoutParams(clockParams);
tc.setTextColor(getResources().getColor(R.color.white));
tc.setGravity(Gravity.CENTER);
clockText = (TextClock) tc;
}
catch(Throwable t){
Log.e("Alarm", t.getMessage());
DigitalClock dc = new DigitalClock(Alarm.this);
dc.setLayoutParams(clockParams);
dc.setTextColor(getResources().getColor(R.color.white));
dc.setGravity(Gravity.CENTER);
clockText = (TextView) dc;
}
clockLayout.addView(clockText,0);
UtilityFunctions.assignText(Alarm.this, clockText, "fonts/Roboto-Thin.ttf");
SimpleDateFormat sdf = new SimpleDateFormat("EEE. LLLL dd");
String currentDateandTime = sdf.format(new Date());
dateText.setText(currentDateandTime.toLowerCase());
clockLayout.post(new Runnable(){
public void run(){
float clockHeight = (float) (clockLayout.getHeight()*.35);
float dateHeight = (float) (clockLayout.getHeight()*.15);
if (clockHeight > 45){
clockHeight = 45;
dateHeight = 24;
}
clockText.setTextSize(((float) clockHeight));
dateText.setTextSize(((float) dateHeight));
}
});
//SetupAlarm aSetUp = new SetupAlarm();
//aSetUp.execute();
init();
}
private void init(){
db = new DatabaseHandler(this);
Intent fromIntent = getIntent();
Bundle bundle = fromIntent.getExtras();
id = bundle.getInt("id");
Alarm.ALARM_DATA = db.getAlarmData(id);
snooze = (ImageView) findViewById(R.id.snoozeAlarmBtn);
setupUI();
}
private void setupUI(){
String message = Alarm.ALARM_DATA.getMessage();
if(message != "" && message != null){
TextView tv = new TextView(Alarm.this);
tv.setText(message);
tv.setTextSize(16);
FrameLayout sf = (FrameLayout) findViewById(R.id.snoozFrame);
tv.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
sf.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
sf.addView(tv, tv.getMeasuredWidth(), ViewGroup.LayoutParams.WRAP_CONTENT);
animScroll = new TranslateAnimation(sf.getMeasuredWidth(), tv.getMeasuredWidth()*-1, 0, 0);
long durationMulti = ((sf.getMeasuredWidth()+tv.getMeasuredWidth())/sf.getMeasuredWidth());
int duration = (int) (5000*durationMulti);
animScroll.setDuration(duration);
animScroll.setInterpolator(new LinearInterpolator());
animScroll.setRepeatCount(Animation.INFINITE);
tv.startAnimation(animScroll);
}
snooze.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
handler.removeCallbacks(alertLoop);
handler.removeCallbacksAndMessages(null);
AlarmReceiverRepeating.resetPhone(Alarm.this);
AlarmReceiver ar = new AlarmReceiver();
ar.setOnetimeTimer(Alarm.this, Alarm.ALARM_DATA.getId(), (long) (System.currentTimeMillis() + (1000*60*snoozeInt)),Alarm.ALARM_DATA.getId());
Intent mainIntent = new Intent(Alarm.this,Main.class);
mainIntent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
startActivity(mainIntent);
finish();
AlarmWakeLock.releaseCpuLock();
}
});
mSensorListener.setOnShakeListener(new ShakeEventListener.OnShakeListener() {
public void onShake() {
handler.removeCallbacks(alertLoop);
handler.removeCallbacksAndMessages(null);
AlarmReceiverRepeating.resetPhone(Alarm.this);
Intent mainIntent = new Intent(Alarm.this,Main.class);
mainIntent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
startActivity(mainIntent);
Notifications.setNextAlarmNotification(Alarm.this);
AlarmReceiverRepeating.resetPhone(Alarm.this);
finish();
AlarmWakeLock.releaseCpuLock();
}
});
AlarmReceiverRepeating.setCurrentState(Alarm.this,Alarm.ALARM_DATA.getVolume());
handler.post(alertLoop);
}
//function for playing the ringer and vibrator
public void playAlarm(){
try {
if(AlarmReceiverRepeating.AUDIO_MANAGER == null){
AlarmReceiverRepeating.setCurrentState(Alarm.this, Alarm.ALARM_DATA.getVolume());
}
AlarmReceiverRepeating.REPEAT_COUNT ++;
if(AlarmReceiverRepeating.REPEAT_COUNT > 1){
AlarmReceiverRepeating.REPEAT_COUNT = 0;
if(AlarmReceiverRepeating.CURRENT_VOLUME < AlarmReceiverRepeating.ADJUSTED_MAX_VOLUME)
AlarmReceiverRepeating.CURRENT_VOLUME++;
}
AlarmReceiverRepeating.AUDIO_MANAGER.setStreamVolume(AudioManager.STREAM_RING, AlarmReceiverRepeating.CURRENT_VOLUME, AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE);
Vibrator vibrator = (Vibrator) this.getSystemService(Context.VIBRATOR_SERVICE);
vibrator.vibrate(2000);
AlarmReceiverRepeating.AUDIO_MANAGER.setStreamVolume(AudioManager.STREAM_RING, AlarmReceiverRepeating.CURRENT_VOLUME, AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE);
Uri alarm = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM);
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(Alarm.this);
MediaPlayer mediaPlayer = new MediaPlayer();
try {
mediaPlayer.setDataSource(Alarm.this, alarm);
} catch (Exception e1) {
e1.printStackTrace();
mediaPlayer.release();
return;
}
mediaPlayer.setAudioStreamType(AudioManager.STREAM_RING);
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mediaPlayer) {
mediaPlayer.release();
}
});
try {
mediaPlayer.prepare();
} catch (Exception e1) {
e1.printStackTrace();
mediaPlayer.release();
return;
}
mediaPlayer.setOnSeekCompleteListener(new MediaPlayer.OnSeekCompleteListener() {
@Override
public void onSeekComplete(MediaPlayer mediaPlayer) {
mediaPlayer.stop();
mediaPlayer.start();
}
});
mediaPlayer.setVolume(AlarmReceiverRepeating.CURRENT_VOLUME, AlarmReceiverRepeating.CURRENT_VOLUME);
mediaPlayer.start();
}
catch (Throwable t) {
Log.i("ALARM", "ERROR PLAYING ALARM");
Toast.makeText(this, "there was a problem in the playAlarm function", Toast.LENGTH_SHORT).show();
}
}//end playAlarm
@Override
protected void onStop(){
super.onStop();
Log.i("ALARM", "on stop ran");
handler.removeCallbacks(alertLoop);
handler.removeCallbacksAndMessages(null);
Notifications.setNextAlarmNotification(Alarm.this);
AlarmReceiverRepeating.resetPhone(this);
finish();
AlarmWakeLock.releaseCpuLock();
}
@Override
protected void onStart(){
super.onStart();
}
@Override
protected void onPause(){
super.onPause();
Log.i("ALARM", "on pause ran");
}
@Override
protected void onDestroy(){
super.onDestroy();
}
@Override
protected void onResume() {
super.onResume();
turnOnScreen();
Log.i("ALARM", "on resume ran");
mSensorManager.registerListener(mSensorListener,
mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
SensorManager.SENSOR_DELAY_UI);
}
private void turnOnScreen(){
final Window window = this.getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
+ WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
+ WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
+ WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
}
private class SetupAlarm extends AsyncTask<Void, Void, Void> {
protected Void doInBackground(Void... urls) {
init();
return null;
}
protected void onPostExecute(Void args) {
setupUI();
}
}
}
I have figured out what was going on. It was not a wakelock issue. The issue is that, for whatever reason the onStop function was (is still) being called when the phone wakes from sleeping. Since I had a finish() function running it was killing the activity. I placed the code in the onStop override so that the alarm will stop if the user hits the back or home button so I will need to address that unless someone can enlighten me on why the onStop is called an how to avoid it. Thanks