LoaderManager not initializing... a issue with getLoaderManager().initLoader - android

I know there is a lot of common questions like this out there but I just can't seem to find the solution. When I attempt to initialize my loader using getLoaderManager().initLoader(LOADER_ID, null, this); The error The method initLoader(int, Bundle, LoaderManager.LoaderCallbacks) in the type LoaderManager is not applicable for the arguments (int, null, Gridview) comes up.
This leads me to believe that the program is not recognizing that Gridview implements the loader manager. I'm not sure why this is and where to go from here. I tried playing around with different imports but that didn't work. I also made sure I had the proper downloads to support loaders. The code I am using is below.
package com.example.camerapreview;
import android.support.v4.app.LoaderManager;
import android.support.v4.app.LoaderManager.LoaderCallbacks;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.support.v4.widget.CursorAdapter;
//Omissis imports
public class Gridview extends Activity implements LoaderManager.LoaderCallbacks<Cursor>{
private static final String TAG = "Checking Database";
private static final String TAG1 = "Checking Thumbnail";
Cursor cursor;
int columnindexid;
int columnindexdata;
int videoidindex;
int videopathindex;
GridviewData entry;
GridView gridview;
VideoAdapter videoadapter;
Cursor curs;
ImageLoaderConfiguration config;
String[] mediaColumns = {
MediaStore.Video.Media._ID,
MediaStore.Video.Media.DATA,
MediaStore.Video.Media.TITLE,
MediaStore.Video.Media.MIME_TYPE
};
private static final int LOADER_ID = 1;
int flags = 0;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.preview);
gridview = (GridView) this.findViewById(R.id.gridview);
cursor = getContentResolver().query(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, mediaColumns, null, null, null);
columnindexid = cursor.getColumnIndexOrThrow(MediaStore.Video.Media._ID);
columnindexdata = cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DATA);
entry = new GridviewData(this);
entry.open();
getLoaderManager().initLoader(LOADER_ID, null, this);
DataEntry putitin = new DataEntry(entry, this);
putitin.execute();
//the cursor used in the cursor adapater
curs = entry.adapterCursor();
videoidindex = entry.Indexfinder(curs);
videopathindex = entry.Indexfinder2(curs);
config = new ImageLoaderConfiguration.Builder(this)
.imageDownloader(new BaseImageDownloader(this))
.build();
ImageLoader.getInstance().init(config);
Log.i(TAG, "Before set adapater");
gridview.setAdapter(new VideoAdapter(this, curs, flags));
}
}
EDIT:
#Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
String[] projection = { GridviewData.VIDEOID, GridviewData.VIDEOFILEPATH };
return new CursorLoader(Gridview.this, MyContentProvider.CONTENT_URI, projection, null, null, null);
}
#Override
public void onLoadFinished(Loader<Cursor> loader, Cursor c) {
cursoradapter.swapCursor(c);
}
#Override
public void onLoaderReset(Loader<Cursor> loader) {
cursoradapter.swapCursor(null);
}

The error is caused by your imports:
import android.support.v4.app.LoaderManager;
import android.support.v4.app.LoaderManager.LoaderCallbacks;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.support.v4.widget.CursorAdapter;
they would be fine for FragmentActivity but you are using a normal Activity so they should be:
import android.app.LoaderManager;
import android.app.LoaderManager.LoaderCallbacks;
import android.content.CursorLoader;
import android.content.Loader;
import android.widget.CursorAdapter;
Please note that in this case your android:minSdkVersion should be 11. If you need compatibility with lower versions, just keep the imports as they are and use FragmentActivity.

Related

Android get all details of a contact

I didn't find any solution in the Internet, only a tutorial on Android Developers, which unfortunately gives only a small part of code needed for it. I ended up having something like this:
import android.database.Cursor;
import android.os.Bundle;
import android.provider.ContactsContract.Data;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.support.v7.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<Cursor> {
// Defines the selection clause
private static final String SELECTION = Data.LOOKUP_KEY + " = ?"; // Defines the array to hold the search criteria
private String[] mSelectionArgs = { "" };
private String mLookupKey;
private static final String SORT_ORDER = Data.MIMETYPE;
final int DETAILS_QUERY_ID = 0;
private static final String PROJECTION[] = {
Data._ID, Data.MIMETYPE, Data.DATA1, Data.DATA2, Data.DATA3, Data.DATA4, Data.DATA5, Data.DATA6, Data.DATA7, Data.DATA8, Data.DATA9, Data.DATA10, Data.DATA11, Data.DATA12, Data.DATA13, Data.DATA14, Data.DATA15
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// getLoaderManager().initLoader(DETAILS_QUERY_ID, null, this);
}
#Override
public Loader<Cursor> onCreateLoader(int loaderId, Bundle args) {
switch (loaderId) {
case DETAILS_QUERY_ID:
// Assigns the selection parameter
mSelectionArgs[0] = mLookupKey; // Starts the query
CursorLoader mLoader = new CursorLoader(this, Data.CONTENT_URI, PROJECTION,
SELECTION, mSelectionArgs, SORT_ORDER);
}
return null; // TODO what should be here ?
}
#Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
}
#Override
public void onLoaderReset(Loader<Cursor> loader) {
// switch (loader.getId()) {
// case DETAILS_QUERY_ID:
// }
// break;
// }
}
}
How can I make it work ? https://developer.android.com/training/contacts-provider/retrieve-details.html is really lacking some code and explanation

Call list view lag while scrolling

I am working on sample of calls log application. In this application my fragment displays Dialed Type calls in a list. here in each list item it shows photo from contacts, Number, name and time. It is working fine but it lags while scrolling.
fragment code:
package com.example.vl.calllogs;
import android.content.ContentUris;
import android.content.Context;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.provider.CallLog;
import android.provider.ContactsContract;
import android.support.v4.app.ListFragment;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.util.Log;
import android.view.View;
import android.widget.CursorAdapter;
import android.widget.ImageView;
import android.widget.ResourceCursorAdapter;
import android.widget.TextView;
import org.w3c.dom.Text;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* Created by vl on 12/29/2015.
*/
public class TabDialedFragment extends ListFragment implements LoaderManager.LoaderCallbacks<Cursor> {
CursorAdapter mAdapter;
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setEmptyText("No Dialed Numbers");
mAdapter = new MyCursorAdapter(getActivity(), R.layout.fragment_tab_dialed, null, 0);
setListAdapter(mAdapter);
getLoaderManager().initLoader(0, null, this);
}
private static final String[] PROJECTION = {
CallLog.Calls._ID,
CallLog.Calls.DATE,
CallLog.Calls.CACHED_NAME,
CallLog.Calls.CACHED_PHOTO_ID,
CallLog.Calls.NUMBER,
CallLog.Calls.DURATION
};
#Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
Uri baseUri = CallLog.Calls.CONTENT_URI;
String selection = CallLog.Calls.TYPE + "= 2";
return new CursorLoader(getActivity(), baseUri, PROJECTION,selection, null, CallLog.Calls.DATE + " DESC" );
}
#Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
mAdapter.swapCursor(data);
}
#Override
public void onLoaderReset(Loader<Cursor> loader) {
mAdapter.swapCursor(null);
}
class MyCursorAdapter extends ResourceCursorAdapter{
MyCursorAdapter(Context context, int layout, Cursor cursor, int flags ){
super(context, layout,cursor,flags);
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
TextView name = (TextView) view.findViewById(R.id.name);
String nameString = cursor.getString(cursor.getColumnIndex(CallLog.Calls.CACHED_NAME));
if(nameString == null || "".equals(nameString.trim())){
name.setText("Unknown");
}else{
name.setText(nameString);
}
TextView time = (TextView) view.findViewById(R.id.time);
String timeS = cursor.getString(cursor.getColumnIndex(CallLog.Calls.DATE));
Date callDayTime = new Date(Long.valueOf(timeS));
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("EEE, d MMM yyyy HH:mm");
String str = simpleDateFormat.format(callDayTime);
String durationS = cursor.getString(cursor.getColumnIndex(CallLog.Calls.DURATION));
time.setText(String.format(getActivity().getResources().getString(R.string.thirdLine), str, durationS));
TextView number = (TextView) view.findViewById(R.id.number);
String numberS = cursor.getString(cursor.getColumnIndex(CallLog.Calls.NUMBER));
number.setText(numberS);
int contactID = getContactIDFromNumber(numberS);
ImageView imageView = (ImageView) view.findViewById(R.id.imageView);
imageView.setImageBitmap(getPhoto(contactID+""));
}
public int getContactIDFromNumber(String contactNumber)
{
contactNumber = Uri.encode(contactNumber);
int phoneContactID = -1;
Cursor contactLookupCursor = getActivity().getContentResolver().query(Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI,contactNumber),new String[] {ContactsContract.PhoneLookup.DISPLAY_NAME, ContactsContract.PhoneLookup._ID}, null, null, null);
while(contactLookupCursor.moveToNext()){
phoneContactID = contactLookupCursor.getInt(contactLookupCursor.getColumnIndexOrThrow(ContactsContract.PhoneLookup._ID));
}
contactLookupCursor.close();
return phoneContactID;
}
private Bitmap getPhoto(String id){
Bitmap photo = null;
try{
InputStream inputStream = ContactsContract.Contacts.openContactPhotoInputStream(
getActivity().getContentResolver(),
ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, new Long(id).longValue()));
if(inputStream != null)
photo= BitmapFactory.decodeStream(inputStream);
}catch (Exception e){
}
return photo;
}
}
}
I feel it might be the problem of in efficient way of getting photo from Contacts. here I first get the contact_id and then I queried for the photo using contact ID. Is this the correct way?
Last queries are not working asynchronously. To make async what should I do?
There're three main performance issues on your bindView you should fix.
Most serious issue:
The call to private Bitmap getPhoto that is a SQLite operation followed by a disk loading operation. that takes several milliseconds to happen and is definitely lagging the UI.
Bad news is that background thread image loading and caching is a very complex topic and very difficult to code properly.
Good news is that nowadays we have loads of great libraries that does the work for you. Below is the code to load it using Picasso library
Uri uri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, id);
Picasso.with(getActivity()).load(uri).into(imageView);
Pretty bad issue:
The call public int getContactIDFromNumber is also doing an SQLite query and that's also pretty slow.
Unfortunately I don't have any major suggestion on how you should fix it. It's a slow operation and you should do in a background thread. It will be a major refactor to make it work from inside the adapter.
My suggestion is to extend CursorLoader and make it after it finishes load the cursor (but still on the background thread) to perform all those queries and keep it in some HashMap
Minor issues:
Use a Holder Pattern to avoid all those calls to findViewById(int).
Also avoid creating new objects inside bindView. For example, you should have only 1 private static final SimpleDateFormat simpleDateFormat = new SimpleDateFormat("EEE, d MMM yyyy HH:mm"); for the whole class and use this same instance all the time. Also have just 1 Date object for the Adapter and just call callDayTime.setTime(Long.valueOf(timeS));
Hope it helps.

swapCursor() slow: "The application may be doing too much work on its main thread."

I keep seeing "The application may be doing too much work on its main thread."
Is this being caused by swapCursor() in my code below? It appears so: if I remove it, the above warning disappears.
I still don't understand why it claims to be the main thread that is causing the problem. I have moved the swapCursor() around into various places such as onLoadFinished() and in loadInBackground() but I get the same result.
How can I call swapCursor() so that this warning doesn't appear? The whole reason I used SimpleCursorLoader was avoid holding up the main thread but its still happening.
package com.example.sqlitetest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import android.app.Activity;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.LoaderManager;
import android.support.v4.app.LoaderManager.LoaderCallbacks;
import android.support.v4.content.Loader;
import android.support.v4.content.CursorLoader;
import android.support.v4.widget.SimpleCursorAdapter;
import android.support.v4.widget.SimpleCursorAdapter.ViewBinder;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.AdapterView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams;
import android.widget.ListView;
import android.widget.TextView;
public class MainActivity extends FragmentActivity implements LoaderManager.LoaderCallbacks<Cursor>
{
public static Context mContext;
private LoaderManager.LoaderCallbacks<Cursor> mLoaderCallbacks;
public static SQLiteDatabase db;
public static SimpleCursorAdapter cAdapter;
public static ListView lvCustomList;
public static final class MyCursorLoader extends SimpleCursorLoader
{
public MyCursorLoader( Context context )
{
super( context );
}
#Override
public Cursor loadInBackground()
{
Cursor cursor = null;
cursor = db.rawQuery( "SELECT rowid _id, Name, Rating FROM Tune ORDER BY Name", null );
cAdapter.swapCursor( cursor );
return cursor;
}
}
#Override
public Loader<Cursor> onCreateLoader(int id, Bundle args)
{
return new MyCursorLoader( this );
}
#Override
public void onLoadFinished( Loader<Cursor> loader, Cursor cursor )
{
// cAdapter.swapCursor( cursor );
}
#Override
public void onLoaderReset( Loader<Cursor> loader )
{
cAdapter.swapCursor( null );
}
#Override
public void onCreate( Bundle savedInstanceState )
{
super.onCreate( savedInstanceState );
setContentView( R.layout.tune_artist_album_view );
mContext = this;
String path = "/sdcard/MyDb.sqlite";
db = SQLiteDatabase.openDatabase( path, null, 0 );
lvCustomList = (ListView) findViewById( R.id.lv_custom_list );
String[] columns = new String[] { "Name", "Rating" };
int[] to = new int[] { R.id.lv_tune };
cAdapter = new SimpleCursorAdapter( mContext, R.layout.like_hate_row, null, columns, to, 0 );
lvCustomList.setAdapter( cAdapter );
mLoaderCallbacks = this;
LoaderManager lm = getSupportLoaderManager();
lm.initLoader( 0, null, mLoaderCallbacks );
}
}
Here is SimpleCursorLoader:
package com.example.sqlitetest;
import android.content.Context;
import android.database.Cursor;
import android.support.v4.content.AsyncTaskLoader;
/**
* Used to write apps that run on platforms prior to Android 3.0. When running
* on Android 3.0 or above, this implementation is still used; it does not try
* to switch to the framework's implementation. See the framework SDK
* documentation for a class overview.
*
* This was based on the CursorLoader class
*/
public abstract class SimpleCursorLoader extends AsyncTaskLoader<Cursor>
{
private Cursor mCursor;
public SimpleCursorLoader( Context context )
{
super( context );
}
/* Runs on a worker thread */
#Override
public abstract Cursor loadInBackground();
/* Runs on the UI thread */
#Override
public void deliverResult( Cursor cursor )
{
if( isReset() )
{
// An async query came in while the loader is stopped
if( cursor != null )
{
cursor.close();
}
return;
}
Cursor oldCursor = mCursor;
mCursor = cursor;
if( isStarted() )
{
super.deliverResult( cursor );
}
if( oldCursor != null && oldCursor != cursor && !oldCursor.isClosed() )
{
oldCursor.close();
}
}
/**
* Starts an asynchronous load of the contacts list data. When the result is
* ready the callbacks will be called on the UI thread. If a previous load has
* been completed and is still valid the result may be passed to the callbacks
* immediately.
* <p/>
* Must be called from the UI thread
*/
#Override
protected void onStartLoading()
{
if( mCursor != null )
{
deliverResult( mCursor );
}
if( takeContentChanged() || mCursor == null )
{
forceLoad();
}
}
/**
* Must be called from the UI thread
*/
#Override
protected void onStopLoading()
{
// Attempt to cancel the current load task if possible.
cancelLoad();
}
#Override
public void onCanceled( Cursor cursor )
{
if( cursor != null && !cursor.isClosed() )
{
cursor.close();
}
}
#Override
protected void onReset()
{
super.onReset();
// Ensure the loader is stopped
onStopLoading();
if( mCursor != null && !mCursor.isClosed() )
{
mCursor.close();
}
mCursor = null;
}
}
Methods like query() and rawQuery() don't do what you think they do. Notably, they do not actually query the database. They merely configure the SQLiteCursor that they return. When you attempt to use that Cursor, it executes the query.
Hence, in your loadInBackground() method, in between rawQuery() and swapCursor(), call getCount() on the Cursor you got back from rawQuery(). That is enough to force the Cursor to really do the work for the query, and therefore that work is done on the background thread.

multiple variables, cursor or stringarray dilemma

i want to populate my userinterface elements with data from my database
reading the database happens over my according database class (AbezoeAdapter)
populating my userinterface is done by my mainclass (Bezoekrapporten)
now i am struggling with following code to get my idea working
package com.example.deceunincktechniekers;
import java.util.Date;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Point;
import android.os.Bundle;
import android.util.Log;
import android.util.TypedValue;
import android.view.Display;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.Button;
import android.widget.EditText;
import android.widget.PopupWindow;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.content.res.*;
import android.database.Cursor;
#SuppressLint("SimpleDateFormat") public class bezoekrapporten extends Activity
{
TextView controlelijn;
EditText scanzonedata;
String scanzonestring;
String sScan;
String Bezoeknummer;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.bezoekrapporten);
//////////////////////// here is some code missing///////////////////////////
private void vulbezoekrapportboxin(String bezoeknummer) {
ABezoeAdapter bezoe = new ABezoeAdapter(this);
TextView bezoekrapportnummer;
bezoekrapportnummer = (TextView) findViewById(R.id.boxbrBrnum);
TextView servicenummer;
servicenummer = (TextView) findViewById(R.id.boxbrServicenum);
TextView datum;
datum = (TextView) findViewById(R.id.boxbrBrdatum);
TextView klantnaam;
klantnaam = (TextView) findViewById(R.id.boxbrKlant);
TextView straatnaam;
straatnaam = (TextView) findViewById(R.id.boxbrAdres);
TextView gemeente;
gemeente = (TextView) findViewById(R.id.boxbrGemeente);
TextView machinenummer;
machinenummer = (TextView) findViewById(R.id.boxbrMachinenr);
TextView merk;
merk = (TextView) findViewById(R.id.boxbrMerk);
TextView serienummer;
serienummer = (TextView) findViewById(R.id.boxbrSerial);
if(bezoeknummer == null)
{
bezoekrapportnummer.setText("-----");
}
else
{
Cursor c =bezoe.leesgegevens(bezoeknummer);
if (c.moveToFirst()){
while(!c.isAfterLast()){
String data = c.getString(c.getColumnIndex("bezoekrapportdatum"));
controlelijn.setText(data);
c.moveToNext();
}
}
c.close();
bezoekrapportnummer.setText(bezoeknummer);
}
return;
}
and the code snippet from AbezoeAdapter
package com.example.deceunincktechniekers;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.*;
import android.util.Log;
public class ABezoeAdapter extends ADbAdapter {
public static final String recordnummer = "RECNUM";
public static final String bezoekrapportnummer = "Z01";
public static final String bezoekrapportdatum = "Z02";
public static final String herstellingsoort = "Z03";
//////////////////here is some code missing///////////////////////////:
public static final String basisservicenummer = "Z27";
public static final String verzonden = "Z28";
public static final String[] allekolommen = new String[] {bezoekrapportnummer + " AS _id", bezoekrapportdatum,
herstellingsoort, totaleduur, servicenummer, ONBEKEND, klantnaam, adres, machinenummer, omschrijving,
duur, postcode, gemeente, merk, model, serienummer, opmerkingen, werkgereed, extratijd, urenstand, gecontroleerdbureel,
onderhoudsfiche, uitsplitsen, opmerkingbureel, ONBEKEND2, orderverwerkdatum, ordernummer, basisservicenummer, verzonden};
//////////////////////////////here is some code missing/////////////////////////////////////////////
public Cursor leesgegevens(String bezoeknummer) {
open();
Cursor c = onzedatabase.query(true, databasetabel, allekolommen,
"_id" + "=?", new String[] { bezoeknummer }, null, null, null, null, null);
if (c != null) {
c.moveToFirst();
}
Log.i("cursor leesgegevens", c.toString());
sluit();
return c;
/////////////////////////////////////here is some code missing//////////////////
can anybody inform me with the best way of working to get the data from the database to my UI?
if i am already able to compile my code i get an error in my logcat that looks as follows:
11-24 15:58:34.089: E/AndroidRuntime(785): FATAL EXCEPTION: main
11-24 15:58:34.089: E/AndroidRuntime(785): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.deceunincktechniekers/com.example.deceunincktechniekers.bezoekrapporten}: java.lang.IllegalStateException: Couldn't read row 0, col -1 from CursorWindow. Make sure the Cursor is initialized correctly before accessing data from it.
Here's how I did one of my adapters. First, here's the code that does the query:
private void query (long uuid)
{
// Fill list using adapter
String cols[] = { Instances.TITLE }; // dummy field; we will set all fields together in ViewBinder
int fields[] = { R.id.node_text };
cursorAdapter = new CursorAdapter (this,
R.layout.row_view,
null, // no cursor yet
cols,
fields,
Adapter.NO_SELECTION);
cursorAdapter.setViewBinder (new MyViewBinder(this));
// Setup the adapter filter - this does the query work.
cursorAdapter.setFilterQueryProvider (new FilterQueryProvider()
{
#Override
public Cursor runQuery (CharSequence constraint)
{
Cursor cursor = getContentResolver().query (...your params...);
return cursor;
}
});
listView.setAdapter (cursorAdapter);
listView.setTextFilterEnabled (true);
// Force initial query - notice we setup an adapter with a null cursor.
cursorAdapter.getFilter().filter (null);
}
Notice I did not subclass the adapter. Instead, I subclassed ViewBinder. Normally one lets each call to ViewBinder set one view at a time. I thought it would be more efficient to do all the views together. Here's how I did it:
private class MyViewBinder implements ViewBinder
{
#Override
public boolean setViewValue (View view, Cursor cursor, int column)
{
// Do all columns in one pass.
if (column != SelectAndroidEvent.instancesTitleCol)
throw new IllegalStateException ("viewbinder should only be called for title; " +
"col: " + column);
// Find encompassing layout.
ViewGroup parentView = (ViewGroup)view.getParent();
// Get fields from parentView.
TextView titleView = (TextView)view;
TextView field2 = (TextView)parentView.findViewById (R.id.field2);
...
// set all fields together - easier.
view.setText (cursor.getString (column);
field2.setText (cursor.getString (FIELD2_COL);
...
return true;
}
}
Hope this helps.

Retrieving contacts in list view and displaying the name and phone number in next activity with click action

I have got the code where through content provider i am retrieving the phone contacts and displaying them in list format.
I want to display the phone no and name of the particular person in next activity when i click on the list format contacts from first activity. I am getting errors in this its not able to perform click operation and display it on to next activity Please help me with this.
Here is the first Activity through i am display the contacts through content provider.
import android.app.Activity;
import android.app.ListActivity;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.widget.TextView;
public class MsatActivity extends ListActivity
{
TextView ContactsTV;
ListView lv;
Cursor c;
public static final Uri CONTENT_URI =
Uri.parse("content://com.android.contacts/contacts/1557");
public void onListItemClick(View v)
{
Intent outData = new Intent(this,Full.class);
// setResult(Activity.RESULT_OK, outData);
startActivity(outData);
}
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Uri myContacts = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
c = getContentResolver().query(myContacts, new String[]
{ContactsContract.CommonDataKinds.Phone._ID,
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Phone.NUMBER}
, null, null, null);
String[] columns = new String[]
{
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Phone.NUMBER};
int[] to = new int[] {R.id.text1,R.id.text2};
SimpleCursorAdapter mAdapter = new
SimpleCursorAdapter(this,R.layout.listitems, c, columns, to);
setListAdapter(mAdapter);
lv.setOnItemSelectedListener(new OnItemClickListener()
{
public void onItemClick(AdapterView<?> parent, View view, int pos, long id)
{
int rowId = c.getInt(c.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone._ID));
Uri outURI = Uri.parse(CONTENT_URI.toString() + "/" + rowId);
Intent outData = new Intent();
outData.setData(outURI);
setResult(Activity.RESULT_OK, outData);
finish();
}
});
}
}
Here is the second activity.......
import android.app.Activity;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.view.View;
import android.widget.Button;
public class Full extends Activity
{
private static final int CONTACT_PICKER_RESULT = 1001;
String name;
Cursor cursor;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main1);
Button getContacts = (Button)findViewById(R.id.button1);
getContacts.setOnItemClickListener(new View.OnItemClickListener()
{
public void onClick(View v)
{
Intent i = new Intent(Intent.ACTION_PICK,
ContactsContract.CommonDataKinds.Phone.CONTENT_URI);
startActivityForResult(i, CONTACT_PICKER_RESULT);
}
});
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK)
{
switch (requestCode)
{
case CONTACT_PICKER_RESULT:
try {
Uri result = data.getData();
String id = result.getLastPathSegment();
//Get Name
cursor = getContentResolver().query(result, null, null, null, null);
if (cursor.moveToFirst())
{
name =
cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
}
}
catch (Exception e)
{
}
}
}
}
}
I really can't figure out your code at all. The first activity seems to be creating an Intent to start the Full Activity, but it has two "onclick" methods and it does a setResult() and finish() even though it never did getIntent()!
The second activity creates an ACTION_PICK Intent for the entire Phone table, and handles the return by doing a query on the result, which should be the contact ID of the contact whose # the user picked. I don't think it's the entire URI, though; you should verify that through debug. You then try to get the DISPLAY_NAME for this contact.
Fine, but I don't see why you need the first Activity at all.
I posted some instructions on using the Contacts Provider somewhere else on Stackoverflow; just search for android and ContactsContract.

Categories

Resources