0

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);
        }
    }
halfer
  • 19,824
  • 17
  • 99
  • 186

1 Answers1

1

How to cancel the alarm using notification action button?

You should use the cancel function of the alarm manager to cancel a alarm by specifying its id. The id that you used while setting that particular pendingIntent for a particular alarm which you want to cancel. Refer this for code example.

You can perform this on the click of the action button.

Kaveri
  • 1,060
  • 2
  • 12
  • 21
  • but what about media player sound how should i stop that .cancel alarm method is working which i have specified in my adapter class but sound is not stopping after cancelation . – Gholap Akshay Jul 26 '20 at 06:30
  • You can try to start the braodcast reciever again by another pendingIntent , but this time put some extras's in the intent to specify that this intent is to cancel the alarm, then in catch and check of it in the onReceive() in the receiver , then try calling stop on the media player if it is running. – Kaveri Jul 26 '20 at 10:22
  • Then u should, put your media player code in a service ,then control the start and stop of the media player with the start and stop of service . – Kaveri Jul 26 '20 at 14:21
  • You can easily start and stop service from the already implemented broadcast receiver. – Kaveri Jul 26 '20 at 14:23