Android calendar intent customizing - android

I'm making a back-end function for another area of a program that will add events to the user's calendar. Basically someone will pick an event out from options in a GUI and I want to set an event on the calendar that matches the choice.
The code to make it more clear what I'm working with:
java.sql.Timestamp tsStart = java.sql.Timestamp.valueOf(year + "-" + month + "-" + day + " " + startHour + ":" + startMinute + ":00");
java.sql.Timestamp tsEnd = java.sql.Timestamp.valueOf(year + "-" + month + "-" + day + " " + endHour + ":" + endMinute + ":00");
long startTime = tsStart.getTime();
long endTime = tsEnd.getTime();
Intent intent = new Intent(Intent.ACTION_EDIT);
intent.setType("vnd.android.cursor.item/event");
intent.putExtra("beginTime", startTime);
intent.putExtra("allDay", false);
intent.putExtra("rrule", "FREQ=WEEKLY;COUNT="+numWeeks);
intent.putExtra("endTime", endTime);
intent.putExtra("title", title);
intent.putExtra("description", description);
intent.putExtra("eventLocation", location);
startActivity(intent);
I've been using intent to go about doing this, but there are a few extras that I'd rather not have:
1. When the intent launches, it starts in the text entry for the What field. I've automatically filled all of these fields, so the user shouldn't need to do anything, and when it launches like this, the keyboard takes up a lot of space and looks messy. Is there any way I can either set the focus not to be in the textbox or to fake a back button press?
2. Is it possible to make some of the sections of the intent not show? I don't think it's necessary to ask the time zone, don't need the all day check (because I tell it the start and end time), don't need Guests, would rather hide the repetition because it's customized and might confuse the end user to see, and I DO NOT want reminders, which it automatically makes one for 10 minutes.
-> Is it possible to hide any/all of those items?
3. Is it possible to even make this never display to the user? I like the fact that it allows the user to pick which calendar to use, but I'm fine with it using their default since most people link their phone with their other accounts, and the phone calendar is my main focus. If I can make the 10 minute reminder go away, I would to just make it never display to the user and have it just populate their calendar as I tell it to.
Thanks to anyone who can give any help. I've been reading over intents, calendars, and anything I could think of over at Android Developers, and I've hit a wall that I can't find these answers. Which reminds me, is there a listing anywhere of all of the valid putExtra's? The Android Developers page was good for listing all of the methods, etc, but aside from finding some examples, I don't know what all I can put as valid arguments inside the putExtra.

When you send an intent to add an event to the Calendar, you're launching the Calendar activity. Intents are simply a message out to the system; any activity that can handle the intent is free to "speak up". If more than one activity's intent filter matches the intent, the user sees a "disambiguation" screen, which allows him or her to choose the app to use. In the case of most Intents, it's the MIME type that determines which app(s) are displayed. You could write your own activity for handling events, if you wanted. The activity's intent filter would have to match the Calendar's, and I wouldn't recommend doing this since you're signing yourself up for handling every intent that tries to add something to the calendar!
You have the choice of sending an intent to the Calendar Provider (actually the Calendar app, which accesses the provider) or inserting the data yourself using the ContentResolver API with the Calendar Provider.
You might consider the latter course of action, and provide your own UI instead of using the Calendar activity, but I advise you to use caution in adding recurring events, because getting them right is tricky. In general, developers should use the Calendar activity to allow users to add events.
If you use the Intent to start the Calendar "insert event" activity, you have no control over its UI. As a convenience, the Calendar activity will populate the UI with the Extras you send. If you don't send an Extra, the activity will either populate the field with the default or leave it blank. I'm not certain that it does, but this is standard practice.
Developers often overlook the Developer guides when they develop apps. Take a look at
http://developer.android.com/guide/topics/providers/calendar-provider.html#intents, which describes the Calendar Provider in detail. This page lists all the available Extras, tells you how to use the ContentResolver() process for inserting events, and elaborates on using Intents.
At the moment, I don't think there's a standard way for an application to expose the structure of the Intents it handles, but for the built-in or bundled apps that appear in on a device, you can always just ask here for more information. Remember that some apps are bundled with the platform, but others (such as Google Maps) are separate. They may have public intents/APIs, but you need to be aware that they may not be available for a particular user's device.

Related

Adding birthday to a contact creates 2 entries after sync

I have a very weired problem with my app while I try to add a birthday event on a picked contact.
My code for this is:
int mret = np2.getValue()+1;
ContentResolver cr = v.getContext().getContentResolver();
ContentValues values = new ContentValues();
values.put(ContactsContract.RawContacts.Data.MIMETYPE, ContactsContract.CommonDataKinds.Event.CONTENT_ITEM_TYPE);
values.put(ContactsContract.RawContacts.Data.RAW_CONTACT_ID, rawContactId);
values.put(ContactsContract.CommonDataKinds.Event.TYPE, ContactsContract.CommonDataKinds.Event.TYPE_BIRTHDAY);
if (boolyear == true) {
values.put(ContactsContract.CommonDataKinds.Event.START_DATE, np3.getValue() + "-" + mret + "-" + np1.getValue());
} else {
values.put(ContactsContract.CommonDataKinds.Event.START_DATE, "0000-" + mret + "-" + np1.getValue());
}
Uri bduri= null;
try {
bduri= cr.insert(ContactsContract.Data.CONTENT_URI,values);
} catch (Exception e) {}
The above code works fine as it creates the birthday event but a few seconds later appears a second birthday entry which possibly is a result of sync as it happens only if there is an Internet connection.
This is not a problem of the device because other apps downloaded from Play Store work as expected. It's only my app that creates double birthday entries.
Why is this happening and how to fix that?
Thank you in advance.
UPDATE: I managed to fix it. The problem was the date format. All values (day and month) must be in a two-digit format. E.g. "1980-07-01", not "1980-7-1".
I managed to fix it. The problem was the date format. All values (day and month) must be in a two-digit format. E.g. "1980-07-01", not "1980-7-1".
I am assuming that you are using a Sync Adapter to interface with the Calendar.
The Sync Adapter has two important methods:
onPerformSync(...), and onSyncCanceled(...)
onPerformSync is called whenever you make a ContentResolver.requestSync call or if automatic sync is set to true.
While executing, onPerformSync can be interrupted by Android. This can happen if the device is running low on resources of if your app is not in the foreground anymore.
When interupted, the Sync Adapter will stop execution where it's at and will call onSyncCanceled. The default behavior of the Sync Adapter is to retry the failed sync messages the first chance it gets. So if your app manages to grab onto OS resources again, it will replay the interrupted sync message.
It is possible that some of your messages are being fully processed and, just before onPerformSync is about to complete, the Sync Adapter is interrupted. At this point you managed to save the event, however, the Sync Adapter believes that the sync failed, and therefore will replay the same message again the next time it tries to sync.
I am not sure if you are syncing one event at a time so I can't offer a definitive solution. However, what you can do is change the default behaviour of the Sync Adapter to stop it from replaying "failed" messages.
Bundle extras = new Bundle();
...
extras.putBoolean(ContentResolver.SYNC_EXTRAS_DO_NOT_RETRY, true);
CalendarConstants.AUTHORITY, true);
ContentResolver.requestSync(mAccount, CalendarConstants.AUTHORITY, extras);
In OnSyncCanceled, you can do some light checks to make sure the message succeeded, i.e. is present in the calendar's events table. If not, then manually replay it. If it is present, the SyncAdapter will simply move on to the next message, and you won't get any duplicates.
Alternatively, you could make sure all operations within onPerformSync are atomic.

Make calendar entry readonly

I inserted a calender contract entry like this:
ContentValues values = new ContentValues();
values.put(CalendarContract.Calendars.ACCOUNT_NAME, account.name);
values.put(CalendarContract.Calendars.ACCOUNT_TYPE, account.type);
values.put(CalendarContract.Calendars.NAME, name);
values.put(CalendarContract.Calendars.CALENDAR_DISPLAY_NAME, getDisplayName(account));
values.put(CalendarContract.Calendars.CALENDAR_COLOR, 0xffff0000);
values.put(CalendarContract.Calendars.CALENDAR_ACCESS_LEVEL, CalendarContract.Calendars.CAL_ACCESS_READ);
values.put(CalendarContract.Calendars.OWNER_ACCOUNT, getMailAddressOf(account));
values.put(CalendarContract.Calendars.CALENDAR_TIME_ZONE, TimeZone.getTimeZone("GMT").getDisplayName());
values.put(CalendarContract.Calendars.SYNC_EVENTS, 1);
Uri.Builder builder = CalendarContract.Calendars.CONTENT_URI.buildUpon();
builder.appendQueryParameter(CalendarContract.Calendars.ACCOUNT_NAME, account.name);
builder.appendQueryParameter(CalendarContract.Calendars.ACCOUNT_TYPE, account.type);
builder.appendQueryParameter(CalendarContract.CALLER_IS_SYNCADAPTER, "true");
Uri result = getContext().getContentResolver().insert(builder.build(), values);
This works great, I can enter calender entries etc. But I need to make it now read only so that the user cannot edit the calendar entry.
I thought that when I set CALENDAR_ACCESS_LEVEL to CAL_ACCESS_READ it should be enough to make the calendar read only.
Any idea how to achieve that? By the way I'm testing on a Pixel with Android O.
Don't make the user to be the organizer. When adding the event, the default organizer will be the user. To change it, add this line to the ContentValues when adding the event, assign an organizer email address like this
values.put(CalendarContract.Events.ORGANIZER,"an_organizer_name#gmail.com";
Since the user is not the organizer, the user can still delete the event but not able to edit the event content such as time, title, description, etc.
Well that took some time. In the end I found out that I have to change the mail address of the CalendarContract.Events.ORGANIZER value to prevent that I can edit the calender entry. Just as a hint for others how I sloved the problem I tried a lot of stupid things but then I had the idea to check how it is done in AOSP. So I just searched for "calendar aosp code" and found the code mirrowed on GitHub. After using the code search within the repo I found the method canModifyEvent(...). Now it became oblivious:
public static boolean canModifyEvent(CalendarEventModel model) {
return canModifyCalendar(model)
&& (model.mIsOrganizer || model.mGuestsCanModify);
}
Make sure that the event cannot been edited by guests and by don't be the organizer.
Happy Coding!

Set alarm automomatically when schedule is saved from the DB

I have created a database for schedules, fields are (id integer primary, subject text, description text, DueDateTime DATETIME)
I was able to save the values inserted on the EditTexts and Textview to the database, but I wasn't able to create an alarm for that based on the DueDateTime value. I don't quite understand on how and when should I use the intent service, broadcastreceiver, alarm manager etc.
My goal is to set an alarm for the schedule saved in the database when is on due An activity will popup like this on the screen even if the app is closed or when the device is re-booted.
These are pictures. The character is a picture only and the balloon is also a picture but in there Subject name of the particular data will be written and also the these pictures are clickable, when clicked anywhere from the pictures it will be closed
Ok I found this code https://dhimitraq.wordpress.com/tag/multiple-alarms/ which could (maybe) resolve my problem but I don't understand how he use it, so I can't relate it to my app since he has a lot of things he added (some of are hard-codded) which I don't need much of them, he even added a link to download his sample.
You want to schedule an alarm manager with due date?
You can schedule in the following way.
Code :
get (Due_Date_in_milli_sec - current_date_time_in_milli_sec)
now schedule an alarm manager with resultant milliseconds.in case of system bootup you will need to restart alarm manager again.

How do I set multiple notifications using one date selection?

I need to set multiple notifications at the same time based on a list of mutiple choice questions. I will figure the radio buttons and if statements out later, for now I'm just setting the dates randomly for testing purposes.
If the user selects jan 1st and clicks a button. It will set a notification in the future with a reminder to do an activity. It also saves this information so the user can edit the details if he desires or change a few options.
This part I already have coded and it works just fine. however, It only sets a single notification currently. It is a pretty involved code consisting database, receivers, fragments, etc. that all talk to each other.
As I said, this part I have working just fine but I am not including all the code because it is seriously involved and no one would try to break it down if i drown you in a sea of code. I can certainly post specific code if someone request it.
My issue is that I need it to set a good amount of notifications at various future dates upon the button click, not just one. I need to change the notification message to a preset variable string for each additional notification event but some things like title will remain the same.
my current working code executes like this....
User Selects Jan 1 > User Clicks Button > Notification set for Feb 14 with a unique title and message set by the user and saved for future editing...
At the same time the notifications are set they are saved so the user can change the date and a few options if needed. I want only one title and a single date saved. I have the save feature already working but I need to know how to link the additional reminders to the existing saved item. Im trying to make all the data linked so that if the user deletes the saved item, all the set notifications for that file are deleted and not just the one that falls on the user selected date.
===== This is what I am trying to pull off
User Picks Some Options and Clicks A Button [I have this working already]
Upon Click of said button, the following notifications are all set in the future :
[currently it sets this notification only]
Jan 1 notification :
(title)Day Master App
(message)Happy New Year
[Im trying to figure out how to add the following notifications upon the above button click and also save this information to the existing db under the same item]
Feb 14 notification : (title)Day Master App - (message)Its V Day
March 1 notification : (title)Day Master App - (message)Spring Is Near
March 14 notification : (title)Day Master App - (message)Its probably raining
(((and we'll just pretend i finished the list...)))
I cant make the future notifications a static number because when the future notifications are set is determined by a bunch of radio button choices before the user clicks the execute button. This is going to be a pretty complex and hacky if/else novel the way I think I have to do it. Am I correct?
I have a display/edit listview that shows your saved notifications and the unique name and date the user set. This works fine currently but only sets a single notification based on user input.
I need to add some more notifications but i dont need to save them under a different item or name. I want them all under the same save item so all the notifications that were set when the button was clicked can be added and deleted as a group. There will be no option to delete certain notifications that were set. It will be all or none.
I would imagine I could just add some more variables into the existing "save notification" code? As in piggyback some more items (like all the dates and messages) for the additional notifications? do i need to write a new function for each future notification I set in order to be able to delete it?
do I need to create a new db for each additional notification that is set? A separate Adapter? Im so confused...
===
Im not looking for a code example exactly, I want to know how this would be implemented into an existing code. I realize there is probably 100 ways to code what I have described. I just need the process explained.
Please explain this to me slowly. I know im way overthinking this.
I tried to explain this as best I could, if you need clarification on something please ask. Thank You.
I have solved my problem although I could not accomplish exactly what I was trying to originally.
I managed to set the multiple notifications on a single click with different dates by simply copying the same code I used to display the single notification and simply giving each additional notification a unique ID and creating a new variables to give them individual text, future dates, separate times, etc. These variables can be easily set programmaticly or by the user when you set them up.
// On clicking the set notifications button
public void SetNotificationsButton(View v){
ReminderDatabase rb = new ReminderDatabase(this);
// Creating Original Reminder
int ID = rb.addReminder(new Reminder(mTitle,
mDate, mTime, mRepeat, mRepeatNo, mRepeatType, mActive));
// Create Feeding Notification
int FeedingID = rb.addReminder(new Reminder("Have you fed the cat today?",
mFeedingDate, mFeedingTime, mRepeat, mRepeatNo, mRepeatType, mActive));
}
//
// and just continued copy and pasting the rest of the notification events
// changing the ID for each individual notification. Without a unique ID
// the current notification will override the previous notification and
// appear to only set the last reminder.
I was not able to remove all notifications by selecting a single list item, I probably could have figured this out by grouping the notifications into a separate variable but once I realized that you can only have a maximum of 50 notifications set at any given time it seemed like overkill.
Since I have a repeat option for certain notifications I can keep my notifications set; numbers low and stay away from the 50 at a time limit while still firing a reminder to the user every day.
I found a great example for setting single notifications I used as reference.
https://github.com/blanyal/Remindly
Thank those of you who took the time to read my question.

How to call phone number with respective name in android

Trying to call number with name.It is possible to make name with number calling.
I successfully calling following code:
Intent callIntentp2 = new Intent(Intent.ACTION_CALL);
callIntentp2.setData(Uri.parse("tel: 55555555");
startActivity(callIntentp2);
It's Output looks like
55555555 Dialing
But I want to call with name just like you saved on contact list on your sim.but i have data in manually not from sim.
John 55555555 Dialing
Is that possible.
ACTION_CALL is a native Android intent. When you call it, Android performs background processes that bring up the default call view. There are ways you could chop together some broadcast receiver to overlay an activity on top of the native call screen, but you are asking for trouble on that end. Without a rooted device, this is a difficult process. This question is actually very similar to:
Replace native outgoing call Screen by custom screen android
I haven't read through the link or anything, but I am pretty sure they are going to say the same thing. Without doing some weird, iffy work-around you aren't likely to achieve this.
You could (theoretically) take the time prior to calling to add the number with the attached name to your contacts list. When the call is made, it will show the name and the number (since the name is listed as a contact and that is Android's default action). Once the call is done you could delete the contact so that it doesn't get stuck in a persons contact list that doesn't want it.
A bit of code for example:
ContentValues contactValues = new ContentValues();
contactValues.put(Data.RAW_CONTACT_ID, 001);
contactValues.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
contactValues.put(Phone.NUMBER, "555-555-5555");
contactValues.put(Phone.TYPE, Phone.TYPE_CUSTOM);
contactValues.put(Phone.LABEL, "John");
Uri dataUri = getContentResolver().insert(
android.provider.ContactsContract.Data.CONTENT_URI, contactValues);
Don't forget to add write contact permission to your applications manifest. Again, this is just an option (the only one I can really think of off the top of my head)

Categories

Resources