I am trying to make an application where using Recycle View and Volley to get data from server and also I used Navigation drawer and fragments,Everything working fine except When no data on recycle-view I want to show a notice like "there is no data!"I searched over internet multiple times but haven't get a proper solution or I couldn't understand properly because I am totally beginner.
bellow is my java files
1.Adapter
package com.eworld.myapplication;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.squareup.picasso.Picasso;
import java.util.List;
public class ExchangesAdapter extends RecyclerView.Adapter<ExchangesViewHolder> {
private List<ExchangesSetterGetter>exchangeList;
private Context context;
public ExchangesAdapter(List<ExchangesSetterGetter> exchangeList, Context context) {
this.exchangeList = exchangeList;
this.context = context;
}
#NonNull
#Override
public ExchangesViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view=LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.cardlayout,viewGroup,false);
ExchangesViewHolder viewHolder=new ExchangesViewHolder(view);
return viewHolder;
}
#Override
public void onBindViewHolder(#NonNull ExchangesViewHolder exchangesViewHolder, int i) {
String status="";
final ExchangesSetterGetter exchangesPosition=exchangeList.get(i);
if (exchangesPosition.getStatus().equals("1")) {
status = "Awaiting Confirmation";
} else if (exchangesPosition.getStatus().equals("2")) {
status = "Awaiting Payment";
} else if (exchangesPosition.getStatus().equals("3")) {
status = "Processing";
} else if (exchangesPosition.getStatus().equals("4")) {
status = "proceed";
} else if (exchangesPosition.getStatus().equals("5")) {
status = "Timeout";
} else if (exchangesPosition.getStatus().equals("6")) {
status = "Denied";
} else if (exchangesPosition.getStatus().equals("7")) {
status = "Canceled";
} else if (exchangesPosition.getStatus().equals("8")) {
status = "Unknown";
}
exchangesViewHolder.gatewayFrom.setText(exchangesPosition.getAmountFrom() + " " + exchangesPosition.getCurrencyFrom() + " " + exchangesPosition.getExchangeFrom());
exchangesViewHolder.gatewayTo.setText(exchangesPosition.getAmountTo() + " " + exchangesPosition.getCurrencyTo() + " " + exchangesPosition.getExchangeTo());
exchangesViewHolder.status.setText(status);
Picasso.get().load("https://eworld.ltd/" + exchangesPosition.getImgSend()).into(exchangesViewHolder.imgSendFrom);
Picasso.get().load("https://eworld.ltd/" + exchangesPosition.getImgReceived()).into(exchangesViewHolder.imgSendTo);
}
#Override
public int getItemCount() {
return exchangeList.size();
}
}
2.View Holder
package com.eworld.myapplication;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
public class ExchangesViewHolder extends RecyclerView.ViewHolder {
ImageView imgSendFrom,imgSendTo;
TextView gatewayFrom,gatewayTo,status;
public ExchangesViewHolder(#NonNull View itemView) {
super(itemView);
imgSendFrom=itemView.findViewById(R.id.img1);
imgSendTo=itemView.findViewById(R.id.img2);
gatewayFrom=itemView.findViewById(R.id.tv1);
gatewayTo=itemView.findViewById(R.id.tv2);
status=itemView.findViewById(R.id.tv3);
}
}
3.Getter and Setter(Data model)
package com.eworld.myapplication;
public class ExchangesSetterGetter {
private String exchangeFrom,exchangeTo,status,imgSend,imgReceived,currencyFrom,currencyTo,amountFrom,amountTo;
public ExchangesSetterGetter(String exchangeFrom, String exchangeTo, String status, String imgSend, String imgReceived, String currencyFrom, String currencyTo, String amountFrom, String amountTo) {
this.exchangeFrom = exchangeFrom;
this.exchangeTo = exchangeTo;
this.status = status;
this.imgSend = imgSend;
this.imgReceived = imgReceived;
this.currencyFrom = currencyFrom;
this.currencyTo = currencyTo;
this.amountFrom = amountFrom;
this.amountTo = amountTo;
}
public String getCurrencyFrom() {
return currencyFrom;
}
public void setCurrencyFrom(String currencyFrom) {
this.currencyFrom = currencyFrom;
}
public String getCurrencyTo() {
return currencyTo;
}
public void setCurrencyTo(String currencyTo) {
this.currencyTo = currencyTo;
}
public String getAmountFrom() {
return amountFrom;
}
public void setAmountFrom(String amountFrom) {
this.amountFrom = amountFrom;
}
public String getAmountTo() {
return amountTo;
}
public void setAmountTo(String amountTo) {
this.amountTo = amountTo;
}
public String getExchangeFrom() {
return exchangeFrom;
}
public void setExchangeFrom(String exchangeFrom) {
this.exchangeFrom = exchangeFrom;
}
public String getExchangeTo() {
return exchangeTo;
}
public void setExchangeTo(String exchangeTo) {
this.exchangeTo = exchangeTo;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getImgSend() {
return imgSend;
}
public void setImgSend(String imgSend) {
this.imgSend = imgSend;
}
public String getImgReceived() {
return imgReceived;
}
public void setImgReceived(String imgReceived) {
this.imgReceived = imgReceived;
}
}
4.And finally my fragment Activity with recycle-view
package com.eworld.myapplication;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.List;
public class ExchangesFrag extends Fragment {
RecyclerView recyclerView;
ExchangesAdapter adapter;
List<ExchangesSetterGetter> listItems;
SharedPrefManager sharedPreferences;
int uid;
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View exchanges=inflater.inflate(R.layout.exchanges_layout,container,false);
recyclerView=exchanges.findViewById(R.id.rview);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
listItems=new ArrayList<>();
sharedPreferences=new SharedPrefManager(getActivity());
uid = sharedPreferences.getUser().getId();
loadData();
return exchanges;
}
public void loadData() {
StringRequest stringRequest=new StringRequest(Request.Method.GET, URLs.url+uid, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONObject jsonObject = new JSONObject(response);
JSONArray jsonArray = jsonObject.getJSONArray("data");
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject receive = jsonArray.getJSONObject(i);
ExchangesSetterGetter exchangesSetterGetter = new ExchangesSetterGetter(
receive.getString("exchangeFrom"),
receive.getString("exchangeTo"),
receive.getString("status"),
receive.getString("imgSend"),
receive.getString("imgReceive"),
receive.getString("sendCurrency"),
receive.getString("receiveCurrency"),
receive.getString("amount_send"),
receive.getString("amount_receive")
);
listItems.add(exchangesSetterGetter);
}
adapter = new ExchangesAdapter(listItems, getContext());
recyclerView.setAdapter(adapter);
} catch(JSONException e){
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getContext(),"error on volley",Toast.LENGTH_LONG).show();
}
});
RequestQueue queue= Volley.newRequestQueue(getContext());
queue.add(stringRequest);
}
}
You can handle the empty state by having a TextView in your layout, which switch its visibility state depending upon the array size you are getting in your response as:
JSONArray jsonArray = jsonObject.getJSONArray("data");
if (jsonArray.length() > 0) {
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject receive = jsonArray.getJSONObject(i);
ExchangesSetterGetter exchangesSetterGetter = new ExchangesSetterGetter(
receive.getString("exchangeFrom"),
receive.getString("exchangeTo"),
receive.getString("status"),
receive.getString("imgSend"),
receive.getString("imgReceive"),
receive.getString("sendCurrency"),
receive.getString("receiveCurrency"),
receive.getString("amount_send"),
receive.getString("amount_receive")
);
listItems.add(exchangesSetterGetter);
}
adapter = new ExchangesAdapter(listItems, getContext());
recyclerView.setAdapter(adapter);
recyclerView.setVisibilty(View.VISIBLE);
noDataText.setVisibilty(View.GONE);
} else {
recyclerView.setVisiblity(View.GONE);
noDataText.setVisiblity(View.VISIBLE);
}
Add an extra textview in your fragment xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="#+id/tv_no_data"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:textSize="22sp"
android:visibility="gone" />
<android.support.v7.widget.RecyclerView
android:id="#+id/rv_ride_list"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
And then in your activity
JSONArray jsonArray = jsonObject.getJSONArray("data");
if(jsonArray.length() > 0){
//process data and initialize adapter
}else{
//Set Text view visible
}
There is a simple solution for that inside your fragment xml where recycler view is being loaded take a relative layout and add a textview with your desired message at last and set it's alignment as per your requirement and inside on create of your fragment set visiblity of your text view to View.INVISIBLE and later on after api is called simply pass an if condition stating that
if(response==null){ textview.setVisiblity = View.Visible}
The way I like to handle this is to wrap your RecyclerView and your NoContentView (this can be whatever you like) in a ViewFlipper like so
<ViewFlipper>
</RecyclerView>
<NoContentView>
</NoContentView>
</ViewFlipper>
Then all you do is to check to see if you have list items and display the appropriate child layout of the ViewFlipper
if(listItems.size() == 0)
{
viewFlipper.setDisplayedChild(1)
}
Related
The code is working but it is taking 14-16 seconds to retrieve data of just 1 video from postgresql server. I think there might be a proper way of retrieving the data. Please help me with this.
Thank you.
FreeClassesAdapter.java
import android.app.Activity;
import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.android.volley.RequestQueue;
import com.athrved.masterclass.PlayerActivity;
import com.athrved.masterclass.R;
import com.squareup.picasso.Picasso;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
public class FreeclassesAdapter extends RecyclerView.Adapter<FreeclassesAdapter.FreeViewHolder> {
ArrayList<FreeHelperClass> featloc;
public static String a,b="FAILED TO LOAD";
public static String videoId1;
RequestQueue requestQueue;
private static String V_id1;
public FreeclassesAdapter(ArrayList<FreeHelperClass> featloc) {
this.featloc = featloc;
}
#NonNull
#Override
public FreeViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.free_class_card_design,parent,false);
FreeViewHolder freeViewHolder = new FreeViewHolder(view);
return freeViewHolder;
}
#Override
public void onBindViewHolder(#NonNull FreeViewHolder holder, int position) {
FreeHelperClass freeHelperClass = featloc.get(position);
holder.imagesmall1.setImageResource(freeHelperClass.getImagesmall1());
holder.imagesmall2.setImageResource(freeHelperClass.getImagesmall2());
holder.title.setText(freeHelperClass.getTitle());
holder.topic.setText(freeHelperClass.getTopic());
holder.author.setText(freeHelperClass.getAuthor());
Database db=new Database();
videoId1=V_id1;
if(position==0){
Picasso.get().load("https://img.youtube.com/vi/"+videoId1+"/maxresdefault.jpg").into(holder.imagebig);
}
if(position==1){
Picasso.get().load("https://img.youtube.com/vi/lrcqt4RelJ4/maxresdefault.jpg").into(holder.imagebig);
}
}
#Override
public int getItemCount() {
return featloc.size();
}
public static class FreeViewHolder extends RecyclerView.ViewHolder{
ImageView imagebig, imagesmall1,imagesmall2;
TextView topic, author;
TextView title;
Button bookmark, bookmark_border;
public FreeViewHolder(#NonNull final View itemView){
super(itemView);
imagebig=itemView.findViewById(R.id.freeimgbig);
imagesmall1=itemView.findViewById(R.id.freec1_image);
imagesmall2=itemView.findViewById(R.id.freec2_image);
bookmark=itemView.findViewById(R.id.bookmarkfree);
bookmark_border=itemView.findViewById(R.id.bookmarkfree_border);
title=itemView.findViewById(R.id.freec_title);
topic=itemView.findViewById(R.id.freec_topic);
author=itemView.findViewById(R.id.freec_author);
bookmark_border.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(getAdapterPosition()==0){
bookmark_border.setVisibility(View.GONE);
bookmark.setVisibility(View.VISIBLE);
}
if(getAdapterPosition()==1){
bookmark_border.setVisibility(View.GONE);
bookmark.setVisibility(View.VISIBLE);
}
}
});
bookmark.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(getAdapterPosition()==0){
bookmark_border.setVisibility(View.VISIBLE);
bookmark.setVisibility(View.GONE);
}
if(getAdapterPosition()==1){
bookmark_border.setVisibility(View.VISIBLE);
bookmark.setVisibility(View.GONE);
}
}
});
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
videoId1=V_id1;
if (getAdapterPosition() == 0) {
Intent intent = new Intent(itemView.getContext(), PlayerActivity.class);
intent.putExtra("VIDEOID", videoId1);
itemView.getContext().startActivity(intent);
Activity activity = (Activity) itemView.getContext();
activity.overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
}
if (getAdapterPosition() == 1) {
Intent intent = new Intent(itemView.getContext(), PlayerActivity.class);
intent.putExtra("VIDEOID", "lrcqt4RelJ4");
itemView.getContext().startActivity(intent);
Activity activity = (Activity) itemView.getContext();
activity.overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
}
}
});
}
}
private class Database {
private Connection connection;
private final String host = "ec2-54-158-232-223.compute-1.amazonaws.com";
private final String database = "ddgaguv61p4m63";
private final int port = 5432;
private final String user = "jfeitasqnyuanh";
private final String pass = "d60b43b4e9ea924c91deb754cf18a51d5948b7a7e58b4e4d0045487767174ad8";
private String url = "jdbc:postgresql://ec2-54-158-232-223.compute-1.amazonaws.com:5432/ddgaguv61p4m63?sslmode=require&user=jfeitasqnyuanh&password=d60b43b4e9ea924c91deb754cf18a51d5948b7a7e58b4e4d0045487767174ad8";
private boolean status;
public Database() {
this.url = String.format(this.url, this.host, this.port, this.database);
connect();
//this.disconnect();
System.out.println("connection status:" + status);
}
private void connect() {
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
try {
Class.forName("org.postgresql.Driver");
connection = DriverManager.getConnection(url, user, pass);
status = true;
getExtraConnection();
System.out.println("connected:" + status);
} catch (Exception e) {
status = false;
System.out.print(e.getMessage());
e.printStackTrace();
}
}
});
thread.start();
try {
thread.join();
} catch (Exception e) {
e.printStackTrace();
this.status = false;
}
}
public Connection getExtraConnection() {
Connection c = null;
Statement stmt = null;
try {
Class.forName("org.postgresql.Driver");
c = DriverManager.getConnection(url, user, pass);
c.setAutoCommit(false);
System.out.println("Opened database successfully");
stmt = c.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM videos WHERE access_count=1;");
while (rs.next()) {
V_id1 = rs.getString("video_id");
//
// System.out.println("NAME = " + Name);
// System.out.println("BIO = " + Bio);
// System.out.println("PHONE = " + Phone);
System.out.println();
}
rs.close();
stmt.close();
c.close();
} catch (Exception e) {
System.err.println(e.getClass().getName() + ": " + e.getMessage());
System.exit(0);
}
System.out.println("Records created successfully");
return c;
}
}
}
Code from the main activity where FreeClassesAdapter is used - UiUxActivity.java:
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.view.MenuItem;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.athrved.masterclass.FetchData;
import com.athrved.masterclass.R;
import java.util.ArrayList;
import java.util.List;
public class UiuxActivity extends AppCompatActivity {
TextView abcde;
TextView ak;
String tit;
String urlname,videoID,tita;
RecyclerView dataList2;
List<String> titles2;
List<Integer> images2;
ImgAdapter2 imgAdapter2;
RecyclerView popRecycler;
RecyclerView.Adapter adapter1;
RecyclerView freeRecycler;
RecyclerView.Adapter adapter2;
RecyclerView menRecycler;
RecyclerView.Adapter adapter3;
RecyclerView allFewRecycler;
RecyclerView.Adapter adapter4;
ArrayList<UiuxAllClasses> allCourseList=new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_uiux);
getSupportActionBar().setTitle("UI UX Design");
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setBackgroundDrawable(new ColorDrawable(getResources().getColor(R.color.greyy)));
// videoID="_vAmKNin0QM";
// urlname="https://noembed.com/embed?url=https://www.youtube.com/watch?v="+videoID;
// tita= respo(urlname);
popRecycler = findViewById(R.id.r1popclass);
featuredRecycler();
freeRecycler=findViewById(R.id.r1freeclass);
freeturedRecycler( tit);
menRecycler=findViewById(R.id.r3menclass);
mentoredRecycler();
allFewRecycler=findViewById(R.id.r4fewalllist);
allfewRecycler();
dataList2 = findViewById(R.id.dataList2);
abcde = findViewById(R.id.tvv1);
ak=findViewById(R.id.ak);
titles2 = new ArrayList<>();
images2 = new ArrayList<>();
titles2.add("Visual Design");
titles2.add("UX Design");
titles2.add("Motion Design");
titles2.add("Prototyping");
titles2.add("3D Design");
titles2.add("Webflow");
images2.add(R.drawable.visuald_logo);
images2.add(R.drawable.uiux_logo);
images2.add(R.drawable.motiond_logo);
images2.add(R.drawable.mach_logo);
images2.add(R.drawable.threed_logo);
images2.add(R.drawable.iot_logo);
imgAdapter2 = new ImgAdapter2(this,titles2,images2);
GridLayoutManager gridLayoutManager = new GridLayoutManager(this,2,GridLayoutManager.VERTICAL,false);
dataList2.setLayoutManager(gridLayoutManager);
dataList2.setAdapter(imgAdapter2);
}
private void featuredRecycler(){
FetchData fetchData = new FetchData();
fetchData.execute();
popRecycler.setHasFixedSize(true);
popRecycler.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false));
ArrayList<PopHelperClass> popLocatio = new ArrayList<>();
popLocatio.add(new PopHelperClass(R.drawable.secndone, R.drawable.ai_logo,0,"Color and Color Theory -\nFundamentals of Visual Design","VISUAL DESIGN","Goutham Naik","Um3BhY0oS2c"));
popLocatio.add(new PopHelperClass(R.drawable.firstone, R.drawable.ai_logo, R.drawable.motiond_logo,"Color and Color Theory -\nFundamentals of Visual Design","UX DESIGN"," Goutham Naik, S. M. Sudhanva Acharya","_vAmKNin0QM"));
adapter1=new PopclassesAdapter(popLocatio);
popRecycler.setAdapter(adapter1);
}
private void freeturedRecycler(String tita){
freeRecycler.setHasFixedSize(true);
freeRecycler.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false));
ArrayList<FreeHelperClass> freeLocatio = new ArrayList<>();
freeLocatio.add(new FreeHelperClass(R.drawable.ai_logo,0,"Top UX Design Interview Questions","VISUAL DESIGN","S M Sudhanva Acharya"));
freeLocatio.add(new FreeHelperClass(R.drawable.ai_logo,0,"White Space in Design","VISUAL DESIGN","Abhinav Chikkara"));
adapter2=new FreeclassesAdapter(freeLocatio);
freeRecycler.setAdapter(adapter2);
}
private void mentoredRecycler(){
menRecycler.setHasFixedSize(true);
menRecycler.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false));
ArrayList<MenHelperClass> menLocatio = new ArrayList<>();
menLocatio.add(new MenHelperClass(R.drawable.oneman,"Goutam Naik","CEO, AthrV-Ed"));
menLocatio.add(new MenHelperClass(R.drawable.twoman,"S M Sudhanva Acharya", "Product Designer, AthrV-Ed"));
menLocatio.add(new MenHelperClass(R.drawable.threeman,"Abhinav Chikkara", "Founder, 10kilogram"));
adapter2=new MenAdapter(menLocatio);
menRecycler.setAdapter(adapter2);
}
private void allfewRecycler(){
allFewRecycler.setHasFixedSize(true);
allFewRecycler.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
ArrayList<FewAllHelperClass> fewAllLocatio = new ArrayList<>();
fewAllLocatio.add(new FewAllHelperClass(R.drawable.webflow_l, R.drawable.ai_logo,"Playing with Grid-\nWeb Design Fundamentals","WEBFLOW","Goutham Naik"));
fewAllLocatio.add(new FewAllHelperClass(R.drawable.protopie_l, R.drawable.ai_logo,"Protopie for Prototyping","PROTOTYPING\n","Abhinav Chikkara"));
fewAllLocatio.add(new FewAllHelperClass(R.drawable.afepluslot_l, R.drawable.ai_logo,"Introduction to After Effects\nand Lottie Files","MOTION DESIGN","S.M Sudhanva Acharya"));
adapter4=new FewAllAdapter(fewAllLocatio);
allFewRecycler.setAdapter(adapter4);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
onBackPressed();
return true;
}
return super.onOptionsItemSelected(item);
}
}
Are you storing the video in your DB as a BLOB / CLOB.
What if you store the video in a different location, and save the address of the location in your DB. This way Db has to return a string, and UI / consumer can take care of rendering from the path.
I made a recycler view to show and choose Instagram posts, in recycler view adapter I handled onclick to show user if items are selected or not and handling sum of chosen posts ... but there is problem when insta post in adapter become more than 12 when i scroll in page some chosen items are shown as not chosen, and some posts that are not choosed they look like you choosed them !!! can any one help me ?
here is my adapter:
package com.example.pinstagram.adaptor;
import android.content.Context;
import android.os.Build;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.example.pinstagram.R;
import com.example.pinstagram.classes.BuyBasketFlow;
import com.example.pinstagram.classes.InstaPosts;
import com.example.pinstagram.classes.SellingItems;
import com.example.pinstagram.viewHolders.InstaPostsRecyclerViewHolders;
import com.squareup.picasso.Picasso;
import java.util.ArrayList;
import java.util.List;
public class InstaPostsRecyclerViewAdapter extends RecyclerView.Adapter<InstaPostsRecyclerViewHolders> {
private List<InstaPosts> instaList;
private List<InstaPosts> selectedPosts;
LinearLayout linearLayout;
private Context context;
TextView numberTextView,eachPostPriceTxt,totalPriceTxt;
BuyBasketFlow buyBasketFlow;
SellingItems sellingItems;
public InstaPostsRecyclerViewAdapter(Context context, List<InstaPosts> itemList,List<InstaPosts> selectedPosts,LinearLayout linearLayout,TextView[] textViews) {
this.instaList = itemList;
this.context = context;
this.selectedPosts = selectedPosts;
this.linearLayout = linearLayout;
numberTextView = textViews[0];
eachPostPriceTxt = textViews [1];
buyBasketFlow = new BuyBasketFlow();
sellingItems = new SellingItems();
selectedPosts.clear();
for(int i = 0; i < instaList.size();i++){
instaList.get(i).setSelected(false);
}
linearLayout.setVisibility(View.GONE);
}
#NonNull
#Override
public InstaPostsRecyclerViewHolders onCreateViewHolder(ViewGroup parent, int viewType) {
View layoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.isnta_posts_listview, null);
InstaPostsRecyclerViewHolders crcv = new InstaPostsRecyclerViewHolders(layoutView);
return crcv;
}
#Override
public void onBindViewHolder(#NonNull final InstaPostsRecyclerViewHolders holder, final int position) {
holder.cardView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Log.i("Log3", " item number: " + position + " is clicked");
instaList.get(position).setSelected(!instaList.get(position).isSelected());
if(buyBasketFlow.getType().compareTo("like")==0) {
if (instaList.get(position).isCanBeSelect()) {
selectingPhase(holder,position);
} else {
Toast.makeText(context, R.string.just_select_photo, Toast.LENGTH_SHORT).show();
Log.i("Log1", instaList.get(position).getTypename());
}
}else if(buyBasketFlow.getType().compareTo("view")==0){
if (instaList.get(position).isViewCanBeSelected()) {
selectingPhase(holder,position);
} else {
Toast.makeText(context, R.string.just_select_video, Toast.LENGTH_SHORT).show();
Log.i("Log1", instaList.get(position).getTypename());
}
}else if(buyBasketFlow.getType().compareTo("comment")==0){
if (instaList.get(position).isViewCanBeSelected()||instaList.get(position).isCanBeSelect()) {
selectingPhase(holder,position);
} else {
Toast.makeText(context, R.string.just_select_video, Toast.LENGTH_SHORT).show();
Log.i("Log1", instaList.get(position).getTypename());
}
}
}
});
Picasso.get().load(instaList.get(position).getThumbnail_url()).into(holder.instaImage);
}
public List<InstaPosts> getSelectedPosts(){
return selectedPosts;
}
#Override
public int getItemCount() {
return this.instaList.size();
}
private void selectingPhase(InstaPostsRecyclerViewHolders holder,int position){
if (instaList.get(position).isSelected()) {
selectedPosts.add(instaList.get(position));
buyBasketFlow.setPostsArrays(selectedPosts);
for (InstaPosts selected : selectedPosts) {
Log.e("Log1", selected.toString());
}
holder.radioBtn.setImageDrawable(context.getDrawable(R.drawable.radio_button_checked));
holder.cardView.setStrokeWidth(10);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
holder.cardView.setStrokeColor(context.getColor(R.color.colorPrimary));
}
} else {
selectedPosts.remove(instaList.get(position));
buyBasketFlow.setPostsArrays(selectedPosts);
for (InstaPosts selected : selectedPosts) {
Log.e("Log1", selected.toString());
}
holder.cardView.setStrokeWidth(0);
holder.radioBtn.setImageDrawable(context.getDrawable(R.drawable.radio_button_unchecked));
}
if (selectedPosts.size() < 1) {
linearLayout.setVisibility(View.GONE);
Log.i("Log1", "layout must become invisible");
} else {
Log.i("Log1", "layout must become visible");
linearLayout.setVisibility(View.VISIBLE);
sellingItems = buyBasketFlow.getSellingItem();
numberTextView.setText("" + selectedPosts.size());
Log.i("Log1", "" + Integer.parseInt(sellingItems.getPrice()));
String text = "قیمت هر پست" + sellingItems.getPrice() + " تومان ";
String sum = Integer.toString((selectedPosts.size() * Integer.parseInt(sellingItems.getPrice())));
text = text + "و قیمت مجموع " + sum + " تومان ";
eachPostPriceTxt.setText(text);
}
}
}
You need to set selected state on onBindViewHolder every time.
In onBindViewHolder:
InstaPosts instaPosts = instaList.get(position);
holder.cardView.setStrokeWidth(instaPosts.isSelected() ? 10 : 0);
holder.radioBtn.setImageDrawable(context.getDrawable(instaPosts.isSelected() ? R.drawable.radio_button_checked : R.drawable.radio_button_unchecked));
package com.example.adapter;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.util.SparseBooleanArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.TextView;
import android.widget.Toast;
import com.example.aayushchaubey.meetdax.R;
import com.google.android.gms.tasks.Task;
import com.google.firebase.firestore.QuerySnapshot;
import java.util.ArrayList;
import java.util.HashMap;
public class DifferentGenderServicesAdapter2 extends RecyclerView.Adapter {
private Task<QuerySnapshot> task;
String id, servicename;
ArrayList<String> serviceArray = new ArrayList<>();
ArrayList<Integer> costArray = new ArrayList<>();
ArrayList<ArrayList<String>> stylistIdArray = new ArrayList<>();
ArrayList<Integer>durationArray=new ArrayList<>();
TextView serviceTv, durationTv;
int count = 0;
String strService;
ArrayList<String> keyArr = new ArrayList<>();
ArrayList<String>serviceDocumentId=new ArrayList<>();
ArrayList<String>selectedServiceId=new ArrayList<>();
ArrayList<String>selectedServiceArray=new ArrayList<>();
ArrayList<Integer>selectedServiceCost=new ArrayList<>();
ArrayList<Integer>durationArr=new ArrayList<>();
String serviceId,strStylist,strDuration;
ArrayList<String>stylist=new ArrayList<>();
ArrayList<ArrayList<String>>selectedStylistId=new ArrayList<>();
public DifferentGenderServicesAdapter2(Task<QuerySnapshot> task, ArrayList<String> id, TextView servicesTv, TextView durationTv) {
this.task = task;
this.serviceTv = servicesTv;
this.durationTv = durationTv;
this.serviceDocumentId=id;
count = task.getResult().size();
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.services_item, parent, false);
return new DifferentGenderServicesAdapter2.listViewHolder(view);
}
#Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) {
try {
((listViewHolder) holder).servicenameTv.setText(task.getResult().getDocuments().get(position).get("name").toString());
((listViewHolder) holder).serviceCost.setText(task.getResult().getDocuments().get(position).get("price").toString());
servicename = task.getResult().getDocuments().get(position).get("name").toString();
Integer price = task.getResult().getDocuments().get(position).getLong("price").intValue();
serviceArray.add(servicename);
costArray.add(price);
ArrayList<HashMap<String,String>>stylistArr=new ArrayList<>();
stylistArr=(ArrayList<HashMap<String, String>>)task.getResult().getDocuments().get(position).get("services");
ArrayList<String> stylistsId = new ArrayList<String>();
stylistsId.clear();
for (int i=0;i<stylistArr.size();i++){
strStylist=stylistArr.get(i).get("stylist").toString();
strDuration=stylistArr.get(i).get("duration").toString();
stylistsId.add(strStylist);
durationArray.add(Integer.parseInt(strDuration));
}
stylistIdArray.add(stylistsId);
((listViewHolder) holder).checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
if(((listViewHolder) holder).checkBox.isChecked()){
String service=serviceArray.get(position);
selectedServiceArray.add(service);
serviceTv.setText(selectedServiceArray.toString().replaceAll("\\[|\\]", ""));
}else {
selectedServiceArray.remove(position);
if (selectedServiceArray.size()== 0) {
serviceTv.setText("0");
} else {
serviceTv.setText(selectedServiceArray.toString());
}
}
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
public ArrayList<String> getServiceId() {
return selectedServiceId;
}
public ArrayList<String> getServices() {
return selectedServiceArray;
}
public Integer getCostArray() {
Integer cost = null;
if(selectedServiceCost.size()>1){
cost=selectedServiceCost.get(0)+selectedServiceCost.get(1);
}else {
cost=selectedServiceCost.get(0);
}
return cost;
}
public Integer getDurationArr() {
Integer duration=null;
if(durationArr.size()>1){
duration=durationArr.get(0)+durationArr.get(1);
}else {
duration=durationArr.get(0);
}
return duration;
}
public ArrayList<ArrayList<String>> getSelectedStylistId() {
return selectedStylistId;
}
#Override
public int getItemCount() {
return count;
}
private class listViewHolder extends RecyclerView.ViewHolder {
private CheckBox checkBox;
private TextView servicenameTv, serviceCost;
int count = 0;
String strService;
public listViewHolder(final View itemView) {
super(itemView);
try {
servicenameTv = (TextView) itemView.findViewById(R.id.damerServiceTV);
serviceCost = (TextView) itemView.findViewById(R.id.damerRsTV);
checkBox = (CheckBox) itemView.findViewById(R.id.checkBox);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
This is the recycleradapter i am using to populate array and checkbox.i want to setText for selected items.If i deselect the items i want to remove text from textview.When i select one item select and deselect is working properly.If i had more than one or if i select and deselct multiples times its not working giving index error
You are trying to delete an item at the given ReciclerView selection, but this position is wrong because you are doing:
selectedServiceArray.add(service);
So you don't know the position which is added because could be other items in this array. You have to request delete the object instead the position. Try this:
if(checkbox.isChecked){
String service=serviceArray.get(getAdapterPosition);
selectedServiceArray.add(service);
holder.serviceNameTv.setText(selectedServiceArray.toString);
} else {
String service=serviceArray.get(getAdapterPosition);
selectedServiceArray.remove(service);
holder.serviceNameTv.setText(selectedServiceArray.toString);
}
Do it like this : -
if(checkbox.isChecked){
String service=serviceArray.get(getAdapterPosition)
selectedServiceArray.add(service);
holder.serviceNameTv.setText(selectedServiceArray.toString);
}
else{
selectedServiceArray.remove(getAdapterPosition);
if (selectedServiceArray.size = 0) {
holder.serviceNameTv.setText("0");
} else{
holder.serviceNameTv.setText(selectedServiceArray.toString);
}
I am working on GoogleFit Api for daily steps count. I am getting the correct result. But when i sign out the application (In this case, app exit the Googlefit fragment's parent activity)
After sign in again, i access the same fragment again, but Googlefit returns the stepsCount as zero and getting times out at result.await.
Here is my Code.
GoogleFitFragment.java
package com.example.mudasirrao.mvvm.Fragments.GoogleFitFragments;
import android.databinding.DataBindingUtil;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.example.mudasirrao.mvvm.R;
import com.example.mudasirrao.mvvm.ViewModel.GoogleFitViewModels.GoogleFitViewModel;
import com.example.mudasirrao.mvvm.databinding.FragmentGoogleFitBinding;
import com.google.android.gms.common.api.PendingResult;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.fitness.ConfigApi;
import com.google.android.gms.fitness.Fitness;
import com.google.android.gms.fitness.result.DataTypeResult;
public class GoogleFitFragment extends Fragment {
GoogleFitViewModel googleFitViewModel;
public GoogleFitFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
FragmentGoogleFitBinding fragmentGoogleFitBinding = DataBindingUtil.inflate(inflater, R.layout.fragment_google_fit, container, false);
View view = fragmentGoogleFitBinding.getRoot();
googleFitViewModel = new GoogleFitViewModel(getActivity(), fragmentGoogleFitBinding);
fragmentGoogleFitBinding.setGoogleFitFragmentViewModel(googleFitViewModel);
return view;
}
}
GoogleFitViewModel.java
package com.example.mudasirrao.mvvm.ViewModel.GoogleFitViewModels;
import android.content.Context;
import android.content.SharedPreferences;
import android.databinding.ObservableField;
import android.os.AsyncTask;
import android.util.Log;
import android.view.View;
import android.widget.Toast;
import com.example.mudasirrao.mvvm.CallBacks.CallBackGoogleFitClient;
import com.example.mudasirrao.mvvm.DataManager.GoogleFitDataManager;
import com.example.mudasirrao.mvvm.databinding.FragmentGoogleFitBinding;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.PendingResult;
import com.google.android.gms.fitness.ConfigApi;
import com.google.android.gms.fitness.Fitness;
import com.google.android.gms.fitness.data.DataSet;
import com.google.android.gms.fitness.data.DataType;
import com.google.android.gms.fitness.data.Field;
import com.google.android.gms.fitness.result.DailyTotalResult;
import java.util.concurrent.TimeUnit;
import static android.content.Context.MODE_PRIVATE;
public class GoogleFitViewModel {
private Context context;
private FragmentGoogleFitBinding fragmentGoogleFitBinding;
public final ObservableField<String> steps = new ObservableField<>();
public GoogleApiClient localGoogleApiClient;
String dailySteps;
public GoogleFitViewModel(Context context, final FragmentGoogleFitBinding fragmentGoogleFitBinding) {
this.context = context;
this.fragmentGoogleFitBinding = fragmentGoogleFitBinding;
SharedPreferences prefs = context.getSharedPreferences("dailySteps", MODE_PRIVATE);
dailySteps = prefs.getString("daily_steps", null);
if (dailySteps != null) {
steps.set(dailySteps);
GoogleFitDataManager.singletonObject(context).buildFitnessClient(new CallBackGoogleFitClient() {
#Override
public void onResponse(GoogleApiClient googleApiClient) {
localGoogleApiClient = googleApiClient;
if (googleApiClient != null) {
new VerifyDataTask().execute(localGoogleApiClient);
fragmentGoogleFitBinding.setGoalLayout.animate().alpha(0.2f).setDuration(1000);
enableDisableLayout(false);
fragmentGoogleFitBinding.previewImage.setVisibility(View.GONE);
fragmentGoogleFitBinding.saveButton.setText("Edit");
fragmentGoogleFitBinding.saveButton.setTag("disabled_edit");
fragmentGoogleFitBinding.goalProgressLayout.setVisibility(View.VISIBLE);
fragmentGoogleFitBinding.goalText.setText("Take " + steps.get() + " steps a day");
}
}
});
} else {
steps.set("0000");
fragmentGoogleFitBinding.setGoalLayout.animate().alpha(1.0f).setDuration(3000);
}
}
public void onClickStepsButton1(View view) {
steps.set("2000");
}
public void onClickStepsButton2(View view) {
steps.set("8000");
}
public void onClickStepsButton3(View view) {
steps.set("10000");
}
public void onClickStepsButton4(View view) {
steps.set("13000");
}
public void onClickSave(View view) {
if ((Integer.valueOf(steps.get()) > 0)) {
if (fragmentGoogleFitBinding.saveButton.getTag() == null) {
GoogleFitDataManager.singletonObject(context).buildFitnessClient(new CallBackGoogleFitClient() {
#Override
public void onResponse(GoogleApiClient googleApiClient) {
localGoogleApiClient = googleApiClient;
if (googleApiClient != null) {
new VerifyDataTask().execute(localGoogleApiClient);
fragmentGoogleFitBinding.setGoalLayout.animate().alpha(0.2f).setDuration(1000);
enableDisableLayout(false);
fragmentGoogleFitBinding.previewImage.setVisibility(View.GONE);
fragmentGoogleFitBinding.saveButton.setText("Edit");
fragmentGoogleFitBinding.saveButton.setTag("disabled_edit");
fragmentGoogleFitBinding.goalProgressLayout.setVisibility(View.VISIBLE);
}
}
});
} else {
if (fragmentGoogleFitBinding.saveButton.getTag().equals("disabled_edit")) {
fragmentGoogleFitBinding.setGoalLayout.animate().alpha(1.0f).setDuration(1000);
enableDisableLayout(true);
fragmentGoogleFitBinding.saveButton.setTag("enabled_edit");
fragmentGoogleFitBinding.saveButton.setText("Save");
} else if (fragmentGoogleFitBinding.saveButton.getTag().equals("enabled_edit")) {
new VerifyDataTask().execute(localGoogleApiClient);
fragmentGoogleFitBinding.setGoalLayout.animate().alpha(0.2f).setDuration(1000);
enableDisableLayout(false);
fragmentGoogleFitBinding.saveButton.setText("Edit");
fragmentGoogleFitBinding.saveButton.setTag("disabled_edit");
}
}
fragmentGoogleFitBinding.goalText.setText("Take " + steps.get() + " steps a day");
} else
Toast.makeText(context, "Please Select Steps", Toast.LENGTH_SHORT).show();
}
protected void renderStepsProgress(int stepsTaken) {
saveDailyStepsInSharedPref(steps.get());
int percentage = (int) (((double) stepsTaken / (double) Integer.valueOf(steps.get())) * 100);
if (percentage > 100) {
percentage = 100;
}
fragmentGoogleFitBinding.waveLoadingView.setCenterTitle(String.valueOf(percentage) + " %");
fragmentGoogleFitBinding.waveLoadingView.setProgressValue(percentage);
fragmentGoogleFitBinding.stepsTakenText.setText("You have taken " + String.valueOf(stepsTaken) + " steps today");
}
private void enableDisableLayout(Boolean visibility) {
View child;
for (int i = 0; i < fragmentGoogleFitBinding.stepButtonLayout1.getChildCount(); i++) {
child = fragmentGoogleFitBinding.stepButtonLayout1.getChildAt(i);
child.setEnabled(visibility);
}
for (int i = 0; i < fragmentGoogleFitBinding.stepButtonLayout2.getChildCount(); i++) {
child = fragmentGoogleFitBinding.stepButtonLayout2.getChildAt(i);
child.setEnabled(visibility);
}
}
private void saveDailyStepsInSharedPref(String dailySteps) {
SharedPreferences.Editor editor = context.getSharedPreferences("dailySteps", MODE_PRIVATE).edit();
editor.putString("daily_steps", dailySteps);
editor.apply();
}
private class VerifyDataTask extends AsyncTask<GoogleApiClient, Void, Integer> {
#Override
protected Integer doInBackground(GoogleApiClient... params) {
int total = 0;
PendingResult<DailyTotalResult> result = Fitness.HistoryApi.readDailyTotal(params[0], DataType.TYPE_STEP_COUNT_DELTA);
DailyTotalResult totalResult = result.await(30, TimeUnit.SECONDS);
if (totalResult.getStatus().isSuccess()) {
DataSet totalSet = totalResult.getTotal();
total = totalSet.isEmpty()
? 0
: totalSet.getDataPoints().get(0).getValue(Field.FIELD_STEPS).asInt();
} else {
Log.d("steps_count_error", "There was a problem getting the step count!!");
}
return total;
}
protected void onPostExecute(Integer result) {
renderStepsProgress(result);
}
}
}
GoogleFitDataManager.java
package com.example.mudasirrao.mvvm.DataManager;
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.FragmentActivity;
import android.util.Log;
import android.widget.Toast;
import com.example.mudasirrao.mvvm.CallBacks.CallBackGoogleFitClient;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.fitness.Fitness;
import com.google.android.gms.fitness.FitnessStatusCodes;
import com.google.android.gms.fitness.data.DataType;
import static com.bumptech.glide.gifdecoder.GifHeaderParser.TAG;
public class GoogleFitDataManager {
private static GoogleFitDataManager googleFitDataManager;
private GoogleApiClient googleApiClient = null;
private Context context;
public GoogleFitDataManager(Context context) {
this.context = context;
}
public static GoogleFitDataManager singletonObject(Context context) {
if (googleFitDataManager == null) {
googleFitDataManager = new GoogleFitDataManager(context);
}
return googleFitDataManager;
}
public void buildFitnessClient(final CallBackGoogleFitClient callBackGoogleFitClient) {
if (googleApiClient == null) {
googleApiClient = new GoogleApiClient.Builder(context)
.addApi(Fitness.HISTORY_API)
.addApi(Fitness.RECORDING_API)
.addApi(Fitness.CONFIG_API)
.addConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks() {
#Override
public void onConnected(#Nullable Bundle bundle) {
subscribeGoogleFit(googleApiClient);
callBackGoogleFitClient.onResponse(googleApiClient);
}
#Override
public void onConnectionSuspended(int i) {
if (i == GoogleApiClient.ConnectionCallbacks.CAUSE_NETWORK_LOST) {
Toast.makeText(context, "Connection lost. Cause: Network Lost.", Toast.LENGTH_SHORT).show();
} else if (i == GoogleApiClient.ConnectionCallbacks.CAUSE_SERVICE_DISCONNECTED) {
Toast.makeText(context, "Connection lost. Reason: Service Disconnected", Toast.LENGTH_SHORT).show();
}
}
}
)
.enableAutoManage((FragmentActivity) context, 0, new GoogleApiClient.OnConnectionFailedListener() {
#Override
public void onConnectionFailed(ConnectionResult result) {
Log.i("TAG", "Google Play services connection failed. Cause: " + result.toString());
Toast.makeText(context, "Exception while connecting to Google Play services: " + result.getErrorMessage(), Toast.LENGTH_SHORT).show();
}
})
.build();
} else {
subscribeGoogleFit(googleApiClient);
callBackGoogleFitClient.onResponse(googleApiClient);
}
}
public void subscribeGoogleFit(GoogleApiClient client) {
Fitness.RecordingApi.subscribe(client, DataType.TYPE_STEP_COUNT_DELTA)
.setResultCallback(new ResultCallback<Status>() {
#Override
public void onResult(Status status) {
if (status.isSuccess()) {
if (status.getStatusCode() == FitnessStatusCodes.SUCCESS_ALREADY_SUBSCRIBED) {
Log.i(TAG, "Existing subscription for activity detected.");
} else {
Log.i(TAG, "Successfully subscribed!");
}
} else {
Log.i(TAG, "There was a problem subscribing.");
}
}
});
}
}
What I was doing that I was creating the static object of the class in which I was making the googlefit client. In this case, when I exit the Activity, the object was not destroying and googlefit client was getting disconnected due to the enableAutoManage in onDestroy of the fragment. And as per my checks, I was not connecting to the googleFit client again.
I removed the object as static and now I stick the API client class object with the life cycle of the activity in which my fragment resides. Also I removed enableAutoManage and now connecting and disconnecting the API client by myself.
I've made an apache thrift server and I have a service which contains several functions.
I'm trying to figure out what is the best way to make calls to the remote server from my android application.
My problem is that I can't make calls from the MainActivity thread (the main thread) - and I need to use most of the remote functions in my main activity methods.
I tried to make a static class with a static member called "Server" equals to the server object, and I set it in another thread and then I tried to call it in the main thread (the main activity class) - but I had errors because of jumping from one thread to another..
To be more specified I want something like that:
public class MainActivity extends Activity {
private service.Client myService;
#Override
protected void onCreate(Bundle savedInstanceState) {
..
... Some stuff that define myService (In a new thread ofcourse) ...
}
...
private void MyFunc1() {
myService.Method1();
}
private void MyFunc2() {
myService.Method2();
}
private void MyFunc3() {
myService.Method3();
}
}
I've got a library for talking to REST APIs. Feel free to slice, dice, and re-use: https://github.com/nedwidek/Android-Rest-API
The code is BSD or GPL.
Here's how I use what I have (I've trimmed MainActivity a bit, hopefully not too much):
package com.hatterassoftware.voterguide.api;
import java.util.HashMap;
public class GoogleCivicApi {
protected final String baseUrl = "https://www.googleapis.com/civicinfo/us_v1/";
protected String apiKey = "AIzaSyBZIP5uY_fMF35SVVrytpKgHtppBbj8J0I";
public static final String DATE_FORMAT = "yyyy-MM-dd";
protected static HashMap<String, String> headers;
static {
headers = new HashMap<String, String>();
headers.put("Content-Type", "application/json");
}
public String createUrl(String uri, HashMap<String, String> params) {
String url = baseUrl + uri + "?key=" + apiKey;
if (params != null) {
for (String hashKey: params.keySet()) {
url += hashKey + "=" + params.get(hashKey) + "&";
}
url = url.substring(0, url.length());
}
return url;
}
}
package com.hatterassoftware.voterguide.api;
import android.util.Log;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.hatterassoftware.restapi.GetTask;
import com.hatterassoftware.restapi.HttpReturn;
import com.hatterassoftware.restapi.RestCallback;
import com.hatterassoftware.voterguide.api.callbacks.ElectionCallback;
import com.hatterassoftware.voterguide.api.models.Election;
public class ElectionsQuery extends GoogleCivicApi implements RestCallback {
GetTask getTask;
ElectionCallback callback;
final String TAG = "ElectionQuery";
public ElectionsQuery(ElectionCallback callback) {
String url = this.createUrl("elections", null);
this.callback = callback;
Log.d(TAG, "Creating and executing task for: " + url);
getTask = new GetTask(url, this, null, null, null);
getTask.execute();
}
#Override
public void onPostSuccess() {
Log.d(TAG, "onPostSuccess entered");
}
#Override
public void onTaskComplete(HttpReturn httpReturn) {
Log.d(TAG, "onTaskComplete entered");
Log.d(TAG, "httpReturn.status = " + httpReturn.status);
if (httpReturn.content != null) Log.d(TAG, httpReturn.content);
if (httpReturn.restException != null) Log.d(TAG, "Exception in httpReturn", httpReturn.restException);
JsonParser parser = new JsonParser();
JsonElement electionArrayJson = ((JsonObject)parser.parse(httpReturn.content)).get("elections");
Log.d(TAG, electionArrayJson.toString());
Gson gson = new GsonBuilder().setDateFormat(GoogleCivicApi.DATE_FORMAT).create();
Election[] elections = gson.fromJson(electionArrayJson.toString(), Election[].class);
callback.retrievedElection(elections);
}
}
package com.hatterassoftware.voterguide;
import java.util.Calendar;
import java.util.List;
import com.actionbarsherlock.app.SherlockFragmentActivity;
import com.hatterassoftware.voterguide.api.ElectionsQuery;
import com.hatterassoftware.voterguide.api.VoterInfoQuery;
import com.hatterassoftware.voterguide.api.callbacks.ElectionCallback;
import com.hatterassoftware.voterguide.api.callbacks.VoterInfoCallback;
import com.hatterassoftware.voterguide.api.models.Election;
import com.hatterassoftware.voterguide.api.models.VoterInfo;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationManager;
import android.os.Bundle;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.text.Editable;
import android.text.Html;
import android.text.TextWatcher;
import android.text.method.LinkMovementMethod;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ProgressBar;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends SherlockFragmentActivity implements ElectionCallback, VoterInfoCallback {
private ProgressBar mProgressBar;
public Button submit;
public Spinner state;
public Spinner election;
public EditText address;
public EditText city;
public EditText zip;
private int count=0;
private Object lock = new Object();
private static final String TAG = "MainActivity";
public static final String VOTER_INFO = "com.hatterassoftware.voterguide.VOTER_INFO";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mProgressBar = (ProgressBar) findViewById(R.id.home_progressBar);
Resources res = getResources();
SharedPreferences mPrefs = getApplicationSharedPreferences();
ImageButton gpsButton = (ImageButton) findViewById(R.id.locate);
try {
LocationManager manager = (LocationManager) getSystemService( Context.LOCATION_SERVICE );
if (!manager.isProviderEnabled(Context.LOCATION_SERVICE)) {
gpsButton.setClickable(false);
}
} catch(Exception e) {
Log.d(TAG, e.getMessage(), e);
gpsButton.setClickable(false);
gpsButton.setEnabled(false);
}
submit = (Button) findViewById(R.id.submit);
submit.setClickable(false);
submit.setEnabled(false);
state = (Spinner) findViewById(R.id.state);
election = (Spinner) findViewById(R.id.election);
address = (EditText) findViewById(R.id.streetAdress);
city = (EditText) findViewById(R.id.city);
zip = (EditText) findViewById(R.id.zip);
submit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
doSubmit();
}
});
gpsButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
doLocate();
}
});
// Let's check for network connectivity before we get down to business.
if (Utils.isNetworkAvailable(this, true)) {
// Show the disclaimer on first run.
if(mPrefs.getBoolean("firstRun", true)) {
AlertDialog alert = new AlertDialog.Builder(this).create();
alert.setCancelable(false);
alert.setTitle(res.getString(R.string.welcome));
LayoutInflater inflater = (LayoutInflater) this.getSystemService(LAYOUT_INFLATER_SERVICE);
View layout = inflater.inflate(R.layout.custom_dialog, null);
TextView alertContents = (TextView) layout.findViewById(R.id.custom_dialog_text);
alertContents.setMovementMethod(LinkMovementMethod.getInstance());
alertContents.setText(Html.fromHtml(res.getString(R.string.welcome_dialog_text)));
alert.setView(alertContents);
alert.setButton(AlertDialog.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
SharedPreferences mPrefs = getApplicationSharedPreferences();
SharedPreferences.Editor editor = mPrefs.edit();
editor.putBoolean("firstRun", false);
editor.commit();
dialog.dismiss();
retrieveElections();
}
});
alert.show();
} else {
retrieveElections();
}
}
}
#Override
public void onResume() {
super.onResume();
// Let's check for network connectivity before we get down to business.
Utils.isNetworkAvailable(this, true);
LocationManager manager = (LocationManager) getSystemService( Context.LOCATION_SERVICE );
if (!(manager.isProviderEnabled(LocationManager.GPS_PROVIDER)
|| manager.isProviderEnabled(LocationManager.NETWORK_PROVIDER))) {
Toast.makeText(this, "GPS is not available", 2).show();
ImageButton gpsButton = (ImageButton) findViewById(R.id.locate);
gpsButton.setClickable(false);
}
}
public SharedPreferences getApplicationSharedPreferences() {
Context mContext = this.getApplicationContext();
return mContext.getSharedPreferences("com.hatterassoftware.voterguide", MODE_PRIVATE);
}
private void showSpinner() {
synchronized(lock) {
count++;
mProgressBar.setVisibility(View.VISIBLE);
}
}
private void hideSpinner() {
synchronized(lock) {
count--;
if(count < 0) { // Somehow we're trying to hide it more times than we've shown it.
count=0;
}
if (count == 0) {
mProgressBar.setVisibility(View.INVISIBLE);
}
}
}
public void retrieveElections() {
Log.d(TAG, "Retrieving the elections");
showSpinner();
ElectionsQuery query = new ElectionsQuery(this);
}
#Override
public void retrievedElection(Election... elections) {
Log.d(TAG, "Retrieved the elections");
hideSpinner();
for (int i=0; i<elections.length; i++) {
Log.d(TAG, elections[i].toString());
}
ArrayAdapter arrayAdapter = new ArrayAdapter(this, android.R.layout.simple_spinner_item, elections);
arrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
Spinner spinner = (Spinner) this.findViewById(R.id.election);
spinner.setAdapter(arrayAdapter);
}
}