I have been struggelig for weeks on this, so now I hope someone here can give me some clarity.
The project I'm working on(pre ICS) includes logging on to my company's server, getting my future work schedule and store this on my phone in a seperate calendar. This calendar should them be viewable in all the major calendar apps (Jorte, Business Calendar, Smooth Calendar ++).
I got the schedule parsed and stored on the phone in an SQLite database. But my struggle is getting from there to create a seperate local calendar and store all the events there. I assumed I had to create an account for this (not to mess up any other account on the phone. That worked well with the code:
AccountManager man = (AccountManager) getSystemService(ACCOUNT_SERVICE);
Account acc = new Account("myCalendar", "com.lumabyte.mycalendar");
But I thought creating a calendar on that account would be quite easy with:
ContentValues calendar = new ContentValues();
calendar.put("_sync_account", "myCalendar"); // My account
calendar.put("_sync_account_type","com.lumabyte.mycalendar");
calendar.put("name", "myCalendar");
calendar.put("displayName", "myCalendar");
calendar.put("hidden",0);
calendar.put("color",0xFF008080);
calendar.put("access_level", 700);
calendar.put("sync_events", 1);
calendar.put("timezone", "Europe/Paris");
calendar.put("ownerAccount", sync_account);
Uri calendarUri = Uri.parse(getCalendarUriBase() + "calendars");
this.getContentResolver().insert(calendarUri, calendar);
The function getCalendarUriBase():
private String getCalendarUriBase() {
String calendarUriBase = null;
Uri calendars = Uri.parse("content://calendar/calendars");
Cursor managedCursor = null;
try {
managedCursor = this.managedQuery(calendars, null, null, null, null);
} catch (Exception e) {
// eat
}
if (managedCursor != null) {
calendarUriBase = "content://calendar/";
} else {
calendars = Uri.parse("content://com.android.calendar/calendars");
try {
managedCursor = this.managedQuery(calendars, null, null, null, null);
} catch (Exception e) {
// eat
}
if (managedCursor != null) {
calendarUriBase = "content://com.android.calendar/";
}
}
managedCursor.close();
return calendarUriBase;
}
The manifest includes:
<uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS"/>
<uses-permission android:name="android.permission.USE_CREDENTIALS" />
<uses-permission android:name="android.permission.MAMAGE_ACCOUNTS"/>
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.READ_CALENDAR">
<uses-permission android:name="android.permission.WRITE_CALENDAR">
and my authenticator.xml is like this:
<?xml version="1.0" encoding="utf-8"?>
<account-authenticator xmlns:android="http://schemas.android.com/apk/res/android"
android:accountType="com.lumabyte.mycalendar"
android:icon="#drawable/icon"
android:smallIcon="#drawable/icon"
android:label="#string/authenticator_label"
/>
I do not get any error messages, but only the account is created, and not the calendar. Is there a small error in the code, or have I misunderstood the whole concept. I know there is no API pre ICS, and that there is risks involved. But I need it done anyway. Prefeably stable on as many phones as possible. Any help or examples would be greatly appreciated.
I'll work with ICS later as I understand they now have i public API for that.
r
hiii rudder............. I have add a calender in 2.3.6 using the following code after lot of R&D.........
ContentValues calendar=new ContentValues();
Uri calendarUri =Uri.parse(getBaseCalUri() + "/calendars");
calendar.put("_sync_account", "Test1");
calendar.put("_sync_account_type", "LOCAL");
calendar.put("name", "CalenTest");
calendar.put("displayName", "calDispName");
calendar.put("color", 0xFF008080);
calendar.put("access_level", 700);
calendar.put("ownerAccount", true);
calendar.put("sync_events", 1);
calendarUri = calendarUri.buildUpon()
.appendQueryParameter("_sync_account", "Test1")
.appendQueryParameter("_sync_account_type", "LOCAL")
.build();
Uri result = getContentResolver().insert(calendarUri, calendar);
and my getBaseCalUri() is
private Uri getBaseCalUri(){
Class<?> calendarProviderClass;
Field uriField;
Uri calendarUri=null;
try {
calendarProviderClass = Class.forName("android.provider.Calendar");
uriField = calendarProviderClass.getField("CONTENT_URI");
calendarUri = (Uri) uriField.get(null);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchFieldException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return calendarUri;
}
try this....
Just add a records in the calendar.db
/data/data/com.android.providers.calendar/databases/calendar.db
as
sqlite3 calendar.db "insert into Calendars (_id,name,displayName,access_level) values (0,'Local','MyCal',700)"
This is a good way that I tried, I hope it helps:
/**
* Add a calendar event.
*/
private void addCalendarEvent(){
Context context = getContext();
Intent intent = new Intent(Intent.ACTION_EDIT);
intent.setType("vnd.android.cursor.item/event");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra("beginTime", stTime);
intent.putExtra("allDay", true);
intent.putExtra("description", description);
intent.putExtra("eventLocation", place);
intent.putExtra("rrule", "FREQ=YEARLY");
intent.putExtra("endTime", enTime);
intent.putExtra("title", category);
context.startActivity(intent);
}
Related
Yesterday I was looking into a way to acquire the call log of an android device.
My idea was to acquire everything posible and then parse it and get only what I really needed.
Following the documentation See CallLog.Calls Documentation I saw the different fields there are but when trying to get them I got erros caused by differences in the documentation.
Finally I got it to work so I wanted to share the code in case anyone else needs it.
In the code I use JSON objects and save them in the Documents folder.
private void getCallLog(Context context) {
#SuppressLint("MissingPermission") Cursor cursor = getApplicationContext().getContentResolver().query(CallLog.Calls.CONTENT_URI, null, null,
null, CallLog.Calls.DATE + " DESC");
if (cursor.getCount() > 0) {
try{
// Get the directory for the user's public pictures directory.
final File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS);
// Make sure the path directory exists.
if (!path.exists()) {
// Make it, if it doesn't exit
path.mkdirs();
}
final File file = new File(path, "call.txt");
file.createNewFile();
FileOutputStream fOut = new FileOutputStream(file);
OutputStreamWriter myOutWriter = new OutputStreamWriter(fOut);
while (cursor.moveToNext()) {
try {
JSONObject object = new JSONObject();
object.put("ANSWERED_EXTERNALLY_TYPE", CallLog.Calls.ANSWERED_EXTERNALLY_TYPE);
object.put("BLOCKED_TYPE", CallLog.Calls.BLOCKED_TYPE);
object.put("CACHED_FORMATTED_NUMBER", cursor.getString(cursor.getColumnIndex(CallLog.Calls.CACHED_FORMATTED_NUMBER)));
object.put("CACHED_LOOKUP_URI", cursor.getString(cursor.getColumnIndex(CallLog.Calls.CACHED_LOOKUP_URI)));
object.put("CACHED_MATCHED_NUMBER", cursor.getString(cursor.getColumnIndex(CallLog.Calls.CACHED_MATCHED_NUMBER)));
object.put("CACHED_NAME", cursor.getString(cursor.getColumnIndex(CallLog.Calls.CACHED_NAME)));
object.put("CACHED_NORMALIZED_NUMBER", cursor.getString(cursor.getColumnIndex(CallLog.Calls.CACHED_NORMALIZED_NUMBER)));
object.put("CACHED_NUMBER_LABEL", cursor.getString(cursor.getColumnIndex(CallLog.Calls.CACHED_NUMBER_LABEL)));
object.put("CACHED_NUMBER_TYPE", cursor.getString(cursor.getColumnIndex(CallLog.Calls.CACHED_NUMBER_TYPE)));
object.put("CACHED_PHOTO_ID", cursor.getString(cursor.getColumnIndex(CallLog.Calls.CACHED_PHOTO_ID)));
object.put("CACHED_PHOTO_URI", CallLog.Calls.CACHED_PHOTO_URI); // Wrong docs
object.put("CONTENT_ITEM_TYPE", CallLog.Calls.CONTENT_ITEM_TYPE); // Wrong docs
object.put("CONTENT_TYPE", CallLog.Calls.CONTENT_TYPE); // Wrong docs
object.put("COUNTRY_ISO", cursor.getString(cursor.getColumnIndex(CallLog.Calls.COUNTRY_ISO)));
object.put("DATA_USAGE", cursor.getString(cursor.getColumnIndex(CallLog.Calls.DATA_USAGE)));
object.put("DATE", cursor.getString(cursor.getColumnIndex(CallLog.Calls.DATE)));
object.put("DEFAULT_SORT_ORDER", CallLog.Calls.DEFAULT_SORT_ORDER); // Wrong docs
object.put("DURATION", cursor.getString(cursor.getColumnIndex(CallLog.Calls.DURATION)));
object.put("EXTRA_CALL_TYPE_FILTER", CallLog.Calls.EXTRA_CALL_TYPE_FILTER); // Wrong docs
object.put("FEATURES", cursor.getString(cursor.getColumnIndex(CallLog.Calls.FEATURES)));
object.put("FEATURES_HD_CALL", CallLog.Calls.FEATURES_HD_CALL);
object.put("FEATURES_PULLED_EXTERNALLY", CallLog.Calls.FEATURES_PULLED_EXTERNALLY);
object.put("FEATURES_VIDEO", CallLog.Calls.FEATURES_VIDEO);
object.put("FEATURES_WIFI", CallLog.Calls.FEATURES_WIFI);
object.put("GEOCODED_LOCATION", cursor.getString(cursor.getColumnIndex(CallLog.Calls.GEOCODED_LOCATION)));
object.put("INCOMING_TYPE", CallLog.Calls.INCOMING_TYPE);
object.put("IS_READ", cursor.getString(cursor.getColumnIndex(CallLog.Calls.IS_READ)));
object.put("LAST_MODIFIED", CallLog.Calls.LAST_MODIFIED); // Wrong docs
object.put("LIMIT_PARAM_KEY", CallLog.Calls.LIMIT_PARAM_KEY); // Wrong docs
object.put("MISSED_TYPE", CallLog.Calls.MISSED_TYPE);
object.put("NEW", cursor.getString(cursor.getColumnIndex(CallLog.Calls.NEW)));
object.put("NUMBER", cursor.getString(cursor.getColumnIndex(CallLog.Calls.NUMBER)));
object.put("NUMBER_PRESENTATION", cursor.getString(cursor.getColumnIndex(CallLog.Calls.NUMBER_PRESENTATION)));
object.put("OFFSET_PARAM_KEY", CallLog.Calls.OFFSET_PARAM_KEY); // Wrong docs
object.put("OUTGOING_TYPE", CallLog.Calls.OUTGOING_TYPE);
object.put("PHONE_ACCOUNT_COMPONENT_NAME", cursor.getString(cursor.getColumnIndex(CallLog.Calls.PHONE_ACCOUNT_COMPONENT_NAME)));
object.put("PHONE_ACCOUNT_ID", cursor.getString(cursor.getColumnIndex(CallLog.Calls.PHONE_ACCOUNT_ID)));
object.put("POST_DIAL_DIGITS", CallLog.Calls.POST_DIAL_DIGITS); // Wrong docs
object.put("PRESENTATION_ALLOWED", CallLog.Calls.PRESENTATION_ALLOWED);
object.put("PRESENTATION_PAYPHONE", CallLog.Calls.PRESENTATION_PAYPHONE);
object.put("PRESENTATION_RESTRICTED", CallLog.Calls.PRESENTATION_RESTRICTED);
object.put("PRESENTATION_UNKNOWN", CallLog.Calls.PRESENTATION_UNKNOWN);
object.put("REJECTED_TYPE", CallLog.Calls.REJECTED_TYPE);
object.put("TRANSCRIPTION", cursor.getString(cursor.getColumnIndex(CallLog.Calls.TRANSCRIPTION)));
object.put("TYPE", cursor.getString(cursor.getColumnIndex(CallLog.Calls.TYPE)));
object.put("VIA_NUMBER", CallLog.Calls.VIA_NUMBER); // Wrong docs
object.put("VOICEMAIL_TYPE", CallLog.Calls.VOICEMAIL_TYPE); // Wrong docs
object.put("VOICEMAIL_URI", cursor.getString(cursor.getColumnIndex(CallLog.Calls.VOICEMAIL_URI)));
myOutWriter.append(object.toString());
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
myOutWriter.close();
fOut.flush();
fOut.close();
} catch (Exception e) {
Log.e("Exception", "File write failed: " + e.toString());
}
}
}
When I click phone call button, how to choose skype, viber, sim1 or sim2, ect. Now, it is called by sim2. I want to choose. I search on Google, no found my problem.
Intent intent = new Intent(Intent.ACTION_CALL);
intent.setData(Uri.parse("tel:" + "123456789"));
try {
startActivity(intent);
} catch (Exception e) {
e.printStackTrace();
}
Permissions in Manifest
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
Reset App preferences before starting intent
Settings->Apps/Application Manager -> Default/Downloaded Apps -> Click on overflow icon (i.e. three dots icon on top right of the screen) -> Reset App Preferences.
Your code looks fine.
Intent intent = new Intent(Intent.ACTION_DIAL);
intent.setData(Uri.parse("tel:" + "123456789"));
try {
startActivity(intent);
} catch (Exception e) {
e.printStackTrace();
}
You need to create a sim chooser dialog and set sim 1 and sim 2 options and set simNumber variable according to the choosen sim number(0 for sim1 and 1 for sim2)
Here is the code that I have implemented for calling from specific sim i.e. SIM 1 or SIM 2.
code:
private final static String simSlotName[] = {
"extra_asus_dial_use_dualsim",
"com.android.phone.extra.slot",
"slot",
"simslot",
"sim_slot",
"subscription",
"Subscription",
"phone",
"com.android.phone.DialingMode",
"simSlot",
"slot_id",
"simId",
"simnum",
"phone_type",
"slotId",
"slotIdx"
};
int simNumber = 0 or 1; //0 for sim1 and 1 for sim2
Intent callIntent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:"
+ phoneNumber));
callIntent.setFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
callIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//Add slots here since different device needs different key so put all together
for (String s : simSlotName)
intent.putExtra(s, simNumber);
//This will only work on API 22 or up
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
intent.putExtra("android.telecom.extra.PHONE_ACCOUNT_HANDLE", (Parcelable) SimSlotHelper.getAccountHandles(context).get(simNumber))
context.startActivity(intent);
Here is a class for sim slot helper which will get phone account handle list by using telecom manager for both sims
code:
public class SimSlotHelper {
public static List getAccountHandles(Context context) {
Class c;
Method m;
TelecomManager telecomManager;
List<PhoneAccountHandle> accountHandles;
TelephonyManager telephony;
telephony = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
try {
c = Class.forName("android.telecom.TelecomManager");
Method m1 = c.getMethod("from", Context.class);
telecomManager = (TelecomManager) m1.invoke(null, context);
m = c.getMethod("getCallCapablePhoneAccounts");
accountHandles = (List<PhoneAccountHandle>) m.invoke(telecomManager);
return accountHandles;
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return null;
}
}
Try using .ACTION_DIAL instead of .ACTION_CALL . This opens a Dialog chooser with apps installed in the device with capability of calling.
Intent intent = new Intent(Intent.ACTION_DIAL);
intent.setData(Uri.parse("tel:" + "123456789"));
try {
startActivity(intent);
} catch (Exception e) {
e.printStackTrace();
}
I am developing an application which needs to send sms in pdu mode.
I am using this code but it gives NoSuchElementException on first line.
try {
Method m2 = sms.getClass().getDeclaredMethod("sendRawPdu", pdu.getClass(), pdu.getClass(), piSent.getClass(), piDelivered.getClass());
m2.setAccessible(true);
SmsMessage.SubmitPdu pdus = SmsMessage.getSubmitPdu(null, "", "Test", false);
Object[] arrayOfObject2 = new Object[5];
arrayOfObject2[0] = pdus.encodedScAddress;
arrayOfObject2[1] = pdus.encodedMessage;
arrayOfObject2[2] = piSent;
arrayOfObject2[3] = piDelivered;
arrayOfObject2[4] = null;
try {
m2.invoke(sms, arrayOfObject2);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
Any help will be appreciated.
I tried it on Lollipop, but there is no method related to sendRawPdu
Do a little more thing just print the list of methods available to check if there is any method related to sendRawPdu
Method[] methods = sms.getClass().getDeclaredMethods();
boolean methodAvailable = false;
for(Method m : methods) {
Log.d("SmsManager", m.toString());
if(m.toString().contains("sendRawPdu")) {
methodAvailable = true;
}
}
now you have methodAvailable, if it is true you can send Raw PDU, if not then you can't. sendRawPdu was available before JellyBeans. Try to run this on Pre JellyBeans devices.
I can receive my mails with Imap with this code sample :
URLName server = new URLName("imaps://" + username + ":"+ password + "#imap.gmail.com/INBOX");
Session session = Session.getDefaultInstance(new Properties(), null);
Folder folder = session.getFolder(server);
if (folder == null)
{
System.exit(0);
}
folder.open(Folder.READ_ONLY);
Message[] messages = folder.getMessages();
But sometimes Imap doesn't give any service and at those times I want to use Pop but I couldn't use it with my code. It is different the other codes for using receive mail. But in Android only this code is working.
What should I change in this code to work with Pop?
First, there's a nice URLName constructor that takes all the component pieces as separate parameters, so you don't have to do string concatenation.
Switch from IMAP to POP3 requires changing the protocol name as well as the host name. See the JavaMail FAQ for examples. The protocol name is "pop3s" and the host name is "pop.gmail.com".
Finally, you should use Session.getInstance instead of Session.getDefaultInstance. Compare the javadocs for the two methods to understand why.
How about this one.Really worked for me!!(Source:here)
String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";
Properties pop3Props = new Properties();
pop3Props.setProperty("mail.pop3.socketFactory.class", SSL_FACTORY);
pop3Props.setProperty("mail.pop3.socketFactory.fallback", "false");
pop3Props.setProperty("mail.pop3.port", "995");
pop3Props.setProperty("mail.pop3.socketFactory.port", "995");
URLName url = new URLName("pop3", "pop.gmail.com", 995, "","youremailid#gmail.com",yourpassword);
Session session = Session.getInstance(pop3Props, null);
Store store = new POP3SSLStore(session, url);
try {
store.connect();
} catch (MessagingException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
Folder folder = null;
try {
folder = store.getDefaultFolder();
folder = folder.getFolder("INBOX");
} catch (MessagingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (folder == null) {
System.exit(0);
}
try {
folder.open(Folder.READ_ONLY);
} catch (MessagingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Try retreiving folder via store object.And also mention that the folder you wish to retreive is INBOX!Also note that in settings,port number is 995 form pop.(You may leave the first six lines as they are.)
I can successfully insert a new record using People.CONTENT_URL according to http://developer.android.com/guide/topics/providers/content-providers.html#addingrecord.
But the People class is deprecated, So i would like to using ContentProviderOperation and Data.CONTENT_URL to insert record. here is my code.
super.onCreate(savedInstanceState);
ArrayList operations = new ArrayList();
operations.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
.withValue(Phone.CONTACT_ID, "23").withValue(CommonDataKinds.Phone.NUMBER,
"13412341234123412341234").build());
try {
getContentResolver().applyBatch(ContactsContract.AUTHORITY, operations);
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (OperationApplicationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
According to my understanding, you simply want to add a new contact, right?
I have answered the question Here. I have used the same piece of code and it works for me.
If you are trying to add a new contact try this code :
Intent intent = new Intent(Intent.ACTION_INSERT);
intent.setType(ContactsContract.Contacts.CONTENT_TYPE);
intent.putExtra(ContactsContract.Intents.Insert.NAME, "name");
intent.putExtra(ContactsContract.Intents.Insert.PHONE, "123456");
startActivity(intent);