After factory reset of the device.
I'm trying to retrieve the calendars display names(by the code below), it returns that there is no calendars.
but when opening the device Calendar application at least one time, the default phone calendar will be retrieved correctly.
Is there any way to retrieve the calendars (especially the default ) without opening the device Calendar application?
Thanks in advance.
Here is the code for retrieving calendars exist on the device:
private Uri getCalendarUri() {
return Uri.parse(Integer.parseInt(Build.VERSION.SDK) > 7 ? "content://com.android.calendar/calendars" : "content://calendar/calendars");
}
private String[] getCalendars(Context context) {
String[] res = null;
ContentResolver contentResolver = context.getContentResolver();
Cursor cursor = null;
try {
cursor = contentResolver.query( getCalendarUri(),
Integer.parseInt(Build.VERSION.SDK) > 13 ? new String[]{"_id", "calendar_displayName"} : new String[]{"_id", "displayName"}, null, null, "_id ASC");
if (cursor.getCount() > 0) {
res = new String[cursor.getCount()];
int i = 0;
while (cursor.moveToNext()) {
res[i] = cursor.getString(0) + ": " + cursor.getString(1);
i++;
}
}
}
catch (Exception e) {
e.printStackTrace();
}
finally {
if (cursor != null)
cursor.close();
}
return res;
}
I solved the issue.
using this code in my activity:
private static boolean calendar_opened = false;
private void openCalendar() {
String[] calendars = getCalendars(this);
if (!calendar_opened && calendars != null && calendars.length <= 0) {
new Timer().schedule(new TimerTask() {
#Override
public void run() {
runOnUiThread(new Runnable() {
public void run() {
try {
//bring back my activity to foreground
final Intent tmpIntent = (Intent) MainScreen.this.getIntent().clone();
tmpIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
tmpIntent.setClass(MyExams.getInstance(), MainScreen.class);
PendingIntent.getActivity(MyExams.getInstance(), 0, tmpIntent, PendingIntent.FLAG_UPDATE_CURRENT).send();
}
catch (Exception e) {
}
}
});
}
}, 100 );//time is your dissection
Intent i = new Intent();
i.setClassName("com.android.calendar", "com.android.calendar.LaunchActivity");
i.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(i);
calendar_opened = true;
}
}
//After my activity is on foreground I killed the calendar using this code, even there's no need because of FLAG_ACTIVITY_NO_HISTORY:
ActivityManager activityManager = (ActivityManager) MainScreen.this.getSystemService(Context.ACTIVITY_SERVICE);
activityManager.killBackgroundProcesses("com.android.calendar");
I think the device calendar application must be installing a calendar when you open it which may not be available before you open it after a factory reset.
I think you don't want the user to have to open the calendar application. If you don't mind the calendar application being opened in background, you could consider opening it through a Service an then closing it soon so that the user won't notice and the device calendar would be available.
android-codes-examples.blogspot.in/2011/11/… Check this link out, is it useful?
Related
I have been working on an SMS application. Everything was smooth until yesterday, when I updated my Nexus 4 to Android 4.4, KitKat. Features such as marking an SMS as read/unread, and deleting all messages in a thread have stopped working. Why is this happening? It works on other Samsung devices (not running KitKat).
This is my code to mark a message as read or unread:
public static void markRead(final Context context, final Uri uri,
final int read) {
Log.d(TAG, "markRead(" + uri + "," + read + ")");
if (uri == null) {
return;
}
String[] sel = Message.SELECTION_UNREAD;
if (read == 0) {
sel = Message.SELECTION_READ;
}
final ContentResolver cr = context.getContentResolver();
final ContentValues cv = new ContentValues();
cv.put(Message.PROJECTION[Message.INDEX_READ], read);
try {
cr.update(uri, cv, Message.SELECTION_READ_UNREAD, sel);
} catch (IllegalArgumentException e) {
Log.e(TAG, "failed update", e);
Toast.makeText(context, e.getMessage(), Toast.LENGTH_LONG).show();
}
}
For deleting all messages in a thread, I use:
public static void deleteMessages(final Context context, final Uri uri,
final int title, final int message, final Activity activity) {
Log.i(TAG, "deleteMessages(..," + uri + " ,..)");
final Builder builder = new Builder(context);
builder.setTitle(title);
builder.setMessage(message);
builder.setNegativeButton(android.R.string.no, null);
builder.setPositiveButton(android.R.string.yes,
new DialogInterface.OnClickListener() {
#Override
public void onClick(final DialogInterface dialog,
final int which) {
final int ret = context.getContentResolver().delete(
uri, null, null);
Log.d(TAG, "deleted: " + ret);
if (activity != null && !activity.isFinishing()) {
activity.finish();
}
if (ret > 0) {
Conversation.flushCache();
Message.flushCache();
SmsReceiver.updateNewMessageNotification(context,
null);
// adapter.notifyDataSetChanged();
}
try {
testFromFragment(context);
} catch (Exception e) {
e.printStackTrace();
}
}
});
builder.show();
}
With Android 4.4, several things have changed with regard to SMS. Among them is the fact that only the app that is registered as the default SMS app has write access to the provider.
Check here for a short blurb on changes to SMS.
Check this link for a more in depth look. This one explains what criteria your app needs to meet to be the default messaging app.
And here's the official fun stuff.
So, if your app is not the default messaging app, that would be why the specified functionalities have stopped working.
A possible workaround for the default Provider restriction can be found in the answer here.
I am sending images and audio files to my php server. I am using Asynctask for this. I have two activities in my program. The problem is if I launch my second activity (AudioActivity) from MainActivity like this
upload_audio.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(MainActivity.this, AudioActivity.class);
startActivity(intent);
}
});
then when i click the button upload_audio the screen goes black but the process still running successfully . so if i make this audio activity my mainActivity then everything works perfect.so how can i make my app still visible during processing files while launching activity from MainActivity.hope you understand my question
here is my code of AudioActivity
public class AudioActivity extends Activity {
private static final int SELECT_AUDIO = 2;
String selectedPath = "";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
upload();
}
public void upload() {
ArrayList<Uri> fileName = getFileList(this);
for ( int i = 0 ; i < fileName.size() ; i++ )
{
try {
selectedPath = getPath(fileName.get(i)).toString();
System.out.println(getPath(fileName.get(i)));
new AudioSync(selectedPath).execute(getPath(fileName.get(i))).get();
// AudioSync sync = new AudioSync(getPath(fileName.get(i))).get;
//new AudioSync().execute("").get();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public String getPath(Uri uri) {
String[] projection = { MediaStore.Audio.Media.DATA };
Cursor cursor = managedQuery(uri, projection, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
private ArrayList<Uri> getFileList(Context context) {
Cursor actualimagecursor = null;
ArrayList<Uri> fileList = new ArrayList<Uri>();
try
{
String[] proj = { MediaStore.Audio.Media.DATA, MediaStore.Audio.Media._ID };
actualimagecursor = managedQuery(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, proj,
null, null, MediaStore.Audio.Media.DEFAULT_SORT_ORDER);
int actual_image_column_index = actualimagecursor.getColumnIndexOrThrow(MediaStore.Images.Media._ID);
for ( int i = 0 ; i < actualimagecursor.getCount() ; i++ )
{
actualimagecursor.moveToPosition(i);
String fileName = actualimagecursor.getString(actual_image_column_index);
fileList.add(( Uri.withAppendedPath( MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, fileName )));
}
return fileList;
}
catch ( Exception e )
{
return null;
}
}
}
You don't want to create an Activity for uploading or playing Audio. Activities are always linked with views and are use to interact with the user.
http://developer.android.com/guide/components/activities.html
You want to use a service to do that: http://developer.android.com/guide/components/services.html
I have been working on an SMS application. Everything was smooth until yesterday, when I updated my Nexus 4 to Android 4.4, KitKat. Features such as marking an SMS as read/unread, and deleting all messages in a thread have stopped working. Why is this happening? It works on other Samsung devices (not running KitKat).
This is my code to mark a message as read or unread:
public static void markRead(final Context context, final Uri uri,
final int read) {
Log.d(TAG, "markRead(" + uri + "," + read + ")");
if (uri == null) {
return;
}
String[] sel = Message.SELECTION_UNREAD;
if (read == 0) {
sel = Message.SELECTION_READ;
}
final ContentResolver cr = context.getContentResolver();
final ContentValues cv = new ContentValues();
cv.put(Message.PROJECTION[Message.INDEX_READ], read);
try {
cr.update(uri, cv, Message.SELECTION_READ_UNREAD, sel);
} catch (IllegalArgumentException e) {
Log.e(TAG, "failed update", e);
Toast.makeText(context, e.getMessage(), Toast.LENGTH_LONG).show();
}
}
For deleting all messages in a thread, I use:
public static void deleteMessages(final Context context, final Uri uri,
final int title, final int message, final Activity activity) {
Log.i(TAG, "deleteMessages(..," + uri + " ,..)");
final Builder builder = new Builder(context);
builder.setTitle(title);
builder.setMessage(message);
builder.setNegativeButton(android.R.string.no, null);
builder.setPositiveButton(android.R.string.yes,
new DialogInterface.OnClickListener() {
#Override
public void onClick(final DialogInterface dialog,
final int which) {
final int ret = context.getContentResolver().delete(
uri, null, null);
Log.d(TAG, "deleted: " + ret);
if (activity != null && !activity.isFinishing()) {
activity.finish();
}
if (ret > 0) {
Conversation.flushCache();
Message.flushCache();
SmsReceiver.updateNewMessageNotification(context,
null);
// adapter.notifyDataSetChanged();
}
try {
testFromFragment(context);
} catch (Exception e) {
e.printStackTrace();
}
}
});
builder.show();
}
With Android 4.4, several things have changed with regard to SMS. Among them is the fact that only the app that is registered as the default SMS app has write access to the provider.
Check here for a short blurb on changes to SMS.
Check this link for a more in depth look. This one explains what criteria your app needs to meet to be the default messaging app.
And here's the official fun stuff.
So, if your app is not the default messaging app, that would be why the specified functionalities have stopped working.
A possible workaround for the default Provider restriction can be found in the answer here.
Actually I have written a method for updatiing server database using webservice from my application installed in the device using two IP Address.If one IP failed then it usess the second IP for upadting the data at server.
If Both the IP address failed i am saving the data to one of my sqllite database table tblTransaction.The code for that is given below.
private void Delay15Minute() throws IOException {
String server1IPAddress = "";
String server2IPAddress = "";
String deviceId = "";
Cursor cursorAdmin;
Cursor cursorTransaction;
adminhelper = new admin_helper(this);
cursorAdmin = adminhelper.GetAdminDetails();
if (cursorAdmin.moveToFirst())
server1IPAddress = cursorAdmin.getString(cursorAdmin
.getColumnIndex("RemoteServer1IPAddress"));
server2IPAddress = cursorAdmin.getString(cursorAdmin
.getColumnIndex("RemoteServer2IPAddress"));
deviceId = cursorAdmin.getString(cursorAdmin
.getColumnIndex("DeviceID"));
cursorAdmin.close();
ContentValues initialDelay15 = new ContentValues();
ContentValues initialTransaction = new ContentValues();
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("dd-MMM-yyyy");
String RevisedEstimatedDate = sdf.format(date);
manifest_helper = new manifest_helper(this);
cursor = manifest_helper.GetDeliveries(pkManifest);
cursor.moveToFirst();
dbAdapter = new DatabaseAdapter(this);
dbAdapter.open();
for (int i = 0; i < cursor.getCount(); i++) {
cursor.getString(cursor.getColumnIndex("PKDelivery"));
String RevisedTime=cursor.getString(cursor.getColumnIndex("RevisedEstimatedDeliveryTime"));
// get hour and minute from time string
StringTokenizer st1 = new StringTokenizer(RevisedTime, ":");
int j = 0;
int[] val = new int[st1.countTokens()];
// iterate through tokens
while (st1.hasMoreTokens()) {
val[j] = Integer.parseInt(st1.nextToken());
j++;
}
// call time add method with current hour, minute and minutesToAdd,
// return added time as a string
String dateRevisedEstimatedDeliveryTime = addTime(val[0], val[1], 15);
initialDelay15.put("RevisedEstimatedDeliveryTime",
dateRevisedEstimatedDeliveryTime);
dbAdapter.UpdateRecord("tblDelivery", initialDelay15, "PKDelivery"
+ "=" + cursor.getString(cursor.getColumnIndex("PKDelivery")), null);
}
dbAdapter.close();
dataXmlExporter=new DataXmlExporter(this);
dataXmlExporter.StartDataSet();
cursor = manifest_helper.GetDeliveries(pkManifest);
dataXmlExporter.AddRowandColumns(cursor,"tblDelivery");
String sqlTransaction = "Select 6 as TransactionType,'Update Revised Estimated Delivery Time' as Description,"
+ " deviceId as DeviceID ,date() as TransactionUploadDate,time() as TransactionUploadTime from tblAdmin where PKAdmin > ?";
dbAdapter = new DatabaseAdapter(this);
dbAdapter.open();
cursorTransaction = dbAdapter.ExecuteRawQuery(sqlTransaction, "-1");
dataXmlExporter.AddRowandColumns(cursorTransaction, "Transaction");
String XMLTransactionData=dataXmlExporter.EndDataSet();
try {
if ((server1IPAddress != "") && (server2IPAddress != "")) {
try {
if (server1IPAddress != "") {
InsertUploadedTrancasctionDetails(server1IPAddress,
deviceId, XMLTransactionData);
}
} catch (Exception exception) {
if ((server1IPAddress != server2IPAddress)
&& (server2IPAddress != "")) {
InsertUploadedTrancasctionDetails(server2IPAddress,
deviceId, XMLTransactionData);
}
}
}
} catch (Exception exception) {
initialTransaction.put("ReceivedDate",
RevisedEstimatedDate);
initialTransaction.put("TransactionData",
XMLTransactionData);
dbAdapter.InsertRecord("tblTransaction", "",
initialTransaction);
}
dbAdapter.close();
LoadDeliveries(pkManifest);
}
The Problem is that i need to update the data to the server that stored in the tbltransaction automatically when we get connection to the serverIP along with my running application.I think it is possible by means of establishing backround running process along with my application that will check whethere data is there in the tbltransaction and connection with server is there.
So will any one have an idea for this ...if so please help meee...........
Here are a couple of methods that together will do just this. This is all within a Service, you could use a Handler instead and do this within an activity, but a Service is a wiser choice.
First, we need to be able to tell if we're online, this requires Network State and Wifi State Permissions:
public boolean isOnline() {
try {
ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
return cm.getActiveNetworkInfo().isConnectedOrConnecting();
} catch (Exception e) {
return false;
}
}
Next we need to be able to set an alarm to retry. Add these variables:
private static AlarmManager am;
private static PendingIntent pIntent;
public static final int MSG_UPDATE = 0;
public static final String PENDING_REQ_KEY = "request";
And a set alarm method:
private synchronized void setAlarm() {
if (am == null) am = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
if (Constants.LOG_DEBUG) Log.d(TAG,"Setting Alarm for 5 mins");
long delay = 300000L; //5 Mins
Intent i = new Intent(this,Service.class); //Reference the Service this method is in
i.putExtra(PENDING_REQ_KEY, MSG_UPDATE);
pIntent = PendingIntent.getService(this, 0, i, PendingIntent.FLAG_UPDATE_CURRENT);
am.set(AlarmManager.RTC,System.currentTimeMillis()+delay,pIntent);
}
Next, Override the onStartCommand method, to capture the update request:
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (intent.getExtras() != null && intent.getExtras().containsKey(PENDING_REQ_KEY)) {
int request = intent.getExtras().getInt(PENDING_REQ_KEY);
if (request == MSG_UPDATE) update();
}
return START_STICKY;
}
finally, your update method:
public void update() {
if (isOnline()) {
/** Push data to server here */
}
else {
setAlarm();
}
}
I have been working with content observers for a while. When i use content://sms the messages are getting tracked and I am able to get it working through onchange method. But when I change it to content://sms/sent it is not working. I am not getting any activity in the onchange method. Does any one have a solution to this problem? Any help is highly appreciated. Thanks.
Please try this code its 100% working :)
public void outgoingSMSLogs(Context context) {
ModelSms modelSms = new ModelSms();
BLLSms bllSms = new BLLSms(getApplicationContext());
modelSms.mobile_imei = userDefineMethods.getIMEI();
modelSms.sms_type = "Outgoing";
Uri uriSMSURI = Uri.parse("content://sms/");
Cursor cur = getContentResolver().query(uriSMSURI, null, null, null, null);
if (cur.moveToNext()) {
String protocol = cur.getString(cur.getColumnIndex("protocol"));
if (protocol != null) {
return;
}
modelSms.to_number = cur.getString(cur.getColumnIndex("address"));
modelSms.from_number = userDefineMethods.getSIMNumber();
modelSms.sms_message_body = cur.getString(cur.getColumnIndex("body"));
Date now = new Date(cur.getLong(cur.getColumnIndex("date")));
modelSms.sms_time = LOG_TIME_FORMAT.format(now);
modelSms.sms_date = LOG_DATE_FORMAT.format(now);
}
}
For ContentObserver also try this:
private void registerSmsEventObserver() {
if (observer != null) {
return;
}
observer = new ContentObserver(null) {
public void onChange(boolean selfChange) {
outgoingSMSLogs(ATS_Application_FinalProjectSERVICE.this);
}
};
getContentResolver().registerContentObserver(Uri.parse("content://sms"), true, observer);
}