Broadcast Receiver issue, Wakeful Broadcast Receiver - java

I'm using wakeful broadcast receiver with alarm manager in my app to performing some tasks at a specific time.
its working well. But I'm facing a minor problem
for example I set my alarm manager at 9:00 PM after that if I remove my app from recent app it's definitely working in background, But after that specific time (9:00 PM) whenever I'm using my app my alarm trigger immediately.
I hope everyone (relating this problem) understand my point.
If anyone knows about this problem tell me.
Thanks.
Here I'm registering my receiver
<receiver
android:name="com.example.chartdemo.MyBroadcastReceiver"
android:enabled="true"
android:exported="true">
</receiver>
Here's my MainActivity.java code
public class MainActivity extends AppCompatActivity {
public static TextView textView,textView1;
Button button, button1,button2,button3;
public static int counter=0, time;
MyBroadcastReceiver myBroadcastReceiver;
myDbAdapter helper;
//private final MyDateChangeReceiver mDateReceiver = new MyDateChangeReceiver();
#RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView=findViewById(R.id.text);
textView1=findViewById(R.id.text1);
button=findViewById(R.id.counterbtn);
button1=findViewById(R.id.showbtn);
button2=findViewById(R.id.savebtn);
button3=findViewById(R.id.delbtn);
helper = new myDbAdapter(this);
loadData(); //for data retrieving from shared preferences
startAlarm(this);
}
private void startAlarm(Context context) {
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, 9);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
cal.set(AM_PM, PM);
time= (int) cal.getTimeInMillis();
AlarmManager alarmManager = (AlarmManager)context.getSystemService(ALARM_SERVICE);
Intent intent = new Intent(context, MyBroadcastReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 234, intent, 0);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
alarmManager.setAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pendingIntent);
Toast.makeText(context, "alarm set after "+cal.getTimeInMillis(), Toast.LENGTH_SHORT).show();
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
alarmManager.setExact(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pendingIntent);
Toast.makeText(context, "alarm set after "+cal.getTimeInMillis(), Toast.LENGTH_SHORT).show();
} else {
alarmManager.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pendingIntent);
Toast.makeText(context, "alarm set after "+cal.getTimeInMillis(), Toast.LENGTH_SHORT).show();
}
}
And Here's my WakefulBroadcastReceiver.java code
public class MyBroadcastReceiver extends WakefulBroadcastReceiver {
MediaPlayer mp;
myDbAdapter helper;
MainActivity mainActivity=new MainActivity();
#Override
public void onReceive(Context context, Intent intent) {
SharedPreferences sh = context.getSharedPreferences("MySharedPref", MODE_PRIVATE);
int a = sh.getInt("counter", 0);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String date = sdf.format(new Date());
helper = new myDbAdapter(context);
long id = helper.insertData(date, String.valueOf(a));
if (id <= 0) {
Toast.makeText(context, "Insertion UnSuccessful", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(context, "Insertion Successful", Toast.LENGTH_SHORT).show();
}
mp = MediaPlayer.create(context, R.raw.alarm);
mp.start();
Toast.makeText(context, "Alarm...!!!!!! ", Toast.LENGTH_LONG).show();
SharedPreferences sharedPreferences = context.getSharedPreferences("MySharedPref", MODE_PRIVATE);
SharedPreferences.Editor myEdit = sharedPreferences.edit();
myEdit.putInt("counter", 0);
myEdit.commit();
}

Related

App is not running in Background (Android Studio java)

I am working on an Android app and I want to activate a daily Alarm (I used 5 min interval just as an example to test).
I used a Brodacast receiver (Static one declared in the manifest file),
but the app still doesn't work. Here's my code:
The Manifest file:
</activity> <receiver android:name=".ExecutableService" android:enabled="true" ></receiver </application>
The AlarmHandler class:
public class AlarmHandler {
private Context context;
public AlarmHandler(Context context) {
this.context = context;
}
//This will active the alarm
public void setAlarmManager(){
Intent intent = new Intent(context,ExecutableService.class);
PendingIntent sender = PendingIntent.getBroadcast(context ,2,intent,0);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
if (alarmManager != null) {
long triggerAfter=60*5*1000;//this will trigger the service after 5 min
long triggerEvery=60*5*1000;//this will repeat alarm every 5 min after that
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,triggerAfter,triggerEvery,sender);
}
}
//This will cancel the alarm
public void cancelAlarm (){
Intent intent = new Intent(context,ExecutableService.class);
PendingIntent sender = PendingIntent.getBroadcast(context,2,intent,0);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
if (alarmManager != null) {
alarmManager.cancel(sender);
}
}
}
This is the Broadcast receiver:
import ...
public class ExecutableService extends BroadcastReceiver {
private static final String TAG="Executable Service";
#Override
public void onReceive(Context context, Intent intent) {
//this will be executed at selected interval Notification show
Toast.makeText(context, "Hello World 2! ", Toast.LENGTH_SHORT).show();
Log.d(TAG, "onReceive: it worked ");
Vibrator v=(Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
v.vibrate(VibrationEffect.createOneShot(500, VibrationEffect.DEFAULT_AMPLITUDE));
} else {
//deprecated in API 26
v.vibrate(500);
}}}
And this is the MainActivty where I activate the alarm:
public class MainActivity2 extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
AlarmHandler alarmHandler = new AlarmHandler(this);
//cancel the previous scheduled alarm
alarmHandler.cancelAlarm();
//set the new alarm after one hour
alarmHandler.setAlarmManager();
Toast.makeText(this, "Alarm Set ! ", Toast.LENGTH_SHORT).show();
}
If this is not the way that I should use to run the app in the background and push a notification (or a simple toast at a specific time), what is the best way to do it?
I tried also jobscheduler services.
you set the alarm start time to long triggerAfter=60*5*1000;
I suggest changing this to
long triggerAfter =60*5*1000+ System.currentTimeMillis()

Android: display alert at specific time

I am trying to display an alert at a specific time every day (a specific hour and minute),
I used the below code and it worked with me and the alert display at the time I choose,
only when I open the app first time, but the problem is whenever I try to open the app again the alert display even that I set a different time.
Here is my code:
Mainactivity.java
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startAlarmBroadcastReceiver(this);
}
public static void startAlarmBroadcastReceiver(Context context) {
Intent _intent = new Intent(context, MyBroadcastReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, _intent, 0);
AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(pendingIntent);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 11);
calendar.set(Calendar.MINUTE, 16);
calendar.set(Calendar.SECOND, 0);
alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
}
MyBroadcastReceiver.java
public class MyBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "Alarm....", Toast.LENGTH_LONG).show();
}
}
Any help will be appreciated.

AlarmManager not Starting Service

Before, the alarm manager was working. I don't think I changed anything, but now it isn't starting at all.
Here is the code where I set the alarm manager:
SettingsActivity.java
Intent intent;
static PendingIntent recurringDownload;
intent = new Intent(context, UpdateScoresService.class);
recurringDownload = PendingIntent.getService(context, 0, intent, 0);
Preference.OnPreferenceChangeListener refreshListener = new Preference.OnPreferenceChangeListener() {
#Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
if(newValue.toString().equals("1")){ /* daily */
background_refresh.setSummary("Scores will be refreshed daily.");
AlarmManager manager = (AlarmManager) getActivity().getSystemService(Context.ALARM_SERVICE);
manager.cancel(recurringDownload);
recurringDownload.cancel();
Log.e("DAILY REFRESH", " ");
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY,10);
calendar.set(Calendar.MINUTE,00);
if(calendar.before(Calendar.getInstance())){
Log.e("AFTER", "10 AM DAILY");
calendar.add(Calendar.DATE, 1);
}
manager.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, recurringDownload);
}else if(newValue.toString().equals("2")){ /* weekly */
Log.e("WEEKLY REFRESH", " ");
background_refresh.setSummary("Scores will be refreshed weekly.");
AlarmManager manager = (AlarmManager) getActivity().getSystemService(Context.ALARM_SERVICE);
manager.cancel(recurringDownload);
recurringDownload.cancel();
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY,10);
calendar.set(Calendar.MINUTE,00);
if(calendar.before(Calendar.getInstance())){
Log.e("AFTER", "10 AM WEEKLY");
calendar.add(Calendar.DATE, 1);
}
manager.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY * 7, recurringDownload);
}else{ /* manually */
background_refresh.setSummary("Scores will be refreshed manually.");
Log.e("MANUAL REFRESH", " ");
AlarmManager manager = (AlarmManager) getActivity().getSystemService(Context.ALARM_SERVICE);
manager.cancel(recurringDownload);
recurringDownload.cancel();
}
return true;
}
};
The UpdateScoresService is here:
public class UpdateScoresService extends IntentService {
public int countChanged;
Context context = this;
public UpdateScoresService() {
super("UpdateScoresService");
}
#Override
protected void onHandleIntent(Intent intent) {
Log.e("onHandleIntent", "grabbing scores");
countChanged = new GetAnimeScores(getApplicationContext()).refreshScores();
if(countChanged>0){ //Display notification if any scores changed
Log.d("Creating notification", " ");
NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
builder.setSmallIcon(R.drawable.ic_timeline_white_24dp);
builder.setContentTitle("MAL Score Tracker");
builder.setAutoCancel(true);
if(countChanged==1){
builder.setContentText("1 score changed since you were gone!");
}else{
builder.setContentText(countChanged+" scores changed since you were gone!");
}
Intent intent1 = new Intent(context, MainActivity.class);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
stackBuilder.addParentStack(MainActivity.class);
stackBuilder.addNextIntent(intent1);
PendingIntent pendingIntent = stackBuilder.getPendingIntent(0,PendingIntent.FLAG_UPDATE_CURRENT);
builder.setContentIntent(pendingIntent);
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0,builder.build());
}
}
}
}
The Log in the SettingsActivity print but the Log in the onHandleIntent from the Service do not print. I'm not sure what is wrong.
It is better to have a BroadcastReceiver which will be responsible for starting the service. The code for it should look something like this:
Create a BroadcastReceiver class:
public class ReceiverToStartService extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
Intent i = new Intent(context, UpdateScoresService.class);
ComponentName service = context.startService(i);
}
}
Register receiver in your Manifest:
<receiver android:name=".ReceiverToStartService"/>
Now change the Intent in your Activity that you are passing to PendingIntent:
intent = new Intent(context, ReceiverToStartService.class);
recurringDownload = PendingIntent.getService(context, 0, intent, 0);

Repeated alarm is not accurate

I made an app which has a number picker ranging from 1 to 60 minutes, and I connected it to a repeated alarm manager. When I gave it a try, I noticed that it's not accurate sometimes, it either takes more minutes to work or less.
What could be the problem?
For the start button:
startB.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
if (startB.isChecked())
{
Calendar calSet = Calendar.getInstance();
calSet.set(Calendar.MINUTE, picker2.getValue());
calSet.set(Calendar.SECOND, 0);
calSet.set(Calendar.MILLISECOND, 0);
setAlarm(calSet);
SharedPreferences.Editor editor = getPreferences(MODE_PRIVATE).edit();
editor.putBoolean("toggleButton", startB.isChecked());
editor.commit();
timerHasStarted = true;
}
else
{
Intent intent = new Intent(getBaseContext(), MainReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(getBaseContext(), RQS_1, intent, 0);
AlarmManager alarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(pendingIntent);
SharedPreferences.Editor editor = getPreferences(MODE_PRIVATE).edit();
editor.putBoolean("toggleButton", startB.isChecked());
editor.commit();
timerHasStarted = false;
}
}
});
For the alarm:
private void setAlarm(Calendar targetCal ) {
// TODO Auto-generated method stub
Intent intent = new Intent(getBaseContext(), MainReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(getBaseContext(), RQS_1, intent, 0);
AlarmManager alarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,
targetCal.getTimeInMillis(),
TimeUnit.MINUTES.toMillis(picker2.getValue()),
pendingIntent);
}
Receiver:
#Override
public void onReceive(Context context, Intent intent) {
MediaPlayer m=MediaPlayer.create(context, R.raw.sound);
m.start();
}
The Android OS is able to shift alarms in order to minimize wakeups and battery consumption (since API 19). Take a look here. I noticed delays up to a few seconds.
A pretty nice tutorial on alarms in general could be found here

Android AlarmManager not working

In my main activity, I am executing this:
Calendar calendar = Calendar.getInstance();
// 9:45 PM
calendar.set(Calendar.HOUR_OF_DAY, 21);
calendar.set(Calendar.MINUTE, 45);
calendar.set(Calendar.SECOND, 0);
AlarmManager am = (AlarmManager) this.getApplicationContext().getSystemService(Context.ALARM_SERVICE);
PendingIntent pi = PendingIntent.getService(this.getApplicationContext(), 0, new Intent(this.getApplicationContext(), MorningReceiver.class), PendingIntent.FLAG_UPDATE_CURRENT);
am.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pi);
Toast msg = Toast.makeText(NotificationScanner.this,
"Scheduled: " + calendar.getTime(), Toast.LENGTH_LONG);
msg.show();
And this is my receiver
public class MorningReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
MediaPlayer mMediaPlayer = new MediaPlayer();
Uri alert = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM);
try {
mMediaPlayer.setDataSource(context, alert);
final AudioManager audioManager = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
if (audioManager.getStreamVolume(AudioManager.STREAM_ALARM) != 0) {
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_ALARM);
mMediaPlayer.start();
PackageManager packageManager = context.getPackageManager();
Intent skype = packageManager.getLaunchIntentForPackage("com.skype.raider");
context.startActivity(skype);
}
}catch(Exception e){
Toast msg = Toast.makeText(context,
"Exception thrown", Toast.LENGTH_LONG);
msg.show();
}
}
}
The Toast from the main activity displays, so I know the alarm is getting set, but the receiver is never getting called (the ring is never playing, nor the Toast exception message). Does anyone know what I'm doing wrong here with my AlarmManager? Am I supposed to do something in my Manifest to get the Receiver working?
Thanks

Categories

Resources