Reverse Pagination in chat app not working - java

I have RecyclerView which i am using for chat and all is working but reverse pagination like loading chat history from local SQLitedatabase is not working like Whatsapp Or Telegram App.
At first load i am loading user chat history by default with only 10 messages from Local SQLite Database. If i pull from top it loads next(older) 10 messages and so on.
I am using Firebase Realtime Database as our chat server which sync in realtime and when user send new message it fetch message and add into SQLite Database then loads at above oldest message Like in Image below
Main Class
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.chat_screen_main_fragment, container, false);
setRetainInstance(true);
// RECYCLER VIEW
recyclerView = v.findViewById(R.id.Chat_Screen_Message_List);
layoutManager = new LinearLayoutManager(getActivity());
layoutManager.scrollToPosition(message.size() - 1);
if (adapter == null) {
adapter = new Chat_Adapter(getActivity(), message);
}
layoutManager.setStackFromEnd(true);
layoutManager.setReverseLayout(true);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(adapter);
chat_database=new Chat_Database(getActivity());
// Testing For Pagination
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
if (newState == AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL){
Log.d(TAG,"Hello I am scrolling screen ");
isScrolling = true;
}
}
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
currentVisible = layoutManager.getChildCount();
TotalItems = layoutManager.getItemCount();
scrolledOutItems = layoutManager.findFirstVisibleItemPosition();
int check = TotalItems - currentVisible+scrolledOutItems;
Log.d(TAG,"Current Visible = "+currentVisible+" Total = "+TotalItems+" Scrolled Out Items = "+scrolledOutItems+" Check = "+check);
if (isScrolling && TotalItems == currentVisible + scrolledOutItems ){
Log.d(TAG,"Fetch Data Now "+OFFSET);
if (chatCount > OFFSET){
Log.d(TAG,"Total item count is more than database = "+chatCount +" "+OFFSET);
new databaseAsync().execute();
isScrolling = false;
}
}
}
});
}
//THIS METHOD WILL FETCH ALL MESSAGES FROM FIREBASE DATABASE
private synchronized void append_chat_conversation(DataSnapshot dataSnapshot) {
Iterator iterator = dataSnapshot.getChildren().iterator();
while (iterator.hasNext()) {
// NOW GET ALL DATA FROM FIREBASE DATABASE AND SAVE IT INTO STRINGS THEN CHECK EACH BY ITS MESSAGE TYPE
Chat_Msg = (String) ((DataSnapshot) iterator.next()).getValue();
Chat_FROM = (String) ((DataSnapshot) iterator.next()).getValue();
Chat_TO = (String) ((DataSnapshot) iterator.next()).getValue();
Chat_Type= (String) ((DataSnapshot) iterator.next()).getValue();
if (Chat_Type.equals("Local_Image")) {
long id = chat_database.Insert_Chat(Session.getUserID(), "Image", Chat_Msg);
if (id==0){
return;
}
Chat_Wrapper image = new Chat_Wrapper(null, Chat_Msg, null, null, null, null, null, Chat_TimeStamp,id );
message.add(image);
adapter.notifyDataSetChanged();
recyclerView.post(new Runnable() {
#Override
public void run() {
recyclerView.smoothScrollToPosition(adapter.getItemCount());
}
});
} else if (Chat_Type.equals("Typed_Message")){
long id=chat_database.Insert_Chat(Session.getUserID(),"Text", Chat_Msg);
//Adding Chat Data Into Database
if (id==0){
return;
}
Chat_Wrapper chat_wrapper = new Chat_Wrapper(Chat_Msg, null, null, null, null, null, null, Chat_TimeStamp,id);
message.add(chat_wrapper);
adapter.notifyDataSetChanged();
recyclerView.post(new Runnable() {
#Override
public void run() {
recyclerView.smoothScrollToPosition(adapter.getItemCount());
}
});
}
}
//FETCHING DATA FROM LOCAL DATABASE
private class databaseAsync extends AsyncTask<Void,Void,Void> {
boolean checkDB_Exist,chatItemsCounts;
private Parcelable recyclerViewState;
#Override
protected void onPreExecute() {
super.onPreExecute();
Log.d(TAG,"Chat Database Function "+OFFSET);
if (OFFSET == 0){
message.clear();
}
recyclerViewState = recyclerView.getLayoutManager().onSaveInstanceState();
//chatCursor=chat_database.getUserChat(UserID_Intent);
chatCount = chat_database.getUserChatCount(UserID_Intent);
chatCursor=chat_database.getLimitUserChat(UserID_Intent,OFFSET);
chatCursor.moveToFirst();
}
#Override
protected Void doInBackground(Void... voids) {
if (checkDB_Exist && chatCursor.getCount()>0) {
chatCursor.moveToFirst();
do {
database_rowID = chatCursor.getInt(chatCursor.getColumnIndex("ID"));
database_userID = chatCursor.getString(chatCursor.getColumnIndex("USER_ID"));
database_ReceiverID = chatCursor.getString(chatCursor.getColumnIndex("RECEIVER_USER_ID"));
database_MessageType = chatCursor.getString(chatCursor.getColumnIndex("MESSAGE_TYPE"));
database_Message = chatCursor.getString(chatCursor.getColumnIndex("USER_MESSAGE"));
database_MsgFrom = chatCursor.getString(chatCursor.getColumnIndex("SENDER_NAME"));
database_MsgTo = chatCursor.getString(chatCursor.getColumnIndex("RECEIVER_NAME"));
database_TimeStamp = chatCursor.getString(chatCursor.getColumnIndex("TIME_STAMP"));
if (database_MessageType.equals("Image")) {
Log.d(TAG, "Message Type Is Image");
Log.d(TAG, "Row ID of Database " + database_rowID);
Chat_Wrapper image = new Chat_Wrapper(null, database_Message, null, null, null, null, null, database_TimeStamp, database_PhoneTo, UserImage_Intent, database_MsgFrom, null, null, database_rowID);
message.add(image);
} else if (database_MessageType.equals("Text")) {
Log.d(TAG, "Message Type Is Text");
Chat_Wrapper text = new Chat_Wrapper(database_Message, null, null, null, null, null, null, database_TimeStamp, database_PhoneTo, UserImage_Intent, database_MsgFrom, null, null, database_rowID);
message.add(text);
}
}
}
while (chatCursor.moveToNext()) ;
chatCursor.close();
}
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
recyclerView.getLayoutManager().onRestoreInstanceState(recyclerViewState);
adapter.notifyDataSetChanged();
OFFSET +=10;
}
}
Chat Adapter
public class Chat_Adapter extends RecyclerView.Adapter<Chat_Adapter.ViewHolder> {
Chat_Wrapper chat_wrapper;
//ARRAYLIST OF MESSAGES OBJECT CONTAINING ALL THE MESSAGES IN THE THREAD
List<Chat_Wrapper> arrayList_message;
public Chat_Adapter(Context context, List<Chat_Wrapper> message) {
this.context = context;
this.arrayList_message = message;
}
#Override
public Chat_Adapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View Layout;
Log.d(TAG,"On Create View Holder Calling ");
if (viewType==1){
Log.d(TAG,"View Tyoe Is "+viewType);
Layout=LayoutInflater.from(parent.getContext()).inflate(R.layout.chat_screen_message_item,parent,false);
// ImagePath=Session.getUserImage();
}
else {
Log.d(TAG,"View Type Is "+viewType);
Layout=LayoutInflater.from(parent.getContext()).inflate(R.layout.chat_screen_message_item_other,parent,false);
// ImagePath=chat_wrapper.getImageView();
}
return new ViewHolder(Layout);
}
#Override
public void onBindViewHolder(final Chat_Adapter.ViewHolder holder, final int position) {
chat_wrapper=arrayList_message.get(position);
context=holder.itemView.getContext();
if (valueofImage){
// Showing Sent User Image in thumbnail
Glide.with(context).load(chat_wrapper.getImageSent()).apply(new RequestOptions()
.fitCenter()
.skipMemoryCache(true))
.thumbnail(0.1f)
.into(holder.Sent_Image);
}
}
else if (valueofMessage){
Log.d(TAG,"Value Of Message Running ImagePath "+ImagePath);
holder.Sent_Video.setVisibility(View.GONE);
holder.Sent_Image.setVisibility(View.GONE);
holder.TimeStampImage.setVisibility(View.GONE);
holder.TimeStampDoc.setVisibility(View.GONE);
holder.TimeStampVideo.setVisibility(View.GONE);
holder.Search_title.setVisibility(View.GONE);
holder.Search_link.setVisibility(View.GONE);
holder.Search_snippet.setVisibility(View.GONE);
holder.Google_Image.setVisibility(View.GONE);
holder.videoView.setVisibility(View.GONE);
holder.Doc_FileName.setVisibility(View.GONE);
holder.Doc_ImageView.setVisibility(View.GONE);
holder.Doc_FileSize.setVisibility(View.GONE);
holder.GeoFencing_Layout.setVisibility(View.GONE);
holder.GeoFencing_Image.setVisibility(View.GONE);
holder.GeoFencing_LatLng.setVisibility(View.GONE);
holder.Message.setVisibility(View.VISIBLE);
holder.TimeStamp.setVisibility(View.VISIBLE);
holder.User_Image.setVisibility(View.VISIBLE);
//CHECK SENDER IS SAME AS LOGGED IN USER
if ((Session.getUserFname()+" "+Session.getUserLname()).equals(chat_wrapper.getSender_UserName())){
ImagePath=Session.getUserImage();
Log.d(TAG,"Session.getUserImage() "+Session.getUserImage());
Log.d(TAG,"Value Of Message Running ImagePath "+ImagePath);
}
else {
holder.Message.setText(chat_wrapper.getMessage());
holder.TimeStamp.setText(chat_wrapper.getTimestamp());
}
#Override
public int getItemCount() {
Log.d(TAG,"GET ITEM COUNT--Array Message List Size "+arrayList_message.size());
return arrayList_message.size();
}
}
SQLite Query
//This method will get row by limit
public Cursor getLimitUserChat(String UserID,int nextChat){
database=this.getReadableDatabase();
cursor = database.rawQuery( "SELECT * FROM " + TABLE_NAME + " Where "+ RECEIVER_USERID +"="+ UserID+" ORDER BY ID DESC LIMIT 10 OFFSET "+nextChat+"",null
return cursor;
}

Using message.add(chat_wrapper); will put the added element to the end of the list so it will be shown at the end of the list while you are reversing the Recycler , use message.add(0,chat_wrapper); so it will be at the beginning of the array list.

Related

RecyclerView does not work sometimes when trying to display Firebase data

I have two RecyclerViews inside a LinearLayout in which I'm trying to display Firebase Storage data on one and some Products data queried from Real-Time Database on the other. While I am able to retrieve the data successfully, I have trouble showing it on the RecyclerView(s).
There are 1 of 3 things that happen spontaneously when I try to display the data:
Case 1: Data does not show on both RecyclerViews OR
Case 2: Data is shown for the first RecyclerView(displays storage
data) OR
Case 3: Data shows for both (but can sometimes take a verrryy long
time to load even though I have only one data each for both).
For the second RecyclerView, I have written the code to query in-app products data from Google Play Console using the billingclient library and I use the data queried from Real-Time DB to see if there is a match in the product IDs. If there is, I display the matching data on the RecyclerView.
While fetching the data is fine, at various times my code gets stuck on setAdapter() and I don't understand why and I don't know how to get it to work properly?
Here's a reference to my current code:
#Override
public View onCreateView(#NonNull LayoutInflater inflater, ViewGroup parent,
Bundle savedInstanceState) {
FirebaseStorage storage = FirebaseStorage.getInstance();
FirebaseDatabase database = FirebaseDatabase.getInstance();
storageRef = storage.getReference();
dataRef = database.getReference().child("products");
view = inflater.inflate(R.layout.course_fragment, parent, false);
mainLayout = view.findViewById(R.id.mainLayout);
filesRv = view.findViewById(R.id.file_recycler_view);
productRv = view.findViewById(R.id.product_recycler_view);
//list storage folder/files
listFilesFolders();
//check for premium data on real-time database and see if productID matches with productID on Google Play Console (display data on recycler view if it matches)
checkForPremium();
return view;
}
private void checkForPremium() {
setBillingClient(getContext());
connectToGooglePlay();
}
private void listFilesFolders() {
fileStorageRef.listAll()
.addOnSuccessListener(listResult -> {
for (StorageReference folder : listResult.getPrefixes()) {
parentFolder = folder.getName();
contentList.add(fileStorageRef.child(parentFolder));
}
for (StorageReference file : listResult.getItems()) {
fileName = file.getName();
contentList.add(fileStorageRef.child(fileName));
}
setFilesRecyclerView();
})
.addOnFailureListener(e -> {
// Some code here
})
.addOnCompleteListener(task -> {
// Some code here
});
}
private void setFilesRecyclerView() {
if(pageTitle.equals(rootFolder) || contentList.isEmpty()) {
displayFolders();
}
else {
displayFiles();
}
}
private void displayFolders() {
int columnCount = 2;
DisplayMetrics displayMetrics = view.getResources().getDisplayMetrics();
int width = displayMetrics.widthPixels; //get screen width
//if screen width is large, increase grid columns
if(width > 800 && width < 1500){
columnCount = 3;}
else if(width >= 1500 && width < 1800){
columnCount = 4; }
else if(width >= 1800){
columnCount = 5;
}
GridLayoutManager gridLayoutManager = new GridLayoutManager(getActivity(), columnCount);
SubFolderAdapter subFolderAdapter = new SubFolderAdapter(getActivity(), contentList);
filesRv.setLayoutManager(gridLayoutManager);
filesRv.setAdapter(subFolderAdapter);
}
private void displayFiles() {
LinearLayoutManager llm1 = new LinearLayoutManager(getActivity());
fileAdapter = new FileAdapter(getActivity(), contentList);
filesRv.setLayoutManager(llm1);
filesRv.setAdapter(fileAdapter);
}
private void displayPremiumData() {
LinearLayoutManager llm2 = new LinearLayoutManager(getActivity());
productsAdapter = new ProductsAdapter3(getActivity(), billingClient, prodDetailsList, path);
productRv.setLayoutManager(llm2);
productRv.setAdapter(productsAdapter);
}
public void setBillingClient(Context context) {
System.out.println("Set billing client");
billingClient = BillingClient.newBuilder(context) //creates instance of billing client
.enablePendingPurchases()
.setListener(this)
.build();
}
public void connectToGooglePlay() {
//Establish a connection to Google Play
billingClient.startConnection(new BillingClientStateListener() {
#Override
public void onBillingSetupFinished(#NonNull BillingResult billingResult) {
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
// The BillingClient is ready. You can query purchases here.
System.out.println("Billing client ready");
listPremium();
} else System.out.println("Billing client NOT ready");
}
#Override
public void onBillingServiceDisconnected() {
// Try to restart the connection on the next request to
// Google Play by calling the startConnection() method.
System.out.println("Billing service disconnected");
}
});
}
private void listPremium() {
premiumDBRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
cProductsList.clear();
for (DataSnapshot snap: snapshot.getChildren()) {
Products products = snap.getValue(Products.class);
String sku;
String name;
String url;
if (products != null) {
sku = products.getProductId();
name = products.getName();
url = products.getUrl();
if(sku != null) {
skuList.add(sku);
}
} else {
System.out.println("Product does not exist!");
}
}
for(String sku : skuList) {
productList.add(
QueryProductDetailsParams.Product.newBuilder()
.setProductId(sku)
.setProductType(BillingClient.ProductType.INAPP)
.build()
);
}
if (!productList.isEmpty()) {
querySkuDetails(productList);
} else {
System.out.println("No products available");
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
public void querySkuDetails(List<QueryProductDetailsParams.Product> productList) {
QueryProductDetailsParams params = QueryProductDetailsParams.newBuilder()
.setProductList(productList)
.build();
billingClient.queryProductDetailsAsync(
params,
(billingResult, productDetailsList) -> {
// check billingResult
// process returned productDetailsList
if (billingResult.getResponseCode() != BillingClient.BillingResponseCode.OK) {
System.out.printf(Locale.ENGLISH, "Unable to query sku details: %d - %s%n", billingResult.getResponseCode(), billingResult.getDebugMessage());
} else {
for (ProductDetails details: productDetailsList) {
prodDetailsList.add(details);
}
displayPremiumData();
}
});
}
Note: When I run the code, there are no errors. The issue is that the RecyclerView is not working consistently as intended.
I have been trying to get this to work but I have been stuck for days now and I would really appreciate some help please!

RecyclerView not updating after creating or deleting playlists in Fragments

I am trying to update my recyclerView by notifyDataSetChanged(). But it's not working. I have to close my specific fragment and open it to see the changes.
This is MyFragment where I call recyclerView
BottomSheetFragment.java
// showing Playlist Names
recyclerPlayListViewName =
bottomView.findViewById(R.id.recycler_play_list_view_name);
playlists = new ArrayList<Playlist>();
PlayListMethodHolder.getplaylistList(getContext(), playlists);
playlistAdapter = new PlaylistAdapter(bottomView.getContext(), playlists,
"bottomsheet");
recyclerPlayListViewName.setHasFixedSize(true);
recyclerPlayListViewName.setLayoutManager(new LinearLayoutManager(getContext()));
recyclerPlayListViewName.setAdapter(playlistAdapter);
playlistAdapter.notifyDataSetChanged();
This is AdapterClass where I call to delete the playlist method.
PlaylistAdapter.java
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem item) {
long plistID = playlists.get(position).getId();
switch (item.getItemId()) {
case R.id.pPlay:
break;
case R.id.pRename:
String dpType = "playlistRename";
PlayListPopDialog popDialog = new PlayListPopDialog(mContext,
dpType, plistID, playlists);
popDialog.show();
break;
case R.id.pDelete:
PlayListMethodHolder.deletePlaylist(mContext, plistID);
break;
And This is another DialogView where I call Create PlayList
PlayListPopDialog.java
findViewById(R.id.btn_playlist_save).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
EditText edtCreateNamePlaylist = findViewById(R.id.edt_create_name_playlist);
String playlistName = edtCreateNamePlaylist.getText().toString().trim();
if (!(playlistName.isEmpty())) {
boolean state = PlayListMethodHolder
.doPlaylistExists(getContext(), playlistName);
if (!state) {
PlayListMethodHolder.createPlaylist(getContext(), playlistName);
dismiss();
} else {
Toast.makeText(getContext(), "This name is already exists.",
Toast.LENGTH_SHORT).show();
}
} else {
Toast.makeText(getContext(), "Empty name", Toast.LENGTH_SHORT).show();
}
}
});
Finally, this is a class for holding all methods of creating or deleting PlayLists
PlayListMethodHolder.java
public class PlayListMethodHolder {
public static void createPlaylist(Context context, String playlistName) {
String[] projectionName = new String [] {
MediaStore.Audio.Playlists._ID,
MediaStore.Audio.Playlists.NAME,
MediaStore.Audio.Playlists.DATA,
};
ContentValues nameValues = new ContentValues();
nameValues.put(MediaStore.Audio.Playlists.NAME, playlistName);
nameValues.put(MediaStore.Audio.Playlists.DATE_ADDED,
System.currentTimeMillis());
nameValues.put(MediaStore.Audio.Playlists.DATE_MODIFIED,
System.currentTimeMillis());
Uri uri = context.getApplicationContext().getContentResolver()
.insert(MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI, nameValues);
if (uri != null) {
context.getApplicationContext().getContentResolver()
.query(uri, projectionName, null, null, null);
context.getApplicationContext().getContentResolver().notifyChange(uri, null);
}
}
// Delete single playlist from list
public static void deletePlaylist (#NonNull final Context context, long playlistId){
String playlistid = String.valueOf(playlistId);
ContentResolver resolver = context.getContentResolver();
String where = MediaStore.Audio.Playlists._ID + "=?";
String[] whereVal = {playlistid};
resolver.delete(MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI, where,
whereVal);
return ;
}
// get Playlist names
public static void getplaylistList(Context context, ArrayList<Playlist> plist) {
Cursor playlistCursor = context.getContentResolver().query(
MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI,
null,
null,
null,
null);
if (playlistCursor != null && playlistCursor.moveToFirst()) {
//get columns
int idColumn = playlistCursor.getColumnIndex
(MediaStore.Audio.Playlists._ID);
int titleColumn = playlistCursor.getColumnIndex
(MediaStore.Audio.Playlists.NAME);
do {
long thisId = playlistCursor.getLong(idColumn);
String thisTitle = playlistCursor.getString(titleColumn);
plist.add(new Playlist(thisId, thisTitle));
} while (playlistCursor.moveToNext());
}
}
Tap to see PlayList Design View

Error getting autocomplete prediction API call: com.google.android.gms.common.api.ApiException: 9003: PLACES_API_ACCESS_NOT_CONFIGURED

My placeautocomplete adapter is not working, I have added the api key, billing is also approved. Whenever I click to search a place it gives me an error of ApiException:9003 and the logcat points to the "PlaceAutocompleteAdapter.java" shown below.
public class PlaceAutocompleteAdapter
extends ArrayAdapter implements Filterable {
private static final String TAG = "PlaceAutoComplete";
private static final CharacterStyle STYLE_BOLD = new StyleSpan(Typeface.BOLD);
private ArrayList<AutocompletePrediction> mResultList;
private GeoDataClient mGeoDataClient;
private LatLngBounds mBounds;
private AutocompleteFilter mPlaceFilter;
public PlaceAutocompleteAdapter(Context context, GeoDataClient geoDataClient,
LatLngBounds bounds, AutocompleteFilter filter) {
super(context, android.R.layout.simple_expandable_list_item_2, android.R.id.text1);
mGeoDataClient = geoDataClient;
mBounds = bounds;
mPlaceFilter = filter;
}
public void setBounds(LatLngBounds bounds) {
mBounds = bounds;
}
#Override
public int getCount() {
return mResultList.size();
}
#Override
public AutocompletePrediction getItem(int position) {
return mResultList.get(position);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = super.getView(position, convertView, parent);
// Sets the primary and secondary text for a row.
// Note that getPrimaryText() and getSecondaryText() return a CharSequence that may contain
// styling based on the given CharacterStyle.
AutocompletePrediction item = getItem(position);
TextView textView1 = (TextView) row.findViewById(android.R.id.text1);
TextView textView2 = (TextView) row.findViewById(android.R.id.text2);
textView1.setText(item.getPrimaryText(STYLE_BOLD));
textView2.setText(item.getSecondaryText(STYLE_BOLD));
return row;
}
#Override
public Filter getFilter() {
return new Filter() {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
// We need a separate list to store the results, since
// this is run asynchronously.
ArrayList<AutocompletePrediction> filterData = new ArrayList<>();
// Skip the autocomplete query if no constraints are given.
if (constraint != null) {
// Query the autocomplete API for the (constraint) search string.
filterData = getAutocomplete(constraint);
}
results.values = filterData;
if (filterData != null) {
results.count = filterData.size();
} else {
results.count = 0;
}
return results;
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
if (results != null && results.count > 0) {
// The API returned at least one result, update the data.
mResultList = (ArrayList<AutocompletePrediction>) results.values;
notifyDataSetChanged();
} else {
// The API did not return any results, invalidate the data set.
notifyDataSetInvalidated();
}
}
#Override
public CharSequence convertResultToString(Object resultValue) {
// Override this method to display a readable result in the AutocompleteTextView
// when clicked.
if (resultValue instanceof AutocompletePrediction) {
return ((AutocompletePrediction) resultValue).getFullText(null);
} else {
return super.convertResultToString(resultValue);
}
}
};
}
private ArrayList<AutocompletePrediction> getAutocomplete(CharSequence constraint) {
Log.i(TAG, "Starting autocomplete query for: " + constraint);
// Submit the query to the autocomplete API and retrieve a PendingResult that will
// contain the results when the query completes.
Task<AutocompletePredictionBufferResponse> results =
mGeoDataClient.getAutocompletePredictions(constraint.toString(), mBounds,
mPlaceFilter);
// This method should have been called off the main UI thread. Block and wait for at most
// 60s for a result from the API.
try {
Tasks.await(results, 60, TimeUnit.SECONDS);
} catch (ExecutionException | InterruptedException | TimeoutException e) {
e.printStackTrace();
}
try {
AutocompletePredictionBufferResponse autocompletePredictions = results.getResult();
Log.i(TAG, "Query completed. Received " + autocompletePredictions.getCount()
+ " predictions.");
// Freeze the results immutable representation that can be stored safely.
return DataBufferUtils.freezeAndClose(autocompletePredictions);
} catch (RuntimeExecutionException e) {
// If the query did not complete successfully return null
Toast.makeText(getContext(), "Error contacting API: " + e.toString(),
Toast.LENGTH_SHORT).show();
Log.e(TAG, "Error getting autocomplete prediction API call", e);
return null;
}
}
}
Maybe you forgot to ENABLE the API in Google Api Console?
Please see:
https://support.google.com/googleapi/answer/6158841?hl=en
According to what I see, you might also be using the deprecated version of the Google Services SDK, which has been decommissioned in July 2019.
Please see here for more info:
https://developers.google.com/places/android-sdk/client-migration

ListView Not Displaying in New Activity

I am trying to get a ListView to appear in a new activity. I can see the record ID in the logcat, and I can see that the proper ID is being selected in debug view, but when I go to the new activity the list array is empty.
This is what I am seeing in debug view:
In the logcat I see this:
2018-10-07 11:39:09.286 12624-12624/ca.rvogl.tpbcui D/SAVEDLEAGUEID_VAL: 1
2018-10-07 11:39:09.286 12624-12624/ca.rvogl.tpbcui D/LEAGUEID_VAL: android.support.v7.widget.AppCompatTextView{e67a170 G.ED..... ......I. 0,0-0,0 #7f080112 app:id/tvLeagueId}
2018-10-07 11:39:09.293 12624-12624/ca.rvogl.tpbcui D/GETALLBOWLERS-SQL: SQL used = >>>>SELECT * FROM bowlers WHERE league_id = '1' ORDER BY timestamp DESC<<<<
2018-10-07 11:39:09.298 12624-12624/ca.rvogl.tpbcui D/GETALLBOWLERS-CNT: Number of rows retrieved = 0
2018-10-07 11:39:09.299 12624-12624/ca.rvogl.tpbcui D/GETALLBOWLERS-CNT: Number of elements in bowlerslist = 0
As you can see from the logcat the savedLeagueId is being passed to the SQLite Query that is suppose to be getting the list of Bowlers for the listview. However the number of elements in the bowlerslist is 0.
I have gone through the code over and over again but I am unable to isolate where the issue is.
LeagueAdapter.java
public class LeagueAdapter extends RecyclerView.Adapter<LeagueAdapter.MyViewHolder> {
private Context context;
private List<League> leaguesList;
public void notifyDatasetChanged(List<League> newleagueslist) {
leaguesList.clear();
leaguesList.addAll(newleagueslist);
super.notifyDataSetChanged();
}
public class MyViewHolder extends RecyclerView.ViewHolder {
public TextView name;
public TextView basescore;
public TextView basescorepercentage;
public TextView id;
public TextView wins;
public TextView losses;
public TextView timestamp;
public TextView buttonViewOption;
public MyViewHolder(View view) {
super(view);
id = view.findViewById( R.id.tvLeagueId);
name = view.findViewById(R.id.tvSeriesName );
basescore = view.findViewById(R.id.tvBaseScore );
basescorepercentage = view.findViewById(R.id.tvBaseScorePercentage );
wins = view.findViewById(R.id.tvLeagueWins );
losses = view.findViewById(R.id.tvLeagueLosses );
timestamp = view.findViewById(R.id.timestamp);
buttonViewOption = (TextView) view.findViewById(R.id.buttonViewOptions);
}
}
public LeagueAdapter(Context context, List<League> leaguesList) {
this.context = context;
this.leaguesList = leaguesList;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.listview_league, parent, false);
return new MyViewHolder(itemView);
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
League league = leaguesList.get(position);
int id = league.getId();
Log.d("id", String.valueOf(id));
int leagueId = id;
Log.d("leagueId", String.valueOf(leagueId));
holder.id.setText(String.valueOf(leagueId));
holder.name.setText(league.getName());
holder.basescore.setText(league.getBaseScore());
holder.basescorepercentage.setText(league.getBaseScorePercentage());
holder.wins.setText(league.getWins());
holder.losses.setText(league.getLosses());
/*if (league.getAverage() != "") {
holder.leagueAverage.setText(String.format("League Avg: %s", league.getAverage()));
} else {
holder.leagueAverage.setText(String.format("League Avg: %s", "0"));
}*/
//Formatting And Displaying Timestamp
holder.timestamp.setText(formatDate(league.getTimestamp()));
holder.buttonViewOption.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//creating a popup menu
PopupMenu popup = new PopupMenu(context, holder.buttonViewOption);
//inflating menu from xml resource
popup.inflate(R.menu.league_options_menu);
//adding click listener
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.profile:
Log.d("leagueId", String.valueOf(position));
int leagueId = league.getId();
String savedLeagueId = String.valueOf(id);
Intent myIntent = new Intent(context, LeagueProfileViewActivity.class);
myIntent.putExtra("leagueId", leagueId);
context.startActivity(myIntent);
break;
case R.id.delete:
((MainActivity) context).deleteLeague(position);
break;
}
return false;
}
});
//displaying the popup
popup.show();
}
});
holder.name.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//String leagueId = String.valueOf(leaguesList.get(position).getId());
int leagueId = league.getId();
String savedLeagueId = String.valueOf(id);
Log.d("leagueId", String.valueOf(position));
Intent myIntent = new Intent(context, BowlerActivity.class);
myIntent.putExtra("leagueId", savedLeagueId);
context.startActivity(myIntent);
}
});
}
#Override
public int getItemCount() {
return leaguesList.size();
}
//Formatting TimeStamp to 'EEE MMM dd yyyy (HH:mm:ss)'
//Input : 2018-05-23 9:59:01
//Output : Wed May 23 2018 (9:59:01)
private String formatDate(String dateStr) {
try {
SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = fmt.parse(dateStr);
SimpleDateFormat fmtOut = new SimpleDateFormat("EEE MMM dd yyyy (HH:mm:ss)");
return fmtOut.format(date);
} catch (ParseException e) {
}
return "";
}
}
I am moving to the BowlerActivity using holder.name, where I am passing the League ID using an intent.
BowlerActivity.java
public class BowlerActivity extends AppCompatActivity {
private BowlerAdapter mAdapter;
private final List<Bowler> bowlersList = new ArrayList<>();
private TextView noBowlersView;
private DatabaseHelper db;
private TextView leagueId;
private String savedLeagueId;
/*private TextView seriesleagueId;
private String seriesLeagueId;
private TextView bowlerAverage;
private TextView bowlerHandicap;
private String savedBowlerAverage;*/
private static final String PREFS_NAME = "prefs";
private static final String PREF_BLUE_THEME = "blue_theme";
private static final String PREF_GREEN_THEME = "green_theme";
private static final String PREF_ORANGE_THEME = "purple_theme";
private static final String PREF_RED_THEME = "red_theme";
private static final String PREF_YELLOW_THEME = "yellow_theme";
#Override protected void onResume() {
super.onResume();
db = new DatabaseHelper( this );
mAdapter.notifyDatasetChanged( db.getAllBowlers(savedLeagueId ) );
}
#Override
protected void onCreate(Bundle savedInstanceState) {
//Use Chosen Theme
SharedPreferences preferences = getSharedPreferences( PREFS_NAME, MODE_PRIVATE );
boolean useBlueTheme = preferences.getBoolean( PREF_BLUE_THEME, false );
if (useBlueTheme) {
setTheme( R.style.AppTheme_Blue_NoActionBar );
}
boolean useGreenTheme = preferences.getBoolean( PREF_GREEN_THEME, false );
if (useGreenTheme) {
setTheme( R.style.AppTheme_Green_NoActionBar );
}
boolean useOrangeTheme = preferences.getBoolean( PREF_ORANGE_THEME, false );
if (useOrangeTheme) {
setTheme( R.style.AppTheme_Orange_NoActionBar );
}
boolean useRedTheme = preferences.getBoolean( PREF_RED_THEME, false );
if (useRedTheme) {
setTheme( R.style.AppTheme_Red_NoActionBar );
}
boolean useYellowTheme = preferences.getBoolean( PREF_YELLOW_THEME, false );
if (useYellowTheme) {
setTheme( R.style.AppTheme_Yellow_NoActionBar );
}
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_bowler);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
Objects.requireNonNull( getSupportActionBar() ).setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startActivity(new Intent(getApplicationContext(),MainActivity.class));
finish();
overridePendingTransition(0, 0);
}
});
savedLeagueId = String.valueOf(getIntent().getStringExtra("leagueId"));
leagueId = findViewById(R.id.tvLeagueId);
Log.d("SAVEDLEAGUEID_VAL", String.valueOf(savedLeagueId));
Log.d("LEAGUEID_VAL", String.valueOf(leagueId));
/*bowlerAverage = (TextView) findViewById(R.id.tvBowlerAverage);
bowlerHandicap = (TextView) findViewById(R.id.tvBowlerHandicap);*/
CoordinatorLayout coordinatorLayout = findViewById( R.id.coordinator_layout );
RecyclerView recyclerView = findViewById( R.id.recycler_view );
noBowlersView = findViewById(R.id.empty_bowlers_view);
db = new DatabaseHelper(this);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.add_bowler_fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//showBowlerDialog(false, null, -1);
boolean shouldUpdate = false;
int bowlerId = -1;
String leagueId = String.valueOf(savedLeagueId);
Intent intent = new Intent(getApplicationContext(), BowlerProfileEditActivity.class);
intent.putExtra("shouldUpdate", shouldUpdate);
intent.putExtra("leagueId", leagueId);
intent.putExtra("bowlerId", bowlerId);
startActivity(intent);
finish();
overridePendingTransition(0, 0);
}
});
mAdapter = new BowlerAdapter(this, bowlersList);
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(mAdapter);
toggleEmptyBowlers();
}
//Inserting New Bowler In The Database And Refreshing The List
private void createBowler(String leagueId, String bowlerName) {
String bowlerAverage = "0";
//Inserting Bowler In The Database And Getting Newly Inserted Bowler Id
long id = db.insertBowler(savedLeagueId, bowlerName, bowlerAverage);
//Get The Newly Inserted Bowler From The Database
Bowler n = db.getBowler(savedLeagueId);
if (n != null) {
//Adding New Bowler To The Array List At Position 0
bowlersList.add( 0, n );
//Refreshing The List
mAdapter.notifyDatasetChanged(db.getAllBowlers(savedLeagueId));
//mAdapter.notifyDataSetChanged();
toggleEmptyBowlers();
}
}
//Updating Bowler In The Database And Updating The Item In The List By Its Position
private void updateBowler(String bowlerName, int position) {
Bowler n = bowlersList.get(position);
//Updating Bowler Text
n.setLeagueId(savedLeagueId);
n.setName(bowlerName);
//Updating The Bowler In The Database
db.updateBowler(n);
//Refreshing The List
bowlersList.set(position, n);
mAdapter.notifyItemChanged(position);
toggleEmptyBowlers();
}
//Deleting Bowler From SQLite Database And Removing The Bowler Item From The List By Its Position
public void deleteBowler(int position) {
Snackbar snackbar = Snackbar.make(findViewById(android.R.id.content), "Series will be deleted.", Snackbar.LENGTH_LONG)
.setActionTextColor(Color.YELLOW)
.setAction("OK", new View.OnClickListener() {
#Override
public void onClick(View v) {
//Deleting The Bowler From The Database
db.deleteBowler(bowlersList.get(position));
//Removing The Bowler From The List
bowlersList.remove(position);
mAdapter.notifyItemRemoved(position);
//db.leagueAverageScore(savedLeagueId);
toggleEmptyBowlers();
}
});
snackbar.show();
}
//Toggling List And Empty Bowler View
private void toggleEmptyBowlers() {
//You Can Check bowlerList.size() > 0
if (db.getBowlersCount() > 0) {
noBowlersView.setVisibility( View.GONE);
} else {
noBowlersView.setVisibility( View.VISIBLE);
}
}
#Override
public void onRestart() {
super.onRestart();
//When BACK BUTTON is pressed, the activity on the stack is restarted
//Do what you want on the refresh procedure here
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate( R.menu.menu_main, menu );
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
Intent intent = new Intent(this, SettingsActivity.class);
startActivity(intent);
overridePendingTransition(0, 0);
return true;
}
return super.onOptionsItemSelected( item );
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
//Check If Request Code Is The Same As What Is Passed - Here It Is 1
if(requestCode==1)
{
String savedLeagueId=data.getStringExtra("seriesLeagueId");
String seriesBowlerId=data.getStringExtra("seriesBowlerId");
bowlersList.addAll(db.getAllBowlers(savedLeagueId));
}
}
#Override
public void onBackPressed() {
startActivity(new Intent(getApplicationContext(),MainActivity.class));
finish();
overridePendingTransition(0, 0);
}
}
Bowler Methods in DatabaseHelper.java
public long insertBowler(String leagueId, String bowlerName, String bowlerAverage) {
String bowlerHandicap ="0";
//Get Writable Database That We Want To Write Data Too
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
//`id` and `timestamp` Will Be Inserted Automatically
values.put(Bowler.COLUMN_LEAGUE_ID, leagueId);
values.put(Bowler.COLUMN_NAME, bowlerName);
values.put(Bowler.COLUMN_BOWLER_AVERAGE, bowlerAverage);
values.put(Bowler.COLUMN_BOWLER_HANDICAP, bowlerHandicap);
//Insert Row
//long id = db.insert(Bowler.TABLE_NAME, null, values);
long id = db.insertOrThrow( Bowler.TABLE_NAME, null, values );
Log.d("INSERTBOWLER","Number of bowlers in db = " + String.valueOf( DatabaseUtils.queryNumEntries(db,Bowler.TABLE_NAME)));
//Close Database Connection
db.close();
//Return Newly Inserted Row Id
return id;
}
public Bowler getBowler(String leagueId) {
//Get Readable Database If We Are Not Inserting Anything
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.query( Bowler.TABLE_NAME,
new String[]{Bowler.COLUMN_ID, Bowler.COLUMN_LEAGUE_ID, Bowler.COLUMN_NAME, Bowler.COLUMN_BOWLER_AVERAGE, Bowler.COLUMN_BOWLER_HANDICAP, Bowler.COLUMN_TIMESTAMP},
Bowler.COLUMN_LEAGUE_ID + "=?",
new String[]{String.valueOf(leagueId)}, null, null, null, null);
Bowler bowler = null;
if (cursor.moveToFirst()) {
//Prepare Bowler Object
bowler = new Bowler(
cursor.getInt(cursor.getColumnIndex(Bowler.COLUMN_ID)),
cursor.getString(cursor.getColumnIndex(Bowler.COLUMN_LEAGUE_ID)),
cursor.getString(cursor.getColumnIndex(Bowler.COLUMN_NAME)),
cursor.getString(cursor.getColumnIndex(Bowler.COLUMN_BOWLER_AVERAGE)),
cursor.getString(cursor.getColumnIndex(Bowler.COLUMN_BOWLER_HANDICAP)),
cursor.getString(cursor.getColumnIndex(Bowler.COLUMN_TIMESTAMP)));
//Close Database Connection
cursor.close();
return bowler;
} else {
return bowler;
}
}
public List<Bowler> getAllBowlers(String leagueId) {
List<Bowler> bowlers = new ArrayList<>();
//Select All Query
String selectQuery = "SELECT * FROM " + Bowler.TABLE_NAME + " WHERE " + Bowler.COLUMN_LEAGUE_ID + " = '" + leagueId + "'" + " ORDER BY " +
Bowler.COLUMN_TIMESTAMP + " DESC";
Log.d("GETALLBOWLERS-SQL","SQL used = >>>>" +selectQuery + "<<<<");
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
Log.d("GETALLBOWLERS-CNT","Number of rows retrieved = " + String.valueOf(cursor.getCount()));
//Looping Through All Rows And Adding To The List
if (cursor.moveToFirst()) {
do {
Bowler bowler = new Bowler();
bowler.setId(cursor.getInt(cursor.getColumnIndex(Bowler.COLUMN_ID)));
bowler.setLeagueId(cursor.getString(cursor.getColumnIndex(Bowler.COLUMN_LEAGUE_ID)));
bowler.setName(cursor.getString(cursor.getColumnIndex(Bowler.COLUMN_NAME)));
bowler.setAverage(cursor.getString(cursor.getColumnIndex(Bowler.COLUMN_BOWLER_AVERAGE)));
bowler.setHandicap(cursor.getString(cursor.getColumnIndex(Bowler.COLUMN_BOWLER_HANDICAP)));
bowler.setTimestamp(cursor.getString(cursor.getColumnIndex(Bowler.COLUMN_TIMESTAMP)));
bowlers.add(bowler);
} while (cursor.moveToNext());
}
cursor.close();
//Close Database Connection
db.close();
Log.d("GETALLBOWLERS-CNT","Number of elements in bowlerslist = " + String.valueOf(bowlers.size()));
//Return Bowlers List
return bowlers;
}
public int getBowlersCount() {
String countQuery = "SELECT * FROM " + Bowler.TABLE_NAME;
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery(countQuery, null);
int count = cursor.getCount();
cursor.close();
//Return The Count
return count;
}
public int updateBowler(Bowler bowler) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(Bowler.COLUMN_LEAGUE_ID, bowler.getLeagueId());
values.put(Bowler.COLUMN_NAME, bowler.getName());
values.put(Bowler.COLUMN_BOWLER_AVERAGE, bowler.getAverage());
//Updating Row
return db.update(Bowler.TABLE_NAME, values, Bowler.COLUMN_ID + " = ?",
new String[]{String.valueOf(bowler.getId())});
}
public void deleteBowler(Bowler bowler) {
SQLiteDatabase db = this.getWritableDatabase();
db.delete( Bowler.TABLE_NAME, Bowler.COLUMN_ID + " = ?",
new String[]{String.valueOf( bowler.getId())});
db.close();
}
I am hoping that someone will be able to point out what I am doing incorrectly in order to fix this issue.
If any additional information is need please let me know and I will post it.
I have figured out why all my new bowler entries have an id of 2. In my edit Bowler Profile Activity I have the following : leagueId = String.valueOf(getIntent().getIntExtra("leagueId",2)); The default value is 2 and because I was not grabbing the information being passed to the new Activity in the proper manner the app was always using 2 as the BowlerId.
I changed the code that was capturing the information from the intent to the following:
Intent intent = getIntent();
leagueId = intent.getStringExtra("leagueId");
With this change I was able to capture all the bowlers that belong to a particular league. I only realized that I was passing the information incorrectly after reading through the following post:
Pass a String from one Activity to another Activity in Android

Mutiple Contact Picker not working in Android api level less than 17

I have a code to read the contacts from the inbuilt phone contacts and it displays all the contacts in a list view in my app.The user can select multiple contacts and display them in another activity.
This code works fine in Android API level 18 and above,but gives an error in the versions below API 18.
I'm attaching the code of the contact picker activity and its adapter.
Error Logcat
private void getSelectedContacts() {
// TODO Auto-generated method stub
StringBuffer sb = new StringBuffer();
dataBase=mHelper.getWritableDatabase();
ContentValues values=new ContentValues();
for (ContactObject bean : ContactsListClass.phoneList) {
if (bean.isSelected()) {
sb.append(bean.getName());
sb.append(bean.getNumber());
sb.append("1");
values.put(DbHelper.KEY_FNAME,bean.getName());
values.put(DbHelper.KEY_LNAME,bean.getNumber() );
values.put(DbHelper.KEY_INVITE,"1" );
dataBase.insert(DbHelper.TABLE_NAME, null, values);
}
}
dataBase.close();
String s = sb.toString().trim();
if (TextUtils.isEmpty(s)) {
Toast.makeText(context, "Select atleast one Contact",
Toast.LENGTH_SHORT).show();
} else {
s = s.substring(0, s.length() - 1);
/**
Toast.makeText(context, "Selected Contacts : " + s,
Toast.LENGTH_SHORT).show();
**/
Intent i = new Intent(Contacts_main.this, MainActivity.class);
i.putExtra("NAME", name);
i.putExtra("EVT_Name", event_name);
i.putExtra("EVT_Date", event_date);
startActivity(i);
}
}
private void addContactsInList() {
// TODO Auto-generated method stub
Thread thread = new Thread() {
#Override
public void run() {
showPB();
try {
Cursor phones = getContentResolver().query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null, null, null, null);
try {
ContactsListClass.phoneList.clear();
} catch (Exception e) {
}
while (phones.moveToNext()) {
String phoneName = phones
.getString(phones
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
String phoneNumber = phones
.getString(phones
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
String phoneImage = phones
.getString(phones
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.CONTACT_ID));
//String pImage =
ContactObject cp = new ContactObject();
cp.setName(phoneName);
cp.setNumber(phoneNumber);
cp.setImage(phoneImage);
//cp.setImage(getResources(R.drawable.prof_active));
ContactsListClass.phoneList.add(cp);
}
phones.close();
lv = new ListView(context);
lv.setDividerHeight(0);
lv.setDivider(null);
lv.setLayoutParams(new LayoutParams(
LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT));
runOnUiThread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
llContainer.addView(lv);
}
});
Collections.sort(ContactsListClass.phoneList,
new Comparator<ContactObject>() {
#Override
public int compare(ContactObject lhs,
ContactObject rhs) {
return lhs.getName().compareTo(
rhs.getName());
}
});
objAdapter = new ContactsAdapter(Contacts_main.this,
ContactsListClass.phoneList);
lv.setAdapter(objAdapter); //ERROR SHOWING HERE
lv.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent,
View view, int position, long id) {
CheckBox chk = (CheckBox) view
.findViewById(R.id.contactcheck);
ContactObject bean = ContactsListClass.phoneList
.get(position);
if (bean.isSelected()) {
bean.setSelected(false);
chk.setChecked(false);
} else {
bean.setSelected(true);
chk.setChecked(true);
}
}
});
} catch (Exception e) {
// e.printStackTrace();
//Toast.makeText(context, "Crash",Toast.LENGTH_SHORT).show();
}
hidePB();
}
};
thread.start();
}
Adapter Class:
Context mContext;
LayoutInflater inflater;
private List<ContactObject> mainDataList = null;
private List<ContactObject> mainInviteesList = null;
private ArrayList<ContactObject> arraylist;
private DbHelper mHelper;
private SQLiteDatabase dataBase;
public ContactsAdapter(Context context, List<ContactObject> mainDataList) {
mContext = context;
this.mainDataList = mainDataList;
inflater = LayoutInflater.from(mContext);
this.arraylist = new ArrayList<ContactObject>();
this.arraylist.addAll(mainDataList);
mHelper=new DbHelper(context);
}
static class ViewHolder {
protected TextView name;
protected TextView number;
protected CheckBox check;
protected ImageView image;
protected EditText invitees;
}
#Override
public int getCount() {
return mainDataList.size();
}
#Override
public ContactObject getItem(int position) {
return mainDataList.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
public View getView(final int position, View view, ViewGroup parent) {
final ViewHolder holder;
if (view == null) {
holder = new ViewHolder();
view = inflater.inflate(R.layout.list_row, null);
holder.name = (TextView) view.findViewById(R.id.contactname);
holder.number = (TextView) view.findViewById(R.id.contactno);
holder.check = (CheckBox) view.findViewById(R.id.contactcheck);
holder.image = (ImageView) view.findViewById(R.id.contactimage);
holder.invitees = (EditText) view.findViewById(R.id.editInvites);
view.setTag(holder);
view.setTag(R.id.contactname, holder.name);
view.setTag(R.id.contactno, holder.number);
view.setTag(R.id.contactcheck, holder.check);
view.setTag(R.id.editInvites, holder.invitees);
holder.check
.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton vw,
boolean isChecked) {
int getPosition = (Integer) vw.getTag();
mainDataList.get(getPosition).setSelected(
vw.isChecked());
/**
dataBase=mHelper.getWritableDatabase();
ContentValues values=new ContentValues();
values.put(DbHelper.KEY_FNAME,mainDataList.get(getPosition).getName());
values.put(DbHelper.KEY_LNAME,mainDataList.get(getPosition).getNumber());
values.put(DbHelper.KEY_INVITE,"1" );
dataBase.insert(DbHelper.TABLE_NAME, null, values);
dataBase.close();
**/
}
});
// holder.invitees.addTextChangedListener(watcher);
} else {
holder = (ViewHolder) view.getTag();
}
holder.check.setTag(position);
//holder.invitees.setTag(position);
holder.name.setText(mainDataList.get(position).getName());
holder.number.setText(mainDataList.get(position).getNumber());
if(getByteContactPhoto(mainDataList.get(position).getImage())==null){
holder.image.setImageResource(R.drawable.prof_active);
}else{
holder.image.setImageBitmap(getByteContactPhoto(mainDataList.get(position).getImage()));
}
holder.check.setChecked(mainDataList.get(position).isSelected());
return view;
}
public void filter(String charText) {
charText = charText.toLowerCase(Locale.getDefault());
mainDataList.clear();
if (charText.length() == 0) {
mainDataList.addAll(arraylist);
} else {
for (ContactObject wp : arraylist) {
if (wp.getName().toLowerCase(Locale.getDefault())
.contains(charText)) {
mainDataList.add(wp);
}
}
}
notifyDataSetChanged();
}
public Bitmap getByteContactPhoto(String contactId) {
Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, Long.parseLong(contactId));
Uri photoUri = Uri.withAppendedPath(contactUri, Contacts.Photo.CONTENT_DIRECTORY);
Cursor cursor = mContext.getContentResolver().query(photoUri,
new String[] {Contacts.Photo.DATA15}, null, null, null);
if (cursor == null) {
return null;
}
try {
if (cursor.moveToFirst()) {
byte[] data = cursor.getBlob(0);
if (data != null) {
return BitmapFactory.decodeStream( new ByteArrayInputStream(data));
}
}
} finally {
cursor.close();
}
return null;
}
}

Categories