I make an app in which phone contact show in listview. but i want to convert it into widget. ie, I want to show contact list on the homescreen in a listview. I searched on google and found some example but none worked. any one has any link. I am not posting my code because it not worked. any help will be appriciated
Update :-
I am able to show list on homescreen. how to bind this listview to contact list
I tried to add this method in my viewfactory class
public void getnumber(ContentResolver cr) {
Cursor phone = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null);
while (phone.moveToNext()) {
Info info = new Info();
ids = phone.getString(phone.getColumnIndex(ContactsContract.CommonDataKinds.Phone._ID));
info.phone=phone.getString(phone.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
info.name=phone.getString(phone.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
info.picture=phone.getString(phone.getColumnIndex(ContactsContract.CommonDataKinds.Phone.PHOTO_URI));
System.out.println("...........name");
aa.add(new ContactStock(info.name,info.phone));
}
phone.close();
//Collections.sort(aa);
adapt=new ContactListAdapter(MainActivity.this, aa);
//listcontact.setAdapter(new ContactListAdapter(MainActivity.this, aa));
//adapter = new ArrayAdapter<Info>(this, android.R.layout.simple_list_item_1);
listcontact.setAdapter(adapt);
}
But it doesn't work, it is working in my app but not in homescreen widget
Update 2 :-
I am showing contact list in widget but all contacts are showing in one row.My remote view class is
public class DialerViewFactory implements RemoteViewsFactory {
private static final int mCount = 2;
private List<Info> mWidgetItems = new ArrayList<Info>();
private Context mContext;
private int mAppWidgetId;
public DialerViewFactory(Context context,Intent intent){
mContext=context;
mAppWidgetId=intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return mCount;
}
#Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
#Override
public RemoteViews getLoadingView() {
// TODO Auto-generated method stub
return null;
}
#Override
public RemoteViews getViewAt(int position) {
// TODO Auto-generated method stub
//ContentResolver cr=mContext.getContentResolver();
//getnumber(cr);
RemoteViews rv=new RemoteViews(mContext.getPackageName(),R.layout.row);
rv.setTextViewText(R.id.textrow1, mWidgetItems.toString());
rv.setTextViewText(R.id.textrow2, "Kya");
Bundle extras = new Bundle();
extras.putInt(DialerWidgetProvider.EXTRA_ITEM, position);
Intent fillInIntent = new Intent();
fillInIntent.putExtras(extras);
rv.setOnClickFillInIntent(R.id.textrow1, fillInIntent);
return rv;
}
#Override
public int getViewTypeCount() {
// TODO Auto-generated method stub
return 1;
}
#Override
public boolean hasStableIds() {
// TODO Auto-generated method stub
return true;
}
#Override
public void onCreate() {
// TODO Auto-generated method stub
ContentResolver cr1=mContext.getContentResolver();
getnumber(cr1);
}
#Override
public void onDataSetChanged() {
// TODO Auto-generated method stub
}
#Override
public void onDestroy() {
// TODO Auto-generated method stub
}
public void getnumber(ContentResolver cr) {
Cursor phone = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null);
while (phone.moveToNext()) {
Info info = new Info();
info.phone=phone.getString(phone.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
info.name=phone.getString(phone.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
info.picture=phone.getString(phone.getColumnIndex(ContactsContract.CommonDataKinds.Phone.PHOTO_URI));
System.out.println("...........name");
mWidgetItems.add(info);
}
phone.close();
}
class Info {
public String name;
public String phone;
public String picture;
#Override
public String toString() {
return name;
}
}
}
What you are looking for is AppWidgets using Collections. This can accept a ListView as the widget for presenting your data.
This will basically consist of
an AppWidgetProvider, as in any widget
a RemoteViewsService / RemoteViewsFactory, responsible for
producing the views in your ListView, much like an Adapter would do.
Since you are not sharing your code, it's hard to say what is not working for you, but you can find working examples in the sdk samples. Note that the samples have apparently been removed from latest sdk versions, so you should probably download the samples for older sdk's, if I remember correctly. You can also browse the source here.
EDIT :
adapt=new ContactListAdapter(MainActivity.this, aa);
listcontact.setAdapter(adapt);
This will not work in app-widgets, for 2 reasons :
You don't have an Activity available. For widgets, you can use the Context provided as argument of the onUpdate callback in your AppWidgetProvider, although in your case it probably won't be needed.
You don't instantiate an Adapter for app-widgets. To bind data to your ListView on your homescreen, you call setRemoteAdapter on the main RemoteView inside your AppWidgetProvider (in the onUpdate method), like this :
Example :
// Setup the intent which points to the StackViewService which will
// provide the views for this collection.
Intent intent = new Intent(context, WidgetService.class);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetIds[i]);
// When intents are compared, the extras are ignored, so we need to embed the extras
// into the data so that the extras will not be ignored.
intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME)));
// Creating the main RemoteView and binding data to it.
RemoteViews rv = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
rv.setRemoteAdapter(R.id.listview, intent);
Basically, the RemoteViewsFactory's getViewAt method acts much like the getView in an Adapter would, you just have to copy and adapt the code of your adapter to make it work in the RemoteViewsFactory. The sample of StackWidget contains a RemoteViewsFactory where all the method are commented to let you know where to perform which tasks.
EDIT 2 :
#Override
public int getCount() {
// This method tells the factory how many rows it has to produce
// you should be returning the size of your data collection
// so in your case :
return mWidgetItems.size();
}
Also, in you getViewAt method you are setting the text as the toString() of the array (this is why you have all contacts in one row), whereas you should read the fields of the individual Info object for the position given by the method:
// get the current Info object by position :
Info currentInfo = mWidgetItems.get(position);
// then use that object to fill each row, like in getView for an Adapter, for example :
rv.setTextViewText(R.id.textrow1, currentInfo.phone);
rv.setTextViewText(R.id.textrow2, currentInfo.name);
Related
I am having a Framelayout and some TextViews in my application for which I am loading data from server and setting the background of FrameLayout with Image loaded from server using Picasso and setting TextViews in the same manner. But I want to share it using intent and I am unable to figure out how to do that? Do I have to download the Image First?
My Code in AsyncTask:
Picasso.with(ctx).load(myPlace.getImg()).into(new Target() {
#Override
public void onPrepareLoad(Drawable arg0) {
// TODO Auto-generated method stub
}
#TargetApi(Build.VERSION_CODES.JELLY_BEAN)
#Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom arg1) {
// TODO Auto-generated method stub
pImg.setBackgroundDrawable(new BitmapDrawable(ctx.getResources(), bitmap));
}
#Override
public void onBitmapFailed(Drawable arg0) {
// TODO Auto-generated method stub
Toast.makeText(ctx, "Failed Loading", Toast.LENGTH_SHORT).show();
}
});
pname.setText(myPlace.getName());
pdes.setText(myPlace.getDescription());
Share Button:
Button shareBtn = (Button) findViewById(R.id.sharebtn);
As Picasso will cache the image, you wont need to re download it in another activity(as long as it is on the same application). Add these to your code and see if it helps
steps one and two required only if myPlace is local to AsyncTask
Step 1: make AsyncTask return a MyPlace object
private class ClassName extends AsyncTask<..., ..., MyPlace> {
...
}
Step 2: return myPlace object from onPostExecute
Step 3: pack values in bundle and send over intent
Intent intent = new Intent(this, NextActivity.class)
Bundle bundle = new Bundle();
bundle.putString(IMG_URL, myPlace.getImg()); // assuming getImg returns string of url
// put name and desc in the same way
intent.addExtra(bundle);
startActivity(intent);
Step 4: get values in new activity
Intent intent = getIntent();
String url = intent.getExtra().getString(IMG_URL);
// others in the smae way
I have a list view which show list of task, on selecting task it shows details about task, when I delete the particular task it returns to the previous activity by finish(). but it does not update the list.
I want to know how and where to use notifyDataSetChanged method and add adapter method is never used.
Other than notifyDataSetChanged() solution is also accepted :) i just want to update the list when it returns to the previous activity.
Do it with startActivityForResult(). When you create intent to open new activity open it for result. The task being deleted is your result. So when it's marked as deleted and you return to your previous activity, the result triggers and you can delete the marked item + call the notify.
More info here : http://developer.android.com/training/basics/intents/result.html
you can use the notifyDataSetChanged on the onResume method, this always update the data itself when the Activity shows
You can also notify your parent activity before finishing your current activity. You just have to register a Receiver in your main activity and all others activities will be able to notify that activity. You can even send data!
As my english is not that good, sample code :
The MainActivity class
public class MainActivity extends AppCompatActivity {
// you can define your name for your receiver as a constant,
// so you can access it from other activities if you want
public static final String MY_SUPER_INTERNAL_NOTIFICATION = "MY_SUPER_INTERNAL_NOTIFICATION";
public static final String MY_OBJECT = "my_object";
public static final String MY_OBJECT_POSITION = "my_object_position" ;
private MyCustomAdapter adapter;
private ListView listView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView)findViewById(R.id.listView);
// set up your list with your adapter and data...
adapter = new MyCustomAdapter(this);
// [...] I suppose you know how to do that, I dont write everything
listView.setAdapter(adapter);
// when you click on a row from your list,
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent intent = new Intent(
MainActivity.this,
SecondActivity.class
);
// you can for example put data in a Bundle and pass it to the other activity
// then on the onCreate you can use that data as you want
Bundle bundle = new Bundle();
// IMPORTANT be sure that the object you are putting in the bundle is Serializable (implements Serializable)
bundle.putSerializable(MY_OBJECT, adapter.getItem(position));
// you can also for example send the position of the row you clicked
bundle.putInt(MY_OBJECT_POSITION, position);
// put your bundle in the intent
intent.putExtras(bundle);
startActivity(intent);
}
});
// register your Receiver! don't forget to do that or you will never be notified
LocalBroadcastManager
.getInstance(this)
.registerReceiver(
broadcastReceiver,
new IntentFilter(MY_SUPER_INTERNAL_NOTIFICATION)
);
}
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (intent != null) {
// get the position sent by the other activity
int position = intent
.getExtras()
.getInt(SecondActivity.MY_EXAMPLE_KEY);
adapter.deleteItem(position);
}
}
};
// adapter class...
private class MyCustomAdapter extends BaseAdapter {
ArrayList<MyObject> data;
public MyCustomAdapter(Context context) {
}
public void deleteItem(int position){
// delete your item from the list of data
data.remove(position);
// dont forget to notify
notifyDataSetChanged();
}
#Override
public int getCount() {
return 0;
}
#Override
public MyObject getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
return null;
}
// adapter class, you can extend your favorite type of adapter
}
}
The SecondActivity class :
public class SecondActivity extends AppCompatActivity {
public static final String MY_EXAMPLE_KEY = "EXAMPLE";
private MyObject myObject;
private int myObjectPosition;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.second_activity);
myObject = (MyObject) getIntent()
.getExtras()
.getSerializable(MainActivity.MY_OBJECT);
myObjectPosition = getIntent()
.getExtras()
.getInt(MainActivity.MY_OBJECT_POSITION);
// do all your stuff with your object
// before calling finish do this
beforeFinishDoThisStuff();
}
private void beforeFinishDoThisStuff() {
sendBroadcastToMainActivity();
finish();
}
private void sendBroadcastToMainActivity() {
// create an intent and put your Receiver name as action name
// like you defined in your MainActivity
Intent intent = new Intent(MainActivity.MY_SUPER_INTERNAL_NOTIFICATION);
Bundle bundle = new Bundle();
// put whatever you want, here I put just the previous position of the object in the list
bundle.putInt(MY_EXAMPLE_KEY, myObjectPosition);
intent.putExtras(bundle);
// notify your MainActivity
LocalBroadcastManager
.getInstance(this)
.sendBroadcast(intent);
// after this finish !
}
}
Hope you understand how to notify activities with BroadcastManager. It's very powerful and simple to use.
Have fun coding !
I have an activity whose only purpose is to display a list view. There is a custom adapter to serve up the views for each element in the array.
I have break points all over and when I debug, it stops in "count" a number of times - the first few times the return value is zero, then it changes to 3 (the correct value in this case). Then we stop in "getView" - all the right stuff happens, and after we're through with all the break points, then presto magico all three records display on the screen. Yea!
So then I try to run the app outside of the debugger. I get the log message that it's visited "count", and the log message displays the return value so I know it's correct - but "getView" never gets called!!
I'm not sure which bits of code are relevant to this question & don't want to pollute the question with the entire project; please let me know if there's a specific section that would be helpful. I've researched all the "getView not called" questions but those consistently are for a case where getView never gets called, which clearly mine can beā¦sometimes :(
EDIT: Adapter code
public class DivisionAdapter extends BaseAdapter {
private static final String TAG = "DIV_ADAPT";
private ArrayList<Division> divisionList;
private Context context;
public DivisionAdapter(Context c, ArrayList<Division> divList) {
divisionList = divList;
context = c;
}
#Override
public int getCount() {
Integer count = 0;
if (divisionList != null) count = divisionList.size();
Log.v(TAG,count.toString());
return count;
}
#Override
public Object getItem(int position) {
Object o = null;
if (divisionList != null)
o = divisionList.get(position);
return o;
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
Log.v(TAG,"getView");
if (divisionList == null)
return null;
LinearLayout divisionView = null;
Division thisDiv = divisionList.get(position);
if (convertView == null) {
divisionView = new LinearLayout(context);
LayoutInflater li = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
li.inflate(R.layout.division_item, divisionView, true);
} else {
divisionView = (LinearLayout) convertView;
}
Log.v(TAG,thisDiv.name());
TextView v = (TextView) divisionView.findViewById(R.id.divisionName);
v.setText(thisDiv.name());
v = (TextView) divisionView.findViewById(R.id.divisionRegion);
v.setText(thisDiv.region());
return divisionView;
}
public void setList(ArrayList<Division> newList) {
divisionList = null;
divisionList = newList;
}
}
And just in case it's useful, some snippets from the activity class:
#Override
public void onResume() {
super.onResume();
refreshList();
}
private void refreshList() {
// use the class static query method to get the list of divisions
Division.query(Division.class,
new StackMobQuery().fieldIsEqualTo("status", "ACTIVE"),
new StackMobQueryCallback<Division>() {
#Override
public void failure(StackMobException arg0) {
// TODO Auto-generated method stub
Log.v(TAG, "query fail");
}
#Override
public void success(List<Division> arg0) {
Log.v(TAG, "query success");
divAdapt.setList((ArrayList<Division>) arg0);
divAdapt.notifyDataSetChanged();
}
});
}
EDIT 2/11:
I found this question: Markers not showing on map after stackmob query which reveals the hitherto unknown fact that stack mob queries run on a background thread. I'm starting to research the relationship between threads and adapters and thought I'd share this clue in case it helps anyone else figure out what's going on here faster than I can. TIA.
idk why this EVER worked in the debugger - that turned out to be a red herring.
As discovered, the StackMobModel static query method does run in a background thread, from which calling NotifyDataSetChanged() is completely ineffectual.
I ended up replacing the success method in the StackMobQueryCallback as follows:
#Override
public void success(final List<Division> arg0) {
Log.v(TAG, "query success");
runOnUiThread(new Runnable() {
public void run() {
updateList((ArrayList<Division>) arg0);
}
});
}
and then added this new method
private void updateList(ArrayList<Division> newList) {
divAdapt.setList(newList);
divAdapt.notifyDataSetChanged();
}
now, when the query returns, the adapter update is directed to run on the proper thread, and hooray, everything looks stitched together just fine and dandy.
whew!
This question already has answers here:
How to pass an object from one activity to another on Android
(35 answers)
Closed 9 years ago.
I am badly stuck to pass object from one activity to another activity using Parcelable but I am getting null pointer exception at line Log.i("Name",""+rcp.getName());, you can check this line in below code. Plz do check code CookingDataModel class at the end.
Here is the code of object Receiving Activity
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);// No title to display
setContentView(R.layout.recipe_ingredient_detail);
CookingDataModel cook = new CookingDataModel();
RecipeDataModel rcp;
ArrayList<IngredientDataModel> ing;
Bundle bundle = this.getIntent().getExtras();
if(bundle!=null)
cook = bundle.getParcelable("Cooking");
rcp = cook.getRecipe();
ing = cook.getIngredientList();
Log.i("Name",""+rcp.getName());
Log.i("Decrp",""+rcp.getDescription());
Log.i("Duration",""+rcp.getPrepTime());
Log.i("Instructions",""+rcp.getInstructions());
for(int k = 0; k < ing.size(); k++)
{
Log.i("Item Name",""+ing.get(k).getItemName());
Log.i("Item Amount",""+ing.get(k).getItemAmount());
}
}
Here is the code where I am sending object of CookingDataModel .
ListView recepeListView = getListView();
recepeListView.setOnItemClickListener(new OnItemClickListener()
{
public void onItemClick(AdapterView<?> arg0, View arg1, int position,long arg3)
{
CookingDataModel cook = recpeList.get(position);
Intent intent = new Intent();
Bundle bundle = new Bundle();
bundle.putParcelable("Cooking",cook);
intent.putExtras(bundle);
intent.setClass(RecipeList.this,RecipeIngredientDetail.class);
startActivity(intent);
}
});
Here is code of the CookingDataModel class.
public class CookingDataModel implements Parcelable{
private RecipeDataModel recipe = null;
private ArrayList<IngredientDataModel> ingredientList = null;
public RecipeDataModel getRecipe() {
return recipe;
}
public void setRecipe(RecipeDataModel recipe) {
this.recipe = recipe;
}
public ArrayList<IngredientDataModel> getIngredientList() {
return ingredientList;
}
public void setIngredientList(ArrayList<IngredientDataModel> ingredientList) {
this.ingredientList = ingredientList;
}
public static final Parcelable.Creator<CookingDataModel> CREATOR = new Parcelable.Creator<CookingDataModel>()
{
public CookingDataModel createFromParcel(Parcel in)
{
return new CookingDataModel(in);
}
public CookingDataModel[] newArray(int size)
{
return new CookingDataModel[size];
}
};
#Override
public int describeContents() {
// TODO Auto-generated method stub
return 0;
}
#Override
public void writeToParcel(Parcel arg0, int arg1) {
// TODO Auto-generated method stub
}
public CookingDataModel(Parcel in) {
// TODO Auto-generated constructor stub
}
public CookingDataModel()
{
}
}
Please help me in this respect that I could proceed my project. Thanks in adavance.
On the main activity:
intent.putExtra("Cooking",cook);
Then on second activity:
getIntent().getExtras().getParcelable("Cooking");
Try this. Do not use bundle if you've just to send a single object.
You may need to cast the getIntent().... part, I'm not sure.
Few things that need change.
No need of creating a new object, it will be overwritten.
CookingDataModel cook = new CookingDataModel();
Typecast when you get the Parcelable object from intent extras,
cook = bundle.getParcelable("Cooking");
Make Sure when you sending the object, it has valid receipe member. If you notice, you are able to get the CookingDataModel from the intent, and also the Receipe from this object but not able to get data from ReceipeModel.
From the code in the sending activity, I cant really say if the CookingDataModel.Receipe is a valid object.
I am using services and broadcast receiver, to launch a listview (I am using only two activity classes first as first class starts it starts service with it..in the services hitting a webservice and parsing data, n passing data into the broadcast receiver,
now the data I am getting in onreceive, and storing that data into another data...now I want this data to access in my activity class which I wl use for listView...please tell how can I do it..without making that var. static.
I also tried this thing within another way please if it is possible in that way too.
There the first screen is getting launch there I kept one button as I click on the button service will start n will do the whole job as I wrote above.....but here as I click the button another activity is being launched which is that listview but that isn't extending listActivity that is extending activity.
so I want to update that list view dynamically how can I do this?
please, any Help is Appreciable.
my code is here where I am getting stuck
public class MessageList extends Activity {
public static final String TAG = MessageList.class.getSimpleName();
Context mContext;
public static ArrayList<String> mData;
public ListView mListView;
private List<Message> messages;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.maina);
System.out.println("check bro"+mData);
System.out.println("In OnCreate of Messagelist class");
System.out.println("1st");
System.out.println("3rd");
mListView = (ListView) findViewById(R.id.mylist);
PlaceAdapter adapter = new PlaceAdapter(this, mData);
mListView.setAdapter(adapter);
}
private OnItemClickListener mItemClickListener = new OnItemClickListener() {
#Override
public void onItemClick(android.widget.AdapterView<?> arg0, View arg1, int arg2, long arg3) {
Intent viewMessage = new Intent(Intent.ACTION_VIEW,Uri.parse(messages.get(arg2).getLink().toExternalForm()));
startActivity(viewMessage);
}
};
/* #Override
protected void onListItemClick(ListView l, View v, int position, long id)
{
super.onListItemClick(l, v, position, id);
Intent viewMessage = new Intent(Intent.ACTION_VIEW, Uri.parse(messages
.get(position).getLink().toExternalForm()));
this.startActivity(viewMessage);
}*/
class MessageListBroadCast extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
System.out.println("hello");
System.out.println("final Done");
Bundle bundle = intent.getExtras();
mData = bundle.getStringArrayList("keya");
Log.d(TAG, "" + mData);
intent.putExtra("name", mData);
}
};
}
that message list is the class which is a list view
Thanks
Rather than working like this, I would use a class derived from CursorAdapter as Adapter and let your service store its results in a ContentProvider and notify changes on your ContentResolver on the same Uri you are using in the CursorAdapter. That way it will refresh automatically and your data is not lost should anything happen with your app (crash, memory,...). But I reckon this might be a bit of overhead, it all depends on what your webservice exactly does etc.