I am developing the alarm application and in that I have used the arraylist to store my alarms and recyclerview to bind alarms on screen, I have used switch button to turn on/off the alarm. Turning on and on triggered alarm is playing sound and also sending notification,the only problem I am facing is while canceling the alarm. How can I stop the media player sound on cancel of alarm. And also how can I cancel the alarm using notification action button.
I have used alarmmanager for setting alarms and used broadcast recevier to receive on trigger event.
Below is code
Alarm fragment:
package com.example.myapplication;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.coordinatorlayout.widget.CoordinatorLayout;
import androidx.core.widget.NestedScrollView;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextClock;
import android.widget.TextView;
import android.widget.TimePicker;
import com.google.android.material.bottomsheet.BottomSheetBehavior;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import java.sql.Time;
import java.util.ArrayList;
import java.util.Timer;
/**
* A simple {@link Fragment} subclass.
*/
public class AlarmFragment extends Fragment {
private FloatingActionButton addAlarmBtn;
private BottomSheetBehavior bottomScrollViewBehavior;
private View v;
private CoordinatorLayout coordinatorLayout;
private TimePicker timePicker;
private Button setAlarm;
private RecyclerView show_alarm;
private ArrayList<String> alarms ;
private RecyclerView.Adapter adapter;
private RecyclerView.LayoutManager layoutManager;
private TextClock textClock;
public String current_Time;
public AlarmFragment() {
// Required empty public constructor
}
@SuppressLint("RestrictedApi")
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_alarm, container, false);
addAlarmBtn=(FloatingActionButton)view.findViewById(R.id.add_alarm_alarm_fragment);
coordinatorLayout=(CoordinatorLayout)view.findViewById(R.id.fragment_alarm_coordinatorLayout);
timePicker = (TimePicker)view.findViewById(R.id.timepicker_alarm_fragment);
timePicker.setIs24HourView(false);
setAlarm =(Button)view.findViewById(R.id.setAlarm_alam_fragment);
show_alarm=(RecyclerView)view.findViewById(R.id.showalarm_listview_alarm_fragment);
v=(View) view.findViewById(R.id.alarmSet_bbottomsheet);
bottomScrollViewBehavior =BottomSheetBehavior.from(v);
textClock=(TextClock)view.findViewById(R.id.text_clock_alarm_fragment);
alarms =new ArrayList<String>();
layoutManager = new LinearLayoutManager(getContext());
adapter = new AlarmAdapter(alarms,getActivity());
show_alarm.setLayoutManager(layoutManager);
new ItemTouchHelper(itemTouchHelper).attachToRecyclerView(show_alarm);
show_alarm.setAdapter(adapter)
setAlarm.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int hour ;
int minutes;
if(Build.VERSION.SDK_INT >=23) {
hour = timePicker.getHour();
minutes = timePicker.getMinute();
}
else {
hour = timePicker.getCurrentHour();
minutes = timePicker.getCurrentMinute();
}
String date =String.format("%02d:%02d", hour, minutes);
alarms.add(date);
adapter.notifyDataSetChanged();
Log.d("Time",date);
bottomScrollViewBehavior.setState(bottomScrollViewBehavior.STATE_COLLAPSED);
}
});
addAlarmBtn.setOnClickListener(new View.OnClickListener() {
@SuppressLint("RestrictedApi")
@Override
public void onClick(View v) {
bottomScrollViewBehavior.setState(bottomScrollViewBehavior.STATE_EXPANDED);
}
});
bottomScrollViewBehavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
@Override
public void onStateChanged(@NonNull View view, int i) {
if(i == BottomSheetBehavior.STATE_COLLAPSED)
{
addAlarmBtn.setVisibility(View.VISIBLE);
}
else
{
addAlarmBtn.setVisibility(View.INVISIBLE);
}
}
@Override
public void onSlide(@NonNull View view, float v) {
}
});
return view;
}
ItemTouchHelper.SimpleCallback itemTouchHelper= new ItemTouchHelper.SimpleCallback(0,ItemTouchHelper.LEFT|ItemTouchHelper.RIGHT) {
@Override
public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) {
return false;
}
@Override
public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {
alarms.remove(viewHolder.getAdapterPosition());
adapter.notifyDataSetChanged();
}
};
}
Alarm Adapter
package com.example.myapplication;
import android.annotation.SuppressLint;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.media.MediaPlayer;
import android.media.Ringtone;
import android.media.RingtoneManager;
import android.os.Parcelable;
import android.os.Vibrator;
import android.provider.Settings;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CompoundButton;
import android.widget.Switch;
import android.widget.TextClock;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import org.w3c.dom.Text;
import java.io.Externalizable;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Timer;
import java.util.TimerTask;
import static android.app.AlarmManager.RTC_WAKEUP;
public class AlarmAdapter extends RecyclerView.Adapter<AlarmAdapter.ViewHolder> {
ArrayList<String> alarm;
Context context;
String hours,mins,a_time;
int id;
Calendar calendar = Calendar.getInstance();
public AlarmAdapter(ArrayList<String> alarms,Context c) {
alarm = alarms;
context = c;
}
@NonNull
@Override
public AlarmAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.alarm_view_layout,parent,false);
return new ViewHolder(view);
}
@SuppressLint("ClickableViewAccessibility")
@Override
public void onBindViewHolder(@NonNull final AlarmAdapter.ViewHolder holder, int position) {
holder.Alarm_name.setText(alarm.get(position));
//timer_set =new Timer();
Timer t=new Timer();
t.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
holder.alarmSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
a_time = holder.Alarm_name.getText().toString();
hours = a_time.substring(0, 2);
mins = a_time.substring(3);
// final Calendar calendar1=Calendar.getInstance();
// calendar1.setTimeInMillis(System.currentTimeMillis());
calendar.set(
calendar.get(Calendar.YEAR),
calendar.get(Calendar.MONTH),
calendar.get(Calendar.DAY_OF_MONTH),
Integer.parseInt(hours),
Integer.parseInt(mins),
0
);
setAlarm(calendar.getTimeInMillis());
}
else {
cancelAlarm();
}
}
});
}
},0,1000);
}
private void setAlarm(long timeInMillis) {
mediaPlayer=RingtoneManager.getRingtone(context,RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE));
AlarmManager alarmManager= (AlarmManager) context.getSystemService(context.ALARM_SERVICE);
Intent intent=new Intent(context,MyAlarmBoardcastClass.class);
id=(int)System.currentTimeMillis();
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, id, intent, 0);
//alarmManager.set(AlarmManager.RTC_WAKEUP, timeInMillis, pendingIntent);
if (alarmManager != null) {
alarmManager.setExact(AlarmManager.RTC_WAKEUP, timeInMillis, pendingIntent);
}
Toast.makeText(context,"Alarm is set",Toast.LENGTH_SHORT).show();
}
private void cancelAlarm()
{
AlarmManager alarmManager= (AlarmManager) context.getSystemService(context.ALARM_SERVICE);
Intent intent=new Intent(context,MyAlarmBoardcastClass.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, id, intent, PendingIntent.FLAG_UPDATE_CURRENT);
if (alarmManager != null) {
alarmManager.cancel(pendingIntent);
}
Toast.makeText(context,"Alarm cancelled",Toast.LENGTH_SHORT).show();
}
@Override
public int getItemCount() {
return alarm.size();
}
public class ViewHolder extends RecyclerView.ViewHolder
{
TextView Alarm_name;
Switch alarmSwitch;
public ViewHolder(@NonNull View itemView) {
super(itemView);
Alarm_name =(TextView)itemView.findViewById(R.id.alarm_textview);
alarmSwitch=(Switch)itemView.findViewById(R.id.alarm_switch);
}
}
}
Broadcast receiver class
package com.example.myapplication;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.media.MediaPlayer;
import android.media.Ringtone;
import android.os.Build;
import android.os.CountDownTimer;
import android.provider.Settings;
import android.widget.Toast;
import androidx.core.app.NotificationCompat;
import androidx.core.app.NotificationManagerCompat;
import java.util.Timer;
import java.util.TimerTask;
public class MyAlarmBoardcastClass extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
MediaPlayer mb =MediaPlayer.create(context,Settings.System.DEFAULT_RINGTONE_URI);
Toast.makeText(context, "hello", Toast.LENGTH_SHORT).show();
mb.start();
NotificationHelper notificationHelper = new NotificationHelper(context);
NotificationCompat.Builder nb = notificationHelper.getChannelNotification();
notificationHelper.getManager().notify(1, nb.build());
}
}
NotificationHelper class
package com.example.myapplication;
import android.annotation.TargetApi;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.Context;
import android.content.ContextWrapper;
import android.os.Build;
import androidx.core.app.NotificationCompat;
public class NotificationHelper extends ContextWrapper {
public static final String channelID = "channelID";
public static final String channelName = "Channel Name";
private NotificationManager mManager;
public NotificationHelper(Context base) {
super(base);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
createChannel();
}
}
@TargetApi(Build.VERSION_CODES.O)
private void createChannel() {
NotificationChannel channel = new NotificationChannel(channelID, channelName, NotificationManager.IMPORTANCE_HIGH);
getManager().createNotificationChannel(channel);
}
public NotificationManager getManager() {
if (mManager == null) {
mManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
}
return mManager;
}
public NotificationCompat.Builder getChannelNotification() {
return new NotificationCompat.Builder(getApplicationContext(), channelID)
.setContentTitle("Alarm!")
.setContentText("Your AlarmManager is working.")
.setSmallIcon(R.drawable.ic_alarm_black_24dp);
}
}