I have a query in my android app that pulls all image paths from a custom table and displays them to a gallery. The problem is with my database I cant seem to get a row of the database to a String[]. I can easily get the results to a listArray but I need the image path in a string or string array. I want to be able to click on an image in the gallery and have it pull up full screen to be able to zoom in on it or delete it etc. This is the basic query i use
public void listimages() {
SimpleCursorAdapter adapter;
String[] columns = {"Image", "ImageDate", "_id"};
query = new TableImages(this);
queryString = query.getData("images", columns, null, null, null, null, "ImageDate", "DESC");
int to[] = {R.id._id1, R.id._id2};
adapter = new SimpleCursorAdapter(this, R.layout.imagelist, queryString, columns, to);
Gallery g = (Gallery) findViewById(R.id.gallery);
g.setAdapter(adapter);
g.setOnItemClickListener(this);
try {
query.destroy();
} catch (Throwable e) {
e.printStackTrace();
}
}
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent i = new Intent(ViewAllImages.this, ImageViewer.class);
Bundle b = new Bundle();
//I want to be able to use this -> b.putString("image_path", Image);
b.putlong("id", id);
i.putExtras(b);
startActivity(i);
}
This passes the ID to my next activity and the next activity queries the DB pulling that one image path. I still have to use a listview to display the image which makes the app crash on the phone due to memory usage (image is too large).
I can compress the image but I need the path as a string and I cant figure out how to do that without creating a custom content provider or adding a textview and using gettext.toString and thats just getto. My head is killing me as it is with all the reading and coding I have done lol. I have searched all over Google and different forums but I am having problems finding an answer.
Is there a way to use the existing query and get a string or a string array as the result?
Thanks.
I just ended up building a custom content provider. Now I have alot more flexability in my queries.
Related
After countless hours of watching YouTube videos and tutorials, and reading up on info and advice, I've come to the conclusion that doing a bible app by using a SQLite database is the way to go.
I've got no knowledge of coding whatsoever and just by taking bits and pieces of tutorial code and advice from someone I've got this far, so please be specific when answering.
I've now created 3x tables.
table_book, table_chapter, and table_verse.
The tables are in one database.
The database gets installed with oncreate when the first Activity is clicked to open.
table_book has 2x columns _id, book_name
table_chapter has 3x columns, _id, id_of_book, chapter_number
table_verse has 4x columns, _id, id_of_chapter, verse_number, verse_text
Furthermore,
I've got 3x Activities, 1 for each table
I've got 3x DBClasses, 1 for each table
I've got 3x DBHandlers, 1 for each table
I've got 3x Adapters, 1 for each table
The idea is that when you open the app and call the class to open the bible, it opens the book class and has a ListView, in the listview is all the bible books, when clicked, it should open the chapter activity and in its ListView display all the book's chapters, when selecting a chapter it should open the verse Activity and in its ListView display all the verses.
So far, the book Activity displays the book names, but when I click on it, it only displays a white screen...
Nothing shows errors in the logcat.
I think I might be messing something up in the way the Activity sends the selected info to the new Activity to open the new ListView?
How should this code look like?
Currently it's like this in the book class:
//Get bible list in db when db exists
DBClassBibledbBookList= DBHelperBook.getListBible();
//Init adapter
adapter_customAdapterBooktext = new customAdapterBooktext(this, DBClassBibledbBookList);
//Set adapter for listview
listviewBible.setAdapter(adapter_customAdapterBooktext);
#Override
public void onItemClick (AdapterView<?> arg0, View view, int arg2, long arg3){
//on selecting a book
//BookActivity will be launched to show chapters inside
Intent bookid = new Intent (getApplicationContext(), ChapterActivity.class);
//send book_id to ChapterActivity to get chapters under that book
String book_id = ((TextView)view.findViewById(R.id.book_id)).getText().toString();
bookid.putExtra("book_id", book_id);
startActivity(bookid );
}
}
);
And in the chapter Activity:
//Get bible list in db when db exists
DBClassBibledbChapterList = DBHelperChapter.getListChapter();
//Init adapter
adapter_customAdapterChaptertext = new customAdapterChaptertext (this,DBClassBibledbChapterList );
//Set adapter for listview
listviewChapter.setAdapter(customAdapterChaptertext );
//Get book id
Intent i = getIntent();
book_id = i.getStringExtra("book_id");
//hashmap for listview
ChapterList = new ArrayList<HashMap<String, String>>();
listviewChapter.setOnItemClickListener(new android.widget.AdapterView.OnItemClickListener(){
#Override
public void onItemClick (AdapterView<?> arg0, View view, int arg2, long arg3){
//on selecting chapter get verse text
Intent chapterid = new Intent(getApplicationContext(),BibleActivityVerse.class);
//to get verse both book_id and chapter_id is needed
String book_id = ((TextView) view.findViewById(R.id.book_id)).getText().toString();
String chapter_id = ((TextView)view.findViewById(R.id.chapter_id)).getText().toString();
chapterid.putExtra("book_id", book_id);
chapterid.putExtra("chapter_id", chapter_id);
startActivity(chapterid);
}
});
The DBClass:
public List<DBClassBibledbChapter> getListChapter(){
DBClassBibledbChapter DBClassBibledbChapter = null;
List<DBClassBibledbChapter> DBClassBibledbChapterList = new ArrayList<>();
opendatabase();
Cursor cursor = mDatabase.rawQuery("SELECT * FROM table_chapter", null);
cursor.moveToFirst();
while (!cursor.isAfterLast()){
DBClassBibledbChapter = new DBClassBibledbChapter (cursor.getInt(0), cursor.getInt(1),cursor.getInt(2));
DBClassBibledbChapterList.add(DBClassBibledbChapter);
cursor.moveToNext();
}
cursor.close();
closeDatabase();
return DBClassBibledbChapterList;
Just try to get the book_id from your list of the DBClassBibledbBookList arraylist on the onItemClick listener as below and then pass it to another activity.
Also check you get the correct book id on your ChapterActivity and fetch the list of chapters from the table_chapter based on the book id from your database.
//Set adapter for listview
listviewBible.setAdapter(adapter_customAdapterBooktext);
#Override
public void onItemClick (AdapterView<?> arg0, View view, int arg2, long arg3){
//on selecting a book
//BookActivity will be launched to show chapters inside
Intent bookid = new Intent (getApplicationContext(), ChapterActivity.class);
//send book_id to ChapterActivity to get chapters under that book
String book_id = DBClassBibledbBookList.get(arg2).getbook_id().toString();
bookid.putExtra("book_id", book_id);
startActivity(bookid );
}
});
Check out the String book_id in the above code.
Hope this will help you.
So far, the book activity displays the book names, but when I click on it, it only displays a white screen...
I think I might be messing something up in the way the activity sends the selected info to the new activity to open the new listview? How should this code look like?
You probably want to get the chapters by a certain book, yes?
So, do this
//Get book id
Intent i = getIntent();
book_id = i.getStringExtra("book_id");
Then use that ID to query the database in a way that gets the chapters
//Get bible list in db when db exists
chapterList = DBHelperChapter.getListChapter(book_id);
//Init adapter
chapterAdapter = new customAdapterChaptertext (this, chapterList);
//Set adapter for listview
listviewChapter.setAdapter(chapterAdapter);
Where DBHelperChapter.getListChapter(book_id) could return the results of this query
mDatabase.rawQuery("SELECT * FROM table_chapter WHERE id_of_book = " + book_id);
Sidenote: since you are using a SQLite database, I may suggest trying to look into using a CursorAdapter rather than an ArrayAdapter for loading a ListView
I am trying to load images and show them as a gallery in the form of list.
The problem is that I am able to do it from default android gallery, but I don't know how to do t for custom folder. for e.g /Pictures folder. I have been trying, here is the code that I use for default gallery, I want it for some other folder, e.g /Pictures/Col.
public static List<PhotoItem> getAlbumThumbnails(Context context){
final String[] projection = {MediaStore.Images.Thumbnails.DATA, MediaStore.Images.Thumbnails.IMAGE_ID};
Cursor thumbnailsCursor = context.getContentResolver().query( MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI,
projection, // Which columns to return
null, // Return all rows
null,
null);
// Extract the proper column thumbnails
int thumbnailColumnIndex = thumbnailsCursor.getColumnIndex(MediaStore.Images.Thumbnails.DATA);
ArrayList<PhotoItem> result = new ArrayList<PhotoItem>(thumbnailsCursor.getCount());
if (thumbnailsCursor.moveToFirst()) {
do {
// Generate a tiny thumbnail version.
int thumbnailImageID = thumbnailsCursor.getInt(thumbnailColumnIndex);
String thumbnailPath = thumbnailsCursor.getString(thumbnailImageID);
Uri thumbnailUri = Uri.parse(thumbnailPath);
Uri fullImageUri = uriToFullImage(thumbnailsCursor,context);
// Create the list item.
PhotoItem newItem = new PhotoItem(thumbnailUri,fullImageUri);
result.add(newItem);
} while (thumbnailsCursor.moveToNext());
}
thumbnailsCursor.close();
return result;
}
What all should I change here, I tried to change projection, query parameters but failed, new in this field, please help :)
You can custom recent-images library for your purpose. It's very simple and easy to use library.
Sorry for such an open-ended question, but I'm new to Android and I genuinely looked all over for an answer and couldn't find anything. I'm wanting to store some sort of information that references an image in a SQLite table, and then use a SimpleCursorAdapter to move that data to an ImageView. I thought that, if I store an integer (the resource ID) and then have the adapter set to the correct view, the resource of the view would be updated to that ID, but that didn't work. Is there any other way to do what I'm wanting to do?
Thanks in advance :)
Edit 1:
This is what I'm doing right now. I'm storing the drawable's ID in the table and then setting the SimpleCursorAdapter to a View whose resource I want to be the drawable. Here's the code I use to store the info:
ContentValues values = new ContentValues();
values.put(SubwayContract.ROUTE_IMG, R.drawable.red_circle);
values.put(SubwayContract.ROUTE, "R");
values.put(SubwayContract.FINAL_STATION, "Howard-Bound");
values.put(SubwayContract.ARRIVAL_TIME, "5:24:00");
final Uri uri = mContentResolver.insert(SubwayContract.CONTENT_URI, values);
The second line stores the image ID. Here's the code I have that sets the adapter:
private final int URL_LOADER = 0;
private String[] mProjections = {SubwayContract._ID, SubwayContract.ROUTE_IMG, SubwayContract.ROUTE, SubwayContract.FINAL_STATION, SubwayContract.ARRIVAL_TIME};
private int[] mTo = {R.id._id, R.id.arrival_icon, R.id.arrival_letter, R.id.arrival_dest, R.id.arrival_time};
private SimpleCursorAdapter mAdaptor = null;
...
getLoaderManager().initLoader(URL_LOADER, null, ArrivalsFragment.this);
ListView mListView = (ListView) rootView.findViewById(R.id.arrivals_list_view);
mAdaptor = new SimpleCursorAdapter(
rootView.getContext(),
R.layout.arrivals_list_item,
null,
mProjections,
mTo,
0
);
mListView.setAdapter(mAdaptor);
The View's ID is R.id.arrival_icon, which is a View. I know that there's no error in the cursor or the loader, as everything works fine if I take out the View and ID. How can I fix this?
You can save resource Id of the image (which is in drawable folder) into database.
You can try as below:
int resID = mContext.getResources().getIdentifier(image_name, "drawable", mContext.getPackageName());
i am reading the string of MediaStore.Images.Media.DATA from an ArrayList into an array so i can use the images from my SD card instead of the images in the R.drawable folder for a coverflow gallery app. and have run into a brick wall. with the problem of reading integer type vs. string type for image information.
was able to get the URIs from all the images from the SD card into the arraylist and don't know what is the next step to take.
is it worth continuing with this approach or is it better to abandon this and try another way to accomplish the task of changing the source of images for this coverflow app from the R.drawables folder to the SD card.
here is what i did
first, here is the way it gets the images from the R.drawable folder in android using an array as part of the process:
public class ImageAdapter extends BaseAdapter {
int mGalleryItemBackground;
private Context mContext;
private FileInputStream fis;
// private Integer[] mImageIds = {
// R.drawable.pic01,
// R.drawable.pic02,
// R.drawable.pic03,
// R.drawable.pic04,
// R.drawable.pic05,
// R.drawable.pic06,
// R.drawable.pic07,
// R.drawable.pic08,
// R.drawable.pic09
// };
private ImageView[] mImages;
my idea was to use a cursor to read the URIs like this "//mnt/sdcard/pic01.png" from the SD card and use these addresses instead of the ones in the array from the R.drawables like this "R.drawable.pic02" in the array.
this is what i did and this part worked with no problems:
i got all the URIs from the images on the SD card and stored them in an arrayList, so far everything works great. i verified that it works perfectly by using a Toast to show the loaded URIs on the activity screen.
ArrayList<String> list1 = new ArrayList<String>();
String[] proj = {MediaStore.Images.Media.DATA};
Cursor cur = getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, proj, null, null, null);
if (cur.getCount() > 0) {
while (cur.moveToNext()) {
String pic = cur.getString(cur.getColumnIndex(MediaStore.Images.Media.DATA));
list1.add(pic);
// Toast.makeText(CoverFlowExample.this, "data name: " + pic, Toast.LENGTH_SHORT).show();
// Log.d("TAG", "ID: " + pic);
}
}
cur.close();
next i tried to read these strings into the array used for the R.drawables array and this is where i got into trouble: the program uses Integer as the type for the array. so i guess this array is the wrong place to read URIs into. then if this is the wrong place. what to do now?
Integer[] mImageIds = new Integer[list1.size()];
for(int t = 0; t<= list1.size(); t++){
mImageIds[t]= list1.get(t); // type mismatch cannot convert string to integer
}
Toast.makeText(CoverFlowExample.this, "data name: " + y , Toast.LENGTH_SHORT).show();
the error i am getting is "type mismatch, cannot convert string to integer" for this part:
mImageIds[t]= list1.get(t);
here is the rest of the code from the getview part of the app: i am now trying to figure out what to do next.
public View getView(int position, View convertView, ViewGroup parent) {
//Use this code if you want to load from resources from external source
ImageView i = new ImageView(mContext);
// this method is what someone suggested to use but i don't know how to use this, what do i put for "image" and how to read URIs from arrayList to this?
i.setImageBitmap(BitmapFactory.decodeFile("image_" + position));
// this works for reading in only one image from the SD card into the coverflow app
i.setImageBitmap(BitmapFactory.decodeFile("/mnt/sdcard/pic04.png"));
// when getting from R.drawable images --> i.setImageResource(mImageIds[position]);
i.setLayoutParams(new CoverFlow.LayoutParams(130, 130));
i.setScaleType(ImageView.ScaleType.MATRIX);
return i;
//return mImages[position];
}
As you have the URIs / file system path already, you can use one of the createFrom* methods of Drawable java doc in android docu to have it loaded.
Here is what I am trying to do and would like some advice on the best methods to do it:
have a database that contains a word, and the name of an image file associated with that word.
the words from the database will be displayed in a listview
when the word is selected, a new activity will start displaying the word and the image in an image view.
Would it be best to store the terms in an array and have the list view populate from this array and then pull from the database onitemclick? Or can the list view be populated with the terms from the database?
Will android be able to display the image if the name of the file is stored in the db?
The best way to achieve what you're looking for is to store the term and image path in the DB, then use the path to fetch the image from whatever location you have put it in.
Images can be stored in the DB, but the general consensus is that it is better to store the image outside the DB and a path to said image in the DB.
Your DB can then be as simple as three columns... "_id", "term" and "term_image".
You can do a simple query to fetch all the info at once (thus only querying the DB once).
Then use the cursor returned by that query to populate your list of terms, and onListItemClick to start a new activity to display the associated image using the path from the list that is in the same record as the term from the list.
Query to fetch data:
public Cursor fetchAllTerms() {
return mDb.query(TERMS_TABLE, new String[] { "_id", "term", "term_img" }, null, null, null, null, null);
}
Using it in your list:
mTermCursor = mDbHelper.fetchAllTerms();
getActivity().startManagingCursor(mTermCursor);
String[] from = new String[] { YourDBClass.term };
int[] to = new int[] { android.R.id.Text1 };
SimpleCursorAdapter ranks = new SimpleCursorAdapter(getActivity(),
android.R.layout.simple_list_item_1, mRankCursor, from, to);
setListAdapter(ranks);
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
String imagePath = mTermCursor.getString(mTermCursor.getColumnIndexOrThrow("term");
// code to start your new activity and put the image path into the bundle to be passed
}