I am a school student learning android. I am doing a simple contacts app! When i click on clear calllog button, my recent contacts listview remains the same. Its not getting cleared. But when i close the app and reopen again, the recent contacts fragment is getting cleared! I debugged the code, code is not entering after cursor.movetoNext() line when i click on clearcall log. Kindly help me techies!
I programmed like updateFragment2ListView() gets called when i clear the call log button in menu!
public class RecentContacts extends Fragment {
HashMap contactMap = new HashMap();
View rootView;
RecentAdapter rr;
ListView list;
private static final int PERMISSIONS_REQUEST_READ_CALLLOG = 100;
Cursor cursor;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
rootView = inflater.inflate(R.layout.fragment_recent_contacts, container, false);
list = (ListView) rootView.findViewById(R.id.customlist);
getRecentContacts();
rr = new RecentAdapter(contactMap, getActivity());
list.setAdapter(rr);
return rootView;
}
public void updateFragment2ListView() {
getRecentContacts();
rr.notifyDataSetChanged();
list.setAdapter(rr);
System.out.println("Fragment recent updated-updateFragment2listview");
}
#Override
public void onResume() {
getRecentContacts();
rr.notifyDataSetChanged();
System.out.println("Fragment recent updated- onresume");
super.onResume();
}
#Override
public void onStart() {
System.out.println("Fragment recent onstart");
super.onStart();
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
void getRecentContacts() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && getContext().checkSelfPermission(Manifest.permission.READ_CALL_LOG) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.READ_CALL_LOG}, PERMISSIONS_REQUEST_READ_CALLLOG);
//After this point you wait for callback in onRequestPermissionsResult(int, String[], int[]) overriden method
System.out.println("Security check ok");
} else {
System.out.println("Entered recent onstart");
int i=0;
Uri queryUri = android.provider.CallLog.Calls.CONTENT_URI;
String[] projection = new String[]{
ContactsContract.Contacts._ID,
CallLog.Calls._ID,
CallLog.Calls.NUMBER,
CallLog.Calls.CACHED_NAME,
CallLog.Calls.DATE,
CallLog.Calls.TYPE};
String sortOrder = String.format("%s limit 500 ", CallLog.Calls.DATE + " DESC");
try {
System.out.println("Entering cursor in recent contacts");
cursor = getActivity().getContentResolver().query(queryUri, projection, null, null, sortOrder);
System.out.println("Entered cursor in recent contacts");
} catch (SecurityException e) {
Log.e("", "");
}
while (cursor.moveToNext()) {
System.out.println("Entered cursor.movetoNext recent contacts");
String phoneNumber = cursor.getString(cursor
.getColumnIndex(CallLog.Calls.NUMBER));
System.out.println("Entered phone number in recent contacts");
String title = (cursor.getString(cursor.getColumnIndex(CallLog.Calls.CACHED_NAME)));
int duration1 = cursor.getColumnIndex(CallLog.Calls.DURATION);
System.out.println("Duration" + duration1);
System.out.println("Entered duration in recent contacts");
int date = cursor.getColumnIndex(CallLog.Calls.DATE);
String callDate = cursor.getString(date);
Date callDayTime = new Date(Long.valueOf(callDate));
System.out.println("Call Date" + callDayTime);
int type = cursor.getColumnIndex(CallLog.Calls.TYPE);
String callType = cursor.getString(type);
String dir = null;
int dircode = Integer.parseInt(callType);
switch (dircode) {
case CallLog.Calls.OUTGOING_TYPE:
dir = "OUTGOING";
break;
case CallLog.Calls.INCOMING_TYPE:
dir = "INCOMING";
break;
case CallLog.Calls.MISSED_TYPE:
dir = "MISSED";
break;
}
System.out.println("Call type" + dir);
// if (phoneNumber == null || title == null) continue;
String uri = "tel:" + phoneNumber;
Intent intent = new Intent(Intent.ACTION_CALL);
intent.setData(Uri.parse(uri));
String intentUriString = intent.toUri(0);
contactMap.put(i, new RecentPojo(title, phoneNumber, duration1, false, callDayTime, dir));
// Toast.makeText(this,title,Toast.LENGTH_SHORT).show();
i++;
}
cursor.close();
}
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions,
int[] grantResults) {
if ((requestCode == PERMISSIONS_REQUEST_READ_CALLLOG)) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Permission is granted
System.out.println("");
getRecentContacts();
} else {
Toast.makeText(getContext(), "Until you grant the permission, we cannot display the names", Toast.LENGTH_SHORT).show();
}
}
}
}
You have to call rr.notifyDataSetChanged(); when you clear it so the ListView is refreshed.
Related
public class MainActivity extends BaseActivity implements View.OnClickListener, LoaderManager.LoaderCallbacks<Cursor>{
private static final String TAG = "ContentProviderDemo";
private int recentOpPerfomed;
private final int LOAD_CONTACTS=1;
private final int WRITE_CONTACTS=2;
private final int UPDATE_CONTACTS=3;
private final int DELETE_CONTACTS=4;
private boolean firstTimeLoaded=false;
private TextView textViewQueryResult;
private Button buttonLoadData, buttonAddContact,buttonRemoveContact,buttonUpdateContact, buttonPhotoTagActivity;
private ContentResolver contentResolver;
private EditText editTextContactName;
private CursorLoader mContactsLoader;
private String[] mColumnProjection = new String[]{
ContactsContract.Contacts._ID,
ContactsContract.Contacts.DISPLAY_NAME_PRIMARY,
ContactsContract.Contacts.HAS_PHONE_NUMBER,
ContactsContract.CommonDataKinds.Phone.NUMBER}
;
private String mSelectionCluse = ContactsContract.Contacts.DISPLAY_NAME_PRIMARY + " = ?";
private String[] mSelectionArguments = new String[]{"Ajay"};
private String mOrderBy = ContactsContract.Contacts.DISPLAY_NAME_PRIMARY;
/**
* ATTENTION: This was auto-generated to implement the App Indexing API.
* See https://g.co/AppIndexing/AndroidStudio for more information.
*/
private GoogleApiClient client;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textViewQueryResult = (TextView) findViewById(R.id.textViewQueryResult);
editTextContactName=(EditText)findViewById(R.id.editTextContactName);
buttonLoadData = (Button) findViewById(R.id.buttonLoadData);
buttonAddContact=(Button)findViewById(R.id.buttonAddContact);
buttonRemoveContact=(Button)findViewById(R.id.buttonRemoveContact);
buttonUpdateContact=(Button)findViewById(R.id.buttonUpdateContact);
buttonPhotoTagActivity=(Button)findViewById(R.id.buttonPhotoTagActivity);
buttonLoadData.setOnClickListener(this);
buttonAddContact.setOnClickListener(this);
buttonRemoveContact.setOnClickListener(this);
buttonUpdateContact.setOnClickListener(this);
buttonPhotoTagActivity.setOnClickListener(this);
contentResolver=getContentResolver();
}
#Override
public Loader<Cursor> onCreateLoader(int i, Bundle bundle) {
if(i==1){
return new CursorLoader(this,ContactsContract.Contacts.CONTENT_URI,mColumnProjection, null,null,null);
}
return null;
}
#Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
if(cursor!=null && cursor.getCount()>0){
StringBuilder stringBuilderQueryResult=new StringBuilder("");
while (cursor.moveToNext()){
if(Integer.parseInt(cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0)
{
// Query phone here. Covered next
Cursor phones = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null,ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = "
+ ContactsContract.Contacts._ID, null, null);
while (phones.moveToNext()) {
String phoneNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
Log.i("Number", phoneNumber);
stringBuilderQueryResult.append(cursor.getString(0)+" , "+cursor.getString(1)+
" , "+cursor.getString(2)+" , "+phoneNumber+"\n");
}
phones.close();
}
}
textViewQueryResult.setText(stringBuilderQueryResult.toString());
}else{
textViewQueryResult.setText("No Contacts in device");
}
}
#Override
public void onLoaderReset(Loader<Cursor> loader) {
}
#Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.buttonLoadData:loadContacts();
break;
case R.id.buttonAddContact: addContact();
break;
case R.id.buttonRemoveContact:deleteContact();
break;
case R.id.buttonUpdateContact: modifyCotact();
break;
case R.id.buttonPhotoTagActivity: startPhotoTagActivity();
break;
default:
break;
}
}
private void startPhotoTagActivity(){
startActivity(new Intent(this,PhotoTaggingActivity.class));
}
private void insertContacts(){
String newName=editTextContactName.getText().toString();
if(newName!=null && !newName.equals("") && newName.length()!=0){
ArrayList<ContentProviderOperation> cops=new ArrayList<ContentProviderOperation>();
cops.add(ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI)
.withValue(ContactsContract.RawContacts.ACCOUNT_TYPE,"accountname#gmail.com")
.withValue(ContactsContract.RawContacts.ACCOUNT_NAME, "com.google")
.build());
cops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)
.withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, editTextContactName.getText().toString())
.build());
try{
getContentResolver().applyBatch(ContactsContract.AUTHORITY,cops);
}catch (Exception exception){
Log.i(TAG,exception.getMessage());
Toast.makeText(this,exception.getMessage(),Toast.LENGTH_SHORT).show();
}
}
}
private void addContact() {
recentOpPerfomed=WRITE_CONTACTS;
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_CONTACTS) == PackageManager.PERMISSION_GRANTED) {
insertContacts();
} else {
requestRunTimePermissions(this,new String[]{Manifest.permission.WRITE_CONTACTS},MY_PERMISSION_REQUEST_WRITE_CONTACTS);
}
}
private void updateContact(){
String [] updateValue=editTextContactName.getText().toString().split(" ");
ContentProviderResult[] result=null;
String targetString=null;
String newString=null;
if(updateValue.length==2){
targetString=updateValue[0];
newString=updateValue[1];
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_CONTACTS) == PackageManager.PERMISSION_GRANTED) {
if(newString!=null && !newString.equals("") && newString.length()!=0)
{
String where= ContactsContract.RawContacts._ID + " = ? ";
String [] params= new String[] {targetString};
ContentResolver contentResolver=getContentResolver();
ContentValues contentValues=new ContentValues();
contentValues.put(ContactsContract.RawContacts.DISPLAY_NAME_PRIMARY,newString);
// UPDATE <table_name> SET column1 = value1, column2 = value2 where column3 = selection_value
contentResolver.update(ContactsContract.RawContacts.CONTENT_URI,contentValues, where,params);
}
}
}
}
private void modifyCotact(){
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_CONTACTS) == PackageManager.PERMISSION_GRANTED) {
updateContact();
} else {
requestRunTimePermissions(this,new String[]{Manifest.permission.WRITE_CONTACTS}, MY_PERMISSION_REQUEST_WRITE_CONTACTS);
}
}
private void removeContacts(){
recentOpPerfomed=DELETE_CONTACTS;
String newName=editTextContactName.getText().toString();
if(newName!=null && !newName.equals("") && newName.length()!=0){
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_CONTACTS) == PackageManager.PERMISSION_GRANTED) {
//display_name = '<entered_value>'
String whereClause=ContactsContract.RawContacts.DISPLAY_NAME_PRIMARY+ " = '"+editTextContactName.getText().toString()+"'";
//DELETE FROM <table_name> where column1 = selection_value
getContentResolver().delete(ContactsContract.RawContacts.CONTENT_URI,whereClause,null);
}
}
}
private void deleteContact(){
recentOpPerfomed=DELETE_CONTACTS;
if(ActivityCompat.checkSelfPermission(this,Manifest.permission.WRITE_CONTACTS)==PackageManager.PERMISSION_GRANTED){
removeContacts();
}else{
requestRunTimePermissions(this,new String[]{Manifest.permission.WRITE_CONTACTS}, MY_PERMISSION_REQUEST_WRITE_CONTACTS);
}
}
private void loadContacts() {
recentOpPerfomed=LOAD_CONTACTS;
if(ActivityCompat.checkSelfPermission(this,Manifest.permission.READ_CONTACTS)==PackageManager.PERMISSION_GRANTED){
Log.i(TAG,"Permisssion is granted");
if (firstTimeLoaded == false) {
getLoaderManager().initLoader(1, null, this);
firstTimeLoaded = true;
} else {
getLoaderManager().restartLoader(1, null, this);
}
}else{
requestRunTimePermissions(this,new String[]{Manifest.permission.READ_CONTACTS}, MY_PERMISSIONS_REQUEST_READ_CONTACTS);
}
}
#Override
public void onRequestPermissionsResult(final int requestCode, #NonNull final String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if(permissions.length==1){
if(requestCode==MY_PERMISSIONS_REQUEST_READ_CONTACTS || requestCode==MY_PERMISSION_REQUEST_WRITE_CONTACTS && grantResults[0]==PackageManager.PERMISSION_GRANTED){
switch (recentOpPerfomed){
case WRITE_CONTACTS: addContact();loadContacts();break;
case DELETE_CONTACTS: deleteContact();loadContacts();break;
case UPDATE_CONTACTS: modifyCotact();loadContacts();break;
case LOAD_CONTACTS:loadContacts();
default: break;
}
}
}
}
}
Wasted almost an day on this. Trying to get Phone Number from Contacts APP.
I am trying to retrieve all contacts phone number using Loader. There is no proper explanation in Logcat where i am going wrong. Any help would be greatly appreciated. I keep getting saying Invalid column data1,but what is Invalid column data1?
I have a Loader class, which loads some data asynchronously in an fragment in a RecyclerView. This works fine, when the user comes to that fragment the first time. If he moves away by clicking an ActionBar Button to insert some new data, and returns, I want that the new data becomes visible in my RecyclerView, but it doesn't.
I initialise the Loader in onStart() and although onStart() is called when the user comes back, the loader is not not updating (No changes to the RecyclerView visible)
Here are the relevant methods from the fragment with the loader:
private static final int TERMIN_LOADER_ID = 1;
private static final int AUFGABEN_LOADER_ID = 2;
#Override
public Loader<Cursor> onCreateLoader(int i, Bundle bundle) {
switch(i){
case TERMIN_LOADER_ID:
return new TerminLoader(getActivity());
case AUFGABEN_LOADER_ID:
throw new UnsupportedOperationException("AUFGABEN_LOADER_ID not implemented yet.");
default:
throw new UnsupportedOperationException("Unknown loader id.");
}
}
#Override
public void onLoadFinished(Loader<Cursor> cursorLoader, Cursor cursor) {
// mAdapter is a CursorAdapter
//mAdapter.swapCursor(cursor);
switch(cursorLoader.getId()){
case TERMIN_LOADER_ID:
RadListView termineListView = (RadListView)getActivity().findViewById(R.id.termineRadListView);
// now here we can fill our termineListView because we got the cursor ready
ArrayList<Termin> termine = new ArrayList<>();
cursor.moveToFirst();
while(!cursor.isAfterLast()){
// loop over the results from the query and build our termine ArrayList
// this is our MatrixCursor from our TerminLoader
long terminId = cursor.getLong(cursor.getColumnIndex(CalendarContract.Events._ID));
String title = cursor.getString(cursor.getColumnIndex(CalendarContract.Events.TITLE));
long begin = cursor.getLong(cursor.getColumnIndex(CalendarContract.Events.DTSTART));
Termin termin = new Termin(terminId, title, begin);
termine.add(termin);
cursor.moveToNext();
}
TerminListViewAdapter terminListViewAdapter = new TerminListViewAdapter(termine, getActivity());
termineListView.setAdapter(terminListViewAdapter);
break;
case AUFGABEN_LOADER_ID:
throw new UnsupportedOperationException("AUFGABEN_LOADER_ID not implemented yet.");
default:
throw new UnsupportedOperationException("Unknown LOADER_ID.");
}
}
#Override
public void onLoaderReset(Loader<Cursor> cursorLoader) {
switch(cursorLoader.getId()){
case TERMIN_LOADER_ID:
// now here we can fill our termineListView because we got the cursor ready
//RadListView termineListView = (RadListView)getActivity().findViewById(R.id.termineRadListView);
ArrayList<Termin> termine = new ArrayList<>();
TerminListViewAdapter terminListViewAdapter = new TerminListViewAdapter(termine, getActivity());
this.termineListView.setAdapter(terminListViewAdapter);
break;
case AUFGABEN_LOADER_ID:
throw new UnsupportedOperationException("AUFGABEN_LOADER_ID not implemented yet.");
default:
throw new UnsupportedOperationException("Unknown LOADER_ID.");
}
}
#Override
public void onStart() {
super.onStart();
loadData();
}
public void loadData(){
// reload termine
getActivity().getSupportLoaderManager().initLoader(TERMIN_LOADER_ID, null, this);
}
This is how the user moves away:
toolbarBottom = (Toolbar) getActivity().findViewById(R.id.toolbar_bottom);
toolbarBottom.inflateMenu(R.menu.menu_toolbar_home);
toolbarBottom.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem menuItem) {
// the selected patient's id
SharedPreferences prefs = HomeFragment.this.getActivity().getSharedPreferences(Constants.SHARED_PREFS_FILE, 0);
long _id = prefs.getLong(Constants.SELECTED_PATIENT_ID, 1);
switch (menuItem.getItemId()) {
case R.id.item_termin_erstellen:
//Toast.makeText(getActivity(), "Termin clicked: " + String.valueOf(_id), Toast.LENGTH_LONG).show();
TerminFragment terminFragment = TerminFragment.newInstance(_id);
Bundle args = new Bundle();
args.putString(Constants.ACTION, Constants.CREATE);
terminFragment.setArguments(args);
FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
fragmentManager.beginTransaction().replace(R.id.content_frame, terminFragment).addToBackStack(Constants.TERMIN_FRAGMENT).commit();
break;
case R.id.item_aufgabe_erstellen:
Toast.makeText(getActivity(), "Aufgabe clicked: " + String.valueOf(_id), Toast.LENGTH_LONG).show();
break;
case R.id.item_dokumentation:
Toast.makeText(getActivity(), "Dokumentation clicked: " + String.valueOf(_id), Toast.LENGTH_LONG).show();
break;
default:
}
return true;
}
});
}
And this is the code in TerminFragment which gets the user back to the first fragment:
MainActivity mainActivity = (MainActivity) getActivity();
FragmentManager fragmentManager = getFragmentManager();
HomeFragment homeFragment = (HomeFragment)fragmentManager.findFragmentByTag(Constants.HOME_FRAGMENT);
if(homeFragment != null){
homeFragment.loadData();
}
fragmentManager.popBackStack();
And finally, this is my Loader class:
public class TerminLoader extends CursorLoader {
private static final String TAG = "TerminLoader";
private Context context;
// This loader loads events by querying the database for additional data
public TerminLoader(Context context) {
super(context);
this.context = context;
}
#Override
public Cursor loadInBackground() {
// we query against the calendar database for all termine of a peticular patient// only fetch the termine of a particular patient
SharedPreferences prefs = context.getSharedPreferences(Constants.SHARED_PREFS_FILE, 0);
long selectedPatientId = prefs.getLong(Constants.SELECTED_PATIENT_ID, 1);
String selection = TerminContract.Columns.PATIENT_ID + " = ? ";
String[] selectionArgs = {String.valueOf(selectedPatientId)};
Cursor cursor = context.getApplicationContext().getContentResolver().query(TerminContract.CONTENT_URI, null, selection, selectionArgs, "");
cursor.moveToFirst();
String[] columnNames = {CalendarContract.Events._ID,
CalendarContract.Events.TITLE,
CalendarContract.Events.DTSTART};
MatrixCursor matrixCursor = new MatrixCursor(columnNames);
while(!cursor.isAfterLast()){
long terminId = cursor.getLong(cursor.getColumnIndex(TerminContract.Columns.TERMIN_ID));
// retrieve the event for this terminId by querying the calendar
Cursor cur = null;
Uri uri = CalendarContract.Events.CONTENT_URI;
ContentResolver cr = context.getContentResolver();
String[] projection2 = {CalendarContract.Events.TITLE,
CalendarContract.Events.DTSTART};
String selection2 = "(" + CalendarContract.Events._ID + " = ?)";
String[] selectionArgs2 = new String[] {String.valueOf(terminId)};
// Submit the query and get a Cursor object back.
cur = cr.query(uri, projection2, selection2, selectionArgs2, null);
cur.moveToFirst();
// Get the field values
String title = cur.getString(cur.getColumnIndex(CalendarContract.Events.TITLE));
//String title = "title";
long dtStart = cur.getLong(cur.getColumnIndex(CalendarContract.Events.DTSTART));
// and add it to our MatrixCursor
MatrixCursor.RowBuilder rowBuilder = matrixCursor.newRow();
rowBuilder.add(terminId)
.add(title)
.add(dtStart);
//move to nexr row
cursor.moveToNext();
}
return matrixCursor;
}
}
Any ideas?
Note, that I can confirm that before the above lines are executed, the data is inserted correctly.
Also note, that the above lines fail to findFragmentByTag.
Thanks
I fixed the problem by a very simple, little change:
public void loadData(){
// reload termine
getActivity().getSupportLoaderManager().destroyLoader(TERMIN_LOADER_ID);
getActivity().getSupportLoaderManager().initLoader(TERMIN_LOADER_ID, null, this);
}
I destroy an existing loader before initialising the loader.
I have an incoming call history app. Every time I call it takes the number and save it in the database, after that it adds it to the list which in turn added to the listview. But I have one problem which is it never checks for old values and it adds duplicated numbers to the database, is there any way to avoid this? Here is my try.
public class Incoming_call_history extends Activity {
private ListView lv;
private ArrayAdapter<String> adapter;
private ArrayList<String>list;
DataSourceCall DS;
boolean duplicated=false;
String temp="";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_incoming_call_history);
DS= new DataSourceCall(this);
DS.open();
lv=(ListView)findViewById(R.id.callHistory);
registerForContextMenu(lv);
list=(ArrayList<String>) DS.getAllCalls();
adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, list);
lv.setAdapter(adapter);
#SuppressWarnings("deprecation")
Cursor mCursor = managedQuery(CallLog.Calls.CONTENT_URI, null, null,
null, null);
int number = mCursor.getColumnIndex(CallLog.Calls.NUMBER);
int date = mCursor.getColumnIndex(CallLog.Calls.DATE);
int duration = mCursor.getColumnIndex(CallLog.Calls.DURATION);
int type = mCursor.getColumnIndex(CallLog.Calls.TYPE);
while (mCursor.moveToNext()) {
String num = mCursor.getString(number);
String dur = mCursor.getString(duration);
String datee = mCursor.getString(date);
String calltype = mCursor.getString(type);
Date d = new Date(Long.valueOf(datee));
String callTypeStr = "";
switch (Integer.parseInt(calltype)) {
case CallLog.Calls.MISSED_TYPE:
callTypeStr = "Missed";
break;
case CallLog.Calls.OUTGOING_TYPE:
callTypeStr = "Outgoing";
break;
case CallLog.Calls.INCOMING_TYPE:
callTypeStr = "Incoming";
break;
}
boolean found = false;
for (int ndx = 0; ndx < list.size(); ndx++)
{
if (num.equals(list.contains(num)))
{
found = true;
DS.deleteCall(num);
adapter.notifyDataSetChanged();
break;
}
}
if (!found)
{
DS.createCall(num);
temp=num;
Log.d("added succesfuly ", num);
}
// list.add("Phone number: "+num+"\n"+"Duration: " + dur+"\n"+"Type: " + callTypeStr+"\n"+"Call date: " + d+"\n");
}
mCursor.close();
adapter.notifyDataSetChanged();
}}
If you don't want to insert already inserted mobile number in the table,Just check whether the mobile number is already inserted not
public int isUserAvailable(int number)
{
int numberCount = 0;
Cursor c = null;
try
{
c = db.rawQuery("select p_number from user_table where p_number = ?", new String[] {String.valueOf(number)});
if(c.getCount() != 0)
numberCount = c.getCount();
}
catch(Exception e) {
e.printStackTrace();
} finally {
if(c!=null) c.close();
}
return numberCount ;
}
If it does not suits with your requirement let me know,I will try to give some other solution.
I have a DialogFragment that I'm working on to display two spinners, side by side, one displays a list of drivers, the other a list of vehicles.
The data to populate these spinners is retrieved from a sqlite database. I am trying to use a LoaderManager to keep the spinners updated or in sync with the database tables, (drivers and vehicles).
When I add/delete/edit a record in either the drivers table or vehicles table in the database, the spinners don't get updated, the driver or vehicle remains unchanged in the spinner.
I'm not sure what I'm missing because I thought LoaderManager is supposed to keep the lists updated or in sync with the database tables automatically right?
I created a button called addDriverVehicle() which is supposed to allow the user to add another driver/vehicle in the future but for now I'm using it as a test to delete a driver to kind of simulate the database tables changing just so i can see if the spinner gets updated automatically but it's not happening. The record is being deleted but the spinner continues to show it.
public class DriverVehiclePickersDialogFragment extends DialogFragment implements LoaderManager.LoaderCallbacks<Cursor>, OnItemSelectedListener {
public static final String ARG_LISTENER_TYPE = "listenerType";
public static final String ARG_DIALOG_TYPE = "dialogType";
public static final String ARG_TITLE_RESOURCE = "titleResource";
public static final String ARG_SET_DRIVER = "setDriver";
public static final String ARG_SET_VEHICLE = "setVehicle";
private static final int DRIVERS_LOADER = 0;
private static final int VEHICLES_LOADER = 1;
private DriverVehicleDialogListener mListener;
// These are the Adapter being used to display the driver's and vehicle's data.
SimpleCursorAdapter mDriversAdapter, mVehiclesAdapter;
// Define Dialog view
private View mView;
// Store Driver and Vehicle Selected
private long[] mDrivers, mVehicles;
// Spinners Containing Driver and Vehicle List
private Spinner driversSpinner;
private Spinner vehiclesSpinner;
private static enum ListenerType {
ACTIVITY, FRAGMENT
}
public static enum DialogType {
DRIVER_SPINNER, VEHICLE_SPINNER, DRIVER_VEHICLE_SPINNER
}
public interface DriverVehicleDialogListener {
public void onDialogPositiveClick(long[] mDrivers, long[] mVehicles);
}
public DriverVehiclePickersDialogFragment() {
// Empty Constructor
Log.d("default", "default constructor ran");
}
public static DriverVehiclePickersDialogFragment newInstance(DriverVehicleDialogListener listener, Bundle dialogSettings) {
final DriverVehiclePickersDialogFragment instance;
if (listener instanceof Activity) {
instance = createInstance(ListenerType.ACTIVITY, dialogSettings);
} else if (listener instanceof Fragment) {
instance = createInstance(ListenerType.FRAGMENT, dialogSettings);
instance.setTargetFragment((Fragment) listener, 0);
} else {
throw new IllegalArgumentException(listener.getClass() + " must be either an Activity or a Fragment");
}
return instance;
}
private static DriverVehiclePickersDialogFragment createInstance(ListenerType listenerType, Bundle dialogSettings) {
DriverVehiclePickersDialogFragment fragment = new DriverVehiclePickersDialogFragment();
if (!dialogSettings.containsKey(ARG_LISTENER_TYPE)) {
dialogSettings.putSerializable(ARG_LISTENER_TYPE, listenerType);
}
if (!dialogSettings.containsKey(ARG_DIALOG_TYPE)) {
dialogSettings.putSerializable(ARG_DIALOG_TYPE, DialogType.DRIVER_VEHICLE_SPINNER);
}
if (!dialogSettings.containsKey(ARG_TITLE_RESOURCE)) {
dialogSettings.putInt(ARG_TITLE_RESOURCE, 0);
}
fragment.setArguments(dialogSettings);
return fragment;
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
// Find out how to get the DialogListener instance to send the callback events to
Bundle args = getArguments();
ListenerType listenerType = (ListenerType) args.getSerializable(ARG_LISTENER_TYPE);
switch (listenerType) {
case ACTIVITY: {
// Send callback events to the hosting activity
mListener = (DriverVehicleDialogListener) activity;
break;
}
case FRAGMENT: {
// Send callback events to the "target" fragment
mListener = (DriverVehicleDialogListener) getTargetFragment();
break;
}
}
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onActivityCreated(savedInstanceState);
Button btnAddDriverVehicle = (Button) mView.findViewById(R.id.addDriverVehicleButton);
btnAddDriverVehicle.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
DatabaseHelper1 mOpenHelper = new DatabaseHelper1(getActivity());
try {
SQLiteDatabase db = mOpenHelper.getWritableDatabase();
db.delete("drivers", " driver_number = 70", null);
} catch (SQLException e) {
}
}
});
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
Bundle args = getArguments();
int titleResource = args.getInt(ARG_TITLE_RESOURCE);
DialogType dialogType = (DialogType) args.getSerializable(ARG_DIALOG_TYPE);
if (args.containsKey(ARG_SET_DRIVER)) {
mDrivers = args.getLongArray(ARG_SET_DRIVER);
}
if (args.containsKey(ARG_SET_VEHICLE)) {
mVehicles = args.getLongArray(ARG_SET_VEHICLE);
}
mView = LayoutInflater.from(getActivity()).inflate(R.layout.driver_vehicle_dialog, null);
if ((dialogType == DialogType.DRIVER_SPINNER) || (dialogType == DialogType.DRIVER_VEHICLE_SPINNER)) {
driversSpinner = (Spinner) mView.findViewById(R.id.driversSpinner);
vehiclesSpinner = (Spinner) mView.findViewById(R.id.vehiclesSpinner);
driversSpinner.setVisibility(View.VISIBLE);
mDriversAdapter = new SimpleCursorAdapter(getActivity(), R.layout.driver_listview_row, null, new String[] { ConsoleContract.Drivers.DRIVER_NUMBER,
ConsoleContract.Drivers.DRIVER_NAME }, new int[] { R.id.driver_number, R.id.driver_name }, 0);
driversSpinner.setAdapter(mDriversAdapter);
driversSpinner.setOnItemSelectedListener(this);
}
if ((dialogType == DialogType.VEHICLE_SPINNER) || (dialogType == DialogType.DRIVER_VEHICLE_SPINNER)) {
vehiclesSpinner.setVisibility(View.VISIBLE);
mVehiclesAdapter = new SimpleCursorAdapter(getActivity(), R.layout.vehicle_listview_row, null, new String[] { ConsoleContract.Vehicles.VEHICLE_NUMBER,
ConsoleContract.Vehicles.VEHICLE_VIN }, new int[] { R.id.vehicle_number, R.id.vehicle_vin }, 0);
vehiclesSpinner.setAdapter(mVehiclesAdapter);
vehiclesSpinner.setOnItemSelectedListener(this);
}
// Prepare the loader. Either re-connect with an existing one, or start a new one.
getLoaderManager().initLoader(DRIVERS_LOADER, null, this);
getLoaderManager().initLoader(VEHICLES_LOADER, null, this);
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setView(mView);
if (titleResource == 0) {
builder.setMessage("Select Driver and Vehicle");
} else {
builder.setMessage(getString(titleResource));
}
builder.setPositiveButton(android.R.string.ok, new OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
mListener.onDialogPositiveClick(mDrivers, mVehicles);
}
});
builder.setNegativeButton(android.R.string.cancel, null);
return builder.create();
}
private static class DatabaseHelper1 extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "test.db";
private static final int DATABASE_VERSION = 1;
DatabaseHelper1(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
// These are the Contacts rows that we will retrieve.
static final String[] DRIVERS_SUMMARY_PROJECTION = new String[] { ConsoleContract.Drivers._ID, ConsoleContract.Drivers.DRIVER_ID, ConsoleContract.Drivers.DRIVER_NUMBER,
ConsoleContract.Drivers.DRIVER_NAME };
static final String[] VEHICLES_SUMMARY_PROJECTION = new String[] { ConsoleContract.Vehicles._ID, ConsoleContract.Vehicles.VEHICLE_ID, ConsoleContract.Vehicles.VEHICLE_NUMBER,
ConsoleContract.Vehicles.VEHICLE_VIN };
#Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
// This is called when a new Loader needs to be created. This
// sample only has one Loader, so we don't care about the ID.
// First, pick the base URI to use depending on whether we are
// currently filtering.
Uri baseUri = null;
String select = null, sortOrder = null;
String[] projection = null;
switch (id) {
case DRIVERS_LOADER:
baseUri = ConsoleContract.Drivers.CONTENT_URI;
select = "((" + Drivers.DRIVER_NAME + " NOT NULL) AND (" + Drivers.DRIVER_NAME + " != '' ))";
sortOrder = Drivers.DRIVER_NUMBER;
projection = DRIVERS_SUMMARY_PROJECTION;
break;
case VEHICLES_LOADER:
baseUri = ConsoleContract.Vehicles.CONTENT_URI;
select = "((" + Vehicles.VEHICLE_NUMBER + " NOT NULL) AND (" + Vehicles.VEHICLE_NUMBER + " != '' ))";
sortOrder = Vehicles.VEHICLE_NUMBER;
projection = VEHICLES_SUMMARY_PROJECTION;
break;
}
return new CursorLoader(getActivity(), baseUri, projection, select, null, sortOrder);
}
#Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
// Swap the new cursor in. (The framework will take care of closing the
// old cursor once we return.)
int id = loader.getId();
MatrixCursor newCursor = null;
switch (id) {
case DRIVERS_LOADER:
newCursor = new MatrixCursor(DRIVERS_SUMMARY_PROJECTION);
break;
case VEHICLES_LOADER:
newCursor = new MatrixCursor(VEHICLES_SUMMARY_PROJECTION);
break;
}
newCursor.addRow(new String[] { "0", "0", "", "" });
Cursor[] cursors = { newCursor, data };
Cursor mergedCursor = new MergeCursor(cursors);
switch (id) {
case DRIVERS_LOADER:
mDriversAdapter.swapCursor(mergedCursor);
break;
case VEHICLES_LOADER:
mVehiclesAdapter.swapCursor(mergedCursor);
break;
}
}
#Override
public void onLoaderReset(Loader<Cursor> loader) {
// This is called when the last Cursor provided to onLoadFinished()
// above is about to be closed. We need to make sure we are no
// longer using it.
int id = loader.getId();
switch (id) {
case DRIVERS_LOADER:
mDriversAdapter.swapCursor(null);
break;
case VEHICLES_LOADER:
mVehiclesAdapter.swapCursor(null);
break;
}
}
#Override
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
if (parent.getId() == R.id.driversSpinner) {
mDriver = id;
} else {
mVehicle = id;
}
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
}
Make sure in your ContentProvider to call the notifyChange() method inside the insert, delete and update methods.
Here a snippet taken from Grokking Android Blog
public Uri insert(Uri uri, ContentValues values) {
if (URI_MATCHER.match(uri) != LENTITEM_LIST) {
throw new IllegalArgumentException("Unsupported URI for insertion: " + uri);
}
long id = db.insert(DBSchema.TBL_ITEMS, null, values);
if (id > 0) {
// notify all listeners of changes and return itemUri:
Uri itemUri = ContentUris.withAppendedId(uri, id);
getContext().getContentResolver().notifyChange(itemUri, null);
return itemUri;
}
// s.th. went wrong:
throw new SQLException("Problem while inserting into " + DBSchema.TBL_ITEMS + ", uri: " + uri); // use another exception here!!!
}
Conversely your Loader won't "heard" DB changes.
#rciovati's answer is good to me. But for me,I used Cursor Loader in my list view so it also need at query method in My ContentProvider.
In your ContentProvider class, query method also need to call notify after query like the code below-
#Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sort) {
SQLiteQueryBuilder queryBuilder=new SQLiteQueryBuilder();
Cursor cursor=queryBuilder.query(dbHelper.getReadableDatabase(),
projection,
selection,
selectionArgs,
null,
null,
sort);
cursor.setNotificationUri(getContext().getContentResolver(), uri);
return cursor;
}
In my application i've one AutoComplete TextView and EditText In this AutoComplete TextView provides all the contact names from Contacts.
I want to get the primary email id which contact was selected in my AutoComplete Textview to the editText. How can i achieve this? Anyone guide me?
public class Contact extends Activity {
/** Called when the activity is first created. */
private static final int CONTACT_PICKER_RESULT = 10;
private static final String DEBUG_TAG = null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
public void doLaunchContactPicker(View view) {
Intent contactPickerIntent = new Intent(Intent.ACTION_PICK,Contacts.CONTENT_URI);
startActivityForResult(contactPickerIntent, CONTACT_PICKER_RESULT);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
switch (requestCode) {
case CONTACT_PICKER_RESULT:
Cursor cursor = null;
String email = "";
try {
Uri result = data.getData();
Log.v(DEBUG_TAG, "Got a contact result: "
+ result.toString());
// get the contact id from the Uri
String id = result.getLastPathSegment();
// query for everything email
cursor = getContentResolver().query(Email.CONTENT_URI, null, Email.CONTACT_ID + "=?", new String[] { id }, null);
int emailIdx = cursor.getColumnIndex(Email.DATA);
// let's just get the first email
if (cursor.moveToFirst()) {
email = cursor.getString(emailIdx);
Log.v(DEBUG_TAG, "Got email: " + email);
} else {
Log.w(DEBUG_TAG, "No results");
}
} catch (Exception e) {
Log.e(DEBUG_TAG, "Failed to get email data", e);
} finally {
if (cursor != null) {
cursor.close();
}
EditText emailEntry = (EditText) findViewById(R.id.invite_email);
emailEntry.setText(email);
if (email.length() == 0) {
Toast.makeText(this, "No email found for contact.",
Toast.LENGTH_LONG).show();
}
}
break;
}
} else {
Log.w(DEBUG_TAG, "Warning: activity result not ok");
}
}
}
Make sure you have READ_CONTACTS permission for your App.
AutoCompleteTextView autoCompleteTextView = (AutoCompleteTextView)findViewById(R.id.autoCompleteTextView1);
Cursor emailCursor = getContentResolver().query(ContactsContract.CommonDataKinds.Email.CONTENT_URI, null, null, null, null);
startManagingCursor(emailCursor);
autoCompleteTextView.setAdapter(new SimpleCursorAdapter(this, android.R.layout.simple_dropdown_item_1line, emailCursor, new String[] {Email.DATA1}, new int[] {android.R.id.text1}));
autoCompleteTextView.setThreshold(0);
Please Note AutoCompleteTextView is Case Sensitive.