Its an Activity with Tabs, I'm getting data from API using Volley library. There is only one Fragment. Whenever Tab is changed either by sliding or clicking the Tab, the function that calls the APIs is called with different data.
Problems:
1) It loads items every time on working internet, but it sometimes shows and sometimes not. When I press home button (i.e. activity is running and in background) and then select the app from opened apps list it shows data. I've to pause and resume app to view changes by pressing home button and reselecting from opened apps. If I lock screen and unlock screen then also it shows the content.
2) Similar to problem 1) there is an info button on top right corner it shows/hides a layout when clicked. But some time when problem 1) occurs it also behaves same.
3) Also looks similar to 1) and 2) there is TextView (Options) that shows/hides a layout when clicked But some time when problem 1) occurs it also behaves same.
Any help would be appreciated, I'm running out of time...
Here is screenshot: Screenshot
RestaurantDetailActivity.java
public class RestaurantDetailActivity extends AppCompatActivity {
LinearLayout contactLayout;
TabLayout tabLayout;
ViewPager viewPager;
TextView nameTv, descrTv, timingsTv, totalRatingsTv;
RatingBar ratingsRb;
ImageView restaurantIv;
String resId;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_restaurant_detail);
//get data from previews activity
Intent intent = getIntent();
//init views
nameTv = findViewById(R.id.nameTv);
ratingsRb = findViewById(R.id.ratingsRb);
descrTv = findViewById(R.id.descrTv);
timingsTv = findViewById(R.id.timingsTv);
totalRatingsTv = findViewById(R.id.totalRatingsTv);
contactLayout = findViewById(R.id.contactLayout);
tabLayout = findViewById(R.id.tabLayout);
viewPager = findViewById(R.id.viewPager);
timingsTv = findViewById(R.id.timingsTv);
restaurantIv = findViewById(R.id.restaurantIv);
resId = intent.getStringExtra("id");
//setup tabs
setupViewPager(viewPager);
tabLayout.setupWithViewPager(viewPager);
final String name = intent.getStringExtra("name");
final String ratings = intent.getStringExtra("ratings");
String description = intent.getStringExtra("description");
String status = intent.getStringExtra("status");
String resPaused = intent.getStringExtra("resPaused");
String open = intent.getStringExtra("openTime");
String close = intent.getStringExtra("closeTime");
//set data in header
nameTv.setText(name);
ratingsRb.setRating(Float.parseFloat(ratings));
descrTv.setText(description);
final String timings;
if (resPaused.equals("0")) {
timings = con24to12(open) + " - " + con24to12(close);timingsTv.setTextColor(getApplicationContext().getResources().getColor(R.color.colorWhite));
} else {
timings = "Closed Today";
timingsTv.setTextColor(getApplicationContext().getResources().getColor(R.color.colorRadish));
}
//set timings
if (Utils.compareOpenTime(open)) {
timingsTv.setTextColor(getApplicationContext().getResources().getColor(R.color.colorWhite));
timingsTv.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_time_white, 0, 0, 0);
timingsTv.setText(con24to12(open));
} else {
timingsTv.setText(timings);
}
totalRatingsTv.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent1 = new Intent(getApplicationContext(), RestaurantReviewsActivity.class);
intent1.putExtra("restId", resId);
intent1.putExtra("restName", name);
intent1.putExtra("restRatings", ratings);
startActivity(intent1);
}
});
final Bitmap b = BitmapFactory.decodeFile(getExternalCacheDir() + "/TopServeImages" + "/" + intent.getStringExtra("image"));
restaurantIv.setImageBitmap(b);
}
ViewPagerAdapter adapter;
private void setupViewPager(ViewPager viewPager) {
adapter = new ViewPagerAdapter(getSupportFragmentManager());
final ProgressDialog progressDialog = new ProgressDialog(this);
progressDialog.setMessage("Getting Menu...");
progressDialog.show();
String token = "auth" + System.currentTimeMillis();
Map<String, String> params = new HashMap<>();
params.put("Token", token);
params.put("RestaurantID", resId);
Log.d("TheToken", Utils.getToken() + "" + Utils.getEmail());
String url = ApiManager.headerUrl + ApiManager.menuItemsUrl;
JsonObjectRequest jsonObjReq = new JsonObjectRequest(Request.Method.POST,
url, new JSONObject(params),
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
progressDialog.dismiss();
Log.d("TheResponse", response.toString());
try {
JSONObject jsonObject = response.getJSONObject("Response");
JSONArray jsonArray = jsonObject.getJSONArray("MenuCategories");
for (int i = 0; i < jsonArray.length(); i++) {
String menuItemCategoryID = jsonArray.getJSONObject(i).getString("MenuItemCategoryID");
String name = jsonArray.getJSONObject(i).getString("Name");
String restaurantID = jsonArray.getJSONObject(i).getString("RestaurantID");
adapter.addFragment(RestaurantFragment.newInstance((i + 1), "" + name, restaurantID, menuItemCategoryID), "" + name);
adapter.notifyDataSetChanged();
}
} catch (Exception e) {
Toast.makeText(getApplicationContext(), "Exception: " + e.getMessage(), Toast.LENGTH_SHORT).show();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
progressDialog.dismiss();
try {
if (error.getMessage().toLowerCase().contains("no address associated with hostname")) {
Toast.makeText(getApplicationContext(), "Slow or no Internet connection...", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getApplicationContext(), "Error: " + error.getMessage(), Toast.LENGTH_SHORT).show();
}
} catch (Exception e) {
Toast.makeText(getApplicationContext(), "Error: " + e.getMessage(), Toast.LENGTH_SHORT).show();
}
}
});
Volley.newRequestQueue(this).add(jsonObjReq);
viewPager.setAdapter(adapter);
}
public class ViewPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> fragmentList = new ArrayList<>();
private final List<String> fragmentTitleList = new ArrayList<>();
public ViewPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
return fragmentList.get(position);
}
#Override
public int getCount() {
return fragmentList.size();
}
public void addFragment(Fragment fragment, String title) {
fragmentList.add(fragment);
fragmentTitleList.add(title);
}
#Nullable
#Override
public CharSequence getPageTitle(int position) {
return fragmentTitleList.get(position);
}
}
public void clicks(View view) {
if (view == findViewById(R.id.backTv)) {
onBackPressed();
} else if (view == findViewById(R.id.infoBtn)) {
if (contactLayout.getVisibility() == View.GONE) {
contactLayout.setVisibility(View.VISIBLE);
} else {
contactLayout.setVisibility(View.GONE);
}
}
}
public String con24to12(String from) {
DateFormat df = new SimpleDateFormat("HH:mm:ss");
DateFormat outputformat = new SimpleDateFormat("hh:mm aa");
Date date = null;
String output = null;
try {
date = df.parse(from);
output = outputformat.format(date);
from = output;
} catch (Exception pe) {
Toast.makeText(getApplicationContext(), "" + pe.getMessage(), Toast.LENGTH_SHORT).show();
}
return from;
}
}
RestaurantFragment.java
public class RestaurantFragment extends Fragment {
String title;
int page;
String restaurantId;
String menuItemCategoryID;
AdapterMenu mAdapter;
List<ModelMenu> menuList;
ImageView fabCartIv;
RecyclerView recyclerView;
public RestaurantFragment() {
}
public static RestaurantFragment newInstance(int page, String title, String restID, String menuItemCategoryID) {
RestaurantFragment fragmentFirst = new RestaurantFragment();
Bundle args = new Bundle();
args.putInt("someInt", page);
args.putString("someTitle", title);
args.putString("restId", restID);
args.putString("menuItemCategoryID", menuItemCategoryID);
fragmentFirst.setArguments(args);
return fragmentFirst;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
page = getArguments().getInt("someInt", 0);
title = getArguments().getString("someTitle");
restaurantId = getArguments().getString("restId");
menuItemCategoryID = getArguments().getString("menuItemCategoryID");
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_restaurant, container, false);
recyclerView = view.findViewById(R.id.menuRecyclerView);
fabCartIv = view.findViewById(R.id.fabCartIv);
loadMenuItems();
return view;
}
private void loadMenuItems() {
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity().getApplicationContext()));
menuList = new ArrayList<>();
String token = "auth" + System.currentTimeMillis();
Map<String, String> params = new HashMap<>();
params.put("Token", token);
params.put("RestaurantID", restaurantId);
String url = ApiManager.headerUrl + ApiManager.menuItemsUrl;
JsonObjectRequest jsonObjReq = new JsonObjectRequest(Request.Method.POST,
url, new JSONObject(params),
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
JSONObject joResponse = response.getJSONObject("Response");
JSONArray jaMainMenu = joResponse.getJSONArray("MainMenu");
JSONArray jaMenuItemImages = joResponse.getJSONArray("MenuItemImages");
JSONArray jaLinkedMenuItems = joResponse.getJSONArray("LinkedMenuItems");
for (int i = 0; i < jaLinkedMenuItems.length(); i++) {
String menuItemCategoryID1 = jaLinkedMenuItems.getJSONObject(i).getString("MenuItemCategoryID");
if (menuItemCategoryID.equals(menuItemCategoryID1)) {
String menuItemID1 = jaLinkedMenuItems.getJSONObject(i).getString("MenuItemID");
for (int j = 0; j < jaMainMenu.length(); j++) {
String deleted = jaMainMenu.getJSONObject(j).getString("Deleted");
String description = jaMainMenu.getJSONObject(j).getString("Description");
String ingredients = jaMainMenu.getJSONObject(j).getString("Ingredients");
String inventory = jaMainMenu.getJSONObject(j).getString("Inventory");
String menuItemID = jaMainMenu.getJSONObject(j).getString("MenuItemID");
String name = jaMainMenu.getJSONObject(j).getString("Name");
String paused = jaMainMenu.getJSONObject(j).getString("Paused");
String price = jaMainMenu.getJSONObject(j).getString("Price");
String rating = jaMainMenu.getJSONObject(j).getString("Rating");
String restaurantID = jaMainMenu.getJSONObject(j).getString("RestaurantID");
String servedEnd = jaMainMenu.getJSONObject(j).getString("ServedEnd");
String servedStart = jaMainMenu.getJSONObject(j).getString("ServedStart");
String imageURL = jaMenuItemImages.getJSONObject(j).getString("ImageURL");
if (menuItemID1.equals(menuItemID)) {
ModelMenu cModels = new ModelMenu("" + deleted,
"" + description,
"" + ingredients,
"" + inventory,
"" + menuItemID,
"" + name,
"" + paused,
"$" + price,
"" + rating,
"" + restaurantID,
"" + servedEnd,
"" + servedStart,
"" + imageURL);
menuList.add(cModels);
}
}
mAdapter = new AdapterMenu(menuList, getActivity().getApplicationContext(), RestaurantFragment.this);
recyclerView.setAdapter(mAdapter);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
try {
if (error.getMessage().toLowerCase().contains("no address associated with hostname")) {
} else {
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
Volley.newRequestQueue(getActivity()).add(jsonObjReq);
}
}
AdapterMenu.java
public class AdapterMenu extends RecyclerView.Adapter<AdapterMenu.MyHolder> {
List<ModelMenu> menuList;
Context context;
Fragment fragment;
public AdapterMenu(List<ModelMenu> menuList, Context context, Fragment fragment) {
this.menuList = menuList;
this.context = context;
this.fragment = fragment;
}
#NonNull
#Override
public MyHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(context).inflate(R.layout.row_menus, viewGroup, false);
return new MyHolder(view);
}
#Override
public void onBindViewHolder(#NonNull final MyHolder myHolder, int i) {
final String title = menuList.get(i).getName();
final String description = menuList.get(i).getDescription();
final String price = menuList.get(i).getPrice();
final String image = menuList.get(i).getImage();
final String ingredients = menuList.get(i).getIngredients();
final String restaurantID = menuList.get(i).getRestaurantID();
final String menuItemID = menuList.get(i).getMenuItemID();
String notServing;
if (menuList.get(i).getServedStart().equals("null") && menuList.get(i).getServedEnd().equals("null")) {
notServing = "";
myHolder.itemView.setBackgroundColor(context.getResources().getColor(R.color.colorWhite));
} else {
String startTime = Utils.timeTo12hr(menuList.get(i).getServedStart());
String endTime = Utils.timeTo12hr(menuList.get(i).getServedEnd());
notServing = "Only Serving between " + startTime + " - " + endTime;
myHolder.itemView.setBackgroundColor(context.getResources().getColor(R.color.colorGray1));
}
myHolder.titleTv.setText(title);
myHolder.descriptionTv.setText(description);
myHolder.priceTv.setText(price);
myHolder.notServingTv.setText(notServing);
myHolder.addHintTv.setText("Add " + title + " To Order");
myHolder.optionsTv.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (myHolder.addItemLayout.getVisibility() == View.VISIBLE) {
myHolder.addItemLayout.setVisibility(View.GONE);
myHolder.optionsTv.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_down_black, 0);
} else {
myHolder.addItemLayout.setVisibility(View.VISIBLE);
myHolder.optionsTv.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_up_black, 0);
}
}
});
myHolder.addItemBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
SharedPreferences sp = context.getSharedPreferences("OderSP", Context.MODE_PRIVATE);
int count = sp.getInt("itemCount", 0);
SharedPreferences.Editor editor = sp.edit();
editor.putInt("itemCount", count + 1);
editor.apply();
onAddField(context, myHolder, title, price);
}
});
myHolder.infoBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(context, MenuDetailActivity.class);
intent.putExtra("title", title);
intent.putExtra("description", description);
intent.putExtra("image", image);
intent.putExtra("ingredients", ingredients);
intent.putExtra("restaurantID", restaurantID);
intent.putExtra("menuItemID", menuItemID);
intent.putExtra("image", image);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}
});
try {
final Bitmap b = BitmapFactory.decodeFile(context.getExternalCacheDir() + "/TopServeImages" + "/" + image);
if (b == null) {
ImageDownloader.execute(new Runnable() {
#Override
public void run() {
new ImageDownloader().awsImageDownload(myHolder, image);
}
});
} else {
myHolder.iconIv.setImageBitmap(b);
}
} catch (Exception e) {
ImageDownloader.execute(new Runnable() {
#Override
public void run() {
new ImageDownloader().awsImageDownload(myHolder, image);
}
});
}
}
private int itemsCount = 0;
private void onAddField(final Context context, MyHolder myHolder, final String title, String price) {
final LinearLayout parentLinearLayout = myHolder.itemView.findViewById(R.id.menu_roLl);
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
final View rowView = inflater.inflate(R.layout.row_additeminfo, null);
parentLinearLayout.addView(rowView, parentLinearLayout.getChildCount() - 1);
final TextView titleTv = rowView.findViewById(R.id.orderInfoTitleTv);
final TextView priceTv = rowView.findViewById(R.id.orderInfoPrice);
final ImageButton removeBtn = rowView.findViewById(R.id.orderInfoRemoveBtn);
itemsCount++;
EasyDB easyDB = EasyDB.init(context, "ITEMS_DB")
.setTableName("ITEMS_TABLE")
.addColumn(new Column("Item_Id", new String[]{"text", "unique"}))
.addColumn(new Column("Item_Name", new String[]{"text", "not null"}))
.addColumn(new Column("Item_Price", new String[]{"text", "not null"}))
.doneTableColumn();
easyDB.addData("Item_Id", title + (parentLinearLayout.getChildCount() - 1))
.addData("Item_Name", title)
.addData("Item_Price", price)
.doneDataAdding();
titleTv.setText("Order: " + itemsCount + " " + title);
priceTv.setText(price);
SharedPreferences sp = context.getSharedPreferences("OderSP", Context.MODE_PRIVATE);
itemsCount = sp.getInt("itemCount", 0);
SharedPreferences.Editor editor = sp.edit();
editor.putInt("itemCount", itemsCount);
editor.apply();
removeBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
onDelete(parentLinearLayout, view, title);
}
});
}
private void onDelete(final LinearLayout parentLinearLayout, final View v, final String title) {
AlertDialog.Builder builder = new AlertDialog.Builder(v.getRootView().getContext());
builder.setTitle("Remove this item?");
builder.setMessage(title);
builder.setPositiveButton("Remove", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
parentLinearLayout.removeView((View) v.getParent());
itemsCount--;
SharedPreferences sp = context.getSharedPreferences("OderSP", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
editor.putInt("itemCount", itemsCount);
editor.apply();
EasyDB easyDB = EasyDB.init(context, "ITEMS_DB")
.setTableName("ITEMS_TABLE")
.addColumn(new Column("Item_Id", new String[]{"text", "unique"}))
.addColumn(new Column("Item_Name", new String[]{"text", "not null"}))
.addColumn(new Column("Item_Price", new String[]{"text", "not null"}))
.doneTableColumn();
easyDB.deleteRow("Item_Id", "" + title + (parentLinearLayout.getChildCount()));
}
});
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
}
});
builder.create().show();
}
#Override
public int getItemCount() {
return menuList.size();
}
class MyHolder extends RecyclerView.ViewHolder {
TextView titleTv, priceTv, descriptionTv, notServingTv, addHintTv, optionsTv, orderInfoTitleTv, orderInfoPrice;
ImageButton infoBtn, orderInfoRemoveBtn;
ImageView iconIv;
Button addItemBtn;
LinearLayout addItemLayout;
RelativeLayout orderInfoLayout;
MyHolder(#NonNull View itemView) {
super(itemView);
iconIv = itemView.findViewById(R.id.iconIv);
titleTv = itemView.findViewById(R.id.titleTv);
priceTv = itemView.findViewById(R.id.priceTv);
descriptionTv = itemView.findViewById(R.id.descriptionTv);
notServingTv = itemView.findViewById(R.id.notServingTv);
addHintTv = itemView.findViewById(R.id.addHintTv);
optionsTv = itemView.findViewById(R.id.optionsTv);
orderInfoTitleTv = itemView.findViewById(R.id.orderInfoTitleTv);
orderInfoPrice = itemView.findViewById(R.id.orderInfoPrice);
infoBtn = itemView.findViewById(R.id.infoBtn);
orderInfoRemoveBtn = itemView.findViewById(R.id.orderInfoRemoveBtn);
addItemBtn = itemView.findViewById(R.id.addItemBtn);
addItemLayout = itemView.findViewById(R.id.addItemLayout);
orderInfoLayout = itemView.findViewById(R.id.orderInfoLayout);
}
}
}
Here is how I fixed the issue:
First, understand the problem.
In the first activity where you fetch the restaurant list, that is fine.
When the restaurant is clicked, you pass the restaurant id to the RestaurantDetailActivity and do an API request.
In the API request you pass the restaurant id and get the response. The response contains a lost of all the categories of that restaurant and also the list of all the dishes provided by the restaurant in all the categories. This is very important.
At this stage you take only the list of categories in the response and start creating a fragment for each category. You pass the category id to each fragment.
Then each fragment does an API request to the the same API which was called at the activity level (point number 3 above). Each fragment does the same request independently and extracts only the list of menu items that belong to that category. That is a waste of resources.
When a fragment goes out of view , it is destroyed and then recreated when user swipes back to the tab. Every time user comes to a fragment, it loads data again. This repeated loading of data was causing the device to go unresponsive.
Now here is what I did. At step 3, when a string request is done for a particular restaurant and all the menu items are received in response. I create a separate List of menu items for each category at this stage and then pass the list to each fragment. Now each fragment has to just display the list it has received from the activity. Each fragment is not responsible for doing its own string request and parsing it to creating its own list of items. Rather it just received the list from activity and displays it. In this was only one API request is done at activity level. No matter how many time the user switches tabs, there is no extra API request.
public class ModelMenu implements Serializable {
private String deleted, description, ingredients, inventory, menuItemID, name, paused, price, rating, restaurantID, servedEnd, servedStart, image;
public ModelMenu() {
}
public ModelMenu(String name, String price) {
this.name = name;
this.price = price;
}
public ModelMenu(String deleted, String description, String ingredients, String inventory, String menuItemID, String name, String paused, String price, String rating, String restaurantID, String servedEnd, String servedStart, String image) {
this.deleted = deleted;
this.description = description;
this.ingredients = ingredients;
this.inventory = inventory;
this.menuItemID = menuItemID;
this.name = name;
this.paused = paused;
this.price = price;
this.rating = rating;
this.restaurantID = restaurantID;
this.servedEnd = servedEnd;
this.servedStart = servedStart;
this.image = image;
}
public String getDeleted() {
return deleted;
}
public void setDeleted(String deleted) {
this.deleted = deleted;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getIngredients() {
return ingredients;
}
public void setIngredients(String ingredients) {
this.ingredients = ingredients;
}
public String getInventory() {
return inventory;
}
public void setInventory(String inventory) {
this.inventory = inventory;
}
public String getMenuItemID() {
return menuItemID;
}
public void setMenuItemID(String menuItemID) {
this.menuItemID = menuItemID;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPaused() {
return paused;
}
public void setPaused(String paused) {
this.paused = paused;
}
public String getPrice() {
return price;
}
public void setPrice(String price) {
this.price = price;
}
public String getRating() {
return rating;
}
public void setRating(String rating) {
this.rating = rating;
}
public String getRestaurantID() {
return restaurantID;
}
public void setRestaurantID(String restaurantID) {
this.restaurantID = restaurantID;
}
public String getServedEnd() {
return servedEnd;
}
public void setServedEnd(String servedEnd) {
this.servedEnd = servedEnd;
}
public String getServedStart() {
return servedStart;
}
public void setServedStart(String servedStart) {
this.servedStart = servedStart;
}
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image;
}
}
public class RestaurantFragment extends Fragment {
private String title;
private int page;
private String restaurantId;
private String menuItemCategoryID;
private AdapterMenu mAdapter;
private List<ModelMenu> menuList;
TextView orderTimeTv, changeTimeTv, tenPercentTv, fifteenPercentTv, twentyPercentTv, customTipTv, totalTipTv, subTotalTv, taxTotalTv, totalTv, pickedTimeTv, pickedDateTv, todayTv, cancelTv, itemCountTv;
ImageView fabCartIv;
RecyclerView recyclerView;
public RestaurantFragment() {
// Required empty public constructor
}
// newInstance constructor for creating fragment with arguments
/*public static RestaurantFragment newInstance(int page, String title, String restID, String menuItemCategoryID) {
RestaurantFragment fragmentFirst = new RestaurantFragment();
Bundle args = new Bundle();
args.putInt("someInt", page);
args.putString("someTitle", title);
args.putString("restId", restID);
args.putString("menuItemCategoryID", menuItemCategoryID);
fragmentFirst.setArguments(args);
return fragmentFirst;
}*/
public static RestaurantFragment newInstance(int page, String title, String restID, String menuItemCategoryID, List<ModelMenu> menuList) {
RestaurantFragment fragmentFirst = new RestaurantFragment();
Bundle args = new Bundle();
args.putInt("someInt", page);
args.putString("someTitle", title);
args.putString("restId", restID);
args.putString("menuItemCategoryID", menuItemCategoryID);
args.putSerializable("menuList", (Serializable) menuList);
fragmentFirst.setArguments(args);
return fragmentFirst;
}
// Store instance variables based on arguments passed
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
page = getArguments().getInt("someInt", 0);
title = getArguments().getString("someTitle");
restaurantId = getArguments().getString("restId");
menuItemCategoryID = getArguments().getString("menuItemCategoryID");
menuList = (List<ModelMenu>) getArguments().getSerializable("menuList");
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_restaurant, container, false);
recyclerView = view.findViewById(R.id.menuRecyclerView);
itemCountTv = view.findViewById(R.id.itemCountTv);
fabCartIv = view.findViewById(R.id.fabCartIv);
/*if (title.equals("Appetizers")) {
loadDataAppetizers();
} else if (title.equals("Breakfast")) {
loadBreakfast();
} else if (title.equals("Noodle")) {
loadNoodle();
}*/
loadMenuItems();
fabCartIv.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
showCartDialog();
}
});
count();
return view;
}
private void loadMenuItems() {
//recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity().getApplicationContext()));
//Log.i("mytag", "list received with size: " + menuList.size() + ", in tab: " + title);
mAdapter = new AdapterMenu(menuList, getActivity().getApplicationContext(), RestaurantFragment.this);
recyclerView.setAdapter(mAdapter);
/*String token = "auth" + System.currentTimeMillis();
final ProgressDialog progressDialog = new ProgressDialog(getActivity());
//show progress dialog
progressDialog.setMessage("Getting Menu Items...");
progressDialog.show();*/
/*Map<String, String> params = new HashMap<>();
params.put("Token", token);
params.put("RestaurantID", restaurantId);
Log.d("TheToken", Utils.getToken() + "" + Utils.getEmail());
String url = ApiManager.headerUrl + ApiManager.menuItemsUrl;
JsonObjectRequest jsonObjReq = new JsonObjectRequest(Request.Method.POST,
url, new JSONObject(params),
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
//progressDialog.dismiss();
Log.d("TheResponse", response.toString());
try {
JSONObject joResponse = response.getJSONObject("Response");
JSONArray jaMainMenu = joResponse.getJSONArray("MainMenu");
JSONArray jaMenuItemImages = joResponse.getJSONArray("MenuItemImages");
JSONArray jaMenuCategories = joResponse.getJSONArray("MenuCategories");
JSONArray jaLinkedMenuItems = joResponse.getJSONArray("LinkedMenuItems");
JSONArray jaMenuSidesTitles = joResponse.getJSONArray("MenuSidesTitles");
JSONArray jaMenuSidesLinks = joResponse.getJSONArray("MenuSidesLinks");
JSONArray jaMenuSides = joResponse.getJSONArray("MenuSides");
*//*for (int j = 0; j < jaMenuCategories.length(); j++) {
String menuItemCategoryID = jaMainMenu.getJSONObject(j).getString("MenuItemCategoryID");
}*//*
for (int i = 0; i < jaLinkedMenuItems.length(); i++) {
String menuItemCategoryID1 = jaLinkedMenuItems.getJSONObject(i).getString("MenuItemCategoryID");
if (menuItemCategoryID.equals(menuItemCategoryID1)) {
String menuItemID1 = jaLinkedMenuItems.getJSONObject(i).getString("MenuItemID");
for (int j = 0; j < jaMainMenu.length(); j++) {
String deleted = jaMainMenu.getJSONObject(j).getString("Deleted");
String description = jaMainMenu.getJSONObject(j).getString("Description");
String ingredients = jaMainMenu.getJSONObject(j).getString("Ingredients");
String inventory = jaMainMenu.getJSONObject(j).getString("Inventory");
String menuItemID = jaMainMenu.getJSONObject(j).getString("MenuItemID");
String name = jaMainMenu.getJSONObject(j).getString("Name");
String paused = jaMainMenu.getJSONObject(j).getString("Paused");
String price = jaMainMenu.getJSONObject(j).getString("Price");
String rating = jaMainMenu.getJSONObject(j).getString("Rating");
String restaurantID = jaMainMenu.getJSONObject(j).getString("RestaurantID");
String servedEnd = jaMainMenu.getJSONObject(j).getString("ServedEnd");
String servedStart = jaMainMenu.getJSONObject(j).getString("ServedStart");
String imageURL = jaMenuItemImages.getJSONObject(j).getString("ImageURL");
if (menuItemID1.equals(menuItemID)) {
ModelMenu cModels = new ModelMenu("" + deleted,
"" + description,
"" + ingredients,
"" + inventory,
"" + menuItemID,
"" + name,
"" + paused,
"$" + price,
"" + rating,
"" + restaurantID,
"" + servedEnd,
"" + servedStart,
"" + imageURL);
menuList.add(cModels);
}
}
//adapter to be set to recyclerview
mAdapter = new AdapterMenu(menuList, getActivity().getApplicationContext(), RestaurantFragment.this);
recyclerView.setAdapter(mAdapter);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
//progressDialog.dismiss();
try {
if (error.getMessage().toLowerCase().contains("no address associated with hostname")) {
} else {
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
Volley.newRequestQueue(getActivity()).add(jsonObjReq);*/
}
private int tipPercentage = 10;
private String date = "";
//used to pass lists in confirm order
private ArrayList idList = new ArrayList();
private ArrayList nameList = new ArrayList();
private ArrayList priceList = new ArrayList();
int ids = 0;
List<ModelMenu> menuList1;
MyAdapters myAdapters;
#SuppressLint("NewApi")
private void showCartDialog() {
View view = LayoutInflater.from(getActivity()).inflate(R.layout.dialog_cart, null);
RecyclerView recyclerView = view.findViewById(R.id.menusLayout);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
menuList1 = new ArrayList<>();
final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setView(view);
builder.setOnCancelListener(new DialogInterface.OnCancelListener() {
#Override
public void onCancel(DialogInterface dialogInterface) {
tipPercentage = 10;
totalPriceAddRemove = 0.0;
idList.clear();
nameList.clear();
priceList.clear();
ids = 0;
}
});
builder.create().show();
orderTimeTv = view.findViewById(R.id.orderTimeTv);
changeTimeTv = view.findViewById(R.id.changeTimeTv);
tenPercentTv = view.findViewById(R.id.tenPercentTv);
fifteenPercentTv = view.findViewById(R.id.fifteenPercentTv);
twentyPercentTv = view.findViewById(R.id.twentyPercentTv);
customTipTv = view.findViewById(R.id.customTipTv);
totalTipTv = view.findViewById(R.id.totalTipTv);
subTotalTv = view.findViewById(R.id.subTotalTv);
taxTotalTv = view.findViewById(R.id.taxTotalTv);
totalTv = view.findViewById(R.id.totalTv);
pickedTimeTv = view.findViewById(R.id.pickedTimeTv);
pickedDateTv = view.findViewById(R.id.pickedDateTv);
todayTv = view.findViewById(R.id.todayTv);
cancelTv = view.findViewById(R.id.cancelTv);
final Button checkoutBtn = view.findViewById(R.id.checkoutBtn);
Button doneDTBtn = view.findViewById(R.id.doneDTBtn);
final TimePicker timePicker = view.findViewById(R.id.timePicker);
HorizontalCalendar hcCalendar = view.findViewById(R.id.hcCalendar);
final LinearLayout dateTimePickLayout = view.findViewById(R.id.dateTimePickLayout);
final RelativeLayout pricesLayout = view.findViewById(R.id.pricesLayout);
dateTimePickLayout.setVisibility(View.GONE);
pricesLayout.setVisibility(View.VISIBLE);
EasyDB easyDB = EasyDB.init(getActivity(), "ITEMS_DB") // "TEST" is the name of the DATABASE
.setTableName("ITEMS_TABLE") // You can ignore this line if you want
.addColumn(new Column("Item_Id", "text", "unique"))
.addColumn(new Column("Item_Name", "text", "not null"))
.addColumn(new Column("Item_Price", "text", "not null"))
.doneTableColumn();
Cursor res = easyDB.getAllData();
while (res.moveToNext()) {
String id = res.getString(1);
String name = res.getString(2);
String price = res.getString(3);
ModelMenu modelMenu = new ModelMenu("" + name, "" + price);
menuList1.add(modelMenu);
idList.add(ids);
nameList.add(name);
priceList.add(price);
ids++;
}
onAddField(getActivity());
myAdapters = new MyAdapters(getActivity(), menuList1);
recyclerView.setAdapter(myAdapters);
timePicker.setIs24HourView(true);
Calendar calendar = Calendar.getInstance();
final int hours = calendar.get(Calendar.HOUR_OF_DAY);
final int minute = calendar.get(Calendar.MINUTE);
final int year = calendar.get(Calendar.YEAR);
final int month = calendar.get(Calendar.MONTH) + 1;
final int day = calendar.get(Calendar.DAY_OF_MONTH);
date = day + "/" + month + "/" + year;
pickedTimeTv.setText(hours + ":" + minute);
pickedDateTv.setText(day + "/" + month + "/" + year);
timePicker.setHour(hours);
timePicker.setMinute(minute);
timePicker.setOnTimeChangedListener(new TimePicker.OnTimeChangedListener() {
#Override
public void onTimeChanged(TimePicker timePicker, int hour, int minute) {
pickedTimeTv.setText(hour + ":" + minute);
}
});
}
Have you tried overriding onStop() in your Activities?
onStop() is called when your app is no longer visible to the user (i.e. pressing Home). You will next receive either onRestart(), onDestroy(), or nothing. This may explain your inconsistent behaviour.
You will likely need to take control and stop any updates to UI elements especially here, and then preserve the state of the UI as the user left it with onSaveInstanceState()
https://developer.android.com/topic/libraries/architecture/saving-states
I'm parsing a json to display a list of files a user can tap to download. I want to display the files the users have chosen to download on my main screen. this is the code when they download a file.
public final class Main extends Activity {
// Log tag for this class
private static final String TAG = "Main";
// Callback code for request of storage permission
final private int PERMISSIONS_REQUEST_STORAGE = 735;
// JSON Node Names
private static final String TAG_TYPE = "plans";
private static final String TAG_NAME = "name";
private static final String TAG_FILENAME = "filename";
private static final String TAG_URL = "url";
private static final String TAG_SHOULD_NOT_CACHE = "shouldNotCache";
// Files to delete
private static final ArrayList<String> filesToGetDeleted = new ArrayList<>();
// Strings displayed to the user
private static String offline;
private static String noPDF;
private static String localLoc;
private static String jsonURL;
// PDF Download
private static DownloadManager downloadManager;
private static long downloadID;
private static File file;
#SuppressLint("StaticFieldLeak")
private static SwipeRefreshLayout swipeRefreshLayout;
private final BroadcastReceiver downloadReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context arg0, Intent arg1) {
final DownloadManager.Query query = new DownloadManager.Query();
query.setFilterById(downloadID);
final Cursor cursor = downloadManager.query(query);
if (cursor.moveToFirst()) {
final int columnIndex = cursor
.getColumnIndex(DownloadManager.COLUMN_STATUS);
final int status = cursor.getInt(columnIndex);
switch (status) {
case DownloadManager.STATUS_SUCCESSFUL:
final Uri path = Uri.fromFile(file);
final Intent pdfIntent = new Intent(Intent.ACTION_VIEW);
pdfIntent.setDataAndType(path, "application/pdf");
pdfIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
try {
startActivity(pdfIntent);
} catch (ActivityNotFoundException e) {
Utils.makeLongToast(Main.this, noPDF);
Log.e(TAG, e.getMessage());
}
break;
case DownloadManager.STATUS_FAILED:
Utils.makeLongToast(Main.this,
getString(R.string.down_error));
break;
case DownloadManager.STATUS_PAUSED:
Utils.makeLongToast(Main.this,
getString(R.string.down_paused));
break;
case DownloadManager.STATUS_PENDING:
Utils.makeLongToast(Main.this,
getString(R.string.down_pending));
break;
case DownloadManager.STATUS_RUNNING:
Utils.makeLongToast(Main.this,
getString(R.string.down_running));
break;
}
}
}
};
// Data from JSON file
private ArrayList<HashMap<String, String>> downloadList = new ArrayList<>();
private static void checkDir() {
final File dir = new File(Environment.getExternalStorageDirectory() + "/"
+ localLoc + "/");
if (!dir.exists()) dir.mkdir();
}
#Override
protected void onResume() {
super.onResume();
final IntentFilter intentFilter = new IntentFilter(
DownloadManager.ACTION_DOWNLOAD_COMPLETE);
registerReceiver(downloadReceiver, intentFilter);
}
#Override
protected void onPause() {
super.onPause();
unregisterReceiver(downloadReceiver);
}
#Override
protected void onDestroy() {
super.onDestroy();
// Delete files which should not get cached.
for (String file : filesToGetDeleted) {
final File f = new File(file);
if (f.exists()) {
f.delete();
}
}
}
#Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case PERMISSIONS_REQUEST_STORAGE:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Utils.makeLongToast(Main.this, getString(R.string.permission_write_external_storage_success));
}
else {
final String permission_write_external_storage_failure = getString(R.string.permission_write_external_storage_failure);
final String app_title = getString(R.string.app_name);
final String message = String.format(permission_write_external_storage_failure, app_title);
Utils.makeLongToast(Main.this, message);
boolean showRationale = ActivityCompat.shouldShowRequestPermissionRationale(Main.this, permissions[0]);
if (!showRationale) {
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", getPackageName(), null);
intent.setData(uri);
startActivity(intent);
}
}
break;
}
}
private void update(boolean force, boolean firstLoad) {
downloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
swipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipeRefreshLayout_main);
offline = getString(R.string.status_offline);
noPDF = getString(R.string.except_nopdf);
localLoc = getString(R.string.gen_loc);
jsonURL = getString(R.string.gen_json);
checkDir();
if (firstLoad) {
try {
downloadList = (ArrayList<HashMap<String, String>>) Utils.readObject(this, "downloadList");
if (downloadList != null) {
setList(true, true);
}
} catch (ClassNotFoundException | IOException e) {
Log.e(TAG, e.getMessage());
}
}
// Parse the JSON file of the plans from the URL
JSONParse j = new JSONParse();
j.force = force;
j.online = !Utils.isNoNetworkAvailable(this);
j.execute();
}
private void setList(final boolean downloadable, final boolean itemsAvailable) {
if (itemsAvailable) {
try {
Utils.writeObject(this, "downloadList", downloadList);
} catch (IOException e) {
Log.e(TAG, e.getMessage());
}
}
final ListView list = (ListView) findViewById(R.id.listView_main);
final ListAdapter adapter = new SimpleAdapter(this, downloadList,
android.R.layout.simple_list_item_1, new String[]{TAG_NAME},
new int[]{android.R.id.text1});
list.setAdapter(adapter);
// React when user click on item in the list
if (itemsAvailable) {
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View v, int pos,
long id) {
int hasStoragePermission = ContextCompat.checkSelfPermission(Main.this,
Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (hasStoragePermission != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(Main.this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
PERMISSIONS_REQUEST_STORAGE);
return;
}
final Uri downloadUri = Uri.parse(downloadList.get(pos).get(TAG_URL));
final String title = downloadList.get(pos).get(TAG_NAME);
final String shouldNotCache = downloadList.get(pos).get(TAG_SHOULD_NOT_CACHE);
file = new File(Environment.getExternalStorageDirectory() + "/"
+ localLoc + "/"
+ downloadList.get(pos).get(TAG_FILENAME) + ".pdf");
final Uri dst = Uri.fromFile(file);
if (file.exists()) {
final Intent pdfIntent = new Intent(Intent.ACTION_VIEW);
pdfIntent.setDataAndType(dst, "application/pdf");
pdfIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
try {
startActivity(pdfIntent);
} catch (ActivityNotFoundException e) {
Utils.makeLongToast(Main.this, noPDF);
Log.e(TAG, e.getMessage());
}
return;
}
if (downloadable && !Utils.isNoNetworkAvailable(Main.this)) {
// Download PDF
final Request request = new Request(downloadUri);
request.setTitle(title).setDestinationUri(dst);
downloadID = downloadManager.enqueue(request);
if (shouldNotCache.equals("true")) {
filesToGetDeleted.add(file.toString());
}
} else {
Utils.makeLongToast(Main.this, offline);
}
}
});
}
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
update(true, false);
}
});
}
private class JSONParse extends AsyncTask<String, String, JSONObject> {
public boolean force = false;
public boolean online = false;
#Override
protected void onPreExecute() {
super.onPreExecute();
swipeRefreshLayout.post(new Runnable() {
#Override
public void run() {
swipeRefreshLayout.setRefreshing(true);
}
});
}
#Override
protected JSONObject doInBackground(String... args) {
return JSONParser.getJSONFromUrl(Main.this, jsonURL, force, online);
}
#Override
protected void onPostExecute(JSONObject json) {
swipeRefreshLayout.post(new Runnable() {
#Override
public void run() {
swipeRefreshLayout.setRefreshing(false);
}
});
downloadList.clear();
if (json == null) {
String error = getString(R.string.except_json);
if (!online) {
error = offline;
}
final HashMap<String, String> map = new HashMap<>();
map.put(TAG_NAME, error);
downloadList.add(map);
setList(false, false);
return;
}
try {
// Get JSON Array from URL
final JSONArray j_plans = json.getJSONArray(TAG_TYPE);
for (int i = 0; i < j_plans.length(); i++) {
final JSONObject c = j_plans.getJSONObject(i);
// Storing JSON item in a Variable
final String ver = c.getString(TAG_FILENAME);
final String name = c.getString(TAG_NAME);
final String api = c.getString(TAG_URL);
String shouldNotCache = "";
if (c.has(TAG_SHOULD_NOT_CACHE)) {
shouldNotCache = c.getString(TAG_SHOULD_NOT_CACHE);
}
// Adding value HashMap key => value
final HashMap<String, String> map = new HashMap<>();
map.put(TAG_FILENAME, ver);
map.put(TAG_NAME, name);
map.put(TAG_URL, api);
map.put(TAG_SHOULD_NOT_CACHE, shouldNotCache);
downloadList.add(map);
setList(online, true);
}
} catch (JSONException e) {
Log.e(TAG, e.getMessage());
}
}
}
SO how do I get the result of the above code and display it on main screen every time the user opens app
I m trying to make a simple version facebook messenger.The code that i used has worked well for gtalk and requires facebook authentication to be used for chatting with facebook friends.For that, i have used SASLXFacebookPlatfromMechanism class where i will store the api token and api key along with the apisecret of my app. The problem is SASLXFacebookPlatfromMechanism.java class is full of errors which i cannot resolve at all.Here are my classes-
**MainActivity.java**
public class MainActivity extends ActionBarActivity {
private ArrayList<String> messages = new ArrayList();
private Handler mHandler = new Handler();
private SettingsDialog mDialog;
private EditText mRecipient;
private EditText mSendText;
private ListView mList;
private XMPPConnection connection;
/**
* Called with the activity is first created.
*/
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
Log.i("XMPPClient", "onCreate called");
setContentView(R.layout.activity_main);
mRecipient = (EditText) this.findViewById(R.id.recipient);
Log.i("XMPPClient", "mRecipient = " + mRecipient);
mSendText = (EditText) this.findViewById(R.id.sendText);
Log.i("XMPPClient", "mSendText = " + mSendText);
mList = (ListView) this.findViewById(R.id.listMessages);
Log.i("XMPPClient", "mList = " + mList);
setListAdapter();
// Dialog for getting the xmpp settings
mDialog = new SettingsDialog(this);
// Set a listener to show the settings dialog
Button setup = (Button) this.findViewById(R.id.setup);
setup.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
mHandler.post(new Runnable() {
public void run() {
mDialog.show();
}
});
}
});
// Set a listener to send a chat text message
Button send = (Button) this.findViewById(R.id.send);
send.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
try
{
String to = mRecipient.getText().toString();
String text = mSendText.getText().toString();
Log.i("XMPPClient", "Sending text [" + text + "] to [" + to + "]");
Message msg = new Message(to, Message.Type.chat);
msg.setBody(text);
connection.sendPacket(msg);
messages.add(connection.getUser() + ":");
messages.add(text);
setListAdapter();
}catch(Exception e)
{
Toast.makeText(MainActivity.this, "Error="+e.getMessage(), Toast.LENGTH_LONG).show();
}
}
});
}
/**
* Called by Settings dialog when a connection is establised with the XMPP server
*
* #param connection
*/
public void setConnection (XMPPConnection connection) {
this.connection = connection;
if (connection != null) {
// Add a packet listener to get messages sent to us
PacketFilter filter = new MessageTypeFilter(Message.Type.chat);
connection.addPacketListener(new PacketListener() {
public void processPacket(Packet packet) {
Message message = (Message) packet;
if (message.getBody() != null) {
String fromName = StringUtils.parseBareAddress(message.getFrom());
Log.i("XMPPClient", "Got text [" + message.getBody() + "] from [" + fromName + "]");
messages.add(fromName + ":");
messages.add(message.getBody());
// Add the incoming message to the list view
mHandler.post(new Runnable() {
public void run() {
setListAdapter();
}
});
}
}
}, filter);
}
}
private void setListAdapter
() {
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
R.layout.multi_line_list_item,
messages);
mList.setAdapter(adapter);
}
}
SettingsDialog.java
public class SettingsDialog extends Dialog implements android.view.View.OnClickListener {
private MainActivity xmppClient;
public SettingsDialog(MainActivity xmppClient) {
super(xmppClient);
this.xmppClient = xmppClient;
}
protected void onStart() {
super.onStart();
setContentView(R.layout.settings);
getWindow().setFlags(4, 4);
setTitle("XMPP Settings");
Button ok = (Button) findViewById(R.id.ok);
ok.setOnClickListener(this);
}
public void onClick(View v) {
final String host = "chat.facebook.com";
final String port = ""+5222;
final String service = "chat.facebook.com";
final String username = "*****";
final String password = "****";
new Thread() {
public void run() {
// Create a connection
ConnectionConfiguration connConfig =new ConnectionConfiguration(host, Integer.parseInt(port), service);
connConfig.setSASLAuthenticationEnabled(true);
XMPPConnection connection = new XMPPConnection(connConfig);
try {
connection.connect();
Log.i("XMPPClient", "[SettingsDialog] Connected to " + connection.getHost());
} catch (Exception ex) {
Log.e("XMPPClient", "[SettingsDialog] Failed to connect to " + connection.getHost());
Log.e("XMPPClient", ex.toString());
xmppClient.setConnection(null);
}
try {
connection.login(username, password);
Log.i("XMPPClient", "Logged in as " + connection.getUser());
// Set the status to available
Presence presence = new Presence(Presence.Type.available);
connection.sendPacket(presence);
xmppClient.setConnection(connection);
} catch (XMPPException ex) {
Log.e("XMPPClient", "[SettingsDialog] Failed to log in as " + username);
Log.e("XMPPClient", ex.toString());
xmppClient.setConnection(null);
}
}
}.start();
dismiss();
}
private String getText(int id) {
EditText widget = (EditText) this.findViewById(id);
return widget.getText().toString();
}
}
SASLXFacebookPlatformMechanism.java
public class SASLXFacebookPlatformMechanism extends SASLMechanism
{
private static final String NAME = "X-FACEBOOK-PLATFORM";
private String apiKey = "";
private String applicationSecret = "";
private String sessionKey = "";
/**
* Constructor.
*/
public SASLXFacebookPlatformMechanism(SASLAuthentication saslAuthentication)
{
super(saslAuthentication);
}
#Override
protected void authenticate() throws IOException, XMPPException
{
getSASLAuthentication().send(new AuthMechanism(NAME, ""));
}
#Override
public void authenticate(String apiKeyAndSessionKey, String host,
String applicationSecret) throws IOException, XMPPException
{
if (apiKeyAndSessionKey == null || applicationSecret == null)
{
throw new IllegalArgumentException("Invalid parameters");
}
String[] keyArray = apiKeyAndSessionKey.split("\\|", 2);
if (keyArray.length < 2)
{
throw new IllegalArgumentException(
"API key or session key is not present");
}
this.apiKey = keyArray[0];
this.applicationSecret = applicationSecret;
this.sessionKey = keyArray[1];
this.authenticationId = sessionKey;
this.password = applicationSecret;
this.hostname = host;
String[] mechanisms = { "DIGEST-MD5" };
Map<String, String> props = new HashMap<String, String>();
this.sc =
Sasl.createSaslClient(mechanisms, null, "xmpp", host, props,
this);
authenticate();
}
#Override
public void authenticate(String username, String host, CallbackHandler cbh)
throws IOException, XMPPException
{
String[] mechanisms = { "DIGEST-MD5" };
Map<String, String> props = new HashMap<String, String>();
this.sc =
Sasl.createSaslClient(mechanisms, null, "xmpp", host, props,
cbh);
authenticate();
}
#Override
protected String getName()
{
return NAME;
}
#Override
public void challengeReceived(String challenge) throws IOException
{
byte[] response = null;
if (challenge != null)
{
String decodedChallenge = new String(Base64.decode(challenge));
Map<String, String> parameters = getQueryMap(decodedChallenge);
String version = "1.0";
String nonce = parameters.get("nonce");
String method = parameters.get("method");
long callId = new GregorianCalendar().getTimeInMillis();
String sig =
"api_key=" + apiKey + "call_id=" + callId + "method="
+ method + "nonce=" + nonce + "session_key="
+ sessionKey + "v=" + version + applicationSecret;
try
{
sig = md5(sig);
} catch (NoSuchAlgorithmException e)
{
throw new IllegalStateException(e);
}
String composedResponse =
"api_key=" + URLEncoder.encode(apiKey, "utf-8")
+ "&call_id=" + callId + "&method="
+ URLEncoder.encode(method, "utf-8") + "&nonce="
+ URLEncoder.encode(nonce, "utf-8")
+ "&session_key="
+ URLEncoder.encode(sessionKey, "utf-8") + "&v="
+ URLEncoder.encode(version, "utf-8") + "&sig="
+ URLEncoder.encode(sig, "utf-8");
response = composedResponse.getBytes("utf-8");
}
String authenticationText = "";
if (response != null)
{
authenticationText =
Base64.encodeBytes(response, Base64.DONT_BREAK_LINES);
}
// Send the authentication to the server
getSASLAuthentication().send(new Response(authenticationText));
}
private Map<String, String> getQueryMap(String query)
{
Map<String, String> map = new HashMap<String, String>();
String[] params = query.split("\\&");
for (String param : params)
{
String[] fields = param.split("=", 2);
map.put(fields[0], (fields.length > 1 ? fields[1] : null));
}
return map;
}
private String md5(String text) throws NoSuchAlgorithmException,
UnsupportedEncodingException
{
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(text.getBytes("utf-8"), 0, text.length());
return convertToHex(md.digest());
}
private String convertToHex(byte[] data)
{
StringBuilder buf = new StringBuilder();
int len = data.length;
for (int i = 0; i < len; i++)
{
int halfByte = (data[i] >>> 4) & 0xF;
int twoHalfs = 0;
do
{
if (0 <= halfByte && halfByte <= 9)
{
buf.append((char) ('0' + halfByte));
}
else
{
buf.append((char) ('a' + halfByte - 10));
}
halfByte = data[i] & 0xF;
} while (twoHalfs++ < 1);
}
return buf.toString();
}
#Override
protected String getAuthenticationText(String arg0, String arg1, String arg2) {
// TODO Auto-generated method stub
return null;
}
#Override
protected String getChallengeResponse(byte[] arg0) {
// TODO Auto-generated method stub
return null;
}
}
The code shows error stating
"The method send(String) in the type SASLAuthentication is not applicable for arguments(Response).The constructor Response(String) is undefined"
in the line-->"getSASLAuthentication().send(new Response(authenticationText));"
I am also confused on how to use this SASLXFacebookPlatformMechanism.java class in my MainActivity.class.I have been trying to get a sense of how it works but failing.A complete guideline on how to develop a xmpp facebook chat client using asmack library would be appreciated since the internet lacks enough documentation on it.Thanks.
[I have the apikeys and apitokens,so the empty string will not remain empty]
I want to share text on Linkedin for that i have used below code
public class ShareWithLinkedIn extends Activity {
public static final String CONSUMER_KEY = "YOUR_COUSUMER_KEY";
public static final String CONSUMER_SECRET = "YOUR_SECRET_KEY";
public static final String APP_NAME = "SharePhotoImage";
public static final String OAUTH_CALLBACK_SCHEME = "x-oauthflow-linkedin";
public static final String OAUTH_CALLBACK_HOST = "litestcalback";
public static final String OAUTH_CALLBACK_URL = OAUTH_CALLBACK_SCHEME + "://" + OAUTH_CALLBACK_HOST;
static final String OAUTH_QUERY_TOKEN = "oauth_token";
static final String OAUTH_QUERY_VERIFIER = "oauth_verifier";
static final String OAUTH_QUERY_PROBLEM = "oauth_problem";
static final String OAUTH_PREF = "AppPreferences";
static final String PREF_TOKEN = "linkedin_token";
static final String PREF_TOKENSECRET = "linkedin_token_secret";
static final String PREF_REQTOKENSECRET = "linkedin_request_token_secret";
final LinkedInOAuthService oAuthService = LinkedInOAuthServiceFactory.getInstance().createLinkedInOAuthService(CONSUMER_KEY, CONSUMER_SECRET);
final LinkedInApiClientFactory factory = LinkedInApiClientFactory.newInstance(CONSUMER_KEY, CONSUMER_SECRET);
LinkedInRequestToken liToken;
LinkedInApiClient client;
TextView tv = null;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
tv = new TextView(this);
setContentView(tv);
final SharedPreferences pref = getSharedPreferences(OAUTH_PREF, MODE_PRIVATE);
final String token = pref.getString(PREF_TOKEN, null);
final String tokenSecret = pref.getString(PREF_TOKENSECRET, null);
if (token == null || tokenSecret == null) {
startAutheniticate();
} else {
LinkedInAccessToken accessToken = new LinkedInAccessToken(token, tokenSecret);
showCurrentUser(accessToken);
}
}// end method
void startAutheniticate() {
new Thread() {// added because this will make code work on post API 10
#Override
public void run() {
final LinkedInRequestToken liToken = oAuthService.getOAuthRequestToken(OAUTH_CALLBACK_URL);
final String uri = liToken.getAuthorizationUrl();
final SharedPreferences pref = getSharedPreferences(OAUTH_PREF, MODE_PRIVATE);
SharedPreferences.Editor editor = pref.edit();
editor.putString(PREF_REQTOKENSECRET, liToken.getTokenSecret());
editor.commit();
Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
startActivity(i);
}
}.start();
}// end method
void finishAuthenticate(final Uri uri) {
new Thread() {
#Override
public void run() {
Looper.prepare();
if (uri != null && uri.getScheme().equals(OAUTH_CALLBACK_SCHEME)) {
final String problem = uri.getQueryParameter(OAUTH_QUERY_PROBLEM);
if (problem == null) {
final SharedPreferences pref = getSharedPreferences(OAUTH_PREF, MODE_PRIVATE);
final String request_token_secret = pref.getString(PREF_REQTOKENSECRET, null);
final String query_token = uri.getQueryParameter(OAUTH_QUERY_TOKEN);
final LinkedInRequestToken request_token = new LinkedInRequestToken(query_token, request_token_secret);
final LinkedInAccessToken accessToken = oAuthService.getOAuthAccessToken(request_token, uri.getQueryParameter(OAUTH_QUERY_VERIFIER));
SharedPreferences.Editor editor = pref.edit();
editor.putString(PREF_TOKEN, accessToken.getToken());
editor.putString(PREF_TOKENSECRET, accessToken.getTokenSecret());
editor.remove(PREF_REQTOKENSECRET);
editor.commit();
showCurrentUser(accessToken);
} else {
Toast.makeText(getApplicationContext(), "Application down due OAuth problem: " + problem, Toast.LENGTH_LONG).show();
finish();
}
}
Looper.loop();
}
}.start();
}// end method
void clearTokens() {
getSharedPreferences(OAUTH_PREF, MODE_PRIVATE).edit().remove(PREF_TOKEN).remove(PREF_TOKENSECRET).remove(PREF_REQTOKENSECRET).commit();
}// end method
void showCurrentUser(final LinkedInAccessToken accessToken) {
new Thread() {
#Override
public void run() {
Looper.prepare();
final LinkedInApiClient client = factory.createLinkedInApiClient(accessToken);
try {
final Person p = client.getProfileForCurrentUser();
// /////////////////////////////////////////////////////////
// here you can do client API calls ...
// client.postComment(arg0, arg1);
// client.updateCurrentStatus(arg0);
// or any other API call (this sample only check for current
// user
// and shows it in TextView)
// /////////////////////////////////////////////////////////
runOnUiThread(new Runnable() {// updating UI thread from
// different thread not a
// good idea...
public void run() {
tv.setText(p.getLastName() + ", " + p.getFirstName());
}
});
// or use Toast
// Toast.makeText(getApplicationContext(),
// "Lastname:: "+p.getLastName() + ", First name: " +
// p.getFirstName(), 1).show();
} catch (LinkedInApiClientException ex) {
clearTokens();
Toast.makeText(getApplicationContext(), "Application down due LinkedInApiClientException: " + ex.getMessage() + " Authokens cleared - try run application again.",
Toast.LENGTH_LONG).show();
finish();
}
Looper.loop();
}
}.start();
}// end method
#Override
protected void onNewIntent(Intent intent) {
finishAuthenticate(intent.getData());
}// end method
}// end class
it shows me login and allow screen which is looking like below when i click that button again same screen will be shown,, but i want like when (i click on that button it should share a text with image url)...
can any body help me to solve this problem
By below code i have done
public class ShareInLinkedIn extends Activity implements OnClickListener {
private LinkedInOAuthService oAuthService;
private LinkedInApiClientFactory factory;
private LinkedInRequestToken liToken;
private LinkedInApiClient client;
public static final String LINKEDIN_PREF = "GamePrefs";
#SuppressLint({ "NewApi", "NewApi", "NewApi" })
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.linkedin);
if (android.os.Build.VERSION.SDK_INT > 9) {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}
oAuthService = LinkedInOAuthServiceFactory.getInstance().createLinkedInOAuthService(Constants.CONSUMER_KEY, Constants.CONSUMER_SECRET, Constants.SCOPE_PARAMS);
System.out.println("oAuthService : " + oAuthService);
factory = LinkedInApiClientFactory.newInstance(Constants.CONSUMER_KEY, Constants.CONSUMER_SECRET);
liToken = oAuthService.getOAuthRequestToken(Constants.OAUTH_CALLBACK_URL);
System.out.println("onCreate:linktoURL : " + liToken.getAuthorizationUrl());
Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse(liToken.getAuthorizationUrl()));
startActivity(i);
}
#Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
try {
linkedInImport(intent);
} catch (NullPointerException e) {
e.printStackTrace();
}
}
private void linkedInImport(Intent intent) {
String verifier = intent.getData().getQueryParameter("oauth_verifier");
System.out.println("liToken " + liToken);
System.out.println("verifier " + verifier);
LinkedInAccessToken accessToken = oAuthService.getOAuthAccessToken(liToken, verifier);
//SharedPreferences settings = getSharedPreferences(LINKEDIN_PREF, MODE_PRIVATE);
// final Editor edit = settings.edit();
// edit.putString(OAuth.OAUTH_TOKEN, accessToken.getToken());
// edit.putString(OAuth.OAUTH_TOKEN_SECRET,
// accessToken.getTokenSecret());
// edit.putString("linkedin_login", "valid");
// edit.commit();
client = factory.createLinkedInApiClient(accessToken);
// client.postNetworkUpdate("LinkedIn Android app test");
Person profile = client.getProfileForCurrentUser(EnumSet.of(ProfileField.ID, ProfileField.FIRST_NAME, ProfileField.LAST_NAME, ProfileField.HEADLINE));
System.out.println("First Name :: " + profile.getFirstName());
System.out.println("Last Name :: " + profile.getLastName());
System.out.println("Head Line :: " + profile.getHeadline());
OAuthConsumer consumer = new CommonsHttpOAuthConsumer(Constants.CONSUMER_KEY, Constants.CONSUMER_SECRET);
consumer.setTokenWithSecret(accessToken.getToken(), accessToken.getTokenSecret());
DefaultHttpClient httpclient = new DefaultHttpClient();
HttpPost post = new HttpPost("https://api.linkedin.com/v1/people/~/shares");
try {
consumer.sign(post);
post.setHeader("content-type", "text/XML");
String myEntity = "<share><comment>This is a test</comment><visibility><code>anyone</code></visibility></share>";
post.setEntity(new StringEntity(myEntity));
org.apache.http.HttpResponse response = httpclient.execute(post);
// Get the response
BufferedReader rd = new BufferedReader
(new InputStreamReader(response.getEntity().getContent()));
StringBuffer strBfr = new StringBuffer();
String line = "";
while ((line = rd.readLine()) != null) {
strBfr.append(line);
}
System.out.println("Response is : "+strBfr.toString());
Toast.makeText(ShareInLinkedIn.this, strBfr.toString(), Toast.LENGTH_LONG).show();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
}
}
Constants.java
public class Constants {
public static final String CONSUMER_KEY = "YOUR_CONSUMER_KEY";
public static final String CONSUMER_SECRET = "YOUR_CONSUMER_SECRET_KEY";
public static final String OAUTH_CALLBACK_SCHEME = "x-oauthflow-linkedin";
public static final String OAUTH_CALLBACK_HOST = "litestcalback";
public static final String OAUTH_CALLBACK_URL = OAUTH_CALLBACK_SCHEME + "://" + OAUTH_CALLBACK_HOST;
public static final String SCOPE_PARAMS = "rw_nus+r_basicprofile";
}
AndroidManifiest.xml file
<activity
android:name="com.linkedin.ShareInLinkedIn"
android:launchMode="singleInstance" >
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="litestcalback"
android:scheme="x-oauthflow-linkedin" />
</intent-filter>
</activity>