I'm working on the music streaming service project. I like to show thumbnail jacket images when I started the application in the first place.
I've fetched all the String Json results, and I've converted Jason results to hashmap by using Gson lib.
What I'm trying to do is combine the base url with map value and return? or pass the result, so that I can use the result with another thread in order to show the thumbnail images. please give me some answers..:(
MainActivity.java
private static final String baseURLforgetNewMusic = "https://s3-ap-northeast-1.amazonaws.com/goblinsbucket/Artists/";
....
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
new Connection().execute(getMusicInfo_URL + "getNewMusic.php");
// Connect to the server.
}
private class Connection extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... urls) {
return getMusicInfo(urls[0]);
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
}
}
....
private String getMusicInfo(String url) {
InputStream inputStream = null;
String inputStr = "";
HashMap<String, Object> map = new HashMap<String, Object>();
try {
URL getMusicUrl = new URL(url);
conn = (HttpURLConnection) getMusicUrl.openConnection();
conn.setDoInput(true);
conn.connect();
Log.d(TAGCP, "MADE POST REQUEST TO THE GIVEN URL");
inputStream = conn.getInputStream();
if (inputStream != null) {
inputStr = Util.convertInputStreamToString(inputStream);
Log.i(TAGCS, inputStr);
Music list = new Gson().fromJson(inputStr, Music.class);
for (Music.MusicInfo info : list.musicInfo) {
System.out.println(baseURLforgetNewMusic + info.artists
+ "/" + info.file_name);
}
} else {
inputStr = "Did not work!";
Log.d(TAGRR, inputStr);
}
} catch (Exception e) {
Log.i("InputStream", e.getLocalizedMessage());
}
return inputStr;
}
Results: (I want to use these url to show thumbnail images on the main view.)
I/System.out(22054): https://s3-ap-northeast-1.amazonaws.com/goblinsbucket/Artists/BrunoMars/Grenade
I/System.out(22054): https://s3-ap-northeast-1.amazonaws.com/goblinsbucket/Artists/BrunoMars/Justthewayyouare
I/System.out(22054): https://s3-ap-northeast-1.amazonaws.com/goblinsbucket/Artists/Beenzino/Aquaman
I/System.out(22054): https://s3-ap-northeast-1.amazonaws.com/goblinsbucket/Artists/Gummy/Thinkaboutme
Try using volley to load your images. It will be faster and easier to use than Universal Image Loader. The library contains a class called NetworkImageView that will load all of your images for you.
Try showing images with this library:
https://github.com/nostra13/Android-Universal-Image-Loader
You can pass the list of URLs here and will show images in a gridview.
If you want to make something cool like CoverFlow for showing album covers use this:
https://github.com/Polidea/android-coverflow
Related
I am making a guessing app in Android Studio 2.2.3 for which I need to load some data from a website. I am using an AsyncTask class, which accepts the URL of the website as a String, and returns the data as String.
The problem is that the loading is extremely slow and so the app shows a blank white screen on the phone for about 15-20 seconds until (I presume) the whole thing is downloaded.
What I want to do is show an indeterminate progress bar (I think that's what the rotating circle is called) until the app loads the data.
For this, I tried to pass in the AsyncTask, and then made the progressbar view visible in the onPreExecute() and invisible again in the onPostExecute().
But this didn't work out and it still showed the same white screen.
Here's my AsyncTask:
public class DownloadTask extends AsyncTask<String, Void, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
pb.setVisibility(ProgressBar.VISIBLE);
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
pb.setVisibility(ProgressBar.INVISIBLE);
}
#Override
protected String doInBackground(String... urls) {
String result = "";
URL url;
HttpURLConnection urlConnection;
try {
url = new URL(urls[0]);
urlConnection = (HttpURLConnection) url.openConnection();
InputStream in = urlConnection.getInputStream();
InputStreamReader isr = new InputStreamReader(in);
int data = isr.read();
while (data != -1) {
char current = (char) data;
result += current;
data = isr.read();
}
return result;
} catch (Exception e) {
e.printStackTrace();
}
//if try fails
return null;
}
}
And this is when I call it in the onCreate()
DownloadTask downloadTask = new DownloadTask();
String result;
try {
String websiteUrl = "http://www.india-forums.com/celebrity/bollywood/";
result = downloadTask.execute(websiteUrl).get();
I read somewhere that the get() blocks the main UI thread, but if I remove it, I get an Incompatible types error, so couldn't still resolve it...
What am I missing/doing wrong?
Any help would be appreciated!
I am currently wondering how to use AsyncTask in multiple Activitys without copying it.
I used this Guide to do it in one Activity and that worked just fine. But to load and use this information in more than one Activity seems to me like to much work. I tried to put my LoadUrl function into another Class and just pass my Textfield I want to be edited. But my App crashes when i start it. (I am not sure if this is the right approach )
public class LoadFromUrl {
public void loadAccountInfo(String key) {
if( key != null ) {
new DownloadWebpageTask().execute();
}
}
private class DownloadWebpageTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... urls) {
// params comes from the execute() call: params[0] is the url.
try {
return downloadUrl(urls[0]);
} catch (IOException e) {
return "Unable to retrieve web page. URL may be invalid.";
}
}
// onPostExecute displays the results of the AsyncTask.
#Override
protected void onPostExecute(String result) {
//textView.setText(result);
}
// Given a URL, establishes an HttpUrlConnection and retrieves
// the web page content as a InputStream, which it returns as
// a string.
private String downloadUrl(String myurl) throws IOException {
InputStream is = null;
// Only display the first 500 characters of the retrieved
// web page content.
int len = 500;
try {
URL url = new URL(myurl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(10000 /* milliseconds */);
conn.setConnectTimeout(15000 /* milliseconds */);
conn.setRequestMethod("GET");
conn.setDoInput(true);
// Starts the query
conn.connect();
int response = conn.getResponseCode();
//Log.d(DEBUG_TAG, "The response is: " + response);
is = conn.getInputStream();
// Convert the InputStream into a string
String contentAsString = readIt(is, len);
return contentAsString;
// Makes sure that the InputStream is closed after the app is
// finished using it.
} finally {
if (is != null) {
is.close();
}
}
}
// Reads an InputStream and converts it to a String.
public String readIt(InputStream stream, int len) throws IOException, UnsupportedEncodingException {
Reader reader = null;
reader = new InputStreamReader(stream, "UTF-8");
char[] buffer = new char[len];
reader.read(buffer);
return new String(buffer);
}
}
}
and calling it in:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
selectedAccount.setKey("google.com");
loadUrl.loadAccountInfo(selectedAccount.getKey());
}
All I want to do is, load the information of an URL and use this to fill my activitys (like multiple TextViews). Every activity uses different urls and structures.
Create DownloadWebPageTask in a separate file, as a public class. Then override its constructor to pass anything you need (a textfield, key, etc).
Put DownloadWebPageTask in a separate class. Then in onPostExecute, run a callback to the activity or fragment that will update its UI. This is done by having an activity implement a callback which is an inner interface inside the the DownloadWebpageTask (doesn't have to be an inner interface!). As you can see, the inner interface I put with your code is WebpageCallbacks.
This is your asynctask in another class (the spacing isn't perfect sorry...):
public class DownloadWebpageTask extends AsyncTask<String, Void, String> {
/**
* Any activity or fragment that implements WebPageCallbacks
*/
private WebPageCallbacks callbacks;
//start by referencing your activity to call onURLLoaded() for onPostExecute()
public DownloadWebpageTask(WebPageCallbacks callbacks) {
this.callbacks = callbacks; //note: I think weak references are preferred though
}
//no changes here
#Override
protected String doInBackground(String... urls) {
// params comes from the execute() call: params[0] is the url.
try {
return downloadUrl(urls[0]);
} catch (IOException e) {
return "Unable to retrieve web page. URL may be invalid.";
}
}
// onPostExecute displays the results of the AsyncTask by callback's onURLLoaded()
#Override
protected void onPostExecute(String result) {
//each activity or fragment will has a method to change their UI
callbacks.onURLLoaded(result);
}
// Given a URL, establishes an HttpUrlConnection and retrieves
// the web page content as a InputStream, which it returns as
// a string. No changes here
private String downloadUrl(String myurl) throws IOException {
InputStream is = null;
// Only display the first 500 characters of the retrieved
// web page content.
int len = 500;
try {
URL url = new URL(myurl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(10000 /* milliseconds */);
conn.setConnectTimeout(15000 /* milliseconds */);
conn.setRequestMethod("GET");
conn.setDoInput(true);
// Starts the query
conn.connect();
int response = conn.getResponseCode();
//Log.d(DEBUG_TAG, "The response is: " + response);
is = conn.getInputStream();
// Convert the InputStream into a string
String contentAsString = readIt(is, len);
return contentAsString;
// Makes sure that the InputStream is closed after the app is
// finished using it.
} finally {
if (is != null) {
is.close();
}
}
/**
* Any Activity or fragment that implements this will have
* onURLLoaded() method to update its own UI.
*/
public interface WebpageCallbacks {
void onURLLoaded(String result);
}
}
I would then add implements DownloadWebpageTask.WebpageCallBacks to all your fragments and activities that will use this asynctask.
Here is your activity:
public class ExampleActivity extends AppCompatActivity implements DownloadWebpageTask.WebpageCallBacks {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
selectedAccount.setKey("google.com");
//changed your oncreate at line below to run your accountInfo
runAccountInfo(selectedAccount.getKey());
}
.......................
//runs the asynctask to load url info from account info like your old loadURLInfo()
public void runAccountInfo(String key) {
if( key != null ) {
//get url with getURL(key)
new DownloadWebpageTask(this).execute(getURL(key));
}
}
//this will be run from onPostExecute from the asynctask
#Override
public void onURLLoaded(String result) {
textView.setText(result);
}
}
If you have the time though, I suggest to not use AsyncTask at all and look into other libraries like rxJava/rxAndroid. I hope this code is ok........
I have an android code which receives images as base64 string from the server in the form of json data. The code is given below. After receiving the images I have to decode the images as bitmap. And after that I have to display that images in an image gridview. How can this acheived? please help me. Thanks in advance.
package com.example.mygallery;
//skipping the import section
public class Gallery extends Activity
{
int refresh=0;
Bitmap decodedByte;
GridView gridView;
String username,password,count1,status;
int count;
ArrayList<String>imagearraylist;
ProgressDialog pd;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_gallery);
gridView = (GridView) findViewById(R.id.grid_view);
SharedPreferences sp=getSharedPreferences("My_login", MODE_PRIVATE);
username=sp.getString("username", "");
password=sp.getString("password", "");
new serverconnection().execute();
}
public class serverconnection extends AsyncTask<Void, String, Void>
{
#Override
protected Void doInBackground(Void... params)
{
// TODO Auto-generated method stub
try
{
String link="http://tonyjoseph.site90.com/sendimage.php";
String data = URLEncoder.encode("username", "UTF-8") + "=" + URLEncoder.encode(username, "UTF-8");
URL url = new URL(link);
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
OutputStreamWriter wr = new OutputStreamWriter (conn.getOutputStream());
wr.write( data );
wr.flush();
BufferedReader reader = new BufferedReader (new InputStreamReader(conn.getInputStream()));
StringBuilder sb=new StringBuilder();
String line = null; // Read Server Response
while((line = reader.readLine()) != null)
{
sb.append(line);
break;
}
String status=sb.toString();
JSONObject jsonResponse1;
try
{
/****** Creates a new JSONObject with name/value mappings from the JSON string. ********/
jsonResponse1 = new JSONObject(status);
/***** Returns the value mapped by name if it exists and is a JSONArray. Returns null otherwise.*******/
JSONArray jsonMainNode=jsonResponse1.optJSONArray("Android");
/*********** Process each JSON Node ************/
int lengthJsonArr = jsonMainNode.length();
Log.d("Json Array Length",String.valueOf(lengthJsonArr));
for(int j1=0;j1<lengthJsonArr;j1++)
{
Context mContext;
/****** Get Object for each JSON node.***********/
JSONObject jsonChildNode = jsonMainNode.getJSONObject(j1);
/******* Fetch node values **********/
String index=jsonChildNode.optString("index").toString();
String imagename=jsonChildNode.optString("imagename").toString();
//Here I get the images from server as string one after another
byte[] decodedString = Base64.decode(imagename, Base64.DEFAULT);
decodedByte = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length);
// At this stage I will be getting a list of bitmapsfrom the server which is converted from the received json
// i need to display these bitmaps into a image grid view ie display the images as a grid
// how can this be acheived??
}
}
catch(Exception ex)
{
System.out.print(ex);
}
}
catch(Exception ex)
{
ex.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void result)
{
// TODO Auto-generated method stub
super.onPostExecute(result);
Toast.makeText(Gallery.this, "Loading complete", Toast.LENGTH_LONG).show();
pd.dismiss();
}
#Override
protected void onPreExecute()
{
// TODO Auto-generated method stub
super.onPreExecute();
pd=new ProgressDialog(Gallery.this);
pd.setTitle("Loading images..");
pd.setMessage("Please wait");
pd.setCancelable(false);
pd.show();
}
}
}
At that stage use runOnUiThread to place the received Bitmap 'in the grid'. But if you do not first save or cache all received bitmaps the grid will loose them with UI updates. The actual placing in the grid will be done by getView() calls after notify dataset changed.
Actually you do not need runOnUiThread at all. Just in doInBackGround save all images to a specific folder. Then in onPostExecute do a notifyDataSetChanged. The listview knows to retrieve from that folder.
In my custom ListView contains two textview and one Imageview im using AsyncTask to read the Text from Internet same with the imageView .As im reading and assigning all three view elemnt at the same time it takes to much time . In such case ineed to Convert url to Bitmap in another AsyncTask when the text part is done.
As a logic it recquire some concept of updating my ImageView resource .But i do not
know how to do it....
Thanks In Advance..
private class AsynchTask extends AsyncTask<Void, Integer, Void> {
URLConnection tc;
BufferedReader in;
URL twitter;
int num=0;
#Override
protected void onPreExecute() {
super.onPreExecute();
try {
mProgressBar.setVisibility(View.VISIBLE);
} catch (Exception e) {
Log.e(TAG,""+e.getMessage());
}
}
#Override
protected Void doInBackground(Void... params) {
try{
twitter = new URL("https://twitter.com/statuses/public_timeline.json");
tc = twitter.openConnection();
my = new ArrayList<HashMap<String,Object>>();
in = new BufferedReader(new InputStreamReader(
tc.getInputStream()));
ImageList=new ArrayList<String>();
while ((line = in.readLine()) != null) {
JSONArray ja = new JSONArray(line);
for (int i = 0; i < ja.length(); i++) {
JSONObject jo = (JSONObject) ja.get(i);
/**Data Insert into the HashMap Object*/
hm=new HashMap<String, Object>();
hm.put(TEXT,jo.getString("text"));
hm.put(USER,jo.getJSONObject("user").getString("name"));
// String str=jo.getJSONObject("user").getString("profile_image_url"); hm.put(URL,"http://twitter.com/#!/"+jo.getJSONObject("user").getString("screen_name"));
// hm.put(IMAGEURL,getDrawable_from_url(str));
ImageList.add(jo.getJSONObject("user").getString("profile_image_url"));
Log.e(TAG,""+num);
my.add(hm);
num++;
Log.e("Count",""+num);
publishProgress(num);
}
num++;
publishProgress(num);
}
} catch (Exception e) {
Log.e(TAG,""+e.getMessage());
}
return null;
}
#Override
protected void onProgressUpdate(Integer... values) {
mProgressBar.setProgress(values[0]);
super.onProgressUpdate(values);
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
mProgressBar.setProgress(0);
mProgressBar.setVisibility(View.GONE);
adapter = new Simpleadapter(HelloWorldActivity.this, my, R.layout.listcontent,
new String[]{TEXT,USER}, new int[]{R.id.text2,R.id.text1});
listView.setAdapter(adapter);
new AsynchTaskForImageLoading().execute();
}
}
/**Method to convert Url to the Bitmap*/
private Bitmap getDrawable_from_url(String url) {
try{
Bitmap x;
HttpURLConnection connection = (HttpURLConnection)new URL(url).openConnection();
connection.setRequestProperty("User-agent","Mozilla/4.0");
connection.connect();
InputStream input = connection.getInputStream();
x = BitmapFactory.decodeStream(input);
return x;
}
catch (Exception e) {
Log.e(TAG,""+e.getMessage());
return null;
}
}
I've used this LazyList with great success: https://github.com/thest1/LazyList
For your needs, you can swap out the supplied stub image with the one you'd like to use. I've also used a 1x1 blank png to show no image.
Also, one change that i've made in my code and that I strongly suggest when using this package is to change the code from using the SD card to use the built in cache. You do this by modifying the FileCache.java file from using .getExternalStorageDirectory() to .getCacheDir().
Hope this helps.
I have to download an image from a url and then show the downloaded image in a imageview on the UI.
For this i am using the code mentioned below:
public class ShowUIData extends AsyncTask<Void, Void, Void> {
String productvalues[];
Drawable productimagebitmap;
#Override
protected Void doInBackground(Void... params) {
productvalues = hb.getProductDetailsWithJson(id + 1);
if (productvalues != null) {
productimagebitmap = getImage(productvalues[3]);
}
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
if (productvalues != null) {
// Set the values obtained from the database.
// Check if image returned from URL is not null.
if (productimagebitmap != null) {
ImageView productimage = (ImageView) findViewById(R.id.productimage);
productimage.setImageDrawable(productimagebitmap);
}
}
dismissDialog();
}
// Download image from URL obtained for database.
private Drawable getImage(String address) {
try {
Log.i("product details", "starting image download");
URL url = new URL(address);
URLConnection conn = url.openConnection();
conn.connect();
InputStream is = conn.getInputStream();
Drawable d = Drawable.createFromStream(is, "src name");
is.close();
return d;
} catch (Exception e) {
Log.i("the url", address);
e.printStackTrace();
return getApplicationContext().getResources().getDrawable(
R.drawable.noimage);
}
}
A valid URL is being passed to the getImage function and no exception is being thrown , still the image is not being set on the imageview. When i debug my application, then the image is setting properly.
I believe i need to put a blocking call until the image is download and then call image.setImageDrawable.
What is the problem occuring over here. I am not able to figure out why i am not able to load any images and why only when i debug , i see an image?
thank you in advance.
you should try this example. It runtime fetches images from the url and also displays it in listview. I think this will help you.
Non UI thread can't update UI component. Use handler to update UI component.