How can I send a whatsapp message to a number at a particular time automatically from my app? is there an android intent to it?
String toNumber="91XXXXXXXXXX";
PackageManager packageManager = context.getPackageManager();
Intent intent = new Intent(Intent.ACTION_VIEW);
try {
String url = "https://api.whatsapp.com/send?phone="+ toNumber +"&text=" + URLEncoder.encode(whatsAppMessage, "UTF-8");
intent.putExtra(Intent.EXTRA_TEXT, whatsAppMessage);
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_STREAM, whatsAppImage);
intent.setType("image/jpeg");
intent.setPackage("com.whatsapp");
intent.setData(Uri.parse(url));
if(Calendar.HOUR==10){
startActivity(intent);
}
}
catch (Exception e){
e.printStackTrace();
}
So, your question is really about how to execute some code at a particular time, not really about whatsapp?
The simple answer is to start a timer, have it fire every second, check the current time in the timer code. If the time is 22:00:00 (10PM) or 10:00:00 (10AM), call your function.
You don't want to just check Calendar.HOUR==10 because that will be true for every second of that hour, so, you may send out many more messages than you want to.
Keep in mind, this will only happen if the app is running, and possibly only if it is running the the foreground. If you need this to happen 24 hours a day, then you probably want to create some type of system service and have it send out the messages.
//Declare the timer
Timer t = new Timer();
//Set the schedule function and rate
t.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
//Called each time when 1000 milliseconds (1 second) (the period parameter)
// Get calendar set to the current date and time
Calendar cal = Calendar.getInstance();
// ensures we're using the same current time
Calendar cal2 = cal;
// Set time of calendar to 22:00:00.000
cal.set(Calendar.HOUR_OF_DAY, 22);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
// Check if current time is after or before 22:00:00.000 today
if ((cal2.after(cal)) || (cal2.before(cal)) {
return;
}
PackageManager packageManager = context.getPackageManager();
Intent intent = new Intent(Intent.ACTION_VIEW);
try {
String url = "https://api.whatsapp.com/send?phone="+ toNumber +"&text=" + URLEncoder.encode(whatsAppMessage, "UTF-8");
intent.putExtra(Intent.EXTRA_TEXT, whatsAppMessage);
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_STREAM, whatsAppImage);
intent.setType("image/jpeg");
intent.setPackage("com.whatsapp");
intent.setData(Uri.parse(url));
startActivity(intent);
}
catch (Exception e){
e.printStackTrace();
}
}
},
//Set how long before to start calling the TimerTask (in milliseconds)
0,
//Set the amount of time between each execution (in milliseconds)
1000);
Related
I'm building an Android pedometer app that sends data to a SQLite database at 30 minute intervals using AlarmManager; if the phone is off when the transfer is supposed to occur, it will do the transfer immediately when the phone is switched back on.
(30 minutes is for testing - the actual interval will be 1 week).
I was told alarms wouldn't persist unless I used "intent.action.BOOT_COMPLETED" in the manifest, so I put that as a filter for my Alarm.java class.
My code to set the alarm (in MainActivity.java) is as follows:
public void insertData(View view) {
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
long time= System.currentTimeMillis();
Date d = new Date(time);
editor.putLong("alarmtime", time); //the next ring time for the alarm is put in SharedPreferences
editor.apply();
Intent intent = new Intent(this, Alarm.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(
this,
0,
intent,
PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager.setRepeating(AlarmManager.RTC, time, AlarmManager.INTERVAL_DAY, pendingIntent);
Toast.makeText(MainActivity.this, "Alarm Set", Toast.LENGTH_LONG).show();
}
The code in the Alarm.java class (which extends BroadcastReceiver) is as follows:
Context context; //plus other declared variables
#Override
public void onReceive(Context context, Intent intent) {
this.context = context;
preferences = context.getSharedPreferences("MyPreferences", context.MODE_PRIVATE);
editor = preferences.edit();
long startedtime = preferences.getLong("alarmtime", 0); //get the next ring time
Date nextRingTime = new Date(startedtime);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
String action = intent.getAction();
//sometimes the onReceive() is called by the phone turning on
if (action != null && action.equals(Intent.ACTION_BOOT_COMPLETED)) {
//if phone turned on again before the alarm, just re-create the alarm for the same time, don't transfer data
Date currenttime = new Date(System.currentTimeMillis());
if ((currenttime.compareTo(nextRingTime) < 0)) {
Intent newintent = new Intent(context, Alarm.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(
context,
0,
newintent,
PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager.setRepeating(AlarmManager.RTC, startedtime, AlarmManager.INTERVAL_HALF_HOUR, pendingIntent);
return;
}
else if ((currenttime.compareTo(nextRingTime) > 0)) {
//if the phone was off when the alarm was supposed to make the transfer, set the alarm to the next intended ring time and insert data to db immediately
Calendar d = Calendar.getInstance();
d.setTime(nextRingTime);
d.add(Calendar.MINUTE, 30);
long newtime = d.getTimeInMillis();
Intent newintent = new Intent(context, Alarm.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(
context,
0,
newintent,
PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager.setRepeating(AlarmManager.RTC, newtime, AlarmManager.INTERVAL_HALF_HOUR, pendingIntent);
}
}
myDb = new DatabaseHelper(context);
// code for inserting data into database
//finally, update next intended ring time in SharedPreferences now that this particular transfer is done:
Calendar c = Calendar.getInstance();
c.setTime(nextRingTime);
c.add(Calendar.MINUTE, 30);
Log.v("insertdone, alarrm now", c.getTime().toString());
long nexttime = c.getTimeInMillis();
editor.putLong("alarmtime", nextime);
editor.apply();
}
Unfortunately, if the phone is off at the time of a scheduled alarm, when I turn it on afterwards, it calls onReceive() TWICE, meaning it inserts data twice.
How can this be stopped?
A solution would maybe be to use RTC_WAKEUP, but I really don't want to do that unless as an absolute last resort.
N.B. I have a separate bootBroadcastReceiver class that uses "intent.action.BOOT_COMPLETED" to restart a pedometer service, and am wondering whether having 2 different things started by the boot is causing problems...
I'm writing the application and I want to send information to server in every 10 second. Firstly I was using the Timer and TimerTask, but it wasn't good choice because when I asleeped the device I wasn't work good. So now I want to try using AlarmManager but I have a problem when I want to set repeat
void startRepeatingSend() {
AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, MainReceiver.class); // odbiornik
intent.setAction("com.example.marcin.sbdintheroom.CYCLE");
PendingIntent alarmIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, 5000, 5000, alarmIntent);
}
I set the intervalMillis on 5 seconds, but my receiver receive broadcast only one time per minute
You can delay you application with Thread.sleep(miliseconds);
try {
Thread.sleep(1000); //1000 milliseconds is one second.
} catch(InterruptedException ex) {
Thread.currentThread().interrupt(); // interupt thread when error
// handle error
}
I'm trying to write a service that will check every midnight for new data from the server and will download it.
But when i start the app the mainActivity screen reloads after few seconds.
I'v checed it and it happens because of this service,
Why is this happening?
Her are the files:
MainActivity: i'v created an AlarmManager object to set pendingIntent:
//Set alarm
/* Retrieve a PendingIntent that will perform a broadcast */
Intent alarmIntent = new Intent(getApplicationContext(), AlarmReciever.class);
pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, alarmIntent, 0);
AlarmManager manager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
int interval = 1000 * 24 * 60 * 60;
/* Set the alarm to start at 10:30 AM */
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 00);
calendar.set(Calendar.MINUTE, 00);
manager.setInexactRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), interval, pendingIntent);
AlarmReciever:
public class AlarmReciever extends BroadcastReceiver {
private Data newData = null;
public SharedPreferences settings;
ConnectivityManager cm = null;
NetworkInfo netInfo = null;
#Override
public void onReceive(Context context, Intent intent) {
newData = new Data(context);
// TODO Auto-generated method stub
newData.cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
newData.netInfo = newData.cm.getActiveNetworkInfo();
newData.settings = PreferenceManager.getDefaultSharedPreferences(context);
// System.out.print("-----------------" + newData.netInfo);
newData.checkOnline();
}
}
Data.java:
public void checkOnline(){
if (isOnline()){
System.out.print("**************** YES Internet");
firstAsyncTask task = new firstAsyncTask(this);
try {
Object dobj = task.execute("par1", "par 2", "par 3").get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}else{
System.out.print("**************** NO Internet");
}
}
The data.java file is to big to post in here, but it seems that the "checkOnline" method in in causing the app to reload the MainActivity page, should i send the service differently?
Thanx for reading & answering.
Looks like you have written this line by mistake
pendingIntent = PendingIntent.getService(getApplicationContext(), 0, alarmIntent, 0);
It should be like this
pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, alarmIntent, 0);
Because you are using BroadcastReciever.
Causes the following line network access?
Object dobj = task.execute("par1", "par 2", "par 3").get();
If so then the system might kill your process (ether for networking on main thread or for event loop timeout aka. ANR). And eventually restart it again if its a service.
In your Activity you do this:
manager.setInexactRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), interval, pendingIntent);
This causes the BroadcastReceiver to be triggered immediately, since you have specified System.currentTimeMillis() as the time to trigger the first time.
You probably mean to use calendar.getTimeInMillis() as the first time to trigger the alarm. But even if you change it to that, it will still trigger immediately because you've set the time in your calendar to 00:00 of the current day, which has already passed! You need to either use calendar.getTimeInMillis() + interval (which would be 00:00 of the following day, or you can add 1 day to your calendar before using calendar.getTimeInMillis().
I'm currently working on a notification that has to show at a specific time chosen by the user.
BUT when I run it, notifications show but not at the selected time, only when I ask the time in a timepickerdialog appear, before even choosing a time.
Does anyone know how to change the code so that notifications only appear at the time selected?
showDialog(DIALOG_ID); //this is the dialog that asks for an hour and minute.
alarmMethod1();
private void alarmMethod1(){
Calendar calendari1 = Calendar.getInstance();
calendari1.set(Calendar.HOUR_OF_DAY, hour_x);
calendari1.set(Calendar.MINUTE, minute_x);
calendari1.set(Calendar.SECOND, 00);
Intent myIntent1 = new Intent(Main2Activity.this, NotifyService1.class);
AlarmManager alarmManager1 = (AlarmManager) getSystemService(ALARM_SERVICE);
pendingIntent1 = PendingIntent.getService(Main2Activity.this, 0, myIntent1, 0);
alarmManager1.setRepeating(AlarmManager.RTC_WAKEUP, calendari1.getTimeInMillis(), 24 * 60 * 60 * 1000, pendingIntent1);
}
Then here is the class where the intent goes:
public class NotifyService1 extends Service {
#Override
public IBinder onBind(Intent intent) {
return null;
}
#TargetApi(Build.VERSION_CODES.JELLY_BEAN)
#Override
public void onCreate(){
Uri sound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationManager nNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
Intent intent1 = new Intent(this.getApplicationContext(),Main3Activity.class);
PendingIntent pIntent = PendingIntent.getActivity(this, 0, intent1, 0);
Notification mNotify = new Notification.Builder(this)
.setContentTitle("Hora d'entrenar!")
.setContentText("Clica per començar entrenament de pit i braços")
.setSmallIcon(R.drawable.logofinal)
.setContentIntent(pIntent)
.setSound(sound)
.build();
nNM.notify(1,mNotify);
}
}
Since Android API 19, all alarms are inexact in order to reduce battery consumption, that means that your alarms will not be triggered exactly when you want, but if you really need to do it, you need to use setExact and then write the repeat alarm handler by yourself, there's no longer a "set exact and repeat". Please, see:
http://developer.android.com/reference/android/app/AlarmManager.html#setRepeating(int, long, long, android.app.PendingIntent)
http://developer.android.com/reference/android/app/AlarmManager.html#setExact(int, long, android.app.PendingIntent)
I'm currently developing an application which makes use of Android's AlarmManager. I'm trying to add a new alarm to the AlarmManager, but after several hours of trying various things and checking various threads on SO, I'm still at a brick wall. Are there any problems with my code?
Main Activity - saveAlarm() function
/**
* Saves the current alarm. Adds to the database if it doesn't already exist, or updates if it does.
* Also sets alert with AlarmManager.
*/
public void saveAlarm() {
// Create Database instance
DbHandler db = new DbHandler(getApplicationContext());
if(alarm.getId() == -1) {
// Saving a new alarm
db.open();
alarm.setId(db.addAlarm(alarm));
db.close();
}
else {
db.open();
db.updateAlarm(alarm);
db.close();
}
// Create the wakeup intent
Intent intent = new Intent(this, AlarmReceiver.class);
intent.putExtra("alarm_id", alarm.getId());
// Create the Pending Intent
PendingIntent sender = PendingIntent.getBroadcast(this, AlarmPlayer.REQUEST_ALARM + alarm.getId(), intent, PendingIntent.FLAG_UPDATE_CURRENT);
// Debug
Calendar now = Calendar.getInstance();
long dTime = alarm.getNextAlarmTime().getTimeInMillis() - now.getTimeInMillis();
Log.d(TAG, "Setting alarm for " + (dTime / 1000) + " seconds time");
// Add to Android Alarm Manager
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP, alarm.getNextAlarmTime().getTimeInMillis(), sender);
}
I've verified that the correct time is being passed into am.set (see the debug section above it).
AlarmReceiver.class
/**
* This class listens out for broadcasts from AlarmManager
* and launches the AlarmPlayer activity accordingly.
* #author Michael
*
*/
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context c, Intent intent) {
Log.d("RSS Alarm", "Waking up alarm");
// Launch the AlarmPlayer activity
Intent i = new Intent(c, AlarmPlayer.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
c.startActivity(i);
}
}
I also have <receiver android:process=":remote" android:name="AlarmReceiver" /> set up in AndroidManifest.xml. I have no idea what's causing this problem, but it's happening nonetheless. Any help would be greatly appreciated, many thanks in advance.
Edit 1
Changing the timezone to UTC doesn't seem to solve anything, my calendar seems to default to UTC regardless. Current code:
// Debug
Calendar now = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
long dTime = alarm.getNextAlarmTime().getTimeInMillis() - now.getTimeInMillis();
Log.d(TAG, "Setting alarm for " + (dTime / 1000) + " seconds time");
// Add to Android Alarm Manager
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
Log.d(TAG, "Timezone offset is " + TimeZone.getDefault().getRawOffset());
Log.d(TAG, "UTC time is currently " + Calendar.getInstance(TimeZone.getTimeZone("UTC")).getTimeInMillis() / 1000);
am.set(AlarmManager.RTC_WAKEUP, (alarm.getNextAlarmTime().getTimeInMillis() - TimeZone.getDefault().getRawOffset()), sender);
Is this possibly a case that AlarmManager.set(AlarmManager.RTC_WAKEUP, ...) needs the time in UTC? This causes problems if you're setting a 'local time' and don't adjust to UTC. In short, the alarm may be being properly added but it doesn't trigger when you expect it unless your time-zone is UTC.
From the docs...
public static final int RTC_WAKEUP Since: API Level 1
Alarm time in System.currentTimeMillis() (wall clock time in UTC), which will wake up the device when it goes off.
In your manifest, I believe you need android:name".AlarmReceiver" note the dot.
If that doesn't do it, post your manifest file. Also, does your logcat mention adding alarm and alarm triggering?
Edit: You might try this
AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Other than that, I don't see anything jumping out at me. Good Luck