Created UpcomingAlarmReceiver to handle upcoming alarm notifications
This commit is contained in:
parent
37e7d3dd3b
commit
f7c788cf46
@ -9,7 +9,7 @@
|
|||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:theme="@style/AppTheme">
|
android:theme="@style/AppTheme">
|
||||||
<activity
|
<activity
|
||||||
android:name="com.philliphsu.clock2.MainActivity"
|
android:name=".MainActivity"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:theme="@style/AppTheme.NoActionBar">
|
android:theme="@style/AppTheme.NoActionBar">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
@ -19,17 +19,23 @@
|
|||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
<activity
|
<activity
|
||||||
android:name="com.philliphsu.clock2.ringtone.RingtoneActivity"
|
android:name=".ringtone.RingtoneActivity"
|
||||||
android:configChanges="orientation|keyboardHidden|screenSize"
|
android:configChanges="orientation|keyboardHidden|screenSize"
|
||||||
android:label="@string/title_activity_ringtone"
|
android:label="@string/title_activity_ringtone"
|
||||||
android:theme="@style/FullscreenTheme">
|
android:theme="@style/FullscreenTheme">
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
<service
|
<service
|
||||||
android:name="com.philliphsu.clock2.ringtone.RingtoneService"
|
android:name=".ringtone.RingtoneService"
|
||||||
android:enabled="true"
|
android:enabled="true"
|
||||||
android:exported="false">
|
android:exported="false">
|
||||||
</service>
|
</service>
|
||||||
|
|
||||||
|
<receiver
|
||||||
|
android:name=".UpcomingAlarmReceiver"
|
||||||
|
android:enabled="true"
|
||||||
|
android:exported="false">
|
||||||
|
</receiver>
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
</manifest>
|
</manifest>
|
||||||
@ -63,7 +63,7 @@ public class MainActivity extends AppCompatActivity {
|
|||||||
@Override
|
@Override
|
||||||
public void onClick(View view) {
|
public void onClick(View view) {
|
||||||
scheduleAlarm();
|
scheduleAlarm();
|
||||||
Snackbar.make(view, "Alarm set for 1 minute from now", Snackbar.LENGTH_LONG)
|
Snackbar.make(view, "Alarm set for 1 minute from now", Snackbar.LENGTH_INDEFINITE)
|
||||||
.setAction("Dismiss", new View.OnClickListener() {
|
.setAction("Dismiss", new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
@ -180,17 +180,32 @@ public class MainActivity extends AppCompatActivity {
|
|||||||
// by this one. For most of our uses, the relevant criteria for equality will be the
|
// by this one. For most of our uses, the relevant criteria for equality will be the
|
||||||
// action, the data, and the class (component). Although not documented, the request code
|
// action, the data, and the class (component). Although not documented, the request code
|
||||||
// of a PendingIntent is also considered to determine equality of two intents.
|
// of a PendingIntent is also considered to determine equality of two intents.
|
||||||
|
|
||||||
|
// WAKEUP alarm types wake the CPU up, but NOT the screen. If that is what you want, you need
|
||||||
|
// to handle that yourself by using a wakelock, etc..
|
||||||
|
// We use a WAKEUP alarm to send the upcoming alarm notification so it goes off even if the
|
||||||
|
// device is asleep. Otherwise, it will not go off until the device is turned back on.
|
||||||
|
// todo: use alarm's ring time - (number of hours to be notified in advance, converted to millis)
|
||||||
|
am.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), notifyUpcomingAlarmIntent());
|
||||||
// todo: get alarm's ring time
|
// todo: get alarm's ring time
|
||||||
am.setExact(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 60000, alarmIntent());
|
am.setExact(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 10000, alarmIntent());
|
||||||
}
|
}
|
||||||
|
|
||||||
private PendingIntent alarmIntent() {
|
private PendingIntent alarmIntent() {
|
||||||
// TODO: Use appropriate subclass instead
|
// TODO: Use appropriate subclass instead
|
||||||
Intent intent = new Intent(this, RingtoneActivity.class)
|
Intent intent = new Intent(this, RingtoneActivity.class)
|
||||||
.setData(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM));
|
.setData(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM));
|
||||||
|
// TODO: Pass in the id of the alarm to the intent. Alternatively, if the upcoming alarm note
|
||||||
|
// only needs to show the alarm's ring time, just pass in the alarm's ringsAt().
|
||||||
// TODO: Use unique request codes per alarm.
|
// TODO: Use unique request codes per alarm.
|
||||||
// If a PendingIntent with this request code already exists, then we are likely modifying
|
// If a PendingIntent with this request code already exists, then we are likely modifying
|
||||||
// an alarm, so we should cancel the existing intent.
|
// an alarm, so we should cancel the existing intent.
|
||||||
return PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
|
return PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private PendingIntent notifyUpcomingAlarmIntent() {
|
||||||
|
Intent intent = new Intent(this, UpcomingAlarmReceiver.class);
|
||||||
|
// TODO: Use unique request codes per alarm.
|
||||||
|
return PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,29 @@
|
|||||||
|
package com.philliphsu.clock2;
|
||||||
|
|
||||||
|
import android.app.Notification;
|
||||||
|
import android.app.NotificationManager;
|
||||||
|
import android.content.BroadcastReceiver;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.support.v4.app.NotificationCompat;
|
||||||
|
|
||||||
|
public class UpcomingAlarmReceiver extends BroadcastReceiver {
|
||||||
|
public static final String ACTION_CANCEL_NOTIFICATION
|
||||||
|
= "com.philliphsu.clock2.action.CANCEL_NOTIFICATION";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onReceive(Context context, Intent intent) {
|
||||||
|
NotificationManager nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||||
|
if (ACTION_CANCEL_NOTIFICATION.equals(intent.getAction())) {
|
||||||
|
nm.cancel("tag", 0);
|
||||||
|
} else {
|
||||||
|
Notification note = new NotificationCompat.Builder(context)
|
||||||
|
.setSmallIcon(R.mipmap.ic_launcher)
|
||||||
|
.setContentTitle("Upcoming alarm")
|
||||||
|
.setContentText("Ring time here")
|
||||||
|
.build();
|
||||||
|
// todo actions
|
||||||
|
nm.notify("tag", 0, note);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -11,6 +11,7 @@ import android.view.MotionEvent;
|
|||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
import com.philliphsu.clock2.R;
|
import com.philliphsu.clock2.R;
|
||||||
|
import com.philliphsu.clock2.UpcomingAlarmReceiver;
|
||||||
|
|
||||||
import static com.philliphsu.clock2.util.Preconditions.checkNotNull;
|
import static com.philliphsu.clock2.util.Preconditions.checkNotNull;
|
||||||
|
|
||||||
@ -19,7 +20,7 @@ import static com.philliphsu.clock2.util.Preconditions.checkNotNull;
|
|||||||
* status bar and navigation/system bar) with user interaction.
|
* status bar and navigation/system bar) with user interaction.
|
||||||
*
|
*
|
||||||
* TODO: Make this abstract and make appropriate subclasses for Alarms and Timers.
|
* TODO: Make this abstract and make appropriate subclasses for Alarms and Timers.
|
||||||
* TODO: Use this together with RingtoneService.
|
* TODO: Implement dismiss and extend logic here.
|
||||||
*/
|
*/
|
||||||
public class RingtoneActivity extends AppCompatActivity {
|
public class RingtoneActivity extends AppCompatActivity {
|
||||||
/**
|
/**
|
||||||
@ -97,9 +98,14 @@ public class RingtoneActivity extends AppCompatActivity {
|
|||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
setContentView(R.layout.activity_ringtone);
|
setContentView(R.layout.activity_ringtone);
|
||||||
|
// Play the ringtone
|
||||||
Uri ringtone = checkNotNull(getIntent().getData());
|
Uri ringtone = checkNotNull(getIntent().getData());
|
||||||
Intent intent = new Intent(this, RingtoneService.class).setData(ringtone);
|
Intent intent = new Intent(this, RingtoneService.class).setData(ringtone);
|
||||||
startService(intent);
|
startService(intent);
|
||||||
|
// Cancel the upcoming alarm notification
|
||||||
|
Intent intent2 = new Intent(this, UpcomingAlarmReceiver.class)
|
||||||
|
.setAction(UpcomingAlarmReceiver.ACTION_CANCEL_NOTIFICATION);
|
||||||
|
sendBroadcast(intent2);
|
||||||
|
|
||||||
mVisible = true;
|
mVisible = true;
|
||||||
mControlsView = findViewById(R.id.fullscreen_content_controls);
|
mControlsView = findViewById(R.id.fullscreen_content_controls);
|
||||||
|
|||||||
@ -111,9 +111,9 @@ public class RingtoneService extends Service {
|
|||||||
private void scheduleAutoSilence() {
|
private void scheduleAutoSilence() {
|
||||||
// TODO: Read prefs
|
// TODO: Read prefs
|
||||||
//SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(this);
|
//SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(this);
|
||||||
int minutes = 2; /*Integer.parseInt(pref.getString(
|
/*int minutes = Integer.parseInt(pref.getString(
|
||||||
getString(R.string.key_silence_after),
|
getString(R.string.key_silence_after),
|
||||||
"15"));*/
|
"15"));*/
|
||||||
mSilenceHandler.postDelayed(mSilenceRunnable, minutes * 60000);
|
mSilenceHandler.postDelayed(mSilenceRunnable, 10000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,19 @@
|
|||||||
|
package com.philliphsu.clock2;
|
||||||
|
|
||||||
|
import com.philliphsu.clock2.ringtone.RingtoneService;
|
||||||
|
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.runners.MockitoJUnitRunner;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Phillip Hsu on 5/28/2016.
|
||||||
|
*
|
||||||
|
* TODO: Write unit tests...
|
||||||
|
*/
|
||||||
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
|
public class RingtoneServiceTest {
|
||||||
|
|
||||||
|
@Mock RingtoneService mRingtoneService;
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user