onReceive(); method executes before time I set - java

I trying to set an alarm with date and time. Everything is fine, but after I set the alarm, the notification that I want it appears before the time (in minute) that I set before.
* ViewNote.java:
private DatePicker datePicker;
private TimePicker timePicker;
private Calendar dateTime;
private final static int REMINDER_RQS_CODE = 1;
...
...
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_view_note, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId())
{
case R.id.set_reminder:
datePicker = (DatePicker) findViewById(R.id.datePicker);
timePicker = (TimePicker) findViewById(R.id.timePicker);
Calendar now = Calendar.getInstance();
if(datePicker != null)
{
datePicker.init(Calendar.YEAR,
Calendar.MONTH,
Calendar.DAY_OF_MONTH,
null);
}
if(timePicker != null)
{
timePicker.setCurrentHour(now.get(Calendar.HOUR_OF_DAY));
timePicker.setCurrentMinute(now.get(Calendar.MINUTE));
}
AlertDialog.Builder setDateDialog = new AlertDialog.Builder(this)
.setView(R.layout.date_picker_dialog)
.setTitle("Pick date")
.setIcon(R.drawable.context_menu)
.setPositiveButton("Next", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
dateTime = Calendar.getInstance();
if(datePicker != null)
{
dateTime.set(datePicker.getYear(),
datePicker.getMonth(),
datePicker.getDayOfMonth());
}
AlertDialog.Builder setTimeDialog = new AlertDialog.Builder(ViewNote.this)
.setView(R.layout.time_picker_dialog)
.setTitle("Pick time")
.setIcon(R.drawable.context_menu)
.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
dateTime = Calendar.getInstance();
if(timePicker != null)
{
dateTime.set(timePicker.getCurrentHour(),
timePicker.getCurrentMinute(),
00);
}
setReminder(dateTime);
}
});
setTimeDialog.show();
}
});
setDateDialog.show();
return true;
}
return super.onOptionsItemSelected(item);
}
private void setReminder(Calendar dateTime)
{
Intent intent = new Intent(ViewNote.this, RemainderReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(ViewNote.this, REMINDER_RQS_CODE, intent, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP, dateTime.getTimeInMillis(), pendingIntent);
}
* date_picker_dialog.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<DatePicker
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/datePicker"
android:layout_gravity="center_horizontal" />
</LinearLayout>
* time_picker_dialog.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TimePicker
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/timePicker"
android:layout_gravity="center_horizontal" />
</LinearLayout>
* ReminderReceiver.java:
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
public class RemainderReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
/*Intent intent1 = new Intent(context, MyReminderService.class);
context.startService(intent1);*/
Log.i("ReminderReceiver", "onReceive method called");
try
{
Utils.generateNotification(context);
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
* MyReminderService.java:
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.support.annotation.Nullable;
public class MyReminderService extends Service {
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
}
#Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
}
#Override
public void onDestroy() {
super.onDestroy();
}
}
* AndroidManifest.xml:
...
...
<uses-permission android:name="android.permission.WAKE_LOCK" />
...
...
<service android:name=".MyReminderService"
android:enabled="true" />
<receiver android:name=".RemainderReceiver"/>
</application>
</manifest>

To me it seems you call the wrong method of Calendar in onClick of the "PositiveButton". There you call:
dateTime.set(
timePicker.getCurrentHour(),
timePicker.getCurrentMinute(),
00);
It does not set the hour, minute and millisecond. Instead this method of java.util.Calendar is called which results in a nonsense value:
public final void set(int year,
int month,
int date)
See here: https://docs.oracle.com/javase/7/docs/api/java/util/Calendar.html#set%28int,%20int,%20int%29
You can fix this by converting the time of the TimePicker into milliseconds and add that to the time of "dateTime" like below.
dateTime = Calendar.getInstance();
if(timePicker != null)
{
dateTime.setTimeInMillis(
dateTime.getTimeInMillis()
+ (timePicker.getCurrentHour() * 360000)
+ (timePicker.getCurrentMinute() * 60000));
}
setReminder(dateTime);
Of course 1 hour is 60 minutes which are 360 seconds which are 360000 milliseconds, and 1 minute is 60 seconds which are 60000 milliseconds.

Related

Range seekbar to trim audio

I'm trying to incorporate somehow into Android audio player, functionality of marking of the fragment of the song in the player that it is supposed to play. I see this like clipping of the fragment as in Audacity. I'm trying to get it with a range seekbar (two blue dots on a line that can be adjust) on which user mark the beginning and the end to play and when replay mode is enabled the player will play that marked section over and over again.
This player looks like this
The application is written in the Java language.
Below are the related code.
Dependency
implementation 'com.yahoo.mobile.client.android.util.rangeseekbar:rangeseekbar-
library:0.1.0'
PlayerActivity.java
package com.example.marcin.playerexperiment;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.database.Cursor;
import android.media.AudioAttributes;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Handler;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import com.yahoo.mobile.client.android.util.rangeseekbar.RangeSeekBar;
import android.widget.Button;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;
import java.io.IOException;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class PlayerActivity extends AppCompatActivity {
RangeSeekBar<Integer> mRangeSeekBar;
MediaPlayer mMediaPlayer;
Button playButton, openButton, replayButton;
int max;
SeekBar mSeekBar;
public static final int PICK_FILE =99;
ScheduledExecutorService timer;
TextView title, elapse, mEndTextView;
String duration;
Boolean isRepeat = false;
Runnable mRunnable;
Handler mHandler;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_player);
//otwórz
openButton = findViewById(R.id.open);
//powtórz
replayButton = findViewById(R.id.replayButton);
//range seekbar
mRangeSeekBar = findViewById(R.id.rangeSeekBar);
//seekbar - linia dzwięku
mSeekBar = findViewById(R.id.seekBar);
//mRangeSeekBar.setNotifyWhileDragging(true);
title = (TextView) findViewById(R.id.title);
elapse = (TextView) findViewById(R.id.elapse);
playButton = findViewById(R.id.play);
// mEndTextView = findViewById(R.id.end_duration);
mHandler = new Handler();
//Odtwórz |>
playButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(mMediaPlayer != null){
if(mMediaPlayer.isPlaying()){
mMediaPlayer.pause();
playButton.setText("ODTWÓRZ");
timer.shutdown();
}else{
mMediaPlayer.start();
playButton.setText("PAUZA");
timer = Executors.newScheduledThreadPool(1);
timer.scheduleAtFixedRate(new Runnable() {
#Override
public void run() {
// playProgress ();
if (mMediaPlayer != null) {
if (!mSeekBar.isPressed()) {
mSeekBar.setProgress(mMediaPlayer.getCurrentPosition());
}
}
}
},10,10, TimeUnit.MILLISECONDS);
}
}
}
});
//otwieranie pliku dzwiękowego
openButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("audio/*");
startActivityForResult(intent, PICK_FILE);
}
});
mRangeSeekBar.setOnRangeSeekBarChangeListener(new RangeSeekBar.OnRangeSeekBarChangeListener<Integer>() {
#Override
public void onRangeSeekBarValuesChanged(RangeSeekBar<?> bar, Integer minValue, Integer maxValue) {
mMediaPlayer.seekTo(minValue);
max = maxValue;
String infoMax = String.valueOf(max);
Log.i("MAX", infoMax);
}
});
mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
if (mMediaPlayer != null){
int millis = mMediaPlayer.getCurrentPosition();
long total_secs = TimeUnit.SECONDS.convert(millis, TimeUnit.MILLISECONDS);
long mins = TimeUnit.MINUTES.convert(total_secs, TimeUnit.SECONDS);
long secs = total_secs - (mins*60);
elapse.setText(mins + ":" + secs + " / " + duration);
//Log.i("Duration:", duration);
}
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
if (mMediaPlayer != null) {
mMediaPlayer.seekTo(seekBar.getProgress());
}
}
});
//Loop
replayButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//repeat = false
if(isRepeat){
isRepeat = false;
mMediaPlayer.setLooping(false);
replayButton.setText("Powtórka wyłączona");
Toast.makeText(PlayerActivity.this, "Tryb powtórki jest wyłączony", Toast.LENGTH_SHORT).show();
}else{
isRepeat = true;
mMediaPlayer.setLooping(true);
replayButton.setText("Powtórka włączona");
Toast.makeText(PlayerActivity.this, "Tryb powtórki jest włączony", Toast.LENGTH_SHORT).show();
}
//mediaPlayer.setLooping(true);
// Toast.makeText(PlayerActivity.this, "Repeat if ON", Toast.LENGTH_SHORT).show();
}
});
playButton.setEnabled(false);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PICK_FILE && resultCode == RESULT_OK){
if (data != null){
Uri uri = data.getData();
createMediaPlayer(uri);
}
}
}
public void createMediaPlayer(Uri uri){
mMediaPlayer = new MediaPlayer();
mMediaPlayer.setAudioAttributes(
new AudioAttributes.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
.setUsage(AudioAttributes.USAGE_MEDIA)
.build()
);
try {
mMediaPlayer.setDataSource(getApplicationContext(), uri);
mMediaPlayer.prepare();
title.setText(getNameFromUri(uri));
playButton.setEnabled(true);
mRangeSeekBar.setNotifyWhileDragging(true);
mRangeSeekBar.setRangeValues(0, mMediaPlayer.getDuration());
max = mMediaPlayer.getDuration();
mSeekBar.setMax(max);
mSeekBar.setProgress(0);
long total_secs = TimeUnit.SECONDS.convert(max, TimeUnit.MILLISECONDS);
long mins = TimeUnit.MINUTES.convert(total_secs, TimeUnit.SECONDS);
long secs = total_secs - (mins*60);
duration = mins + ":" + secs;
elapse.setText("00:00 / " + duration);
mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
releaseMediaPlayer();
}
});
} catch (IOException e){
title.setText(e.toString());
}
}
#SuppressLint("Range")
public String getNameFromUri(Uri uri){
String fileName = "";
Cursor cursor = null;
cursor = getContentResolver().query(uri, new String[]{
MediaStore.Images.ImageColumns.DISPLAY_NAME
}, null, null, null);
if (cursor != null && cursor.moveToFirst()) {
fileName = cursor.getString(cursor.getColumnIndex(MediaStore.Images.ImageColumns.DISPLAY_NAME));
}
if (cursor != null) {
cursor.close();
}
return fileName;
}
private void playProgress () {
if (mMediaPlayer.getCurrentPosition() == max) {
mMediaPlayer.stop();
}
if (mMediaPlayer.isPlaying()) {
mRunnable = new Runnable() {
#Override
public void run() {
playProgress();
}
};
mHandler.postDelayed(mRunnable, 0);
}
}
#Override
protected void onDestroy() {
super.onDestroy();
releaseMediaPlayer();
}
public void releaseMediaPlayer(){
if (timer != null) {
timer.shutdown();
}
if (mMediaPlayer != null) {
mMediaPlayer.release();
mMediaPlayer = null;
}
playButton.setEnabled(false);
elapse.setText("TYTUL");
elapse.setText("00:00 / 00:00");
mSeekBar.setMax(100);
mSeekBar.setProgress(0);
}
}
Activity_player.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context=".PlayerActivity">
<Button
android:id="#+id/play"
android:layout_width="wrap_content"
android:layout_height="37dp"
android:layout_marginStart="150dp"
android:layout_marginEnd="173dp"
android:text="Play"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/seekBar" />
<com.yahoo.mobile.client.android.util.rangeseekbar.RangeSeekBar
android:id="#+id/rangeSeekBar"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="357dp"
android:layout_marginBottom="20dp"
app:layout_constraintBottom_toTopOf="#+id/seekBar"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/elapse"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="287dp"
android:layout_marginBottom="51dp"
android:text="00-00"
app:layout_constraintBottom_toTopOf="#+id/rangeSeekBar"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.461"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="1.0" />
<SeekBar
android:id="#+id/seekBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/rangeSeekBar" />
<androidx.constraintlayout.widget.Barrier
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="top"
tools:layout_editor_absoluteX="92dp"
tools:layout_editor_absoluteY="357dp" />
<Button
android:id="#+id/open"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="154dp"
android:layout_marginEnd="163dp"
android:layout_marginBottom="140dp"
android:backgroundTint="#color/teal_200"
android:text="Open file"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/play" />
<TextView
android:id="#+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="173dp"
android:layout_marginEnd="202dp"
app:layout_constraintBottom_toTopOf="#+id/elapse"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.824" />
<Button
android:id="#+id/replayButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="150dp"
android:layout_marginEnd="142dp"
android:backgroundTint="#color/purple_500"
android:text="Replay"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/open" />
</androidx.constraintlayout.widget.ConstraintLayout>

Countdown timer which runs in the background in android

Here is my fully functional code in which when I press the button, the button gets disabled and the countdown timer gets started and whenever it gets over button gets enabled. My problem is that if I leave that activity the process resets.
My question is how that can be done in the background so even if I close the application the timer runs in the background?
package com.mycompany.myapp;
import android.app.*;
import android.os.*;
import android.widget.*;
import android.view.View.*;
import android.view.*;
public class MainActivity extends Activity {
Button btnCountdown;
TextView tvCountdown;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btnCountdown = findViewById(R.id.btnCountdown);
tvCountdown = findViewById(R.id.tvCountdown);
btnCountdown.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Timer();
btnCountdown.setEnabled(false);
}
});
}
private void Timer() {
new CountDownTimer(30*1000,1000) {
#Override
public void onTick(long millisUntilFinished) {
long second = (millisUntilFinished / 1000) % 60;
long minutes = (millisUntilFinished / (1000*60)) % 60;
tvCountdown.setText(minutes + ":" + second);
}
#Override
public void onFinish() {
tvCountdown.setText("Fin");
btnCountdown.setEnabled(true);
}
}.start();
}
}
Add to your AndroidManifest.xml
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
BroadcastReceiver.java
public class BroadcastReceiver extends AppCompatActivity {
TextView tvTimer, tvTimerRunningState, tvTimerFinishedState;
private static final String TAG = "CountdownTimer";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_broadcast_receiver);
}
public void handleStartTimer(View view) {
Intent intent = new Intent(this, BroadcastService.class);
intent.putExtra("inputExtra", "");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
ContextCompat.startForegroundService(this, intent);
} else {
this.startService(intent);
}
Log.i(TAG, "timerStarted");
}
public void handleCancelTimer (View view) {
Intent intent = new Intent(this, BroadcastService.class);
stopService(intent);
}
/* CountDown */
final private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
updateGUI(intent);
}
};
#Override
public void onResume() {
super.onResume();
registerReceiver(broadcastReceiver, new IntentFilter(BroadcastService.COUNTDOWN_BR));
Log.i(TAG, "Registered broadcast receiver");
}
#Override
public void onPause() {
super.onPause();
unregisterReceiver(broadcastReceiver);
Log.i(TAG, "Unregistered broadcast receiver");
}
#Override
public void onStop() {
try {
unregisterReceiver(broadcastReceiver);
} catch (Exception e) {
// Receiver was probably already stopped in onPause()
}
super.onStop();
}
private void updateGUI(Intent intent) {
if (intent.getExtras() != null) {
long millisUntilFinished = intent.getLongExtra("countdown", 0);
long seconds = (millisUntilFinished / 1000) % 60;
long minutes = (millisUntilFinished / (1000*60)) % 60;
long hours = (millisUntilFinished / (1000*60*60)) % 60;
String time = (hours + " : " + minutes + " : " + seconds);
tvTimer = findViewById(R.id.tvTimer);
tvTimer.setText(time);
boolean countdownTimerRunning = intent.getBooleanExtra("countdownTimerRunning", false);
tvTimerRunningState = findViewById(R.id.tvTimerRunningState);
if (countdownTimerRunning) {
tvTimerRunningState.setText("CountdownTimerRunning");
} else {
tvTimer.setText("0 : 0 : 0");
tvTimerRunningState.setText("CountdownTimerNotRunning");
}
boolean countdownTimerFinished = intent.getBooleanExtra("countdownTimerFinished", false);
tvTimerFinishedState = findViewById(R.id.tvTimerFinishedState);
if (countdownTimerFinished) {
tvTimerFinishedState.setText("Finished");
} else {
tvTimerFinishedState.setText("Unfinished");
}
}
}
activity_broadcast_receiver.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<Button
android:id="#+id/btnStartJob"
android:onClick="handleStartTimer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Start Timer" />
<Button
android:id="#+id/btnStopJob"
android:onClick="handleCancelTimer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Cancel Timer" />
<TextView
android:id="#+id/tvTimer"
android:text="0 : 0 : 0"
android:gravity="center"
android:textSize="30sp"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/tvTimerFinishedState"
android:gravity="center"
android:textSize="20sp"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/tvTimerRunningState"
android:gravity="center"
android:textSize="18sp"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
BroadcastService.java
public class BroadcastService extends Service {
public static final String CHANNEL_ID = "ForegroundServiceChannel";
private final static String TAG = "BroadcastService";
public static final String COUNTDOWN_BR = "your.package.name";
Intent bi = new Intent(COUNTDOWN_BR);
CountDownTimer cdt = null;
#Override
public void onCreate() {
super.onCreate();
Log.i(TAG, "Starting timer...");
cdt = new CountDownTimer(30000, 1000) {
#Override
public void onTick(long millisUntilFinished) {
Log.i(TAG, "Countdown seconds remaining: " + millisUntilFinished / 1000);
bi.putExtra("countdown", millisUntilFinished);
bi.putExtra("countdownTimerRunning", true);
bi.putExtra("countdownTimerFinished", false);
sendBroadcast(bi);
}
#Override
public void onFinish() {
Log.i(TAG, "Timer finished");
bi.putExtra("countdownTimerFinished", true);
sendBroadcast(bi);
stopForeground(true);
stopSelf();
}
}; cdt.start();
}
#Override
public void onDestroy() {
cdt.cancel();
Log.i(TAG, "Timer cancelled");
bi.putExtra("countdownTimerRunning", false);
sendBroadcast(bi);
super.onDestroy();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
/* Notification */
String input = intent.getStringExtra("inputExtra");
createNotificationChannel();
Intent notificationIntent = new Intent(this, BroadcastReceiver.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this,
0, notificationIntent, 0);
/* NotificationBuilder */
Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle("Foreground Service")
.setContentText(input)
.setSmallIcon(R.drawable.ic_launcher_background)
.setContentIntent(pendingIntent)
.build();
startForeground(1, notification);
return START_NOT_STICKY;
}
#Nullable
#Override
public IBinder onBind(Intent arg0) {
return null;
}
private void createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel serviceChannel = new NotificationChannel(
CHANNEL_ID,
"Foreground Service Channel",
NotificationManager.IMPORTANCE_DEFAULT
);
NotificationManager manager = getSystemService(NotificationManager.class);
manager.createNotificationChannel(serviceChannel);
}
}

No message shows up - Notification

I am trying to set a Alarm. The user selects a time with the time picker and when time comes a Notification shows up. This works perfectly. But the problem is, the User Input the name of the alarm the user wrote doesn't show up. I do NOT get a error message!
https://prnt.sc/mfs5hx
https://prnt.sc/mfs5w2
NotificationHelper.java:
public NotificationCompat.Builder getChannelNotification() {
LayoutInflater inflater = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View frAl = inflater.inflate(R.layout.fragment_alarm, null);
titelAlarm = frAl.findViewById(R.id.eingUserAlarm);
String nameAlarm = titelAlarm.getText().toString();
return new NotificationCompat.Builder(getApplicationContext(), channelID)
.setContentTitle("Erinnerung")
.setContentText(nameAlarm)
.setSmallIcon(R.drawable.ic_one);
}
The EditText where the user can name the Alarm is inside a Fragment which can be accessed by a Navigation Drawer.
<EditText
android:id="#+id/eingUserAlarm"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="180dp"
android:hint="Was wirst du machen?" />
Also the code for the Alarm is inside my Fragment.java.
Fragment.java:
Button buttonTimePicker = fraAla.findViewById(R.id.button_timepicker);
buttonTimePicker.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
DialogFragment timePicker = new AlarmTimePicker();
timePicker.show(getChildFragmentManager(), "time picker");
}
});
Button buttonCancelAlarm = fraAla.findViewById(R.id.button_cancel);
buttonCancelAlarm.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
cancelAlarm();
}
});
return fraAla;
}
#Override
public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
Calendar c = Calendar.getInstance();
c.set(Calendar.HOUR_OF_DAY, hourOfDay);
c.set(Calendar.MINUTE, minute);
c.set(Calendar.SECOND, 0);
updateTimeText(c);
startAlarm(c);
}
private void updateTimeText(Calendar c) {
String timeText = "Wir erinnern dich um ";
timeText += DateFormat.getTimeInstance(DateFormat.SHORT).format(c.getTime());
mTextView.setText(timeText);
}
private void startAlarm(Calendar c) {
AlarmManager alarmManager = (AlarmManager) getContext().getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(getActivity(), AlertReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(getActivity(), 1, intent, 0);
if (c.before(Calendar.getInstance())) {
c.add(Calendar.DATE, 1);
}
alarmManager.setExact(AlarmManager.RTC_WAKEUP, c.getTimeInMillis(), pendingIntent);
}
private void cancelAlarm() {
AlarmManager alarmManager = (AlarmManager) getContext().getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(getActivity(), AlertReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(getActivity(), 1, intent, 0);
alarmManager.cancel(pendingIntent);
mTextView.setText("Wir werden nicht stören!");
}

CountdownTimer Service restarting when activity screen is re-opened

I'm trying to make a countdown timer screen on Android that will continue to count down if you back out of the app or go to different screens in the app or whatever. I'm running it as a Service but I'm still getting the problem of it starting over when I re-open the activity. Any help would be great. Here's my code.
Service Class
import android.app.Service;
import android.content.Intent;
import android.os.CountDownTimer;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.support.v4.content.LocalBroadcastManager;
public class CountdownService extends Service{
public static final String
ACTION_LOCATION_BROADCAST = CountdownService.class.getName() + "LocationBroadcast";
#Override
public void onCreate() {
super.onCreate();
new CountDownTimer(360000, 60000) {
public void onTick(long millisUntilFinished) {
int timeLeftInt = (int) Math.ceil((double) millisUntilFinished / 60000); //Whole number of minutes left, ceiling
sendBroadcastMessage(timeLeftInt);
if(timeLeftInt == 5){
Notify("Not Done");
}
}
public void onFinish() {
sendBroadcastMessage(0);
Notify("done");
}
}.start();
}
private void sendBroadcastMessage(int timeSent) {
Intent intent = new Intent(ACTION_LOCATION_BROADCAST);
intent.putExtra("timeSent", timeSent);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
private void Notify(String doneness){
NotificationManager notificationManager = (NotificationManager)
getSystemService(NOTIFICATION_SERVICE);
Intent intent = new Intent(this, Map.class);
PendingIntent pIntent = PendingIntent.getActivity(this, (int) System.currentTimeMillis(), intent, 0);
if(doneness.equals("done")) {
Notification n = new Notification.Builder(this)
.setContentTitle("Time to leave!")
.setContentText("Your PrePark spot has expired, time to go home!")
.setSmallIcon(R.mipmap.ic_launcher)
.setContentIntent(pIntent)
.setAutoCancel(true)
.build();
notificationManager.notify(0, n);
}
else{
Notification n = new Notification.Builder(this)
.setContentTitle("Ya got 5 minutes left in your PrePark spot!")
.setContentText("Better get going soon here")
.setSmallIcon(R.mipmap.ic_launcher)
.setContentIntent(pIntent)
.setAutoCancel(true)
.build();
notificationManager.notify(0, n);
}
}
Main Activity
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.support.v4.content.LocalBroadcastManager;
import android.os.Bundle;
import android.widget.TextView;
public class Countdown extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_countdown);
LocalBroadcastManager.getInstance(this).registerReceiver(
new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
TextView textView= findViewById(R.id.t1);
int timeLeft = intent.getIntExtra("timeSent", 0);
if(timeLeft>0) {
textView.setText("You have " + timeLeft + " minutes left");
}
else{
textView.setText("Y'all outta time, see ya again soon!");
}
}
}, new IntentFilter(CountdownService.ACTION_LOCATION_BROADCAST)
);
}
#Override
protected void onResume() {
super.onResume();
startService(new Intent(this, CountdownService.class));
}
#Override
protected void onPause() {
super.onPause();
stopService(new Intent(this, CountdownService.class));
}
}
XML for main activity
<RelativeLayout android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:android="http://schemas.android.com/apk/res/android"
android:gravity="center">
<TextView
android:id="#+id/t1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:layout_centerInParent="true"
android:textSize="32sp"
/>
</RelativeLayout>
Probably this happens because you're starting countdown service in onResume() and you're stopping the service in onPause()
And also in the onCreate() method of your service you're creating new instance from countdown timer.

SMS scheduling not sending sms

i am trying to send Message at a scheduled time in my app
here is my activty
public class Lenditem extends Activity {
Context mContext;
private int mHour;
private int mMin;
private int mYear;
private int mMonth;
private int mDay;
Button b1, b2, b3;
EditText et1, et2,et3;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
//Full screen code
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.lenditem);
b1 = (Button)findViewById(R.id.bselectcontactlenditem);
b3 = (Button)findViewById(R.id.bcancellenditem);
et1 = (EditText)findViewById(R.id.etdesclenditem);
et2 = (EditText)findViewById(R.id.etamountlenditem);
et3 = (EditText)findViewById(R.id.lietentercontact);
Button dateSet=(Button) findViewById(R.id.limyDatePickerButton);
Button timeSet=(Button) findViewById(R.id.limyTimePickerButton);
b3.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View arg0) {
boolean diditWork = true;
try {
String Desc1 = et1.getText().toString();
String Amt1 = et2.getText().toString();
Databaselentitem entry = new Databaselentitem(Lenditem.this);
entry.open();
entry.createEntry1(Desc1, Amt1);
entry.close();
} catch (Exception e) {
diditWork = false;
Toast.makeText(getApplicationContext(), "Something's Wrong.!!", Toast.LENGTH_LONG).show();
} finally {
if (diditWork) {
Toast.makeText(getApplicationContext(), "Reminder saved successfully.!!", Toast.LENGTH_LONG).show();
}
}
}
});
b1.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
// user BoD suggests using Intent.ACTION_PICK instead of
// .ACTION_GET_CONTENT to avoid the chooser
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
// BoD con't: CONTENT_TYPE instead of CONTENT_ITEM_TYPE
intent.setType(ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE);
startActivityForResult(intent, 1);
}
});
dateSet.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
Intent localIntent1 = new Intent();
localIntent1.setClass(Lenditem.this.mContext, TimePickerActivity.class);
Lenditem.this.startActivityForResult(localIntent1, 0);
return;
/* DatePickerDialog.OnDateSetListener d=new DatePickerDialog.OnDateSetListener() {
#Override
public void onDateSet(DatePicker view, int year, int monthofyear, int dayofmonth) {
// TODO Auto-generated method stub
// Use the current date as the default date in the picker
final Calendar c = Calendar.getInstance();
int mYear = c.get(Calendar.YEAR);
int mMonth = c.get(Calendar.MONTH);
int mDay = c.get(Calendar.DAY_OF_MONTH);
mMonth=monthofyear;
mYear=year;
mDay=dayofmonth;
Toast.makeText(getBaseContext(), "Date Set is :"+mDay+"/"+(mMonth+1)+"/"+mYear, Toast.LENGTH_SHORT).show();
}
};
// TODO Auto-generated method stub
new DatePickerDialog(Lenditem.this,d,Calendar.YEAR,Calendar.MONTH,Calendar.DAY_OF_MONTH).show();
*/ }
});
timeSet.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
TimePickerDialog.OnTimeSetListener t = new TimePickerDialog.OnTimeSetListener() {
#Override
public void onTimeSet(TimePicker view2, int hour, int min) {
// TODO Auto-generated method stub
mHour = hour;
mMin = min;
if (mHour >= 12)
mHour = mHour - 12;
Log.d("MYAPP", "hh:" + mHour + "\nmm:" + mMin);
Toast.makeText(getBaseContext(),
"Time Set is:" + mHour + ":" + mMin + ":00",
Toast.LENGTH_SHORT).show();
}
};
Calendar cal = Calendar.getInstance();
new TimePickerDialog(Lenditem.this, t, cal
.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE),
true).show();
}
});
Button saveAndClearBtn = (Button) findViewById(R.id.bSubmitlenditem);
saveAndClearBtn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
Calendar myCal = Calendar.getInstance();
long timeToTrigger;
myCal.set(Calendar.YEAR, mYear);
myCal.set(Calendar.MONTH, mMonth);
myCal.set(Calendar.DAY_OF_MONTH, mDay);
myCal.set(Calendar.HOUR, mHour);
myCal.set(Calendar.MINUTE, mMin);
myCal.set(Calendar.SECOND, 0);
long setTime = myCal.getTimeInMillis();
if (setTime > System.currentTimeMillis()) {
timeToTrigger = setTime - System.currentTimeMillis();
EditText edt1 = (EditText) findViewById(R.id.bselectcontactlenditem);
EditText edt2 = (EditText) findViewById(R.id.litxtMessage);
String msg = edt2.getText().toString();
String telno = edt1.getText().toString();
int count = 0;
SQLiteDatabase db = openOrCreateDatabase("MYDBli",
MODE_PRIVATE, null);
db.execSQL("CREATE TABLE IF NOT EXISTS mySmsSchedulerli(SlNo VARCHAR,Number VARCHAR,Msg VARCHAR);");
String s = "INSERT INTO mySmsSchedulerli VALUES ('" + count
+ "','" + telno + "','" + msg + "');";
db.execSQL(s);
Log.d("MYREC", "Insertion of data successfull");
db.close();
edt1.setText("");
edt2.setText("");
Intent intent = new Intent();
intent.setClass(Lenditem.this, MyBroadcastRecieverli.class);
Bundle b = new Bundle();
b.putString("index", Integer.toString(count));
intent.putExtras(b);
PendingIntent pendingIntent = PendingIntent.getBroadcast(
Lenditem.this, (int) Math.random(), intent, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP,
System.currentTimeMillis() + timeToTrigger,
pendingIntent);
count++;
Toast.makeText(
getBaseContext(),
"Sms Scheduled after:" + (timeToTrigger / (1000*60*60))+" Hours "+(timeToTrigger/(1000*60))+" Minutes "
+(timeToTrigger/1000)+ " sec.", Toast.LENGTH_SHORT).show();
Log.d("MYAPP", "Set Time:" + (setTime / 1000) + "Sec. \n"
+ "Cur time:" + System.currentTimeMillis() / 1000);
Log.d("MYAPP", "Time to trigger:" + (timeToTrigger / 1000)
+ "sec.");
} else {
Toast.makeText(getBaseContext(),
"Please Enter a valid time", Toast.LENGTH_SHORT)
.show();
Calendar calendar = Calendar.getInstance();
int h = calendar.get(Calendar.HOUR);
int m = calendar.get(Calendar.MINUTE);
Log.d("MYAPP", "cur HH:" + h + "\ncur MM:" + m);
}
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (data != null) {
Uri uri = data.getData();
if (uri != null) {
Cursor c = null;
try {
c = getContentResolver().query(uri, new String[]{
ContactsContract.CommonDataKinds.Phone.NUMBER,
ContactsContract.CommonDataKinds.Phone.TYPE },
null, null, null);
if (c != null && c.moveToFirst()) {
String number = c.getString(0);
int type = c.getInt(1);
showSelectedNumber(type, number);
}
} finally {
if (c != null) {
c.close();
}
}
}
}
}
public void showSelectedNumber(int type, String number) {
et3.setText(number);
}
}
this is broadcast class
public class MyBroadcastRecieverli extends BroadcastReceiver {
#Override
public void onReceive(Context arg0, Intent intent) {
// TODO Auto-generated method stub
int myCount;
String cnt=intent.getStringExtra("index");
if(cnt==null)
Log.d("MYAPP","Data not received");
Log.d("MYAPP", "Count:"+cnt);
myCount=Integer.parseInt(cnt);
Log.d("MYAPP","Broadcast receiver called...");
SQLiteDatabase db=arg0.openOrCreateDatabase("MYDB",Context.MODE_PRIVATE, null);
Cursor c=db.rawQuery("SELECT Number, Msg FROM mySmsSchedulerli WHERE SlNo=="+myCount, null);
Log.d("MYAPP", "Cursor reference obtained...");
if(c!=null)
{
c.moveToFirst();
}
else
Log.d("MYAPP", "cursor is null");
/* c.moveToFirst();*/
String num=c.getString(c.getColumnIndex("Number"));
String myMsg=c.getString(c.getColumnIndex("Msg"));
Log.d("MYAPP", "number:"+num+"\nMsg:"+myMsg);
SmsManager sm = SmsManager.getDefault();
sm.sendTextMessage(num, null, myMsg, null, null);
Log.d("MYAPP", "Message Sent");
Toast.makeText(arg0, "Msg sent successfully", Toast.LENGTH_LONG).show();
String table="mySmsSchedulerli";
String whereClause = "SlNo = ?";
String[] whereArgs = new String[] { Integer.toString(Sms.count) };
db.delete(table, whereClause, whereArgs);
db.close();
Log.d("MYAPP", "Entry deleted..");
}
}
it is showing the toast that your msg will be send after xxxx seconds but not sending msg at scheduled time.
can anybody help me plzzz
Try to use Broadcast Receive first and then start a service.
Something like that:
create a function:
public static void setRecurringAlarm(Context context, Class<?> cls, int time, int minute) {
Calendar updateTime = Calendar.getInstance();
updateTime.setTimeZone(TimeZone.getDefault());
updateTime.set(Calendar.HOUR_OF_DAY, time);
updateTime.set(Calendar.MINUTE, minute);
Intent alarm = new Intent(context, cls);
PendingIntent recurringAlarm = PendingIntent.getBroadcast(context, 654789, alarm, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager alarms = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
alarms.setRepeating(AlarmManager.RTC_WAKEUP, updateTime.getTimeInMillis(), AlarmManager.INTERVAL_DAY, recurringAlarm);
}
If you don't want to set a recurring alarm, just change setRepeating to set.
In your code, you need to call:
// to start the receiver at 9:00am
setRecurringAlarm(this, AlarmManagerReceiver.class, 9, 0);
So, you need to create the AlarmManagerReceiver.java:
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class AlarmManagerReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent alarmService = new Intent(context, AlarmManagerService.class);
context.startService(alarmService);
}
}
And now, you need the service:
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.IBinder;
import android.preference.PreferenceManager;
public class AlarmManagerService extends Service {
private Context context;
#Override
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
context = this.getApplicationContext();
}
#Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
// Do what you need to do.
stopSelf();
}
}
In manifest:
<receiver android:name=".AlarmManagerReceiver" >
<intent-filter>
<action android:name=".AlarmManagerReceiver" />
</intent-filter>
</receiver>
<service
android:name=".AlarmManagerService"
android:enabled="true" >
<intent-filter>
<action android:name=".AlarmManagerService" />
</intent-filter>
</service>

Categories