I'm trying to create a Service that checks every x minutes for new messages on a server.
I was quit happy to found this post : Alarm Manager Example
MainActivity
package com.example.alarmexample;
import android.app.Activity;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class MainActivity extends Activity {
Button b1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startAlert();
} public void startAlert() {
int timeInSec = 2;
Intent intent = new Intent(this, MyBroadcastReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(
this.getApplicationContext(), 234, intent, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + (timeInSec * 1000), pendingIntent);
Toast.makeText(this, "Alarm set to after " + i + " seconds",Toast.LENGTH_LONG).show();
}
}
MyBroadcastReceiver.java
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.media.MediaPlayer;
import android.widget.Toast;
public class MyBroadcastReceiver extends BroadcastReceiver {
MediaPlayer mp;
#Override
public void onReceive(Context context, Intent intent) {
mp=MediaPlayer.create(context, R.raw.alarm);
mp.start();
Toast.makeText(context, "Alarm", Toast.LENGTH_LONG).show();
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.alarmexample" >
<uses-permission android:name="android.permission.VIBRATE" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.example.alarmexample.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name="MyBroadcastReceiver" >
</receiver>
</application>
</manifest>
This does exact the thing I want. But if I try to use the Context from the BroadcastReceiver-class to notify the user. The App doesn't starts when the user clicks on the notification.
Is there something spezial I have to do to archive this ?
This is not a direct answer to your question (cant comment because not enough reputation) , but do you really need to check the server every x minutes for an event? I dont know anything about your project, but firebase https://firebase.google.com/docs/cloud-messaging/ would probably be a good alternative. It allows you to send Push Notifications to your client so that the client doesnt need to poll constantly.
Open application after clicking on Notification
Here is the answer - I was looking at the wrong end from this problem.
Related
I am writing a simple application that triggers an alarm 5 seconds after the app launch, in which another activity (AlarmDialog) is launched. However, when I run my app, I get the following error:
Caused by: android.content.ActivityNotFoundException: Unable to find
explicit activity class {com.example.basicalarmsetter/AlarmDialog};
have you declared this activity in your AndroidManifest.xml?
This seems strange, considering that I believe I have declared the activity in my AndroidManifest.xml file:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.basicalarmsetter">
<uses-permission android:name="com.android.alarm.permission.SET_ALARM" />
<application
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="MainActivity" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".AlarmDialog"
android:label="#string/app_name"
android:theme="#style/Theme.AppCompat.Light.NoActionBar">
</activity>
<receiver android:name=".AlarmReceiver"/>
</application>
</manifest>
Below is my code for the app's other classes:
MainActivity.java:
package com.example.basicalarmsetter;
import android.app.Activity;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
public class MainActivity extends Activity {
private Context context;
private AlarmManager alarmMgr;
private PendingIntent alarmIntent;
// Creates the Pending Intent used to set off the alarm
private PendingIntent generateAlarmPendingIntent(Context context) {
Intent intent = new Intent(context, AlarmReceiver.class);
// Each alarm requires a unique id
int alarmId = (int) (Math.random() * (10000 - 1 + 1) + 1);
System.out.println("alarmId = " + alarmId);
PendingIntent alarmPendingIntent = PendingIntent.getBroadcast(context, alarmId, intent, 0);
return alarmPendingIntent;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
context = getApplicationContext();
// Set an alarm 5 seconds after now
alarmMgr = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmMgr.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 5000,
generateAlarmPendingIntent(context));
}
}
AlarmReceiver:
package com.example.basicalarmsetter;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context k1, Intent k2) {
System.out.println("Alarm received!");
Intent i = new Intent();
i.setClassName("com.example.basicalarmsetter", "AlarmDialog");
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
k1.startActivity(i);
}
}
AlarmDialog:
package com.example.basicalarmsetter;
import android.app.Activity;
import android.os.Bundle;
public class AlarmDialog extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.alarm_dialog);
}
}
File Structure: All classes MainActivity, AlarmDialog, and AlarmReceiver, are under the same directory.
Replace:
Intent i = new Intent();
i.setClassName("com.example.basicalarmsetter", "AlarmDialog");
with:
Intent i = new Intent(k1, AlarmDialog.class);
This will use a better constructor, one that helps avoid the mistake in your hard-coded strings. As a bonus, if you use an IDE to rename the AlertDialog class, your Intent will be modified as well.
I need to programme alarm. To achieve this,i decided to use class AlarmManager. But when i build and run my app the first time alarm triggerafter about a minute,but it must trigger immediately. When i open this app again,it works well,so the alarm trigger immediately. Help me please,How i can programme,to alarm triggered even if i run my app the first time after booting the device. May be instead of using AlarmManager for alarm the best way to use another classes,such as timer,countDownTimer,etc? Help me please in it. I catch alarm,using receiver. I tryed to work with receiver in onCreate() method of activity,but it not help for me. It also not help,when i use setExact method instead of set method in AlarmManager. Repeating of alarm trigger inexact even when i run my app after running it the first time after booting the device. Here is my code of mainActivity,AlarmReceiver and manifest. Thanks everybody for help.
MainActivity.java
package ru.AlexandrKozlovskiy.alarm;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Toast;
import ru.AlexandrKozlovskiy.alarm.AlarmReceiver;
import ru.AlexandrKozlovskiy.alarm.AlarmReceiver;
import ru.AlexandrKozlovskiy.alarm.R;
public class MainActivity extends AppCompatActivity {
public static AlarmReceiver alarm;
#Override
protected void onStart() {
super.onStart();
alarm = new AlarmReceiver();
if(alarm!=null) alarm.setAlarm(this.getApplicationContext(),System.currentTimeMillis(),5000);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
protected void onDestroy() {
super.onDestroy();
// cancel alarm and free of resources
alarm.cancelAlarm(this.getApplicationContext());
alarm=null;
}
}
AlarmReceiver.java
package ru.AlexandrKozlovskiy.alarm;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.media.AudioManager;
import android.media.ToneGenerator;
import android.os.PowerManager;
import android.provider.MediaStore;
import android.widget.Toast;
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// keep screen on
PowerManager pm=(PowerManager) context.getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wl= pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,"alarm");
wl.acquire();
// show notification and generate tone during alarm.
Toast.makeText(context,"Testing of alarm",3).show();
ToneGenerator toneGenerator = new ToneGenerator(AudioManager.STREAM_MUSIC,ToneGenerator.MAX_VOLUME);
toneGenerator.startTone(toneGenerator.TONE_CDMA_ALERT_CALL_GUARD,500);
toneGenerator.release();
wl.release();
}
public void setAlarm(Context context,long timeInMilis,long intervalInMilis)
{
AlarmManager am=(AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent=new Intent(context, AlarmReceiver.class);
PendingIntent pi= PendingIntent.getBroadcast(context,0, intent,0);
// set usual or repeating alarm according the parameter intervalInMilis
if (intervalInMilis>0) am.setRepeating(AlarmManager.RTC_WAKEUP,timeInMilis,intervalInMilis,pi); else am.set(AlarmManager.RTC_WAKEUP,timeInMilis,pi);
}
public void cancelAlarm(Context context)
{
Intent intent=new Intent(context, AlarmReceiver.class);
PendingIntent sender= PendingIntent.getBroadcast(context,0, intent,0);
AlarmManager alarmManager=(AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(sender);
}
}
manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="ru.AlexandrKozlovskiy.alarm">
<uses-permission android:name="android.permission.SET_ALARM"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity"
android:launchMode="singleInstance"
android:configChanges="orientation|screenSize|keyboardHidden">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name=".AlarmReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
</application>
</manifest>
As noted HERE:
Note: Beginning with API 19 (KITKAT) alarm delivery is inexact: the OS will shift alarms in order to minimize wakeups and battery use. There are new APIs to support applications which need strict delivery guarantees; see setWindow(int, long, long, PendingIntent) and setExact(int, long, PendingIntent). Applications whose targetSdkVersion is earlier than API 19 will continue to see the previous behavior in which all alarms are delivered exactly when requested.
Suppose I have a MainActivity.java, where if I press a button(id=get_button), I will go to the onReceive() of NotificationReceiver.java 2 minutes later :
But I am not going there. As for this and this and many other resources I googled, This seems to be the right way.
My MainActivity.java :
package com.example.insanes.chothavandar;
import android.app.Activity;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import java.util.Calendar;
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.get_button).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
Intent intent = new Intent(MainActivity.this, NotificationReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(
MainActivity.this,
0,
intent,
PendingIntent.FLAG_UPDATE_CURRENT);
Calendar cal = Calendar.getInstance();
cal.set(Calendar.MINUTE, cal.get(Calendar.MINUTE) + 2);
cal.set(Calendar.SECOND, 0);
am.setRepeating(
AlarmManager.RTC_WAKEUP,
cal.getTimeInMillis(),
AlarmManager.INTERVAL_DAY,
pendingIntent);
}
});
}
}
My NotificationReceiver.java :
package com.example.insanes.chothavandar;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
public class NotificationReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// Not logging after 2 minutes
// Am I doing something wrong?
Log.d("DEBUG-EXISTENSE", "Reached in the broadcastreceiver");
}
}
I have registered the receiver in the manifest:
My menifest.xml :
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.insanes.chothavandar">
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name=".NotificationReceiver"/>
</application>
</manifest>
you want to write this code in your manifest file.
ex :
android:name="com.example.insanes.chothavandar.NotificationReceiver"
android:exported="true">
<intent-filter>
<action android:name="com.example.insanes.chothavandar.SHOW_NOTIFICATION" />
</intent-filter>
</receiver>
If you will go to the onReceive() of NotificationReceiver.java 2 minutes later so, you will use a handler in your class.
ex:
private Handler mStatusHandler = new Handler();
private Runnable mStatusRunnable;
private void checkStatus() {
mStatusRunnable = new Runnable() {
#Override
public void run() {
// Hear right your on button click code.
checkStatus();
}
};
mStatusHandler.postDelayed(mStatusRunnable, 2000);
}
i don't know about the right way or not , but this can be done via Handler in pretty simple way,
int TIME=2000
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
// do stuff
}
}, TIME);
I'm a student learning programming in Android Studio and I met some difficulties when developing my Alarm clock project. I've done lots of experiments and research in my code but still I couldn't find the solution. I wanted to try to make a normal alarm that is when the alarm is activated, display another full screen activity to remind the user. I don't want my alarm app to just ring and toast notification. I want it to also display a screen.
Here is my code:
package com.example.android.exno11;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.EditText;
import android.widget.TimePicker;
import android.widget.Toast;
import android.widget.ToggleButton;
import com.example.android.exno11.AlarmReceiver;
import com.example.android.exno11.R;
import java.util.Calendar;
import static android.R.id.message;
import static android.provider.AlarmClock.EXTRA_MESSAGE;
public class MainActivity extends AppCompatActivity {
TimePicker alarmTimePicker;
PendingIntent pendingIntent;
AlarmManager alarmManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
alarmTimePicker = (TimePicker) findViewById(R.id.timePicker);
alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
}
// Toggle button
public void OnToggleClicked(View view) {
long time;
if (((ToggleButton) view).isChecked()) {
Toast.makeText(MainActivity.this, "Activated", Toast.LENGTH_SHORT).show();
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, alarmTimePicker.getCurrentHour());
calendar.set(Calendar.MINUTE, alarmTimePicker.getCurrentMinute() + 1);
Intent intent = new Intent(this, AlarmReceiver.class);
pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
time=(calendar.getTimeInMillis()-(calendar.getTimeInMillis()%60000));
if(System.currentTimeMillis()>time) {
if (calendar.AM_PM == 0)
time = time + (1000*60*60*12);
else
time = time + (1000*60*60*24);
}
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, time, 120000, pendingIntent);
}
else {
Toast.makeText(MainActivity.this, "OFF", Toast.LENGTH_SHORT).show();
alarmManager.cancel(pendingIntent);
}
}
}
And this is the manifest, not sure what I'm doing is right.Thank you for helping.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.android.exno11">
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name=".AlarmReceiver"></receiver>
</application>
</manifest>
I've found several tutorials about setting the alarm receiver to send a toast message in set intervals. and i've been following the code and broken down my own project into 3 classes.
the HelloDroidActivity.java is:
package com.example.helloandroid;
import java.util.Calendar;
import android.app.Activity;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
import android.widget.Toast;
import com.example.helloandroid.alarms.MyAlarmReciever;
public class HelloDroidActivity extends Activity {
/** Called when the activity is first created. */
public static int RTC_WAKEUP;
public static long INTERVAL_FIFTEEN_MINUTES;
private AlarmManager alarmMgr;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TextView tv = new TextView(this);
tv.setText("Hello, Krishneel");
setContentView(tv);
Toast.makeText(this, "Alarm went off", Toast.LENGTH_SHORT).show();
Log.d("OnCreate", "abcdabcdabcdabcdabcdabcdabcdabcdabcdabcd");
alarmMgr = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, MyAlarmReciever.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0,
intent, PendingIntent.FLAG_UPDATE_CURRENT);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.add(Calendar.SECOND, 5);
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP,
calendar.getTimeInMillis(), 7000, pendingIntent);
}
}
also the MyAlarmReciever.java(i am already aware of the spelling mistake on the name):
package com.example.helloandroid.alarms;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.widget.Toast;
public class MyAlarmReciever extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
Log.e("onReceive", "ladskjflsakjdflskjdflskjdfslkjdflasdf");
Toast.makeText(context, "OnReceive alarm test", Toast.LENGTH_SHORT).show();
}
}
and the Android Manifest which looks like this :
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.helloandroid"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="7" />
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<activity
android:name="com.example.helloandroid.HelloDroidActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name="AlarmReceiver">
<intent-filter>
<action android:name="com.example.helloandroid.alarms" />
</intent-filter>
</receiver>
</application>
</manifest>
I have read that in order to get the project to receive my alarmReceiver java class I need to edit the manifest with a new receiver. but I'm fairly new to XML and dont know which direction to take.
There is already a receiver that you have defined in your manifest file. But the name is not correct see the name needs to be the full class name i.e the package.RecieverName. And in your case the name of your receiver is MyAlarmReciever. So the receiver will be defined as follows
<receiver android:name=".alarms.MyAlarmReciever">
<intent-filter>
<action android:name="com.example.helloandroid.alarms" />
</intent-filter>
</receiver>
In your manifest, the receiver is listening to an action called com.example.helloandroid.alarms. But in your HelloDroidActivity.java there is not such action is added to the intent.
public class HelloDroidActivity extends Activity {
//....
#Override
public void onCreate(Bundle savedInstanceState) {
//....
Intent intent = new Intent(this, MyAlarmReciever.class);
intent.setAction("com.example.helloandroid.alarms");
//....
}
}