I'm trying to make an application which grabs all the ParseFiles in a ParseObject and display them in a GridView, successively.
I've done so with one activity, which represents a news feed, and everything works fine.
But when I'm trying to implement the same method in my other activity, it doesn't work.
I'm using an AsyncTask to load the images in the background.
This is my code:
ThumbnailItems.java (POJO class)
public class ThumbnailItems {
Bitmap thumb;
// Empty constructor.
public ThumbnailItems(){
}
// Constructor.
public ThumbnailItems(Bitmap thumb){
super();
this.thumb = thumb;
}
// Getter.
public Bitmap getImage(){
return thumb;
}
// Setter.
public void setImage(Bitmap thumb){
this.thumb = thumb;
}
}
My AsyncTask:
private class RemoteDataTask extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected Void doInBackground(Void... params) {
thumbItemsList = new ArrayList<ThumbnailItems>();
try {
ParseQuery<ParseObject> postQuery = new ParseQuery<ParseObject>("Posts");
postQuery.orderByDescending("createdAt");
objectList = postQuery.find();
for (ParseObject posts : objectList){
final ThumbnailItems thumbItems = new ThumbnailItems();
// Locate user profile picture.
ParseFile thumbFile = (ParseFile) posts.get("author_img");
thumbFile.getDataInBackground(new GetDataCallback() {
#Override
public void done(byte[] bytes, ParseException e) {
if (e == null) {
Bitmap userImage = Bitmap.createScaledBitmap(
BitmapFactory.decodeByteArray(bytes, 0, bytes.length)
, 150, 150, false);
thumbItems.setImage(userImage);
} else {
Log.d("ParseException", "Error: " + e.getMessage());
e.printStackTrace();
}
}
});
thumbItemsList.add(thumbItems);
}
} catch (ParseException e){
Log.e("ParseException", "Error: " + e.getMessage() + " with code: " + e.getCode());
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void result) {
LayoutInflater layoutInflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View activityView = layoutInflater.inflate(R.layout.activity_profile, null, false);
gridView = (GridView) activityView.findViewById(R.id.gridView);
gridViewAdapter = new GridViewAdapter(getApplicationContext()
, R.layout.profile_viewpager_tab1_children
, thumbItemsList);
gridView.setAdapter(gridViewAdapter);
}
}
(I've already seen this tutorial, but I really want to be consistent with my code)
i think batter to use Like.
and don't use AsyncTask to load the images in the background.
ParseQuery<ParseObject> query = new ParseQuery<ParseObject>(
"ClassName");
query.findInBackground(new FindCallback<ParseObject>() {
#Override
public void done(List<ParseObject> list, ParseException e) {
// TODO Auto-generated method stub
if (e == null) {
// hear u will get responce.
for (ParseObject parseObject : list) {
ParseFile image = (ParseFile) parseObject.get(""); // hear
// set
// column
// name
// same
// as
// parse
// table
if (image != null) {
// hear store image into your custom array.
// Like...
Log.e("get Image ",
" IMAGE URL IS " + image.getUrl());
}
}
// and hear u can set your adapter
// and yr grid view
// in adapter to use Picasso libary for image shower.
// how to use picasso lib.
Picasso.with(getApplicationContext()).load("image url")
.fit().into(imageview);
} else {
// hear is yr fail responce
// e.getMessage()
}
}
});
Related
I want to retrieve a bitmap from a separate class. The separate class has a method that downloads a bitmap from an online server with a data callback. By default the method returns null until the bitmap is downloaded. When I call the method from my main class I get null. How can I wait for this retrieval to be non null (i.e the bitmap has been downloaded) before continuing any main class operations?
Main Class
profileBitmap = myParse.getImageBitmap(getContext(), tagId);
Separate Class
public Bitmap getImageBitmap (final Context context, String tagId) {
// give us the user's photo
ParseQuery<ParseObject> parseQuery = new ParseQuery<>("Photo");
parseQuery.whereEqualTo("username", tagId);
parseQuery.getFirstInBackground(new GetCallback<ParseObject>() {
#Override
public void done(ParseObject object, ParseException e) {
if (object != null && e == null) {
ParseFile profilePic = (ParseFile) object.get("profilePicture");
//download process
profilePic.getDataInBackground(new GetDataCallback() {
#Override
public void done(byte[] data, ParseException e) {
if (data != null && e == null) {
// converts file to image
selectedImageBitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
} else {
// returns error user bitmap
selectedImageBitmap = BitmapFactory.decodeResource(context.getResources(), android.R.drawable.ic_dialog_alert);
FancyToast.makeText(context, "Error: " + e.getMessage(), FancyToast.LENGTH_SHORT, FancyToast.ERROR, false).show();
}
}
});
} else {
// returns empty user bitmap
selectedImageBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.empty_user);
FancyToast.makeText(context, "Error: " + e.getMessage(), FancyToast.LENGTH_SHORT, FancyToast.ERROR, false).show();
}
}
});
return selectedImageBitmap;
}
I would use a listener:
Create an interface in a new file:
public interface onBitmapDownloadedListener{
void onDownloadFinished(Bitmap bitmap);
}
In your main class implement the interface, and pass the reference of your main class to the MyParse class
class MainClass implements onBitmapDownloadedListener{
//now when you create an instance of myParse, pass the listener
......
myParse = new MyParse(this);
#Override
public void onDownloadFinished(Bitmap bitmap){
//here you get the bitmap
profileBitmap = bitmap
}
Make a constructor in MyParse class that accepts the interface:
class MyParse {
private onBitmapDownloadedListener listener;
//constrcutor
public MyParse(onBitmapDownloadedListener listener){
this.listener = listener
}
//your method
public Bitmap getImageBitmap (final Context context, String tagId) {
........
........
........
#Override
public void done(byte[] data, ParseException e) {
if (data != null && e == null) {
// converts file to image
selectedImageBitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
//notify here
listener.onDownloadFinished(selectedImageBitmap);
}
....
....
....
}
}
I'm making an application that implements the Camera, and I was wondering why does the image get saved to a tiny bitmap when I take a picture?
When I press the capture button, for some reason the image gets scaled down (I need to save the image to INTERNAL memory, not external/sd card) and I end up having to scale it back up to display it in the ImageView, which obviously makes the photo a little bit more grainy than the camera preview is. Is there a better way to do this?
I want it to be similar to SnapChat, where the picture you take is displayed exactly how it looked when you took it...
Here's the main Activity:
public class MainActivity extends FragmentActivity {
private static final String TAG = "CameraActivity";
public static final int MEDIA_TYPE_IMAGE = 1;
private Camera mCamera;
private CameraPreview mPreview;
private Context mContext;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mContext = this;
if(checkCameraHardware(mContext)){
// Create an instance of Camera
mCamera = getCameraInstance();
// Create our Preview view and set it as the content of our activity.
mPreview = new CameraPreview(this, mCamera);
FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
preview.addView(mPreview);
// Add a listener to the Capture button
Button captureButton = (Button) findViewById(R.id.button_capture);
captureButton.setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View v) {
// get an image from the camera
mCamera.takePicture(null, null, mPicture);
}
}
);
}
}
private Camera.PictureCallback mPicture = new Camera.PictureCallback() {
#Override
public void onPictureTaken(final byte[] data, Camera camera) {
new AsyncTask<Void, Void, String>() {
#Override
protected String doInBackground(Void... params) {
try {
FileOutputStream fos = openFileOutput("img.jpg", Context.MODE_PRIVATE);
fos.write(data);
fos.close();
return "img.jpg";
} catch (FileNotFoundException e) {
Log.d(TAG, "File not found: " + e.getMessage());
return null;
} catch (IOException e) {
Log.d(TAG, "Error accessing file: " + e.getMessage());
return null;
}
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
if(result != null){
Intent intent = new Intent(mContext, ImageDisplayActivity.class);
intent.putExtra(ImageDisplayActivity.KEY_PATH, "img.jpg");
startActivity(intent);
}
}
}.execute();
}
};
private boolean checkCameraHardware(Context context) {
if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)){
// this device has a camera
return true;
} else {
// no camera on this device
return false;
}
}
public static Camera getCameraInstance(){
Camera c = null;
try {
c = Camera.open(); // attempt to get a Camera instance
}
catch (Exception e){
// Camera is not available (in use or does not exist)
}
return c; // returns null if camera is unavailable
}
/** Create a File for saving an image or video */
}
And here's the Image Display Activity:
public class ImageDisplayActivity extends FragmentActivity {
public static final String KEY_PATH = "img.jpg";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_image_display);
Intent intent = getIntent();
String path = getIntent().getStringExtra(ImageDisplayActivity.KEY_PATH);
try {
java.io.FileInputStream in = this.openFileInput(path);
Bitmap bitmap = BitmapFactory.decodeStream(in);
ZoomInZoomOut touch = (ZoomInZoomOut)findViewById(R.id.IMAGEID);
touch = arrangeImageView(touch);
touch.setImageBitmap(bitmap);
in.close();
Canvas c = new Canvas(bitmap);
} catch (Exception e) {
e.printStackTrace();
}
}
private ZoomInZoomOut arrangeImageView(ZoomInZoomOut img){
try {
img.setRotation(90);
img.setScaleX(2f);
img.setScaleY(2f);
} catch (Exception e) {
e.printStackTrace();
}
return img;
}
}
So, I want to display a spinning loading indicator while my ListView is being populated. I successfully have implemented the progress bar, BUT for some reason it disappears BEFORE all of the listings are displayed. What I want is the progressbar to be present during the TOTAL load time of the listings. Basically, what it seems like, each listing is being displayed one at a time, not all at once when they are all loaded.
What I'm doing is
1. Creating a new custom adapter class
2. Populating the ListView in an AsyncTask using this adapter class
3. Setting the ListView to this adapter
This works properly, the progress bar just disappears before all of the listings are displayed. Does anyone have any ideas?
Activity class:
public class MainActivity extends ActionBarActivity {
ArrayList<Location> arrayOfLocations;
LocationAdapter adapter;
// public static Bitmap bitmap;
Button refresh;
ProgressBar progress;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
progress=(ProgressBar)findViewById(R.id.progressbar_loading);
// Construct the data source
arrayOfLocations = new ArrayList<Location>();
// Create the adapter to convert the array to views
adapter = new LocationAdapter(this, arrayOfLocations);
FillLocations myFill = new FillLocations();
myFill.execute();
refresh = (Button) findViewById(R.id.refresh);
refresh.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
finish();
startActivity(getIntent());
}
});
}
private class FillLocations extends AsyncTask<Integer, Void, String> {
String msg = "Done";
protected void onPreExecute() {
progress.setVisibility(View.VISIBLE);
}
// Decode image in background.
#Override
protected String doInBackground(Integer... params) {
String result = "";
InputStream isr = null;
try {
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://afs.spotcontent.com/"); // YOUR
// PHP
// SCRIPT
// ADDRESS
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
isr = entity.getContent();
// resultView.setText("connected");
} catch (Exception e) {
Log.e("log_tag", "Error in http connection " + e.toString());
}
// convert response to string
try {
BufferedReader reader = new BufferedReader(
new InputStreamReader(isr, "iso-8859-1"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
isr.close();
result = sb.toString();
} catch (Exception e) {
Log.e("log_tag", "Error converting result " + e.toString());
}
// parse json data
try {
JSONArray jArray = new JSONArray(result);
for (int i = 0; i < jArray.length(); i++) {
final JSONObject json = jArray.getJSONObject(i);
try {
BitmapWorkerTask myTask = new BitmapWorkerTask(
json.getInt("ID"), json);
myTask.execute();
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} catch (Exception e) {
// TODO: handle exception
Log.e("log_tag", "Error Parsing Data " + e.toString());
}
return msg;
}
protected void onPostExecute(String msg) {
// Attach the adapter to a ListView
ListView listView = (ListView) findViewById(R.id.listView1);
// View header = (View) getLayoutInflater().inflate(
// R.layout.listview_header, null);
// listView.addHeaderView(header);
listView.setAdapter(adapter);
progress.setVisibility(View.GONE);
}
}
}
Adapter class:
public class LocationAdapter extends ArrayAdapter<Location> {
public LocationAdapter(Context context, ArrayList<Location> locations) {
super(context, R.layout.item_location, locations);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// Get the data item for this position
Location location = getItem(position);
// Check if an existing view is being reused, otherwise inflate the view
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.item_location, parent, false);
}
// Lookup view for data population
TextView tvName = (TextView) convertView.findViewById(R.id.tvName);
TextView tvDetails = (TextView) convertView.findViewById(R.id.tvDetails);
TextView tvDistance = (TextView) convertView.findViewById(R.id.tvDistance);
TextView tvHours = (TextView) convertView.findViewById(R.id.tvHours);
ImageView ivIcon = (ImageView) convertView.findViewById(R.id.imgIcon);
// Populate the data into the template view using the data object
tvName.setText(location.name);
tvDetails.setText(location.details);
tvDistance.setText(location.distance);
tvHours.setText(location.hours);
ivIcon.setImageBitmap(location.icon);
// Return the completed view to render on screen
return convertView;
}
}
The reason for that behavior is that you are starting multiple threads.
FillLocations preExecute --> SHOW ProgressBar
BitmapWorkerTask_1 --> new thread
BitmapWorkerTask_2 --> new thread
...
BitmapWorkerTask_N --> new thread
FillLocations postExecute --> HIDE ProgressBar
BitmapWorkerTask_K --> continue execution
BitmapWorkerTask_K+1 --> continue execution
etc.
If you want the list to be displayed until it's all loaded, Simply make BitmapWorker's processing synchronous. If you still want to display the list right away but keep the spinner until it's all finished, then keep a counter in your activity and increase it in preexecute and decrease it in postExecute of BitmapWorker via a setter. Once the counter hits 0, remove hide the progressBar.
In activity:
private int asynchCounter = 0;
private void updateCounter(int delta){
asynchCounter+=delta;
if(asynchCounter<=0){
progress.setVisibility(View.GONE);
}else{
progress.setVisibility(View.VISIBLE);
}
}
And instead of BitmapWorkerTask use
class CountedBitmapWorkerTask extends BitmapWorkerTask {
protected void onPreExecute() {
super.onPreExecute();
updateCounter(1);
}
protected void onPostExecute(String msg) {
super.onPostExecute();
updateCounter(-1);
}
}
I had this exact problem, to solve it I had to write AsyncTask complete listener. Which sends a notification to UI thread, that data was loaded and it has to change something, in this case hide the ProgressBar.
This is the basic example of how this should look like. I am not sure this will work for you after you copy it to your project, but complete listener is what you need, so after studying this case you should be able to find a solution.
AsyncTaskCompleteListener.java - listener interface.
public interface AsyncTaskCompleteListener {
public void onTaskComplete();
}
LoadDataTask.java
class LoadDataTask extends AsyncTask<Object, Object, Object> {
/* Your object types according to your task. */
private AsyncTaskCompleteListener callback; // Callback field
public LoadDataTask(AsyncTaskCompleteListener cb){
this.callback = cb;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected Object doInBackground(String... urls) {
/* Your task here */
return result;
}
#Override
protected void onPostExecute(Object o) {
callback.onTaskComplete(); // Set the Callback
}
}
MainActivity.java
public class MainActivity implements AsyncTaskCompleteListener{
/* ...Other methods and fields... */
/* onTaskComplete method which fires after your data is loaded. */
#Override
public void onTaskComplete(){
// Hide ProgressBar
}
}
Self Plug: https://github.com/horvste/EasyWebPageDownloadForAndroid
This would separate the threading from the implementation and solve your problem. This is very similar to what Tony suggested except it's already implemented for you.
Github Readme:
Good for connecting to REST API's, HTML parsing, and many other uses. Using this library is meant to be easy:
Create a class which implements OnProgressUpdate
public class SampleClass implements OnProgressUpdate {
#Override
public void onUpdate(Integer percentProgress) {
}
#Override
public void onUpdateFailure() {
}
#Override
public void onSuccess(StringBuilder result) {
}
#Override
public void onFailure() {
}
}
}
Instantiate DownloadWebPage object
DownloadWebPage webPage = new DownloadWebPage(new SampleClass(), myUrl);
Call .downloadHtml() from the DownloadWebPage
webPage.downloadHtml();
Also if the asynchtask is updating properly and the amount of items is to large look here:
listing a listview is taking too much time and memory in android
Another option would be to only list a certain amount of items then have a next page button or gesture to deal with the ListView loading too slow.
I want to get file from parse to ImageView. I'm try to get by "getDataInBackgound" But when I call to this method' UI is stuck and I get the last image.
ParseFile image = tableParseObjects.getParseFile(PARSE_IMAGES);
image.getDataInBackground(new GetDataCallback() {
#Override
public void done(byte[] data, ParseException e) {
Bitmap bitpic = BitmapFactory.decodeByteArray(data, 0, data.length);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitpic.compress(Bitmap.CompressFormat.PNG, 100, stream);
vectorSample.setPic(bitpic);
}
});
I think you have to load the image using Picasso or the ImageLoader class. I had the same doubt and I used a ParseImageView too. This is my code:
Retrieve from parse.com the ParseFile (the image) with an asynctask:
public class BackgroundQuery extends AsyncTask<Object, Void, Object> {
private String id;
public BackgroundQuery(String id) {
this.id = id;
}
#Override
protected Object doInBackground(Object... params) {
Object o = null;
try {
ParseQuery<ParseObject> query = ParseQuery.getQuery(params[0]
.getClass().getSimpleName());
query.whereEqualTo("objectId", id);
List<ParseObject> result = query.find();
if (result != null) {
for (ParseObject obj : result) {
o = obj.getParseFile("photo"); // Photo is the ParseFile
}
}
} catch (ParseException e) {
Log.e(TAG, e.getMessage());
}
return o;
}
}
In your layout use this like an ImageView:
<com.parse.ParseImageView
android:id="#id/imgv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:adjustViewBounds="true />
Use this line for load the picture in the ParseImageView:
Picasso.with(this).load(parsefile.getUrl()).into(parseimageview);
An alternative to load bigger pics quickly it´s using an ImageLoader. Please check this.
Hope this help :)
Hello I implemented a simple RSS Feed reader using an AsyncTask, and It works perfectly.
I am trying upgrade my little APP to work with an ASYNCTASKLOADER, to learn how to use Loaders.
Notice the two lines of code on the:
public void onCreate(Bundle savedInstanceState){
of the RSSMain class...
new getRSSFeeds().execute();
getLoaderManager().initLoader(0, null, callBacks1);
By un/commenting these two lines I decide which mode to try my app with.
When I attempt to read RSS Feeds with getLoaderManager, all I get is a blank Activity.
My code is attached. I must have some conceptual mistake on my code, since I am new to all these things. Does somebody now how to solve it?
Take into account I started programming for Android 3 weeks ago, and my code
may be far from perfect, so any comments towards improvement are welcome!
public class RSSMain extends ListActivity {
private ArrayList<rssentry> itemlist2 = null; //LIST OF ALL RSS FEEDS
private RSSListAdaptor2 rssadaptor2 = null; //A SINGLE RSS POST
private String sourceurl=null;
public final static String EXTRA_MESSAGE = "com.example.rssjosh.MESSAGE"; //DECLARE PAYLOAD MESSAGE FOR THE ACTIVITY-CALLING INTENT
private static final int LENGTH_SHORT = 0;
private static final int LENGTH_LONG = 1;
String toastxt="empty...";
Toast toast;
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
//LoaderManager lmanager = getLoaderManager().initLoader(0, null, new RSSLoaderCallback, getBaseContext());
//getLoaderManager().initLoader(0, savedInstanceState, new RSSLoader(null));
sourceurl="http://stackoverflow.com/feeds/tag?tagnames=android&sort=newest";
itemlist2 = new ArrayList<rssentry>();
getLoaderManager().initLoader(0, null, callBacks1); //CREATES AND INITS. LOADER (ASYNCTASKLOADER MODE)
//new getRSSFeeds().execute();
}
#Override
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
String s=null;
rssentry data = itemlist2.get(position); //GET THE RSSENTRY THAT WAS TOUCHED BY THE USER
//TEMPORARY TOAST TO CHECK CORRECT STRING FORMATION
//String toastxt="XD!";
//int duration = Toast.LENGTH_LONG; //toastxt=toastxt+data.title+"\n"+data.published+"\n"+data.link+"\n"+data.summary.substring(30,140)+"\n";
//FORM THE HTML TEXT TO BE SENT TO THE SIGLE-RSSFEED DISPLAY ACTIVITY
StringBuilder htmlString = new StringBuilder();
htmlString.append(data.title+"$");
htmlString.append("Published on: "+data.published+"$");
htmlString.append(data.summary+"$");
htmlString.append("URL: "+data.link+"$");
Intent intent = new Intent(this,Rssactivity.class);
//LOADS THE INTENT WITH THE <HTML> PAYLOAD
intent.putExtra(EXTRA_MESSAGE, htmlString.toString()); ///public final static String EXTRA_MESSAGE = "com.example.rssjosh.MESSAGE"; DECLARED ABOVE
startActivity(intent); //LAUNCHES INTENT
}
//SERVICE METHOD TO private String retrieveRSSFeed2(String urlToRssFeed)
// _URLstring -> INPUT_STREAM
private InputStream downloadUrl(String urlString) throws IOException {
URL url = new URL(urlString);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(10000 /* milliseconds */);
conn.setConnectTimeout(15000 /* milliseconds */);
conn.setRequestMethod("GET");
conn.setDoInput(true);
// STARTS QUERYING THE STREAM
conn.connect();
InputStream stream = conn.getInputStream();
return stream;
}
//URL -> (INPUT_STREAM) -> List<rssentry> entries
//THIS VARIANT OF THE RETRIEVERSSFEED2 METHOD, RETURNS RESULT IN A STRING FORMAT (OPTIONAL METHOD)
private ArrayList<rssentry> retrieveRSSFeed2Str(String urlToRssFeed) throws XmlPullParserException, IOException
{
ArrayList<rssentry> itemlist = new ArrayList<rssentry>();
//INSTANTIATES A NEW PARSER "parsero", AND AN EMPTY RSSENTRY ARRAYLIST
InputStream stream = null;
//List<rssentry> entries = null; UPGRADED TO PUBLIC CLASS ATTRIBUTE
xmlparser parsero = new xmlparser();
//This Try does URL->Stream
try {
stream = downloadUrl(urlToRssFeed); //OBTAIN A CHARACTER STREAM FROM THE rssURL
itemlist = parsero.parse(stream); //PARSE STREAM AND STORE rssENTRIES IN THE "ENTRIES" ARRAYLIST <rssentry>
} finally {
if (stream != null) {
stream.close(); //CLOSE STREAM AFTER USING IT
}
}
return itemlist;
}
//GETS RSS FEED IN ASYNCHRONOUS MODE
class ATLgetfeeds extends AsyncTaskLoader <ArrayList<rssentry>>{
private ArrayList<rssentry> rsslist=null;
private ProgressDialog progress = null;
public ATLgetfeeds(Context context) {
super(context);
}
#Override
protected void onStartLoading() {
if (rsslist != null)
deliverResult(rsslist); // Use the cache
else
forceLoad();
}
#Override
public ArrayList<rssentry> loadInBackground() {
try {
itemlist2 = null; //<=THIS LIST IS TO BE LOADED WITH THE RSS URL BELOW
rsslist = retrieveRSSFeed2Str("http://stackoverflow.com/feeds/tag?tagnames=android&sort=newest"); //SETS ITEMLIST2
} catch (XmlPullParserException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
//LOADS DATA INTO RSSADAPTER (PARSER2)
rssadaptor2 = new RSSListAdaptor2(RSSMain.this, R.layout.rssitemview,rsslist);
return null;
}
#Override
public void deliverResult(ArrayList<rssentry> data) {
rsslist = data; // Caching
super.deliverResult(data);
}
#Override
protected void onReset() {
super.onReset();
// Stop the loader if it is currently running
onStopLoading();
rsslist = null;
}
#Override
public void onCanceled(ArrayList<rssentry> data) {
// Attempt to cancel the current async load
super.onCanceled(data);
rsslist = null;
}
protected void onPreExecute() {
progress = ProgressDialog.show( RSSMain.this, null, "RSSJosh Loading..."); //LOADING MESSAGE
// super.onPreExecute();
}
protected void onPostExecute(Void result) {
itemlist2=rsslist;
setListAdapter(rssadaptor2);
progress.dismiss(); //Dismisses loading progress dialog
//s super.onPostExecute(result);
}
}
//GETS RSS FEED IN ASYNCHRONOUS MODE
private class getRSSFeeds extends AsyncTask<Void, Void, Void>
{
private ProgressDialog progress = null;
ArrayList<rssentry> atlist = new ArrayList<rssentry>();
#Override
protected Void doInBackground(Void... params) {
try {
itemlist2 = null; //<=THIS LIST IS TO BE LOADED WITH THE RSS URL BELOW
atlist = retrieveRSSFeed2Str("http://stackoverflow.com/feeds/tag?tagnames=android&sort=newest");
} catch (XmlPullParserException e) {
e.printStackTrace(); // TODO Auto-generated catch block
} catch (IOException e) {
e.printStackTrace(); // TODO Auto-generated catch block
}
//LOADS DATA INTO UI RSSADAPTER (PARSER2)
rssadaptor2 = new RSSListAdaptor2(RSSMain.this, R.layout.rssitemview,atlist);
return null;
}
#Override
protected void onCancelled() {
super.onCancelled();
}
#Override
protected void onPreExecute() {
progress = ProgressDialog.show( RSSMain.this, null, "RSSJosh Loading..."); //LOADING MESSAGE
super.onPreExecute();
}
#Override
protected void onPostExecute(Void result) {
setListAdapter(rssadaptor2);
itemlist2=atlist;
progress.dismiss(); //Dismisses loading progress dialog
super.onPostExecute(result);
}
#Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
}
}
//RSS ADAPTER (TYPE2) FOR STACK-OVERFLOW RSSFEEDS
private class RSSListAdaptor2 extends ArrayAdapter<rssentry>{
private List<rssentry> objects = null;
public RSSListAdaptor2(Context context, int textviewid, List<rssentry> objects) {
super(context, textviewid, objects);
this.objects = objects;
}
#Override
public int getCount() {
return ((null != objects) ? objects.size() : 0);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public rssentry getItem(int position) {
return ((null != objects) ? objects.get(position) : null);
}
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
if(null == view)
{
LayoutInflater vi = (LayoutInflater)RSSMain.this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = vi.inflate(R.layout.rssitemview, null);
}
rssentry data = objects.get(position);
if(null != data)
{ //CREATE TEXTVIEW OBJECTS FORTITLE, DATE AND DESCRIPTION DATA
TextView title = (TextView)view.findViewById(R.id.txtTitle);
TextView date = (TextView)view.findViewById(R.id.txtDate);
TextView description = (TextView)view.findViewById(R.id.txtDescription);
//PUT TEXT ON TITLE AND DATE VIEWS
title.setText(data.title);
date.setText("Published on: " + data.published); //PREVIOUSLY date.setText("on " + data.date);
//PREPARE AND LOAD TEXT FOR THE SUMMARY VIEW
String txt=null;
//Clean and trim summary string before displaying
txt=data.summary.toString().substring(30,data.summary.toString().length());
if (txt.length()>=300)
txt=txt.substring(0,299)+"..."; ///DISPLAY A SUMMARY OF 300 CHARACTERS MAX, IN THE RSS HEADLINES
description.setText(txt); //PUT TEXT
}
return view;
}
}
LoaderManager.LoaderCallbacks<ArrayList<rssentry>> callBacks1 = new LoaderManager.LoaderCallbacks<ArrayList<rssentry>>() {
/* Implement the three callback methods here */
public android.content.Loader<ArrayList<rssentry>> onCreateLoader( //START LOADING
int arg0, Bundle arg1) {
// TODO Auto-generated method stub
android.content.Loader<ArrayList<rssentry>> rsslist=null;
//TEMPORARY TOAST TO DEBUG CORRECT STRING FORMATION
toastxt="Toastiee! Preparing for ATL Task";
toast = Toast.makeText(getBaseContext(), toastxt, LENGTH_SHORT);
toast.show();
ATLgetfeeds a= new ATLgetfeeds(getBaseContext());
//TEMPORARY TOAST TO DEBUG CORRECT STRING FORMATION
toastxt="Toastiee! ATL Task created";
toast = Toast.makeText(getBaseContext(), toastxt, LENGTH_SHORT);
toast.show();
return rsslist;
}
#Override
public void onLoadFinished( //START LOADING
android.content.Loader<ArrayList<rssentry>> arg0,
ArrayList<rssentry> arg1) {
// TODO Auto-generated method stub
}
#Override
public void onLoaderReset(android.content.Loader<ArrayList<rssentry>> arg0) {
// TODO Auto-generated method stub
}
};
}