So I have used Cursor in my application to retrieve all tracks from the storage. The problem is that it is returning only one track not all the tracks. The code is perfect and no errors. Even I have tried accessing the ArrayList in which I am retrieving and storing all the tracks. The ArrayList's size is 1 instead of many. I am attcahing the code below:
private void Encrypt() {
Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
Cursor cursor = getContentResolver().query(uri, null, null, null, null);
if(cursor!= null && cursor.moveToFirst()){
int TrackTitle = cursor.getColumnIndex(MediaStore.Audio.Media.TITLE);
int Artist = cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST);
int Path = cursor.getColumnIndex(MediaStore.Audio.Media.DATA);
do{
String Tracktitle = cursor.getString(TrackTitle);
String Trackartist = cursor.getString(Artist);
String Trackpath = cursor.getString(Path);
arrayList = new ArrayList<CustomListView>();
arrayList.add(new CustomListView(R.drawable.none, Tracktitle, Trackartist, Trackpath));
CustomListViewAdapter customListViewAdapter = new CustomListViewAdapter(this, arrayList);
tracks.setAdapter(customListViewAdapter);
tracks.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
}
});
}while (cursor.moveToNext());
What the heck is wrong with code??
You are creating a new ArrayList in each loop, move this line out of your do-while loop:
arrayList = new ArrayList<CustomListView>();
do {
...
Related
I have a list of Leagues that that I want to display the number of bowlers for in each entry. For Example:
I want to display a count of the number of bowlers in each list under each League name in the list. For Example:
This is meant to be a quick view about each League.
I tried to accomplish this with the following code:
DatabaseHelper
//Getting Number of Bowlers in League
public String leagueBowlerCount(String leagueId)
{
SQLiteDatabase db = this.getReadableDatabase();
String countQuery = "SELECT * FROM " + Bowler.TABLE_NAME + " WHERE " + Bowler.COLUMN_LEAGUE_ID + " = '" + leagueId + "'";
Cursor cursor = db.rawQuery(countQuery, null);
int count = 0;
if(null != cursor)
if(cursor.getCount() > 0){
cursor.moveToFirst();
count = cursor.getInt(0);
}
cursor.close();
db.close();
return String.valueOf(count);
}
League Adapter
public class MyViewHolder extends RecyclerView.ViewHolder {
public TextView id;
public TextView name;
public TextView baseScore;
public TextView basePercentage;
public TextView bowlerCount;
TextView timestamp;
public TextView buttonViewOption;
MyViewHolder(View view) {
super(view);
if (!(itemView instanceof AdView)) {
id = view.findViewById( R.id.tvLeagueId);
name = view.findViewById(R.id.tvLeagueName );
baseScore = view.findViewById( R.id.tvBaseScore);
basePercentage = view.findViewById(R.id.tvBaseScorePercentage);
bowlerCount = view.findViewById(R.id.tvNumberOfBowlers);
timestamp = view.findViewById(R.id.timestamp);
buttonViewOption = view.findViewById(R.id.buttonViewOptions);
}
}
}
public LeagueAdapter(Context context, List<League> leaguesList) {
this.context = context;
this.leaguesList = leaguesList;
mainActivity = (Activity) context;
inflater = LayoutInflater.from(context);
}
public LeagueAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
AdView adview;
MyViewHolder holder;
if (viewType == AD_TYPE) {
adview = new AdView(mainActivity);
adview.setAdSize( AdSize.BANNER);
// this is the good adview
adview.setAdUnitId(mainActivity.getString(R.string.admob_ad_id));
float density = mainActivity.getResources().getDisplayMetrics().density;
int height = Math.round(AdSize.BANNER.getHeight() * density);
AbsListView.LayoutParams params = new AbsListView.LayoutParams(AbsListView.LayoutParams.MATCH_PARENT, height);
adview.setLayoutParams(params);
// dont use below if testing on a device
// follow https://developers.google.com/admob/android/quick-start?hl=en to setup testing device
AdRequest request = new AdRequest.Builder().build();
adview.loadAd(request);
holder = new MyViewHolder(adview);
}else{
View view = inflater.inflate(R.layout.listview_league, parent, false);
holder = new MyViewHolder(view);
}
return holder;
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
if(position % 10 != 5) {
League league = leaguesList.get(position);
int id = league.getId();
String leagueId = String.valueOf(id);
holder.id.setText(leagueId);
holder.name.setText(league.getName());
holder.baseScore.setText(league.getBasisScore());
holder.basePercentage.setText(league.getBaseScorePercentage());
holder.bowlerCount.setText(db.leagueBowlerCount(leagueId));
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();
((MainActivity) context).openDialog(true, leaguesList.get(position), position);
break;
case R.id.delete:
((MainActivity) context).deleteLeague(position);
break;
}
return false;
}
});
//displaying the popup
popup.show();
}
});
}
}
I have been messing around with this for a number of days, I cannot figure out why this will not work. Any assistance would be greatly appreciated. I am thinking that there is probably a much easier way of accomplishing this that I am not aware of.
In the logcat I am seeing the following message:
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String ca.vogl.r.tenpinbowlingcompanion.database.DatabaseHelper.leagueBowlerCount(java.lang.String)' on a null object reference.
As was pointed out below, the error seems to be happening in leagueBowlerCount(), which is listed above.
After making making the following addition to the onBindViewHolder : db = new DatabaseHelper (mainActivity). I am seeing values where I should be but they are not correct. See images below.
Test League 1 (there are three bowlers, one is hidden by the test ad)
Test League 2 (there is only 1 bowler)
Test League 3 (there are three bowlers, one is hidden by the test ad)
So basically you should be seeing a 3 for Test League 1, a 1 for Test League 2 and a 3 for Test League 3
So it now seems that the problem is with the leagueBowlercount function that I wrote. It is not getting the counts that are associated only to the individual league Id
I believe that your issue is that you are returning the id of the first selected bowler rather than the row count.
That is you, after checking the number of rows is greater than 0, move to the first row and then use count = cursor.getInt(0); which will be the value stored in the first column of the first row that has been extracted.
try using :-
public String leagueBowlerCount(String leagueId)
{
String rv = "0";
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.query(Bowler.TABLE_NAME,new String[]{"count(*)"},Bowler.COLUMN_LEAGUE_ID + "=?",new String[]{leagueId},null,null,null);
if (cursor.moveToFirst()) {
rv = String.valueOf(cursor.getLong(0));
}
cursor.close();
db.close();
return rv;
}
This uses the aggregate function count to extract the number of rows for the respective league.
Note the above code is in-principle code, it has not been tested or run and may therefore have some errors.
Alternatively you could use :-
public String leagueBowlerCount(String leagueId)
{
SQLiteDatabase db = this.getReadableDatabase();
String countQuery = "SELECT * FROM " + Bowler.TABLE_NAME + " WHERE " + Bowler.COLUMN_LEAGUE_ID + " = '" + leagueId + "'";
Cursor cursor = db.rawQuery(countQuery, null);
int count = cursor.getCount();
cursor.close();
db.close();
return String.valueOf(count);
}
In regard to your code :-
int count = 0;
if(null != cursor)
if(cursor.getCount() > 0){
cursor.moveToFirst();
count = cursor.getInt(0);
}
cursor.close();
Checking for a null Cursor is useless, as a Cursor returned from an SQLiteDatabase method, such as rawQuery, will never be null. Instead a valid, perhaps empty, Cursor will be returned.
Additionally checking if a Cursor has rows using the getCount method and then using moveToFirst is not needed as just using if (cursor.moveToFirst) {.....} is sufficient as if there are no rows the moveToFirst method will return false, as the move cannot be actioned.
I have a Spinner I'm filling with a ArrayAdapter objects, but i need that first position of this Array Always be null or appear something like "Select an object". I searched here Forums but without success, solutions for ArrayList String or spinner.setPrompt that did not work =/
ArrayList<Object> objects = null;
objects= findMyObjects();
final ArrayAdapter<Object> adapterObjects = new ArrayAdapter<Object>(contexto, R.layout.spinner_item, objects);
mySpinner = (Spinner) viewPai.findViewById(R.id.s_spinner);
mySpinner.setAdapter(adapterObjects);
adapterObjects.notifyDataSetChanged();
mySpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
}
#Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
});
public ArrayList<Object> findMyObjects() {
allObjects = new ArrayList<Object>();
Cursor cursor;
String sql = "SELECT * FROM Object; ";
cursor = database.rawQuery(sql, null);
if (cursor.getCount() >= 0) {
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
Objects object = new Objects();
object.setId(cursor.getLong(0));
allObjects.add(object);
cursor.moveToNext();
}
}
cursor.close();
return allObjects;
}
You can try this example.
link : http://android--code.blogspot.in/2015/08/android-spinner-hint.html
Quick
Make a dummy object then when put in the adapter displays = "Select an object"
Bit longer
Extend the arrayadapter or the view in which you are placing your values so that the first object is always a text saying "Select an object".
Im struggling with a bit of my code for my database, I have managed to access the id number of the item i click however i cannot access any more of the data? How can i do this?
For example now i have my id number i want to display all of that data on that row in a seperate window but i cant seem to pull the data with the cursor
String itemselect = String.valueOf(spinner.getSelectedItem());
Toast.makeText(Developer.this, itemselect, Toast.LENGTH_LONG).show();
final Cursor cursor = mydb.getAllRows(itemselect);
startManagingCursor(cursor);
String[] fromfieldnames = new String[]{
DatabaseHelper.COL_1, DatabaseHelper.COL_2, DatabaseHelper.COL_3,
DatabaseHelper.COL_4, DatabaseHelper.COL_5, DatabaseHelper.COL_6 };
int[] toviewids = new int[]{R.id.textone, R.id.texttwo, R.id.textthree, R.id.textfour, R.id.textfive, R.id.textsix};
final SimpleCursorAdapter mycursoradapter = new SimpleCursorAdapter(this, R.layout.listtext, cursor, fromfieldnames, toviewids);
listView.setAdapter(mycursoradapter);
listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
Long string = mycursoradapter.getItemId(position);
Toast.makeText(Developer.this, string.toString(),Toast.LENGTH_LONG).show();
return true;
}
});
There are no errors in this code I just need to try and add this extra functionality
Thanks in advance M.
The data is stored in your Cursor at the row position position in onItemLongClick. Use the moveToPosition() method on cursor, and retrieve the values:
String one, two, three;
listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
cursor.moveToPosition(position);
one = cursor.getString(cursor.getColumnIndex(DatabaseHelper.COL_1));
two = cursor.getString(cursor.getColumnIndex(DatabaseHelper.COL_2));
// Etc...
}
};
use the cursor in the following way:
public Cursor getRowByID(int ID) {
SQLiteDatabase db = this.getReadableDatabase();
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
String [] sqlSelect = {"id, col_1, col_2, col_3"};
String sqlTables = "your_table";
String filter = "id= "+ID;
qb.setTables(sqlTables);
Cursor c = qb.query(db, sqlSelect, filter,null, null,
null, null, null);
c.moveToFirst();
return c;
}
public Cursor Retrive_SubCategory1(String id) {
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery("select "
+ "column_Name1 , "+"column_name2 " + " from "
+"table_name " + " where "
+ "column_name " + "='" + id+ "'",
null);
return cursor;
}
I'm trying to group of several ArrayLists for a music player. The current list generates the artists for every song instead of just the one artist. Hopefully this should explain it better:
My current code for one of my fragments is this:
public class ArtistsFragment extends Fragment {
private ArrayList<Artist> artistList;
View view;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_artists, container, false);
GridView gvArtists = (GridView) view.findViewById(R.id.gvArtists);
//instantiate list
artistList = new ArrayList<>();
//get artists from device
getArtistList();
// Group ArrayList..
artistList = new ArrayList<>(new HashSet<>(artistList));
//sort alphabetically by title
Collections.sort(artistList, new Comparator<Artist>() {
public int compare(Artist a, Artist b) {
return a.getArtist().compareTo(b.getArtist());
}
}
);
//create and set adapter
ArtistAdapter artistAdt = new ArtistAdapter(getActivity(), artistList);
gvArtists.setAdapter(artistAdt);
return view;
}
void getArtistList() {
//retrieve artist info
ContentResolver musicResolver = getActivity().getContentResolver();
Uri musicUri = android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
Cursor musicCursor = musicResolver.query(musicUri, null, null, null, null);
if (musicCursor != null && musicCursor.moveToFirst()) {
//get columns
int idColumn = musicCursor.getColumnIndex
(MediaStore.Audio.Media._ID);
int artistColumn = musicCursor.getColumnIndex
(MediaStore.Audio.Albums.ARTIST);
int artColumn = musicCursor.getColumnIndex
(MediaStore.Audio.Media.ARTIST_ID);
//add artists to list
do {
long thisId = musicCursor.getLong(idColumn);
String thisArtist = musicCursor.getString(artistColumn);
String thisArt = musicCursor.getString(artColumn);
artistList.add(new Artist(thisId, thisArtist, thisArt));
}
while (musicCursor.moveToNext());
musicCursor.close();
}
}
}
Artist.class
class Artist {
private final long id;
private final String artist;
private final String art;
public Artist(long artistID, String theartist, String artistArt) {
id = artistID;
artist = theartist;
art = artistArt;
}
public long getID() {
return id;
}
public String getArtist() {
return artist;
}
public String getArt() {
return art;
}
}
I've looked at Map, I've looked at Set and now i'm just confused...
So, how do I group my ArrayList to remove the duplicates of different artists to then eventually use the OnPicked to change the ArrayList to those grouped songs within that group/category?
Am I even on the right lines or is there a completely different method to sorting Genres/Artists/Albums Etc.?
if clearing your duplicates is your sole problem, then this is how to clear all duplicates on your List (convert it to a Set and back):
Set<Artist> set = new HashSet<Artist>(artistList);
artistList = new ArrayList<Artist>(set);
//then sort it...
or one-line
artistList = new ArrayList<Artist>(new HashSet<Artist>(artistList));
You should also override the equals() and hashCode() methods based on the fields that make an entry to your list unique.
I hate a list created by simple cursor adapter:
Cursor c = myDbHelper.rawQ(select);
startManagingCursor(c);
// the desired columns to be bound
String[] columns = new String[] { "Books.BookTitle",
"Publishers.Publisher" };
// the XML defined views which the data will be bound to
int[] to = new int[] { R.id.ISBN_entry, R.id.Title_entry };
// Getting results into our listview
try {
SimpleCursorAdapter mAdapter = new SimpleCursorAdapter(this,
R.layout.listlayout, c, columns, to);
this.setListAdapter(mAdapter);
} catch (Exception e) {
}
The layout involved with the list are two simple textviews.
What i want to do is create a listener
#Override
protected void onListItemClick(ListView l, View v, int position, long id) {
The part im failing at is retrieving the BookTitle part of the specific entry(row) in order to requery the database and present the data with AlertDialog.Builder.
When i try doing :
String selection = l.getItemAtPosition(position).toString();
i'm only getting android.database.sqlite SQLiteCursor#44f99e80 and im rather confused on how this should be done (I know why it's crashign just can;t get my mind around on how it should be done properly.
Full code atm:
...
Cursor c = myDbHelper.rawQ(select);
startManagingCursor(c);
// the desired columns to be bound
String[] columns = new String[] { "Books.BookTitle",
"Publishers.Publisher" };
// the XML defined views which the data will be bound to
int[] to = new int[] { R.id.ISBN_entry, R.id.Title_entry };
// Getting results into our listview
try {
SimpleCursorAdapter mAdapter = new SimpleCursorAdapter(this,
R.layout.listlayout, c, columns, to);
this.setListAdapter(mAdapter);
} catch (Exception e) {
}
}
#Override
protected void onListItemClick(ListView l, View v, int position, long id) {
// TODO Auto-generated method stub
//super.onListItemClick(l, v, position, id);
String selection = l.getItemAtPosition(position).toString();
new AlertDialog.Builder(v.getContext())
.setTitle("Title")
.setMessage(selection)
.setPositiveButton(android.R.string.ok, null)
.show();
} }
Try something like this...
Cursor theCursor = ((SimpleCursorAdapter)((ListView)l).getAdapter()).getCursor();
String selection = theCursor.getString(theCursor.getColumnIndex("Books.BookTitle"));
Just get the data from the cursor:
l.getItemAtPosition(position).getString(0); // it might be 1
See here.