ListView Adapter setResult() and Finish() error - android

I want to startActivity for Result by using startActivityForResult() method.Now the activity which get started has a listview with adapter class for it.I had wriiten following Listview Adapter so when user selects any item it should return back to calling activity with selected item name.I cant able to call 2 methods
setResult() and finish() in following code
Adapter Code:
view.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
SharedPreferences prefernces = mContext.getSharedPreferences("MyKey111", Context.MODE_PRIVATE);
SharedPreferences.Editor editor1 = prefernces.edit();
editor1.putString("Custname",customerpopulationlist.get(position).getName());
editor1.putString("let_id", customerpopulationlist.get(position).getLetId());
editor1.commit();
Intent intentMessage = new Intent();
// put the message in Intent
intentMessage.putExtra("MESSAGE", "hello");
intentMessage.putExtra("selected_refer", customerpopulationlist.get(position).getLetId());
setResult(RESULT_OK, intentMessage);
finish();
}
});

you must hold an reference to your activity that created the adapter then set result to that. the thing you are doing is setting the result of OnClickListener object !!
add an Activity object to your adapter constructor and save it in a local variable in adapter and call it act then call the setResult() of the activtiy like below:
view.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
SharedPreferences prefernces = mContext.getSharedPreferences("MyKey111", Context.MODE_PRIVATE);
SharedPreferences.Editor editor1 = prefernces.edit();
editor1.putString("Custname",customerpopulationlist.get(position).getName());
editor1.putString("let_id", customerpopulationlist.get(position).getLetId());
editor1.commit();
Intent intentMessage = new Intent();
// put the message in Intent
intentMessage.putExtra("MESSAGE", "hello");
intentMessage.putExtra("selected_refer", customerpopulationlist.get(position).getLetId());
//THESE TWO LINES NEED TO BE CHANGED
act.setResult(RESULT_OK, intentMessage);
act.finish();
}
});

You need override method protected void onActivityResult(int requestCode, int resultCode, intent data on the activity you need to return to i.e. the activity where you have called startActivityforResult().
#override
protected void onActivityResult(int requestCode, int resultCode, intent data){
if(resultCode == -1) // -1 for RESULT_OK
{ // your logic goes here...
}
}

There is difference between an Activity object and A Context object(if there is confusion, better read the documentation for better understanding) So, the answer is simple,
When you want to do an activity based operation, follow like this
Activity activity = this;
Context context = ActivityName.this;
Pass both the objects in the adapter and then use
activity.setResult(Activity.RESULT_OK,intent);
activity.finish();
and for context-based operations use Intent i = new Intent( ListViewAdapter.this.mContext,EventPrivacyAndTicketPrice.class);
see full activity code below:
public class ActivityX extends AppCompatActivity {
Intent intent;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_x);
intent = getIntent();
ListView listView = findViewById(R.id.list_x);
ArrayList<ETypeObject> allTypes= new ArrayList<>();
allTypes = GetData();
ListViewAdapter listViewAdapter= new ListViewAdapter(allTypes,ActivityX.this,intent,this);
listView.setAdapter(listViewAdapter);
}
public ArrayList<ETypeObject> GetData(){
ArrayList<ETypeObject> allTypes= new ArrayList<>();
allTypes.add(new ETypeObject("Object1",0));
allTypes.add(new ETypeObject("Object2, Talk",0));
allTypes.add(new ETypeObject("Object3",0));
return allTypes;
}
}
class ETypeObject {
public String name;
public int imageId;
public ETypeObject(String name, int imageId) {
this.name = name;
this.imageId = imageId;
}
public ETypeObject() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getImageId() {
return imageId;
}
public void setImageId(int imageId) {
this.imageId = imageId;
}
}
class ListViewAdapter extends BaseAdapter{
Activity activity;
Context mContext;
ArrayList<ETypeObject> allTypes= new ArrayList<>();
Intent intent;
public ListViewAdapter(){}
public ListViewAdapter(ArrayList<ETypeObject> AllTypes, Context context,Intent intent,Activity activity){
mContext = context;
allTypes = AllTypes;
activity =activity;
this.intent = intent;
}
#Override
public int getCount() {
return allTypes.size();
}
#Override
public Object getItem(int i) {
return allTypes.get(i);
}
#Override
public long getItemId(int i) {
return i;
}
#Override
public View getView(int i1, View view, ViewGroup viewGroup) {
LayoutInflater layoutInflater= (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (layoutInflater!=null){
view = layoutInflater.inflate(R.layout.lay1,null);
}
TextView type;
type = view.findViewById(R.id.parentInteresttext);
type.setText(allTypes.get(i1).getName());
view.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// Toast.makeText(mContext,allTypes.get(i1).getName(),Toast.LENGTH_LONG).show();
if (intent.getBooleanExtra("fromThirdActivty",false)){
Intent i = new Intent();
i.putExtra("eventType",allTypes.get(i1).getName());
activity.setResult(Activity.RESULT_OK,intent);
activity.finish();
}
Intent i = new Intent( ListViewAdapter.this.mContext,OtherActivity.class);
i.putExtra("eventType",allTypes.get(i1).getName());
ListViewAdapter.this.mContext.startActivity(i);
}
});
return view;
}
}

Related

How to save items inside an ArrayList when an app is restarted? (Android)

Whenever I restart my app, all the information I saved inside an ArrayList during its runtime is deleted. In addition, sometimes when I go to another activity and then come back from that second activity. The information is deleted again. I'm not sure what's causing this. I want the information to be permanently saved unless deleted by the user. Usually, the error I'm receiving are IndexOutOfBounds exception when I need to call an item from my ArrayList.
Main Activity Code:
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private TextView preset;
private Button add;
private ListView exercises;
private ArrayList<String> exerciseName;
public ArrayList<Exercise> Exercises;
private MyAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Exercises = new ArrayList<Exercise>();
preset = findViewById(R.id.preset_title);
add = findViewById(R.id.add_exercise);
exercises = findViewById(R.id.exercises);
exerciseName = FileHelper.readData(this);
this.adapter = new MyAdapter(exerciseName, this, Exercises);
exercises.setAdapter(adapter);
add.setOnClickListener(this);
}
#Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.add_exercise:
final int CODE = 1;
Intent i = new Intent(this, add_activity.class);
startActivityForResult(i, CODE);
break;
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch(requestCode) {
case 1:
if(resultCode == RESULT_OK && data != null) {
Bundle passBack = data.getExtras();
Exercise exercise = passBack.getParcelable("exercise");
adapter.addData(exercise);
adapter.list.add(exercise.getName());
FileHelper.writeData(exerciseName, this);
adapter.notifyDataSetChanged();
}
case 2:
if (resultCode == RESULT_OK && data != null) {
Bundle passBack = data.getExtras();
Exercise exercise = passBack.getParcelable("exercise");
int position = passBack.getInt("position");
adapter.setData(exercise, position);
adapter.notifyDataSetChanged();
}
}
}
}
Custom Adapter Code (where my ArrayList data is stored):
public class MyAdapter extends ArrayAdapter<String> {
public ArrayList<String> list;
private Context context;
private TextView list_txt;
private ArrayList<Exercise> data;
public MyAdapter(ArrayList<String> records, Context context, ArrayList<Exercise> data) {
super(context, 0, records);
this.list = records;
this.data = data;
this.context = context;
}
public void addData(Exercise d){
data.add(d);
}
public void setData(Exercise d, int position) {
data.set(position, d);
}
#Override
public View getView(final int position, View convertView, final ViewGroup parent) {
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.listview_custom, parent, false);
}
Button list_but = (Button) convertView.findViewById(R.id.list_but);
TextView list_txt = (TextView) convertView.findViewById((R.id.list_txt));
Button edit = (Button) convertView.findViewById(R.id.list_but2);
Button start = (Button) convertView.findViewById(R.id.list_but3);
list_txt.setText(list.get(position));
edit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
final int CODE2 = 2;
Activity origin = (Activity)context;
Intent edit = new Intent(parent.getContext(), add_activity.class);
Bundle newBundle = new Bundle();
newBundle.putParcelable("exercise", data.get(position));
newBundle.putInt("position", position);
edit.putExtras(newBundle);
origin.startActivityForResult(edit, CODE2);
}
});
start.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent start = new Intent(parent.getContext(), timer_activity.class);
start.putExtra("exercise", data.get(position));
parent.getContext().startActivity(start);
}
});
list_but.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
AlertDialog.Builder alert = new AlertDialog.Builder(context);
alert.setTitle("Delete?");
alert.setMessage("Are you sure you want to delete this exercise?");
alert.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
list.remove(position);
try {
data.remove(position);
} catch(IndexOutOfBoundsException ex) {
}
notifyDataSetChanged();
}
});
alert.setNegativeButton("No", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
}
});
alert.create().show();
}
});
return convertView;
}
}
Every time You destroy activity You are losing all saved data in ListView. You have to save it before destroying and restore when You start an activity. You can do it with gson and SharedPreferences.
In Your MainActivity override onSaveInstanceState and inside this method save all Your exercises from Exercises list using gson.
Gson gson = new Gson();
String exercisesJSON = gson.toJson(Exercises);
SharedPreferences sharedPref = getPreferences(Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPref.edit();
editor.putString("KEY_BETTER_USE_CONST", exercisesJSON);
editor.commit();
And then in onCreate restore this data:
SharedPreferences sharedPref = getPreferences(Context.MODE_PRIVATE);
String exercisesJSON = sharedPref.getInt("KEY_BETTER_USE_CONST", "DEFAULT_VALUE_EMPTY");
//check if exercisesJSON is equal to "DEFAULT_VALUE_EMPTY" if yes, init array as empty, if not deserialize it using gson
Gson gson = new Gson();
Exercises[] exercises = gson.fromJson(exercisesJSON, Exercise[].class);
Haven't debugged this code but I think it should look something like this. I based on: Gson — Mapping of Arrays and Lists of Objects

Android: Why the listview.add function is always adding elements on position 1 in the list

I am trying to implement two activities that are exchanging information between them using intents.
Activity#1 contains an empty listview and a button that starts Activity#2 when pressed. On Activity#2 I have some textbox fields and a "Save" button that sends through intent.putExtra methods information to Activity#1.
The issue is that each time I try to create a new View with the information passed by Activity#2, the list is overriding the first element.
You can see below the OnCreate method from Activity#1:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list_explorer);
notesList = findViewById(R.id.listviewNotes);
FloatingActionButton myFab = this.findViewById(R.id.fabAddNote);
myFab.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent intentNoteEditor = new Intent(getApplicationContext(), NoteEditor.class);
startActivity(intentNoteEditor);
//Log.i("Lista",notesList.getCount()+"");
}
});
Intent intent =getIntent();
Bundle extras =intent.getExtras();
if(extras!=null){
if(extras.containsKey("isnewNote")){
isnewElement=extras.getBoolean("isnewNote",false);
}
}
if(isnewElement==true){
//***************Fetch data from intent***************//
notetext = intent.getStringExtra("noteText");
notecolor = intent.getStringExtra("noteColor");
notelocation = intent.getStringExtra("noteLocation");
notereminder = intent.getStringExtra("noteReminder");
Note receivednote = new Note(notetext, notecolor, notereminder, notelocation);
MyAdapter adapter = new MyAdapter(this, R.layout.list_item, notesArray);
notesArray.add(receivednote);
notesList.setAdapter(adapter);
//***************End Fetch data from intent***********//
}
}
I am also attaching the custom adapter implemented.
public class MyAdapter extends ArrayAdapter {
private Context mContext;
private int mResource;
private ArrayList<Note> mNotes = new ArrayList<>();
private String TAG = "Adapter Class";
public MyAdapter(#NonNull Context context, int resource, ArrayList<Note> objects) {
super(context, resource, objects);
mContext = context;
mResource = resource;
mNotes = objects;
}
#Override
public int getCount() {
return mNotes.size();
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View listItem =convertView;
if(listItem==null){
listItem=LayoutInflater.from(mContext).inflate(mResource,parent,false);
Note currentNote = mNotes.get(position);
String text = mNotes.get(position).getText();
String color = mNotes.get(position).getColor();
String location = mNotes.get(position).getLocation();
String reminder = mNotes.get(position).getReminder();
TextView nttxt = listItem.findViewById(R.id.noteText);
TextView ntcolor = listItem.findViewById(R.id.textcolor);
TextView ntrem = listItem.findViewById(R.id.reminder);
TextView ntlocat = listItem.findViewById(R.id.location);
nttxt.setText(text);
ntcolor.setText(color);
ntrem.setText(reminder);
ntlocat.setText(location);
}
return listItem;
}
}
I logged the list size and it is always 1. For some reason, it does not keep the current elements after the Activity#2 is launched.
Any advice will be appreciated.
The problem is that every time you press the "Save" button in Activity#2 you are launching a new instance of Activity#1 hence the single note in the list. You need to use the startActivityForResult() method when launching Activity2 and then override onActivityResult() in order to get the data returned data. Activity#1 can look like this:
public static final int NEW_NOTE_REQUEST = 23;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list_explorer);
notesList = findViewById(R.id.listviewNotes);
FloatingActionButton myFab = this.findViewById(R.id.fabAddNote);
myFab.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent intentNoteEditor = new Intent(getApplicationContext(), NoteEditor.class);
startActivityForResult(intentNoteEditor, NEW_NOTE_REQUEST);
//Log.i("Lista",notesList.getCount()+"");
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// Check the returned result and parse the data
if(resultCode == RESULT_OK && requestCode == NEW_NOTE_REQUEST){
notetext = intent.getStringExtra("noteText");
notecolor = intent.getStringExtra("noteColor");
notelocation = intent.getStringExtra("noteLocation");
notereminder = intent.getStringExtra("noteReminder");
Note receivednote = new Note(notetext, notecolor, notereminder, notelocation);
MyAdapter adapter = new MyAdapter(this, R.layout.list_item, notesArray);
notesArray.add(receivednote);
notesList.setAdapter(adapter);
}
}
And then in Activity#2:
public void onSaveButtonClick(View view) {
Intent intent = new Intent();
// Add note data to intent
// return the result to Activity#1
setResult(RESULT_OK, intent);
finish();
}
You can also achieve the same function by creating a shared data repository, like a singleton class that will hold your notes list and both the activities will have a reference to the same notes list.

Android - Adding objects to a list view from another activity

I've got a custom list view with my own adapter. I can add objects to this list within the same activity, but what I want to do is add objects from another activity. In this other activity there are two Edit Text boxes. One is responsible for Main text, second for Description, and two radio buttons that are determining image. At the bottom is Add button, that should add entered data to the list view.
I tried to do this with Parcelable, but I don't know exactly how to implement it. Below is my ListView class:
public class Activity_4 extends AppCompatActivity {
private ListView listView;
private myAdapter mAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_4);
listView = (ListView)findViewById(R.id.listView4);
ArrayList<Object> objectList = new ArrayList<>();
objectList.add(new Object(R.drawable.row_img, "After Earth" , "2013"));
objectList.add(new Object(R.drawable.row_img, "After Earth" , "2013"));
objectList.add(new Object(R.drawable.row_img, "After Earth" , "2013"));
objectList.add(new Object(R.drawable.row_img, "After Earth" , "2013"));
objectList.add(new Object(R.drawable.row_img, "After Earth" , "2013"));
objectList.add(new Object(R.drawable.row_img, "After Earth" , "2013"));
mAdapter = new myAdapter(this,objectList);
listView.setAdapter(mAdapter);
}
public class Object implements Parcelable {
int imageID;
String mainText;
String description;
public Object (int imageID, String mainText, String description) {
this.imageID = imageID;
this.mainText = mainText;
this.description = description;
}
public Object() {
}
public int getImageID() {
return imageID;
}
public void setImageID(int imageID) {
this.imageID = imageID;
}
public String getMainText () {
return mainText;
}
public void setMainText() {
this.mainText = mainText;
}
public String getDescription() {
return description;
}
public void setDescription() {
this.description = description;
}
public Object(Parcel in) {
this.imageID = in.readInt();
this.mainText = in.readString();
this.description = in.readString();
}
public final Parcelable.Creator<Object> CREATOR = new Parcelable.Creator<Object>() {
#Override
public Object createFromParcel(Parcel in) {
return new Object(in);
}
#Override
public Object[] newArray(int size) {
return new Object[size];
}
};
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(imageID);
dest.writeString(mainText);
dest.writeString(description);
}
}
public class myAdapter extends ArrayAdapter<Object> {
private Context mContext;
private List<Object> objectList = new ArrayList<>();
public myAdapter(#NonNull Context context, ArrayList<Object> list) {
super(context,0,list);
mContext = context;
objectList = list;
}
#NonNull
#Override
public View getView (int position, #Nullable View convertView, #NonNull ViewGroup parent) {
View listItem = convertView;
if (listItem == null)
listItem = LayoutInflater.from(mContext).inflate(R.layout.list_row, parent, false);
Object currentObject = objectList.get(position);
ImageView image = (ImageView) listItem.findViewById(R.id.row_image);
image.setImageResource(currentObject.getImageID());
TextView mainTxt = (TextView) listItem.findViewById(R.id.row_tv1);
mainTxt.setText(currentObject.getMainText());
TextView description = (TextView) listItem.findViewById(R.id.row_tv2);
description.setText(currentObject.getDescription());
return listItem;
}
}
Can anyone help with this problem?
Thanks
You can other Activity using startActivityForResult() and pass data in bundle as result on click of add button from other Activity, so current activity will add the data to it's list.
Calling Other Activity to add
startActivityForResult(intent,reqCode);
On Result
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (data != null && requestCode == reqCode) {
Object object = new Object();
object.setImageID(data.getIntExtra("image_id"));
object.setMainText(data.getStringExtra("main_text");
object.setDescription(data.getStringExtra("desc");
objectlist.add(object);
mAdapter.notifyDataSetChanged();
}
}
Other Activity
public void onAddClick(){
Intent intent = new Intent();
intent.putIntExtra("image_id",*<value>*);
intent.putStringExtra("main_text",*<value>*);
intent.putStringExtra("desc",*<value>*);
setResult(intent);
finish();
}
A good starting point might be to start your EditText activity using startActivityForResult and pass the updates to the list to your adapter through the result, after you added everything you wanted by calling setResult with your new data. For further reference see Getting a Result from an Activity. Good luck!
When opening 2nd Activity from 1st Activity
do
Intent mIntent=new Intent(this,YourSecondActivity.class);
startActivityForResult(mIntent,SOME_STATIC_INT)
In another activity
on click of AddButton
Intent mIntent=new Intent(this,YourFirstActivity.class);
mIntent.putExtra("DATA",Object)
setResult(SOME_STATIC_INT,mIntent)
now in 1st Activity
Override onActivity Result
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (data != null && requestCode == SOME_STATIC_INT) {
Object object = data.getParcelableExtra("DATA")
objectlist.add(object);
mAdapter.notifyDataSetChanged();
}
}

QR code reader thrown from an image of an item of a ListView

I want that when the image of the item is pressed launches QR code reader provided by the library zxing.
I tested two options.
The first option has been my custom adapter trying to launch the intent.
The second option has been following the first and a topic of this forum, and I got kind of my custom adapter in the main class and I created two methods.
This last option gives me syntax error, but if you run:
android.content.ActivityNotFoundException: No Activity found to handle Intent { act=com.google.zxing.client.android.SCAN (has extras) } at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:1659)
Actually, this is my code:
public class Inventario extends Activity implements OnItemClickListener {
private ArrayList<Obra> obras;
private ListView lvObras;
private ObrasAdapter adapter;
private TextView num, iden,ubi,hombres,material;
private int pulsado = -1;
Toast toast1 ;
private int operacion = -1;
List<String> equiDisp;
ArrayList<String> marcado;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.inventario);
equiDisp = new ArrayList<String>();
marcado = new ArrayList<String>();
for(int i=1; i<11; i++)
{
equiDisp.add(String.valueOf(i));
}
// Inicializamos las variables.
obras = new ArrayList<Obra>();
rellenarArrayList();
actualizarDisplay();
}
...
public void abrirLector(){
Intent intent = new Intent("com.google.zxing.client.android.SCAN");
intent.putExtra("SCAN_MODE", "QR_CODE_MODE");
startActivityForResult(intent, 0);
}
public void actualizarDisplay()
{
adapter = new ObrasAdapter(this, obras);
lvObras = (ListView) findViewById(R.id.lvItems);
lvObras.setAdapter(adapter);
lvObras.setOnItemClickListener(this);
}
public class ObrasAdapter extends ArrayAdapter<Obra> {
public Context context;
private ArrayList<Obra> datos;
public void DisplayProjectListAdapter(Context c) {
context = c;
}
public ObrasAdapter(Context context, ArrayList<Obra> datos) {
super(context, R.layout.listview_item, datos);
this.context = context;
this.datos = datos;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View item = convertView;
ObrasHolder holder;
if (item == null) {
item = LayoutInflater.from(context).inflate(R.layout.listview_item,
null);
holder = new ObrasHolder();
holder.qr = (ImageView) item.findViewById(R.id.qr);
item.setTag(holder);
}
holder = (ObrasHolder) item.getTag();
holder.qr.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
holder.qr.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v) {
abrirLector();
}
});
}
});
return item;
}
Can anyone help me out? Thank you
The problem you are getting related to ActivityNotFoundException can be fixed by the steps you can find in this link. This is the official documentation for zxing that tells you how to open the scanner in the yet provided dialog they have. Replace it by your code:
public void abrirLector(){
Intent intent = new Intent("com.google.zxing.client.android.SCAN");
intent.putExtra("SCAN_MODE", "QR_CODE_MODE");
startActivityForResult(intent, 0);
}
Add holder.qr.setOnClickListener(new OnImageClickListener()); to the get view method.
Then add an inner class to this class:
private class OnImageClickListener implements OnClickListener {
#Override
public void onClick(View v) {
Main sct = (Main) activity;
sct.onClick();
return void;
}
Then go ahead and add a method called onClick() to your Main activity and add the code to call the intent in that method

Android - Issue with facebook implementation

I am trying to integrate facebook capabilities into my Android app. So, I have an adapter which is going to display a list of items. Once user clicks on a button, it will start the authentication/authorizing process. But I am having errors on my code. Have I missed out any declarations or anything? I am following the example from here
Error 1: MODE_PRIVATE cannot be resolved to a variable
Error 2: The method onActivityResult(int, int, Intent) is undefined for the type BaseAdapter
Adapter.java
public class LazyAdapter extends BaseAdapter {
Facebook facebook = new Facebook("132789674563789674");
private Activity activity;
private String[] data;
private String[] text;
private static LayoutInflater inflater=null;
public ImageLoader imageLoader;
private static final String APP_ID = "132789674563789674";
private ProgressDialog mProgress;
private Handler mRunOnUi = new Handler();
String FILENAME = "AndroidSSO_data";
private SharedPreferences mPrefs;
public LazyAdapter(Activity a, String[] d, String[] t) {
activity = a;
data=d;
text = t;
inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
imageLoader=new ImageLoader(activity.getApplicationContext());
}
public int getCount() {
return data.length;
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public static class ViewHolder{
public TextView text;
public ImageView image;
}
public View getView(final int position, View convertView, ViewGroup parent) {
View vi=convertView;
ViewHolder holder;
if(convertView==null){
vi = inflater.inflate(R.layout.item, null);
holder=new ViewHolder();
holder.text=(TextView)vi.findViewById(R.id.text);;
holder.image=(ImageView)vi.findViewById(R.id.image);
vi.setTag(holder);
ImageButton fbBtn = (ImageButton) vi.findViewById(R.id.fb);
fbBtn.setOnClickListener(
new Button.OnClickListener() {
public void onClick(View v)
{
/*
* Get existing access_token if any
*/
mPrefs = getPreferences(MODE_PRIVATE); <--- MODE_PRIVATE cannot be resolved to a variable
String access_token = mPrefs.getString("access_token", null);
long expires = mPrefs.getLong("access_expires", 0);
if(access_token != null) {
facebook.setAccessToken(access_token);
}
if(expires != 0) {
facebook.setAccessExpires(expires);
}
/*
* Only call authorize if the access_token has expired.
*/
if(!facebook.isSessionValid()) {
facebook.authorize(activity, new String[] {"publish_stream", "publish_checkins"}, new DialogListener() {
#Override
public void onComplete(Bundle values)
{
//postToFacebook(String image);
SharedPreferences.Editor editor = mPrefs.edit();
editor.putString("access_token", facebook.getAccessToken());
editor.putLong("access_expires", facebook.getAccessExpires());
editor.commit();
}
#Override
public void onFacebookError(FacebookError error) {}
#Override
public void onError(DialogError e) {}
#Override
public void onCancel() {}
});
}
}
}
);
}
else
holder=(ViewHolder)vi.getTag();
holder.text.setText(text[position]);
holder.image.setTag(data[position]);
imageLoader.DisplayImage(data[position], activity, holder.image);
return vi;
postToFacebook("");
}//close getView
private void postToFacebook(String data) {
mProgress.setMessage("Posting ...");
mProgress.show();
AsyncFacebookRunner mAsyncFbRunner = new AsyncFacebookRunner(facebook);
Bundle params = new Bundle();
params.putString("message", "Visit me here!");
params.putString("name", "My Name");
params.putString("caption", "google.com");
params.putString("link", "http://www.google.com");
params.putString("description", "Visit the search engine");
params.putString("image", data);
mAsyncFbRunner.request("me/feed", params, "POST", new WallPostListener());
}//close posttofacebook
private final class WallPostListener extends BaseRequestListener {
public void onComplete(final String response) {
mRunOnUi.post(new Runnable() {
#Override
public void run() {
mProgress.cancel();
Toast.makeText(activity, "Posted to Facebook", Toast.LENGTH_SHORT).show();
}
});
}//close oncomplete
}//close wallpostlistener
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data); <----- The method onActivityResult(int, int, Intent) is undefined for the type BaseAdapter
facebook.authorizeCallback(requestCode, resultCode, data);
}
}
Problems:
Error 1: MODE_PRIVATE cannot be resolved to a variable
getPreferences() and MODE_PRIVATE are not available in BaseAdapter, these both are available in Context class (so it is also available in Activity) and you can access them using context.getPreferences(Context.MODE_PRIVATE);
Error 2: The method onActivityResult(int, int, Intent) is undefined
for the type BaseAdapter
onActivityResult() is method of Activity not a method of BaseAdapter
Solution:
You should put facebook authentication and post to wall related code in Activity.
and now the point is:
how Activity will know the FB ImageButton was pressed.
how Activity will know that it should do postToFacebook(String);
We will use interface, make an interface in your LazyAdapter like this:
public class LazyAdapter extends BaseAdapter {
FBookTaskListener taskListener;
//--all your other class members as above in your code.
public void setTaskListener(FBookTaskListener listener)
{
this.taskListener = listener;
}
//-- here all your other stuff constructor getView() getCount() etc. as above in your code.
public static interface FBookTaskListener{
public void doAuthentication(); //paramas may be added if needed
public void postToWall(); //paramas may be added if needed
}
}
now in your LazyAdapter's getView() where you set OnClickListener for FBButton
fbBtn.setOnClickListener(new Button.OnClickListener() {
public void onClick(View v)
{
taskListener.doAuthentication(); // will be handled in Activity :)
}
});
now in your Activity where you set Adapter.
LazyAdapter adapter = new LazyAdapter(this, a, b);
listView.setAdapter(adapter);
adapter.setTaskListener(new FBookTaskListener(){
public void doAuthentication()
{
// here all your FB authentication related stuff.
}
public void postToWall()
{
postToFacebook();
}
});
take all method like onActivityResult() and postToFacebook() and WallPostListener in your Activity class from LazyAdapter

Categories

Resources