I'm trying to implement a ContentObserver for CallLog.Calls content provider. I mean, If I make a call, or receive a call, etc, the observer must notify me that the CallLog.Calls content provider has changed. But the onchange method only returns false, even with the observers registered, and notified. Maybe I'm doing something wrong.
This is my code. It's an Activity.
package com.psyhclo;
public class RatedCalls extends ListActivity {
private static final String LOG_TAG = "RatedCallsObserver";
private Handler handler = new Handler();
private RatedCallsContentObserver callsObserver = null;
private SQLiteDatabase db;
private CallDataHelper dh = null;
StringBuilder sb = new StringBuilder();
OpenHelper openHelper = new OpenHelper(RatedCalls.this);
class RatedCallsContentObserver extends ContentObserver {
public RatedCallsContentObserver(Handler h) {
super(h);
}
public void onChange(boolean selfChange) {
Log.d(LOG_TAG, "RatedCallsContentObserver.onChange( " + selfChange
+ ")");
}
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
registerContentObservers();
fillList();
}
#Override
public void onStart() {
super.onStart();
registerContentObservers();
}
#Override
public void onStop() {
super.onStop();
unregisterContentObservers();
}
private void fillList() {
Cursor cursor = getContentResolver().query(
android.provider.CallLog.Calls.CONTENT_URI, null, null, null,
android.provider.CallLog.Calls.DATE + " DESC ");
cursor.setNotificationUri(getBaseContext().getContentResolver(),
android.provider.CallLog.Calls.CONTENT_URI);
dh = new CallDataHelper(this);
db = openHelper.getWritableDatabase();
startManagingCursor(cursor);
int numberColumnId = cursor
.getColumnIndex(android.provider.CallLog.Calls.NUMBER);
int durationId = cursor
.getColumnIndex(android.provider.CallLog.Calls.DURATION);
int contactNameId = cursor
.getColumnIndex(android.provider.CallLog.Calls.CACHED_NAME);
int dateId = cursor.getColumnIndex(android.provider.CallLog.Calls.DATE);
int numTypeId = cursor
.getColumnIndex(android.provider.CallLog.Calls.CACHED_NUMBER_TYPE);
// int contactIdColumnId =
// cursor.getColumnIndex(android.provider.ContactsContract.RawContacts.CONTACT_ID);
Date dt = new Date();
int hours = dt.getHours();
int minutes = dt.getMinutes();
int seconds = dt.getSeconds();
String currTime = hours + ":" + minutes + ":" + seconds;
ArrayList<String> callList = new ArrayList<String>();
if (cursor.moveToFirst()) {
do {
String contactNumber = cursor.getString(numberColumnId);
String contactName = cursor.getString(contactNameId);
String duration = cursor.getString(durationId);
String callDate = DateFormat.getDateInstance().format(dateId);
String numType = cursor.getString(numTypeId);
ContentValues values = new ContentValues();
values.put("contact_id", 1);
values.put("contact_name", contactName);
values.put("number_type", numType);
values.put("contact_number", contactNumber);
values.put("duration", duration);
values.put("date", callDate);
values.put("current_time", currTime);
values.put("cont", 1);
getBaseContext().getContentResolver().notifyChange(
android.provider.CallLog.Calls.CONTENT_URI, null);
this.db.insert(CallDataHelper.TABLE_NAME, null, values);
Toast.makeText(getBaseContext(), "Inserted!", Toast.LENGTH_LONG);
callList.add("Contact Number: " + contactNumber
+ "\nContact Name: " + contactName + "\nDuration: "
+ duration + "\nDate: " + callDate);
} while (cursor.moveToNext());
}
setListAdapter(new ArrayAdapter<String>(this, R.layout.listitem,
callList));
ListView lv = getListView();
lv.setTextFilterEnabled(true);
lv.setOnItemClickListener(new android.widget.AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
Toast.makeText(getApplicationContext(),
((TextView) view).getText(), Toast.LENGTH_SHORT).show();
}
});
}
private void registerContentObservers() {
ContentResolver cr = getContentResolver();
callsObserver = new RatedCallsContentObserver(handler);
cr.registerContentObserver(android.provider.CallLog.Calls.CONTENT_URI,
true, callsObserver);
}
private void unregisterContentObservers() {
ContentResolver cr = getContentResolver();
if (callsObserver != null) { // just paranoia
cr.unregisterContentObserver(callsObserver);
callsObserver = null;
}
}
}
This is the answer for this question.
Android onChange() method only returns false
Related
I'm new to android and using sqlite rawquery dynamic where clause condition for the first time and didn't know how to use it. I want to give dynamic value to where clause to get the listview according to particular "mid". How to provide the mid value from SubjectActivty
Here is my code:
TestTable:
public long insert(String id, String time, int mid, String cmarks, String nmarks,
String questions, String testType, String test,String marks) {
log("insert test : " + test);
ContentValues values = new ContentValues();
values.put(KEY_TESTID, id);
values.put(KEY_MID,mid);
values.put(KEY_TEST, test);
values.put(KEY_TIME, time);
values.put(KEY_CMARK, cmarks);
values.put(KEY_NMARK, nmarks);
values.put(KEY_TESTTYPE, testType);
values.put(KEY_QUESTION, questions);
values.put(KEY_Total_Marks, marks);
return db.insert(TABLE_NAME2, null, values);
}
public ArrayList<NotificationListItem> getAllList(
ArrayList<NotificationListItem> privateArrayList) {
openToRead();
privateArrayList.clear();
Cursor cursor = null;
String sql ="SELECT * FROm test_list WHERE mid=?";
cursor= db.rawQuery(sql, null);
log("getAlllist() cursor : " + cursor.getCount());
if (cursor != null) {
log("getAlllist() cursor not null ");
int index = 0;
cursor.moveToFirst();
while (index < cursor.getCount()) {
NotificationListItem item = new NotificationListItem();
int idIndex = cursor.getColumnIndex(TestTable.KEY_TESTID);
int subid= cursor.getColumnIndex(TestTable.KEY_MID);
int nameIndex = cursor.getColumnIndex(TestTable.KEY_TEST);
int idTime = cursor.getColumnIndex(TestTable.KEY_TIME);
int cMarks = cursor.getColumnIndex(TestTable.KEY_CMARK);
int nMarks = cursor.getColumnIndex(TestTable.KEY_NMARK);
int testTypeIndex = cursor.getColumnIndex(TestTable.KEY_TESTTYPE);
int questions = cursor.getColumnIndex(TestTable.KEY_QUESTION);
item.name = cursor.getString(nameIndex);
item.testID = cursor.getString(idIndex);
item.mid=cursor.getInt(subid);
item.time = cursor.getString(idTime);
item.cmark = cursor.getString(cMarks);
item.nmark = cursor.getString(nMarks);
item.testType = cursor.getString(testTypeIndex);
item.questions = cursor.getString(questions);
index++;
privateArrayList.add(item);
cursor.moveToNext();
}
log(" query(): cursor closing");
cursor.close();
db.close();
db = null;
}
return privateArrayList;
}
SubjectActvity.class
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_subject);
privateListLV = (ListView) findViewById(R.id.privateListLV);
privatelistTable = new SubjectTable(SubjectActivity.this);
testTableStatic = new StaticTestTable(this);
testTable = new TestTable(SubjectActivity.this);
privatelistTable.openToWrite();
privatelistTable.deleteAll();
privatelistTable.insert(10, "Biology");
privatelistTable.insert(20, "Chemistry");
privatelistTable.insert(30, "English");
privatelistTable.insert(40, "Maths");
privatelistTable.insert(50, "GK");
testTable.openToWrite();
testTable.deleteAll();
testTable.insert("1", "10", 10, "5", "2", "2", "Both", "Anatomy", "10");
testTable.insert("2", "10", 20, "5", "2", "2", "Both", "Paper1", "10");
privateArrayList = new ArrayList<NotificationListItem>();
listAdapter = new SubjectCustomListAdapter(this, privateArrayList,
privatelistTable);
privateListLV.setAdapter(listAdapter);
privateListLV.setOnItemClickListener(new OnItemClickListener() {
#SuppressWarnings("unchecked")
public void onItemClick(AdapterView<?> adapter, View arg1,
int position, long arg3) {
NotificationListItem selection = (NotificationListItem) adapter
.getItemAtPosition(position);
String item = selection.getName();
System.out.println("item" +item);
if (!item.contentEquals(" ")) {
subjectid = privatelistTable.getSinlgeEntry(item);
Log.e("selected Value", " " + subjectid);
Intent testact = new Intent(getApplicationContext(),
TestsActivity.class);
testact.putExtra("subject", item);
testact.putExtra("mid",subjectid);
startActivity(testact);
} else {
return;
}
}
});
}
#Override
protected void onResume() {
super.onResume();
updateList();
}
private void updateList() {
privatelistTable.getAllList(privateArrayList);
listAdapter.notifyDataSetChanged();
}
Do as #Der Golem answer OR another way is
Cursor c =db.rawQuery("SELECT * FROM " + tableName + " where mid=" + mid , null);
I want to display the events for only one week in the listView,but I got all the events and it is displaying in the listview.
I am using this code to get the events for particular date ,but is not getting any events from calendar.The event count is 0.I am struct with this problem! How to get events for particular date or week?
public class Meeting extends Activity {
public ConferenceAdapter adapter;
ListView meetingListView;
static Cursor cursor;
private String description = null;
private String where = null;
public String[] number;
static List<GoogleCalendar> gCalendar = null;
private static String startString;
private static String endString;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.ec_meeting);
adapter = new ConferenceAdapter(this);
readCalendar(this);
meetingListView = (ListView) findViewById(R.id.meetinglistView);
meetingListView.setAdapter(new MeetingListViewAdapter(Meeting.this, adapter, gCalendar));
meetingListView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View view, int arg2, long arg3) {
TextView descriptionId1 = ((TextView) view.findViewById(R.id.descriptionmeeting));
TextView where=((TextView) view.findViewById(R.id.wheretextView));
TextView tittle = ((TextView) view.findViewById(R.id.titlemeeting));
Meeting.this.where=where.getText().toString();
description = descriptionId1.getText().toString();
StringBuffer numbers =new StringBuffer();
String a=Meeting.this.where.replaceAll("-","").replaceAll(" ", "").replaceAll("\\(","").replaceAll("\\)","")+description.replaceAll("-","").replaceAll(" ", "").replaceAll("\\(","").replaceAll("\\)","");
if(a.isEmpty()){
Toast.makeText(getApplicationContext(),"Sorry no conference numbers found", Toast.LENGTH_LONG).show();
}else{
Pattern p = Pattern.compile("[0-9]+[0-9]");
Matcher m = p.matcher(a);
while (m.find()) {
Meeting.this.addComma(numbers,m.group().toString());
}
number = numbers.toString().split(",");
Intent intent = new Intent(Meeting.this,EcConferenceNumber.class);
intent.putExtra("strings", number);
startActivity(intent);
finish();
}
}
});
}
public void addComma(StringBuffer updatedString,String value){
if(updatedString.length() >0 && updatedString != null ){
updatedString.append(",");
}
updatedString.append(value);
}
public static void readCalendar(Context context) {
ContentResolver contentResolver = context.getContentResolver();
Calendar c_start = Calendar.getInstance();
c_start.set(2014,2,4,0,0); //Note that months start from 0 (January)
Calendar c_end = Calendar.getInstance();
c_end.set(2013,2,11,0,0); //Note that months start from 0 (January)
String selection = "((dtstart >= "+c_start.getTimeInMillis()+") AND (dtend <= "+c_end.getTimeInMillis()+"))";
String[] selectionArgs = new String[] {startString, endString};
cursor = contentResolver.query(Uri.parse("content://com.android.calendar/events"),
(new String[] { "calendar_id", "title", "description", "dtstart", "dtend", "eventLocation"})
,null,selectionArgs,selection);
gCalendar = new ArrayList<GoogleCalendar>();
try {
System.out.println("Count=" + cursor.getCount());
if (cursor.getCount() > 0) {
System.out.println("the control is just inside of the cursor.count loop");
while (cursor.moveToNext()) {
GoogleCalendar googleCalendar = new GoogleCalendar();
gCalendar.add(googleCalendar);
int calendar_id = cursor.getInt(0);
googleCalendar.setCalendar_id(calendar_id);
String title = cursor.getString(1);
googleCalendar.setTitle(title);
String description = cursor.getString(2);
googleCalendar.setDescription(description);
String dtstart = cursor.getString(3);
googleCalendar.setDtstart(dtstart);
String dtend = cursor.getString(4);
googleCalendar.setDtend(dtend);
String eventlocation = cursor.getString(5);
googleCalendar.setEventlocation(eventlocation);
}
}
} catch (AssertionError ex) {
ex.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}
// inner class for setting the home screen value to the list view
class MeetingListViewAdapter extends BaseAdapter {
private List<GoogleCalendar> calendars = null;
LayoutInflater inflater = null;
public MeetingListViewAdapter(Activity activity, ConferenceAdapter adapter, List<GoogleCalendar> gCalendar) {
this.calendars = gCalendar;
inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return calendars.size();
}
#Override
public Object getItem(int position) {
return position;
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View vi = convertView;
if (convertView == null)
vi = inflater.inflate(R.layout.calendar_events, null);
TextView titleNameTV = (TextView) vi.findViewById(R.id.titlemeeting);
TextView timeTV = (TextView) vi.findViewById(R.id.profileStepCountTV);
TextView whereTv=(TextView) vi.findViewById(R.id.wheretextView);
TextView descriptionTV = (TextView) vi.findViewById(R.id.descriptionmeeting);
GoogleCalendar calendar = calendars.get(position);
titleNameTV.setText(calendar.getTitle());
descriptionTV.setText(calendar.getDescription());
whereTv.setText(calendar.getEventlocation());
return vi;
}
}
Any answer will be helpfull for me to proceed.
Replace this code :
ContentResolver contentResolver = context.getContentResolver();
Calendar c_start = Calendar.getInstance();
c_start.set(2014,2,4,0,0); //Note that months start from 0 (January)
Calendar c_end = Calendar.getInstance();
c_end.set(2013,2,11,0,0); //Note that months start from 0 (January)
String selection = "((dtstart >= "+c_start.getTimeInMillis()+") AND (dtend <= "+c_end.getTimeInMillis()+"))";
String[] selectionArgs = new String[] {startString, endString};
cursor = contentResolver.query(Uri.parse("content://com.android.calendar/events"),
(new String[] { "calendar_id", "title", "description", "dtstart", "dtend", "eventLocation"})
,null,selectionArgs,selection);
With this:
Uri l_eventUri;
Calendar calendar = Calendar.getInstance();
if (Build.VERSION.SDK_INT >= 8) {
l_eventUri = Uri.parse("content://com.android.calendar/events");
} else {
l_eventUri = Uri.parse("content://calendar/events");
}
ContentResolver contentResolver = context.getContentResolver();
String dtstart = "dtstart";
String dtend = "dtend";
String[] l_projection = new String[] { "title", "dtstart", "dtend" };
SimpleDateFormat formatter = new SimpleDateFormat("MM/dd/yy");
// Date dateCC = formatter.parse("04/27/2013");
Date dateCC = formatter.parse("11/13/2013");
calendar.setTime(dateCC);
long after = calendar.getTimeInMillis();
SimpleDateFormat formatterr = new SimpleDateFormat("MM/dd/yy hh:mm:ss");
Calendar endOfDay = Calendar.getInstance();
Date dateCCC = formatterr.parse("17/13/2013 23:59:59");
// Date dateCCC = formatterr.parse(startDate + " 23:59:59");
endOfDay.setTime(dateCCC);
cursor= contentResolver.query(l_eventUri, new String[] { "title",
"dtstart", "dtend" }, "(" + dtstart + ">" + after + " and "
+ dtend + "<" + endOfDay.getTimeInMillis() + ")", null,
"dtstart ASC");
Does this Code will Work on Any Device/Android Version since Froyo 2.2 :
public class SmsObserver extends ContentObserver {
private String Name;
private SharedPreferences myPrefs;
public SmsObserver(Handler handler , Context ctx) {
super(handler);
// TODO Auto-generated constructor stub
context = ctx;
initialPos = getLastMsgId();
}
private Context context;
private static int initialPos;
private static final String TAG = "SMSContentObserver";
private static final Uri uriSMS = Uri.parse("content://sms");
#Override
public void onChange(boolean selfChange) {
super.onChange(selfChange);
queryLastSentSMS();
}
public int getLastMsgId() {
Cursor cur = context.getContentResolver().query(uriSMS, null, null, null, null);
cur.moveToFirst();
int lastMsgId = cur.getInt(cur.getColumnIndex("_id"));
Log.i(TAG, "Last sent message id: " + String.valueOf(lastMsgId));
return lastMsgId;
}
protected void queryLastSentSMS() {
new Thread(new Runnable() {
public void run() {
Cursor cur =
context.getContentResolver().query(uriSMS, null, null, null, null);
if (cur.moveToNext()) {
TelephonyManager tm = (TelephonyManager)
context.getSystemService(Context.TELEPHONY_SERVICE);
String myDeviceId = tm.getDeviceId();
String myTelephoneNumber = tm.getLine1Number();
Calendar c = Calendar.getInstance();
int day = c.get(Calendar.DAY_OF_MONTH);
int month = c.get(Calendar.MONTH);
int year = c.get(Calendar.YEAR);
int hour = c.get(Calendar.HOUR);
int minute = c.get(Calendar.MINUTE);
int seconde = c.get(Calendar.SECOND);
try {
String body = cur.getString(cur.getColumnIndex("body"));
String reformated_body =
Normalizer.normalize(body, Normalizer.Form.NFD).replaceAll(
"[^\\p{ASCII}]", "");
if (initialPos != getLastMsgId()) {
myPrefs = context.getSharedPreferences("Preferences", Context.MODE_WORLD_WRITEABLE);
getDisplayNameFromPhoneNo(cur.getString(cur.getColumnIndex("address")));
final String finalTxt = context.getResources().getString(R.string.txtSMSSent) + " " + Name + " " + cur.getString(cur.getColumnIndex("address")) + " " + context.getResources().getString(R.string.txtSMSMessage) + reformated_body;
Log.i(TAG, "Reformated Body : " + reformated_body);
Log.i("account", myDeviceId);
Log.i("date", day + "-" + month + "-" + year + " "
+ hour + ":" + minute + ":" + seconde);
Log.i("sender", myTelephoneNumber);
Log.i("receiver", cur.getString(cur.getColumnIndex("address")));
Log.i("message", reformated_body);
if(!cur.getString(cur.getColumnIndex("address")).equals(Gever)){
// Then, set initialPos to the current position.
initialPos = getLastMsgId();
}
}} catch (Exception e) {
// Treat exception here
}
}
cur.close();
}
}).start();
}
public void getDisplayNameFromPhoneNo(String phoneNo) {
ContentResolver localContentResolver = context.getContentResolver();
Cursor contactLookupCursor =
localContentResolver.query(
Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI,
Uri.encode(phoneNo)),
new String[] {PhoneLookup.DISPLAY_NAME, PhoneLookup._ID},
null,
null,
null);
try {
while(contactLookupCursor.moveToNext()){
String contactName = contactLookupCursor.getString(contactLookupCursor.getColumnIndexOrThrow(PhoneLookup.DISPLAY_NAME));
String contactId = contactLookupCursor.getString(contactLookupCursor.getColumnIndexOrThrow(PhoneLookup._ID));
Log.d("LOGTAG", "contactMatch name: " + contactName);
Log.d("LOGTAG", "contactMatch id: " + contactId);
Name = contactName;
}
} finally {
contactLookupCursor.close();
}
}
}//End of class SmsObserver
I received One report from someone that say its does not Work , for me , its working fine , so this : "content://sms" is the Same for All Android Version ?
i Have two activities A and B. i used intent to jump from A to B. now in B.
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.list_main);
LoadData();
}
now in LoadData(), i have to load a lot of data, wo i want that when it B starts, it show a Progress bar and after loading the data, it jumps back to my activity B. how can I do this???
here is my load function
public void LoadData(Context context)
{
String selection = ContactsContract.Contacts.IN_VISIBLE_GROUP + " = '"
+ ("1") + "'";
String sortOrder = ContactsContract.Contacts.DISPLAY_NAME
+ " COLLATE LOCALIZED ASC";
ContentResolver cr = getContentResolver();
// ContactsContract.Contacts.
// Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI, null,
// null, null, ContactsContract.Contacts.DISPLAY_NAME);
// Find the ListView resource.
Cursor cur;
cur = context.getContentResolver().query(
ContactsContract.Contacts.CONTENT_URI,
null,
selection + " AND "
+ ContactsContract.Contacts.HAS_PHONE_NUMBER + "=1",
null, sortOrder);
mainListView = (ListView) findViewById(R.id.mainListView);
// When item is tapped, toggle checked properties of CheckBox and
// Planet.
mainListView
.setOnItemClickListener(new AdapterView.OnItemClickListener()
{
public void onItemClick(AdapterView<?> parent, View item,
int position, long id)
{
ContactsList planet = listAdapter.getItem(position);
planet.toggleChecked();
PlanetViewHolder viewHolder = (PlanetViewHolder) item
.getTag();
viewHolder.getCheckBox().setChecked(planet.isChecked());
}
});
// Create and populate planets.
planets = (ContactsList[]) getLastNonConfigurationInstance();
// planets = new Planet[10];
// planets.Add("asdf");
ArrayList<ContactsList> planetList = new ArrayList<ContactsList>();
String phoneNumber = null;
String phoneType = null;
count = cur.getCount();
contacts = new ContactsList[count];
if (planets == null)
{
if (cur.getCount() > 0)
{
planets = new ContactsList[cur.getCount()];
int i = 0;
//
while (cur.moveToNext())
{
String id = cur.getString(cur
.getColumnIndex(ContactsContract.Contacts._ID));
String name = cur
.getString(cur
.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
if (Integer
.parseInt(cur.getString(cur
.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0)
{
// Query phone here. Covered next
Cursor pCur = cr
.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID
+ " = ?", new String[]
{ id }, null);
// WHILE WE HAVE CURSOR GET THE PHONE NUMERS
while (pCur.moveToNext())
{
// Do something with phones
phoneNumber = pCur
.getString(pCur
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DATA));
phoneType = pCur
.getString(pCur
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE));
Log.i("Pratik", name + "'s PHONE :" + phoneNumber);
Log.i("Pratik", "PHONE TYPE :" + phoneType);
}
pCur.close();
}
if (phoneNumber != null
&& !planetList.contains(new ContactsList(name,
phoneNumber)))
{
planets = new ContactsList[]
{ new ContactsList(name, phoneNumber) };
contacts[i] = planets[0];
planetList.addAll(Arrays.asList(planets));
}
phoneNumber = null;
i++;
}
}
// for (int i = 0; i < count; i++)
// {
// Log.d("New Selected Names : ", contacts[i].getName());
// }
}
// Set our custom array adapter as the ListView's adapter.
listAdapter = new PlanetArrayAdapter(this, planetList);
mainListView.setAdapter(listAdapter);
Adapter adptr;
adptr = mainListView.getAdapter();
}
Please try this
//////////////////////////////////////////////////////////////////
Edit Check It
public class LoadData extends AsyncTask<Void, Void, Void> {
ProgressDialog progressDialog;
//declare other objects as per your need
#Override
protected void onPreExecute()
{
progressDialog= new ProgressDialog(YourActivity.this);
progressDialog.setTitle("Please Wait..");
progressDialog.setMessage("Loading");
progressDialog.setCancelable(false);
progressDialog.show();
//do initialization of required objects objects here
};
#Override
protected Void doInBackground(Void... params)
{
LoadData();
//do loading operation here
return null;
}
#Override
protected void onPostExecute(Void result)
{
super.onPostExecute(result);
progressDialog.dismiss();
};
}
You can call this using
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.list_main);
LoadData task = new LoadData();
task.execute();
}
for more help read android document
http://developer.android.com/reference/android/os/AsyncTask.html
I am agree with Kanaiya's answer because upto the API level-10 it is fine to call long running tasks on UI thread. But from API-11, any task that takes longer time (nearly more than 5 sec) to complete must be done on background thread. The reason behind this is any task that takes 5 seconds or more on UI thread then ANR(Application Not Responding) i.e. force close happens. To do that we have create some background thread or simply make use of AsyncTask.
You just need to call your LoadData() method in another thread.
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.list_main);
mDailog = ProgressDialog.show(ActivityA.this, "",
"Loading data....!!!", true);
mDailog.show();
new Thread() {
#Override
public void run() {
try {
LoadData();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
}.start();
}
Inside your LoadData(), at the end of the method use a handler to send a message to dismiss the progress bar dialog.
Hope this will help you to avoid the complex logic using AsyncTask.
Try this.
public class BActivtiy extends Activity implements Runnable{
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.list_main);
mainListView = (ListView) findViewById(R.id.mainListView);
mainListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View item, int position, long id) {
ContactsList planet = listAdapter.getItem(position);
planet.toggleChecked();
PlanetViewHolder viewHolder = (PlanetViewHolder) item.getTag();
viewHolder.getCheckBox().setChecked(planet.isChecked());
}
});
pd = ProgressDialog.show(BActivity.this, "Title", "Description", true);
Thread t = new Thread(BActivity.this);
t.start();
}
public void LoadData() {
String selection = ContactsContract.Contacts.IN_VISIBLE_GROUP + " = '" + ("1") + "'";
String sortOrder = ContactsContract.Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC";
ContentResolver cr = getContentResolver();
Cursor cur;
cur = this.getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, null, selection + " AND " + ContactsContract.Contacts.HAS_PHONE_NUMBER + "=1", null, sortOrder);
// Create and populate planets.
planets = (ContactsList[]) getLastNonConfigurationInstance();
// planets = new Planet[10];
// planets.Add("asdf");
ArrayList<ContactsList> planetList = new ArrayList<ContactsList>();
String phoneNumber = null;
String phoneType = null;
count = cur.getCount();
contacts = new ContactsList[count];
if (planets == null) {
if (cur.getCount() > 0) {
planets = new ContactsList[cur.getCount()];
int i = 0;
while (cur.moveToNext()) {
String id = cur.getString(cur.getColumnIndex(ContactsContract.Contacts._ID));
String name = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
if (Integer.parseInt(cur.getString(cur.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0) {
// Query phone here. Covered next
Cursor pCur = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?", new String[] { id }, null);
// WHILE WE HAVE CURSOR GET THE PHONE NUMERS
while (pCur.moveToNext()) {
// Do something with phones
phoneNumber = pCur.getString(pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DATA));
phoneType = pCur.getString(pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE));
Log.i("Pratik", name + "'s PHONE :" + phoneNumber);
Log.i("Pratik", "PHONE TYPE :" + phoneType);
}
pCur.close();
}
if (phoneNumber != null && !planetList.contains(new ContactsList(name, phoneNumber))) {
planets = new ContactsList[] { new ContactsList(name, phoneNumber) };
contacts[i] = planets[0];
planetList.addAll(Arrays.asList(planets));
}
phoneNumber = null;
i++;
}
}
// for (int i = 0; i < count; i++)
// {
// Log.d("New Selected Names : ", contacts[i].getName());
// }
}
}
#Override
public void run() {
LoadData();
mHandler.sendEmptyMessage(0);
}
public Handler mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
pd.dismiss();
listAdapter = new PlanetArrayAdapter(BActivtiy.this, planetList);
mainListView.setAdapter(listAdapter);
Adapter adptr;
adptr = mainListView.getAdapter();
}
};
}
Hey, I'm trying to implement a service on my Android Application. And the Service must do the same task of the Activity. IE, if some change happen on the CallLog.Calls content provider the service must be notified and insert the data in the database even if the application is not running, I mean, a service will be running after the application is started, so if the application is killed, the service will keep running until the OS stop it, right?
So it will be running on background collecting all data that changes on the CallLog.Calls service. But, the service is not running. I star it in onCreate() method of the Activity. And inside the Service I implemented a ContentObserver class that uses the method onChange() in case somethind changes in the CallLog.Calls content provider.
What I don't know is why the Service is not started, and why it doesn't work even if I kill the app on the DDMS perspective.
Here is the code.
The Activity called RatedCalls.java
public class RatedCalls extends ListActivity {
private static final String LOG_TAG = "RATEDCALLSOBSERVER";
private Handler handler = new Handler();
private SQLiteDatabase db;
private CallDataHelper cdh;
StringBuilder sb = new StringBuilder();
OpenHelper openHelper = new OpenHelper(RatedCalls.this);
private Integer contentProviderLastSize;
private Integer contentProviderCurrentSize;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
cdh = new CallDataHelper(this);
db = openHelper.getWritableDatabase();
startService(new Intent(this, RatedCallsService.class));
registerContentObservers();
Log.i("FILLLIST", "calling from onCreate()");
Cursor cursor = getContentResolver().query(
android.provider.CallLog.Calls.CONTENT_URI, null, null, null,
android.provider.CallLog.Calls.DATE + " DESC ");
contentProviderLastSize = cursor.getCount();
}
class RatedCallsContentObserver extends ContentObserver {
public RatedCallsContentObserver(Handler h) {
super(h);
}
#Override
public boolean deliverSelfNotifications() {
return true;
}
#Override
public void onChange(boolean selfChange) {
Log.d(LOG_TAG, "RatedCallsContentObserver.onChange( " + selfChange
+ ")");
super.onChange(selfChange);
searchInsert();
}
}
private void searchInsert() {
Cursor cursor = getContentResolver().query(
android.provider.CallLog.Calls.CONTENT_URI, null, null, null,
android.provider.CallLog.Calls.DATE + " DESC ");
Log.i("FILLLIST", "Calling from searchInsert");
startManagingCursor(cursor);
int numberColumnId = cursor
.getColumnIndex(android.provider.CallLog.Calls.NUMBER);
int durationId = cursor
.getColumnIndex(android.provider.CallLog.Calls.DURATION);
int contactNameId = cursor
.getColumnIndex(android.provider.CallLog.Calls.CACHED_NAME);
int numTypeId = cursor
.getColumnIndex(android.provider.CallLog.Calls.CACHED_NUMBER_TYPE);
Date dt = new Date();
int hours = dt.getHours();
int minutes = dt.getMinutes();
int seconds = dt.getSeconds();
String currTime = hours + ":" + minutes + ":" + seconds;
SimpleDateFormat dateFormat = new SimpleDateFormat("M/dd/yyyy");
Date date = new Date();
cursor.moveToFirst();
String contactNumber = cursor.getString(numberColumnId);
String contactName = cursor.getString(contactNameId);
String duration = cursor.getString(durationId);
String numType = cursor.getString(numTypeId);
stopManagingCursor(cursor);
ContentValues values = new ContentValues();
values.put("contact_id", 1);
values.put("contact_name", contactName);
values.put("number_type", numType);
values.put("contact_number", contactNumber);
values.put("duration", duration);
values.put("date", dateFormat.format(date));
values.put("current_time", currTime);
values.put("cont", 1);
db.insert(CallDataHelper.TABLE_NAME, null, values);
}
public void registerContentObservers() {
this.getApplicationContext()
.getContentResolver()
.registerContentObserver(
android.provider.CallLog.Calls.CONTENT_URI, true,
new RatedCallsContentObserver(handler));
}
And this is the Service called RatedCallsService.java
public class RatedCallsService extends Service {
private static final String TAG = "RatedCallsService";
private static final String LOG_TAG = "RatedCallsService";
private Handler handler = new Handler();
private SQLiteDatabase db;
private CallDataHelper cdh;
OpenHelper openHelper = new OpenHelper(RatedCallsService.this);
class RatedCallsContentObserver extends ContentObserver {
public RatedCallsContentObserver(Handler h) {
super(h);
}
#Override
public boolean deliverSelfNotifications() {
return true;
}
#Override
public void onChange(boolean selfChange) {
Log.d(LOG_TAG, "RatedCallsContentObserver.onChange( " + selfChange
+ ")");
super.onChange(selfChange);
searchInsert();
}
}
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onCreate() {
Toast.makeText(this, "Rated Calls Service Created", Toast.LENGTH_LONG).show();
Log.i(TAG, "onCreate");
registerContentObservers();
}
#Override
public void onDestroy() {
Toast.makeText(this, "Rated Calls Service Stopped", Toast.LENGTH_LONG).show();
Log.i(TAG, "onDestroy");
cdh = new CallDataHelper(this);
db = openHelper.getWritableDatabase();
}
#Override
public void onStart(Intent intent, int startid) {
Toast.makeText(this, "Rated Calls Service Started", Toast.LENGTH_LONG).show();
Log.d(TAG, "onStart");
registerContentObservers();
}
private void searchInsert() {
Cursor cursor = getContentResolver().query(
android.provider.CallLog.Calls.CONTENT_URI, null, null, null,
android.provider.CallLog.Calls.DATE + " DESC ");
Log.i("FILLLIST", "Calling from searchInsert");
int numberColumnId = cursor
.getColumnIndex(android.provider.CallLog.Calls.NUMBER);
int durationId = cursor
.getColumnIndex(android.provider.CallLog.Calls.DURATION);
int contactNameId = cursor
.getColumnIndex(android.provider.CallLog.Calls.CACHED_NAME);
int numTypeId = cursor
.getColumnIndex(android.provider.CallLog.Calls.CACHED_NUMBER_TYPE);
Date dt = new Date();
int hours = dt.getHours();
int minutes = dt.getMinutes();
int seconds = dt.getSeconds();
String currTime = hours + ":" + minutes + ":" + seconds;
SimpleDateFormat dateFormat = new SimpleDateFormat("M/dd/yyyy");
Date date = new Date();
if (cursor.moveToFirst()) {
do {
String contactNumber = cursor.getString(numberColumnId);
String contactName = cursor.getString(contactNameId);
String duration = cursor.getString(durationId);
String numType = cursor.getString(numTypeId);
ContentValues values = new ContentValues();
values.put("contact_id", 1);
values.put("contact_name", contactName);
values.put("number_type", numType);
values.put("contact_number", contactNumber);
values.put("duration", duration);
values.put("date", dateFormat.format(date));
values.put("current_time", currTime);
values.put("cont", 1);
db.insert(CallDataHelper.TABLE_NAME, null, values);
} while (cursor.moveToNext());
cursor.close();
}
}
public void registerContentObservers() {
this.getApplicationContext()
.getContentResolver()
.registerContentObserver(
android.provider.CallLog.Calls.CONTENT_URI, true,
new RatedCallsContentObserver(handler));
}
}
Just see if you have added this Service in your manifest file.......
Thanks.......
When declaring the service in your manifest, try using the full package location of your service class in your manifest.
eg. <service android:name="com.company.project.package.MyService">
My service wasn't starting and that worked for me.
You might want to check out the service lifecycle documentation. If you call Context.startService() the service should start and stay running until someone tells it to stop.
From your code sample, it looks like you are doing that. What makes you think that the service isn't starting?
I'm not sure what you expect to happen when you kill the app... That sounds like a good reason for it not to work.
Hi instead of using a service and a content observer i would observe the phone state. Observing the phone state can trigger your update service.
You need the
android.permission.READ_PHONE_STATE
permission. which isn't a big affair.
The code for the broadcast receiver is
public class CallStateWatcher extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
if (intent.getAction().equals(android.telephony.TelephonyManager.ACTION_PHONE_STATE_CHANGED))
{
String extra = intent.getStringExtra(android.telephony.TelephonyManager.EXTRA_STATE);
if (extra.equals(android.telephony.TelephonyManager.EXTRA_STATE_OFFHOOK))
{
// do something
}
if (extra.equals(android.telephony.TelephonyManager.EXTRA_STATE_IDLE))
{
// do something
}
}
}
}
You have to define that receiver
<receiver
android:name=".core.watcher.CallStateWatcher">
<intent-filter>
<action
android:name="android.intent.action.PHONE_STATE"></action>
</intent-filter>
</receiver>