I'm using json for creating list of items. When user click it opens another screen with some detail about that item. I have problem with sending image to that activity. This is my code for json parsing:
for (int i = 0; i < data.length(); i++) {
JSONObject c = data.getJSONObject(i);
String id = c.getString(TAG_ID);
String name = c.getString(TAG_NAME);
String link_image = c.getString(TAG_LINK_IMAGE);
HashMap<String, String> map = new HashMap<String, String>();
map.put(TAG_ID_RS, id);
map.put(TAG_NAME, name);
map.put(TAG_LINK_IMAGE, link_image);
Data.add(map);
}
and this is for setOnItemClickListener:
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
String name_two = ((TextView) view
.findViewById(R.id.name)).getText()
.toString();
Intent i = new Intent(getApplicationContext(),
SingleItem.class);
i.putExtra("name", name_two);
startActivity(i);
}
In case of sending string "name" i am locating TextView and pulling string out of it, but what about image? Thanks.
Intent bundles aren't meant for passing large amounts of data. They are best used for small amounts of text, such as URIs, or something similar.
Without knowing where the images are coming from, I'm going to guess that they are images saved somewhere within your application's /res or cache directory.
If this is true, I'd say the best bet (if these activities are within the same application) is to just pass along the location of where the image is saved inside the Intent. That way you avoid encoding/decoding of the image through the Intent.
If the two activities are in separate applications. Then this is almost the canonical use case for a Content Provider.
Here are two other questions that are trying to do a similar thing Intent.putExtras size limit? and
Maximum length of Intent putExtra method? (Force close)
, and pass data in an intent. Both ended up with system hanging if you put too much data. I highly recommend NOT using the Application class as a data storage mechanism solution the first one recommends. Very bad Android design, and can lead to emergent errors down the road. Shared Preferences (for application wide settings) or Content Provider/local cached files for file transfer is a much more robust answer.
You have int position and you have a collection called Data
so you can use:
String link = Data.get(position).get(TAG_LINK_IMAGE);
Related
I hope you are good.
I'm developping an application that has to retrieve images from sqlite database, for each row I have one image (using obviously blob as a type), and I was wondering if I could not only add one image but a lot, without knowing how much images the user wants to add, for example: User1 wants to add 3 images to database. User2 5 images and so on. How can I store them? is there a kind of Blob[] or something? And if possible how can I choose more than one image from galery?
I'm not used to make posts in english so I hope I explained well ^^'.
Thank you.
Save the images in a list as base64 strings like:
String img1 = Base64.encode(value_of_image, Base64.DEFAULT);
.
.
.
String img25 = Base64.encode(value_of_image, Base64.DEFAULT);
List<String> imagesListActivity = new ArrayList();
imagesList.add(img1);
.
.
.
imagesList.add(img25);
and in your save method in helper class, you can do sth like:
public void saveImageList(List<String> images){
ContentValues cv = new ContentValues();
for(int i = 0; i < images.length; i++){
cv.put(COL_NAME, images[i);
}
}
and in activity class, try this by passing the actual list like below:
DBHelper dbHelper = new DBHelper();
dbHelper.saveImageList(imagesList);
I have 3 edit-texts in my activity (Name, mobile number, occupation) and a button (Save). I want to save these three data to Parse-cloud every-time when user clicks on the button.
Then new activity to display with a image in imageview that should be saved with the corresponding mobile number.
Saving data to parse is very simple. In your button click handler you just need to get the 3 values that you are interested in then create the new parse object;
String name = nameEditText.getText().toString();
String mobileNumber = mobileNumberEditText.getText().toString();
String occupation = occupationEditText.getText().toString();
ParseObject dataObject = new ParseObject();
dataObject.put("name", name);
dataObject.put("mobilenumber", mobileNumber);
dataObject.put("occupation", occupation);
dataObject.saveInBackground();
Somewhere in your app you will need to remember to set your application id and key as supplied to you by Parse. I tend to do it in an Application object in the onCreate method;
public void onCreate() {
Parse.initialize(this, "Your Application Id", "Your Client Key");
}
The Parse Object API is very simple to work with I tend to find as there isn't too much to get your head around. If you are completely new to Parse and you haven't already then I would recommend taking a look at their quickstart.
I wrote an Android App that pulls data from a MySql Database on a remote web server. The information is parsed and displayed in a listview. The listview also displays images which could slow down the activity. I was wondering how I could only display items 0-9, then when you click a button it will display 10-19, and so on. I can do it in VB using "do until" but as far as android/java, I am kind of lost. Any help would be appreciated.
Below is the class where I need to implement it. I believe I would need to add an Integer to keep count and implement a form of "DO UNTIL" before I loop through the array and add a count to the "Integer" but I am not sure how to go about it here.
class ProductQuery extends AsyncTask<String, String, String>{
#Override
protected String doInBackground(String... file_url) {
// TODO Auto-generated method stub
try{
//Settings to send to PHP
List<NameValuePair> settings = new ArrayList<NameValuePair>();
//Adding Search Criteria(Keyword) to settings
settings.add(new BasicNameValuePair("product", product));
//Getting JSON result from request
JSONObject jObject = jParser.makeHttpRequest(url_to_php, "GET", settings);
//Display JSON in LogCat
Log.d("Product Search", jObject.toString());
//Get Result
int result = jObject.getInt(KEY_RESULT);
//If Result Equals 1 then
if(result==1){
//Getting the KEY_PRODUCTS
products = jObject.getJSONArray(KEY_PRODUCTS);
//Loop through Array
for(int i = 0; i < products.length();i++){
JSONObject x = products.getJSONObject(i);
String proPid = x.getString(KEY_PRODID);
String name = x.getString(KEY_NAME);
String price = x.getString(KEY_PRICE);
String desc = x.getString(KEY_DESCRIPTION);
String img = x.getString(KEY_IMAGE);
// creating new HashMap
HashMap<String, String> hmap = new HashMap<String, String>();
hmap.put(KEY_PRODID, proPid);
hmap.put(KEY_NAME, name);
hmap.put(KEY_PRICE, price);
hmap.put(KEY_DESCRIPTION, desc);
hmap.put(KEY_IMAGE, img);
//Hash to ArrayList
myproducts.add(hmap);
}
} else {
}
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
Instead of making pagination in the app, you should leave this to the server.
On your server, you should change the way you receive requests, so that when you call your server, you post a start index to fetch rows from and how many rows you want fetched for each request.
So the url to the server could look like this:
http://example.com/myjsonrequest.php?startindex=10&numofrows=10
In your PHP select statement on your server, you change it so it selects only the rows you need, like so:
SELECT * FROM my_table LIMIT $startindex, $numofrows;
Remember to check for SQL injections of course.
This way, you only fetch the data you actually want instead of fetching all the data in one go. Remember, your app is on a mobile OS, with a somewhat volatile internet connection sometimes, so if the data you're returning is growing, it wouldn't be nice from a user-perspective to sit and wait for all the data to load, especially when some of it, isn't needed yet.
For instance if you get let's say 1000 rows of data returned, that would take a while to fetch over a mobile internet connection.
After you receive the JSonObject with only a limited amount of entries, you can now parse it without keeping track of how many entries are returned.
Inside your Android app, all you need to keep track of is what index in the database, the user has seen so far and then increment this counter every time the user fetches a new page.
Is the order of items in the .keySet() of a Bundle in the same order as items were inserted? I am trying to send a LinkedHashMap through a parcelable from a service to the activity.
Here is the code to insert a linkedHashMap's items into a Bundle using .putSerializable:
Bundle b = new Bundle();
Iterator<Entry<Integer, String>> _cyclesIterator = cycles.entrySet().iterator();
while (_cyclesIterator.hasNext()) {
Entry<Integer, String> _entry = _cyclesIterator.next();
Log.i(TAG,"Writing to JSON CycleID" + _entry.getKey());
b.putSerializable(_entry.getKey().toString(), _entry.getValue());
}
_dest.writeBundle(b);
I am trying to read this back when the bundle is retrieved using this:
Bundle _b = in.readBundle();
if (_b != null) {
for (String _key : _b.keySet()) {
Log.i(TAG,"Reading JSON for cycle " + _key);
_lhm.put(Integer.valueOf(_key), (String)_b.getString(_key));
}
setCycles(_lhm);
}
When items go in, the log says [1,2,3,4] but when they're read back, it is [3,2,1,4]. Is there a way to ensure the same order in both?
Maps have different approach according to their use.
HashMap - The elements will be in an unpredictable, "chaotic", order.
LinkedHashMap - The elements will be ordered by entry order or last reference order, depending on the type of LinkedHashMap.
TreeMap - The elements are ordered by key.
For getting better idea you can also check this Answer.
Maps and sets (and Bundles) carry no inherent order. You could serialize a single TreeMap<Integer, String> instead of iterating and serializing each entry, or you could iterate like you're doing but then also store one more value -- an ArrayList (also serializable) of the keys.
I have an Android application which retrieves from a external server, a name and a corresponding ID (this could be 1 name and ID combo or multiple name ID combinations), these are all stored in a HashMap<String, String> - The ID as the key and the Name as the value.
What I then would like to implement is a dynamic Spinner that populates itself with the 'Names' from this HashMap and when the user selects one of these names a setting somewhere I set to the ID number. This ID number will then be used in later server requests.
My question is what is the best way to implement this custom Spinner from the HashMap so that when the option is selected the ID number is set somewhere. This ID number has to be accessible from several activities - the spinner is present in several different activities... but should have the same effect on each screen.
Design patterns and pseudo code would be hugely appreciated. At the moment the Spinner is on 2 different screens, at the top below the ActionBar, but obviously the code is in both XML layout files.
Cheers.
EDIT
Code to set names and IDs in HashMap:
// Returns a Map of blog name to blog ID associated with the authenticated user
public Map<String, String> extractBlogInfo(XMLDataExtracter blogData)
{
Log.d(TAG, "BlogOperations::extractBlogInfo()");
ArrayList<String> blogIDs = new ArrayList<String>();
ArrayList<String> blogNames = new ArrayList<String>();
Map<String, String> blogIDNamePairs = new HashMap<String, String>();
// Get ID and Names and store them in blogIDs and blogNames variables
if (blogIDs.size() == blogNames.size())
{
for(int i = 0; i < blogIDs.size(); i++)
{
blogIDNamePairs.put(blogIDs.get(i), blogNames.get(i));
}
}
else
{
// An error occured
Log.d(TAG,
"BlogOperations::extractBlogInfo() > An error occured - ID and Name array sizes do not match");
return null;
}
return blogIDNamePairs;
}
For this you can use Shared preference.. You get the Id of the selected value from spinner and stored it in shared preference..
So that you can access this value any where inside your Apps..
If you want to display the selected spinner value from Say Activity1 in Activity2 get the value from Shared preference, now it will be Id so get the corresponding Name from the Id in hash Map..
For shared preference take a look at this... and this....