0

In my app I am setting the alarm in the MainActivity and I want to cancel that alarm from another activity (FakeRinger). Here's my code below.

MainActivity

public class MainActivity extends AppCompatActivity {

    public static final String LOG_TAG = "MainActivity";

    ImageView imageView;
    EditText number, name;
    Button setTimeButton;
    ImageButton imageButton;
    TimePickerDialog timePicker;
    long selectedTimeInMillis;
    String enteredName, enteredNumber;

    private static final int SELECT_IMAGE = 100;

    public static final int REQUEST_CODE_PI = 1001;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        PreferenceManager.setDefaultValues(this, R.xml.settings, false);

        imageView = findViewById(R.id.image_view);
        setTimeButton = findViewById(R.id.set_time);
        imageButton = findViewById(R.id.place_call_button);

        number = findViewById(R.id.number);
        name = findViewById(R.id.name);

        imageView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent galleryIntent = new Intent(Intent.ACTION_PICK);
                galleryIntent.setType("image/*");
                startActivityForResult(galleryIntent, SELECT_IMAGE);
            }
        });

        setTimeButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                final Calendar calendar = Calendar.getInstance();
                int hour = calendar.get(Calendar.HOUR_OF_DAY);
                int minute = calendar.get(Calendar.MINUTE);
                timePicker = new TimePickerDialog(MainActivity.this, new TimePickerDialog.OnTimeSetListener() {
                    @Override
                    public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
                        calendar.set(Calendar.HOUR_OF_DAY, hourOfDay);
                        calendar.set(Calendar.MINUTE, minute);
                        calendar.set(Calendar.SECOND, 0);
                        calendar.set(Calendar.MILLISECOND, 0);
                        selectedTimeInMillis = calendar.getTimeInMillis();

                        if (hourOfDay > 12) {
                            hourOfDay = hourOfDay - 12;
                        }

                        Toast.makeText(MainActivity.this, hourOfDay + ":" + minute, Toast.LENGTH_SHORT).show();

                        Log.v(LOG_TAG, "Selected time in millis:" + selectedTimeInMillis);
                    }
                }, hour, minute, false);
                timePicker.show();
            }
        });

        imageButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                enteredName = name.getText().toString().trim();
                enteredNumber = number.getText().toString().trim();
                if (enteredNumber.isEmpty()){
                    Toast.makeText(MainActivity.this, "Please enter  a number", Toast.LENGTH_LONG).show();
                    return;
                }

                Intent intent = new Intent(MainActivity.this, AlarmReciever.class);
                intent.putExtra("FAKE_NAME", enteredName);
                intent.putExtra("FAKE_NUMBER", enteredNumber);

                PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), REQUEST_CODE_PI, intent, 0);

                AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
                if (alarmManager != null) {
                    alarmManager.set(AlarmManager.RTC_WAKEUP, selectedTimeInMillis, pendingIntent);
                    Toast.makeText(MainActivity.this, "Your call has been placed", Toast.LENGTH_SHORT).show();
                } else {
                    Toast.makeText(MainActivity.this, "Error: something wrong", Toast.LENGTH_SHORT).show();
                }
            }
        });
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.settings:
                Intent intent = new Intent(MainActivity.this, SettingsActivity.class);
                startActivity(intent);
                return true;

            case R.id.quick_call:
                quickCall();
                return true;

                default:
                return super.onOptionsItemSelected(item);
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (resultCode == RESULT_OK) {
            try {
                Uri imageUri = data.getData();
                InputStream imageStream = null;
                if (imageUri != null) {
                    imageStream = getContentResolver().openInputStream(imageUri);
                }
                Bitmap selectedImage = BitmapFactory.decodeStream(imageStream);
                imageView.setImageBitmap(selectedImage);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
                Toast.makeText(this, "Something went wrong", Toast.LENGTH_SHORT).show();
            }

        } else {
            Toast.makeText(this, "You haven't picked any Image", Toast.LENGTH_SHORT).show();
        }
    }

    public void quickCall(){

        Calendar calendar = Calendar.getInstance();
        calendar.get(Calendar.HOUR_OF_DAY);
        calendar.get(Calendar.MINUTE);
        long millis = calendar.getTimeInMillis();

        Intent quickCallIntent = new Intent(MainActivity.this, AlarmReciever.class);

        PendingIntent quickCallPendingIntent = PendingIntent.getBroadcast(getApplicationContext(), REQUEST_CODE_PI, quickCallIntent, 0);

        AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
        if (alarmManager != null) {
            alarmManager.set(AlarmManager.RTC_WAKEUP, millis + 10000, quickCallPendingIntent);
            Toast.makeText(MainActivity.this, "Your call has been placed", Toast.LENGTH_SHORT).show();
        } else {
            Toast.makeText(MainActivity.this, "Error: something wrong", Toast.LENGTH_SHORT).show();
        }
    }
}

This is the AlarmReciever class.

public class AlarmReciever extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        String getFakeName = intent.getStringExtra("FAKE_NAME");
        String getFakeNumber = intent.getStringExtra("FAKE_NUMBER");

        Intent fakeRinger = new Intent();
        fakeRinger.setClassName("com.example.mani.fakecall", "com.example.mani.fakecall.FakeRinger");
        fakeRinger.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        fakeRinger.putExtra("USER_FAKE_NAME", getFakeName);
        fakeRinger.putExtra("USER_FAKE_NUMBER", getFakeNumber);
        context.startActivity(fakeRinger);

        if(getFakeName != null){
            Log.v("Fake name is", getFakeName);
        }
        if(getFakeNumber != null){
            Log.v("Fake number is", getFakeNumber);
        }
    }
}

And this the FakeRinger activity from which I want to cancel the alarm.

public class FakeRinger extends AppCompatActivity {

    TextView displayName, displayNumber, displayCarrier;
    ImageButton alarmOffButton;
    String carrierName;
    ImageView displayImage;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_fake_ringer);

        displayName = findViewById(R.id.display_name);
        displayNumber = findViewById(R.id.display_number);
        displayCarrier = findViewById(R.id.network_operator);
        displayImage = findViewById(R.id.display_image);

        TelephonyManager telephonyManager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
        if (telephonyManager != null) {
            carrierName = telephonyManager.getNetworkOperatorName();
        }

        if (carrierName != null) {
            displayCarrier.setText(getResources().getString(R.string.incoming_call, carrierName));
        } else {
            displayCarrier.setText(getResources().getString(R.string.incoming_call));
        }

        Intent intent = getIntent();
        String userFakeNumber = intent.getExtras().getString("USER_FAKE_NUMBER");
        displayNumber.setText(userFakeNumber);

        displayName.setText(getFakeName());

        alarmOffButton = findViewById(R.id.hang_up_call);
        alarmOffButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(getApplicationContext(), AlarmReciever.class);
                PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 1001, intent, 0);
                AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
                if (alarmManager != null) {
                    alarmManager.cancel(pendingIntent);
                }
            }
        });
    }

    private String getFakeName(){
        String contacName = null;
        Intent intent = getIntent();
        contacName = intent.getExtras().getString("USER_FAKE_NAME");
        if (contacName.isEmpty()){
            contacName = "Unknown";
        }
        return contacName;
    }
}

The code I am using in the FakeRinger activity is not working. I don't know why.

mani
  • 39
  • 6
  • What exactly do you mean by "cancelling the alarm"? If I am reading your code right, you create a one-time alarm in MainActivity;at the proper time, that alarm fires AlarmReceiver which in turn starts the FakeRinger activity. From an Android system perspective, the alarm is done because it already delivered its intent to AlarmReceiver. Can you explain further what you are trying to accomplish? – Scott Kronheim Dec 20 '17 at 18:24
  • I want to stop that alarm from `FakeRinger` activity. – mani Dec 20 '17 at 18:27
  • If the alarm already ran the code in AlarmReceiver, there is nothing to cancel because the alarm is already done. Perhaps I can ask the question another way - what exactly do you mean by "The code I am using in the FakeRinger activity is not working"? Do you get an error? Does certain behavior occur that should not be happening? – Scott Kronheim Dec 20 '17 at 18:33
  • I have a button in the `FakeRinger` activity i.e `alarmOffbutton`. Inside the `OnClickListener` I am using the code to stop the alarm. But unfortunately, the alarm is not stopping by clicking on that button. – mani Dec 20 '17 at 18:39
  • What exactly do you mean by "the alarm is not stopping"? What is continuing to happen that should be stopped? – Scott Kronheim Dec 20 '17 at 18:42
  • I want to cancel the alarm – mani Dec 20 '17 at 18:44

1 Answers1

0

The quick and dirty way would be to use static calls:

class MainActivity extends AppCompatActivity{
static MainActivity instance;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    instance = this;
}

public static MainActivity getInstance() {
    return instance;
}
....
 public void cancelAlarm(){
 if (alarmManager != null) {
                    alarmManager.cancel(pendingIntent);
                }
}

and in class FakeAlarm:

class FakeAlarm extends AppCompatActivity{
  public void  clearData(){
      MainActivity a = MainActivity.getInstance();
      a.clear();
    }
}

The long way:

Why not change your MainActivity from AppCompatActivity to a FragmentActivity and create FakeRinger as a Fragment. That way you can share components and methods between the parent FragmentActivity and the child Fragments much more easily. Having two separate "Parents" (Activities) creates more problems/hurdles when trying to share methods/data.

So for instance, you could have this once in your MainActivity (FragmentActivity):

 AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);

Then have a method that cancels the alarm in MainActivity:

public void cancelAlarm(){
 if (alarmManager != null) {
                    alarmManager.cancel(pendingIntent);
                }
}

Then call the method in another fragment (FakeAlarm) if you'd like:

((MainActivity)getActivity()).cancelAlarm();

Pass object data between fragments and activity in android

Passing Object from Fragment to Activity

Passing an Object from an Activity to a Fragment

Petro
  • 3,484
  • 3
  • 32
  • 59