Update the Progress Bar in the ListView when downloading - android

I have an Activity that show a list of database records .
In this activity there is a custom ListView.
In the custom ListView, there is a Button and a TextView and a ProgressBar .
My button listener that call AsyncTask is in CustomAdapter class .
DownloadTask downloadTask = new DownloadTask(getContext());
downloadTask.execute(url[position].toString());
AsynkTask work great .
But I want to update the Progress Bar during download process.
I've searched the Internet for three days but were unsuccessful.
I'm sorry for my English
public class listanimals extends ActionBarActivity {
private MyDatabase MyDataBase;
String[] listurl;
ProgressBar progressBar;
TextView url2;
CustomList adapter;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
public class DownloadTask extends AsyncTask<String, Integer, String> {
private Context context;
int myProgress;
public DownloadTask(Context context) {
this.context = context;
}
#Override
protected String doInBackground(String... sUrl) {
InputStream input = null;
final GlobalClass caches = (GlobalClass) context.getApplicationContext();
OutputStream output = null;
HttpURLConnection connection = null;
try {
URL url = new URL(sUrl[0]);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
return "Server returned HTTP " + connection.getResponseCode()
+ " " + connection.getResponseMessage();
}
input = connection.getInputStream();
output = new FileOutputStream("/sdcard/"+caches.getName_cach()+".mp3");
byte data[] = new byte[4096];
long total = 0;
int count;
while ((count = input.read(data)) != -1) {
total += count;
myProgress = (int)(total*100/connection.getContentLength());
output.write(data, 0, count);
}
} catch (Exception e) {
return e.toString();
} finally {
try {
if (output != null)
output.close();
if (input != null)
input.close();
} catch (IOException ignored) {
}
if (connection != null)
connection.disconnect();
}
return null;
}
#Override
protected void onProgressUpdate(Integer... values) {
//MY PROBLEM MAY HERE
progressBar.setProgress(myProgress);
}
#Override
protected void onPostExecute(String result) {
final GlobalClass caches = (GlobalClass) context.getApplicationContext();
if (result != null)
Toast.makeText(context,"Download error: "+result, Toast.LENGTH_LONG).show();
else{
Toast.makeText(context,"File downloaded"+ "" + caches.getName_cach(), Toast.LENGTH_SHORT).show();
}
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////AsynkTask end
///////////////////////////////////////////////////////////////////////////////////////
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_listanimals);
MyDataBase = new MyDatabase(this);
final GlobalClass caches = (GlobalClass) getApplicationContext();
final ListView listView=(ListView)findViewById(R.id.listView);
SQLiteDatabase mydb = MyDataBase.getReadableDatabase();
Cursor cursor = mydb.rawQuery("select * from animals", null);
ArrayList<String> myList = new ArrayList<String>();
final ArrayList<String> myListname = new ArrayList<String>();
ArrayList<String> myListurl = new ArrayList<String>();
try {
while(cursor.moveToNext()) {
myList.add(cursor.getString(cursor.getColumnIndex("_id")));
myListname.add(cursor.getString(cursor.getColumnIndex("name")).trim());
myListurl.add(cursor.getString(cursor.getColumnIndex("url")));
String[] listname = new String[myListname.size()];
listname = myListname.toArray(listname);
listurl = new String[myListurl.size()];
listurl = myListurl.toArray(listurl);
String[] listid = new String[myList.size()];
listid = myList.toArray(listid);
adapter = new
CustomList(listanimals.this, listname,listurl);
listView.setAdapter(adapter);
}} finally{
mydb.close();
}}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
public class CustomList extends ArrayAdapter<String> {
private MyDatabase MyDataBase;
private final Activity context;
private final String[] web;
private final String[] url;
public CustomList(Activity context,
String[] web,String[] url) {
super(context, R.layout.list_file, web);
this.context = context;
this.web = web;
this.url = url;
}
#Override
public View getView(final int position, View view, final ViewGroup parent) {
final GlobalClass caches = (GlobalClass) context.getApplicationContext();
MyDataBase = new MyDatabase(getContext());
LayoutInflater inflater = context.getLayoutInflater();
View rowView= inflater.inflate(R.layout.list_file, null, true);
Typeface kamran= Typeface.createFromAsset(context.getAssets(), "IranNastaliq.ttf");
progressBar=(ProgressBar)rowView.findViewById(R.id.progressBar);
TextView txtTitle3 = (TextView) rowView.findViewById(R.id.textView);
txtTitle3.setTypeface(kamran);
url2=(TextView)rowView.findViewById(R.id.textView2);
url2.setText(url[position]);
txtTitle3.setText(web[position]);
Button download=(Button)rowView.findViewById(R.id.button);
download.setTag(position);// Any data associated with the button has to be added with setTag()
download.setOnClickListener(new View.OnClickListener() {/////////call AsynkTask
#Override
public void onClick(View arg0) {
caches.setName_cach(web[position]);
DownloadTask downloadTask = new DownloadTask(getContext());
downloadTask.execute(url[position].toString());
}
});
return rowView;
}
}
}

You need to call publishProgress from the doInBackground method to update the ProgressBar: publishProgress docs
This will call onProgressUpdate(Integer... values);
You don't need the myProgress instance variable;

Check out this link https://www.youtube.com/watch?v=5HDr9FdGIVg&list=PLonJJ3BVjZW6hmkEaYIvLLm5IEGM0kpwU&index=17
You need to call - publishProgress((int) total*100/connection.getContentLength());
in the while loop
to update your progressbar.Hope it helps.

You have a progress bar in each item of the list, while you keep a single instance in the activity. This means your progress view will point to the one in the last list item that the system asked you to draw. Which might not be the one from the list item you pressed the button for. I suggest you split the classes (take them out from the activity) and you'll better see your problem. But this is going to be only the first of your problems - because you launch the async task and in the meantime you can scroll that item off screen.

Related

Remove an item from view inside an adapter

I am trying to remove an item from view when its flag become 4. I tried mObjects.remove(position) and then notifyDataSetChanged(). but it didn't worked.we tried all the following
if (getItem(position).getFlag().trim().equalsIgnoreCase("4")) {
remove(position);
adapter.notifyDataSetChanged();
matcheslistview.setAdapter(adapter);
also this one
// mObjects.remove(position)
// notifyDataSetChanged();
and this one
// mObjects.remove(position);
//remove(position);
//mainObjects.remove(position);
//notifyDataSetChanged();
and this one
// Object toRemove = adapter.getItem(position);
// mObjects.remove(toRemove);
// mObjects.clear();
and all the time we got java.lang.IndexOutOfBoundsException: Invalid index 1, size is 0.Here is the complete adapter class
private class MatchedDataAdapter extends BaseAdapter implements Filterable {
private AQuery aQuery;
private Activity mActivity;
private LayoutInflater mInflater;
private SessionManager sessionManager;
private int uflag;
MyFilter mfilter;
DatabaseHandler db;
ArrayList<LikeMatcheddataForListview> mObjects;
ArrayList<LikeMatcheddataForListview> mainObjects;
Context context;
public MatchedDataAdapter(Activity context,
ArrayList<LikeMatcheddataForListview> objects,
int imageHeigthAndWidth[]) {
this.mObjects = objects;
mainObjects = objects;
//Log.e("size", Integer.toString(mObjects.size()));
this.mActivity = context;
try {
mInflater = (LayoutInflater) mActivity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
catch (Exception e)
{
e.printStackTrace();
}
aQuery = new AQuery(context);
db = new DatabaseHandler(context);
}
#Override
public int getCount() {
return mObjects.size();
}
#Override
public LikeMatcheddataForListview getItem(int position) {
return mObjects.get(position);
}
#Override
public long getItemId(int i) {
return i;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder();
convertView = mInflater.inflate(R.layout.matchedlistviewitem,
null);
holder.imageview = (ImageView) convertView
.findViewById(R.id.userimage);
holder.textview = (TextView) convertView
.findViewById(R.id.userName);
holder.lastMasage = (TextView) convertView
.findViewById(R.id.lastmessage);
holder.imgStatus = (ImageView) convertView
.findViewById(R.id.imgStatus);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.textview.setText(getItem(position).getUserName());
if (getItem(position).getFlag().trim().equalsIgnoreCase("4")) {
mObjects.remove(position);
adapter.notifyDataSetChanged();
matcheslistview.setAdapter(adapter);
we want to remove Item with flag 4,we are reading this flag with a service from db and onrecive we call class DisplayContentTask as below
class GetLikeMatchedReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
new DisplayContentTask(intent).execute();
}
}
how we can get Item position in order to remove the Item with flag 4...or My be another approach to remove Item with flag 4 we don't know but appreciate your help on this
class DisplayContentTask extends AsyncTask<Void, Void, Void> {
Intent intent;
private Ultilities mUltilities = new Ultilities();
private List<NameValuePair> getuserparameter;
private String likedmatchedata, Unmatchedata;
int match1;
private LikedMatcheData matcheData;
private ArrayList<com.appdupe.flamer.pojo.Likes> likesList;
private LikeMatcheddataForListview matcheddataForListview;
DatabaseHandler mDatabaseHandler = new DatabaseHandler(getActivity());
private boolean isResponseSuccess = true;
ArrayList<LikeMatcheddataForListview> tempArray = new ArrayList<LikeMatcheddataForListview>();
#Override
protected void onPreExecute() {
super.onPreExecute();
AppLog.Log(TAG, "BackgroundTaskForFindLikeMatched onPreExecute ");
}
DisplayContentTask(Intent intent) {
this.intent = intent;
}
#Override
protected Void doInBackground(Void... voids) {
try {
File appDirectory = mUltilities
.createAppDirectoy(getResources().getString(
R.string.appdirectory));
AppLog.Log(TAG,
"BackgroundTaskForFindLikeMatched doInBackground appDirectory "
+ appDirectory);
File _picDir = new File(appDirectory, getResources().getString(
R.string.imagedirematchuserdirectory));
AppLog.Log(TAG,
"BackgroundTaskForFindLikeMatched doInBackground ");
// getuserparameter = mUltilities.getUserLikedParameter(params);
likedmatchedata = intent.getStringExtra("GET_MATCHED_RESPONSE");
// Unmatchedata = intent.getStringExtra("GET_UNMATCHED_RESPONSE");//hadi
AppLog.Log(TAG,
"BackgroundTaskForFindLikeMatched doInBackground likedmatchedata "
+ likedmatchedata);
Gson gson = new Gson();
matcheData = gson.fromJson(likedmatchedata,
LikedMatcheData.class);
AppLog.Log(TAG,
"BackgroundTaskForFindLikeMatched doInBackground matcheData "
+ matcheData);
// "errNum": "51",
// "errFlag": "0",
// "errMsg": "Matches found!",
if (matcheData.getErrFlag() == 0) {
likesList = matcheData.getLikes();
AppLog.Log(TAG,
"BackgroundTaskForFindLikeMatched doInBackground likesList "
+ likesList);
if (tempArray != null) {
tempArray.clear();
}
AppLog.Log(TAG,
"BackgroundTaskForFindLikeMatched doInBackground likesList sized "
+ likesList.size());
Log.v("Matches", "" + likesList.size());
match1 = likesList.size();
for (int i = 0; i < likesList.size(); i++) {
Log.d("likelist", likesList.toString());
matcheddataForListview = new LikeMatcheddataForListview();
String userName = likesList.get(i).getfName();
String facebookid = likesList.get(i).getFbId();
// Log.i(TAG, "Background facebookid......"+facebookid);
String picturl = likesList.get(i).getpPic();
int falg = likesList.get(i).getFlag();
// if (likesList.get(i).getFlag()==4) {
// likesList.remove(getId());
// }
Log.i("komak10",""+likesList.get(i).getFlag());
String latd = likesList.get(i).getLadt();
matcheddataForListview.setFacebookid(facebookid);
matcheddataForListview.setUserName(userName);
matcheddataForListview.setImageUrl(picturl);
matcheddataForListview.setFlag("" + falg);
matcheddataForListview.setladt(latd);
// matcheddataForListview.setFilePath(filePath);
File imageFile = mUltilities.createFileInSideDirectory(
_picDir, userName + facebookid + ".jpg");
// logDebug("BackGroundTaskForUserProfile doInBackground imageFile is profile "+imageFile.isFile());
Utility.addBitmapToSdCardFromURL(likesList.get(i)
.getpPic().replaceAll(" ", "%20"), imageFile);
matcheddataForListview.setFilePath(imageFile
.getAbsolutePath());
if (!preferences.getString(Constant.FACEBOOK_ID, "")
.equals(facebookid)) {
tempArray.add(matcheddataForListview);
}
}
DatabaseHandler mDatabaseHandler = new DatabaseHandler(
getActivity());
// SessionManager mSessionManager = new SessionManager(
// MainActivity.this);
String userFacebookid = preferences.getString(
Constant.FACEBOOK_ID, "");
//
boolean isdataiserted = mDatabaseHandler.insertMatchList(
tempArray, userFacebookid);
} else if (matcheData.getErrFlag() == 1) {
if(tempArray!=null)
{
tempArray.clear();
}
} else {
// do nothing
}
} catch (Exception e) {
AppLog.handleException(
"BackgroundTaskForFindLikeMatched doInBackground Exception ",
e);
// some thing wrong happend
isResponseSuccess = false;
}
return null;
}
Don't remove the object in getview, if you have to filter it, filter it before sending out to adapter. May be possible that while creating the child view the 1st cell has tag "4" now the view didn't create(since return was not called) but you are trying to remove its position, so it will definitely give you IndexOutOfBoundsException.
My best solution would be, set the adapter with
new ArrayList<LikeMatcheddataForListview>()
whenever you start the screen. Once your AsyncTask completes filter out the child with tags "4"(better filter it out in the asynctask only, less task in ui thread) then refresh the adapter, like
public void refresh(ArrayList<LikeMatcheddataForListview>() arrObjects){
objects = arrObjects;
notifyDataSetChanged();
}
Check it out, it should do the trick
Please try following
Your code
if (getItem(position).getFlag().trim().equalsIgnoreCase("4")) {
mObjects.remove(position);
adapter.notifyDataSetChanged();
matcheslistview.setAdapter(adapter);
}
TO
do not set adapter again to list view
if (getItem(position).getFlag().trim().equalsIgnoreCase("4")) {
mObjects.remove(position);
notifyDataSetChanged();
}
This may not be correct approach to remove the item form listview.
Whenever your adapter data is getting changed then just check if that flag matches your string i.e. "4" in each item and remove the respective item from the list and just call notifyItemRemoved with position insted of notifyDataSetChanged

Progress Bar Disappearing before reaching the end in Android

I am trying to download video file using async task. The video is downloading perfectly but the progress bar disappears before reaching the end and it starts downloading again. It doesn't happen when I am downloading image files.
Here is my code.
FileDownloadTask.Java
public class FileDownloadTask extends AsyncTask<String, Integer, String> {
private static final String TAG = FileDownloadTask.class.getSimpleName();
final DownloadInfo mInfo;
//public static String file_url = "http://www.gettyimages.ca/gi-resources/images/Homepage/Category-Creative/UK/UK_Creative_462809583.jpg";
//public static String file_url="http://imaze.net/apps/groups/123.mp4";
// Context context=getApplicationContext();
public FileDownloadTask(DownloadInfo info) {
mInfo = info;
}
#Override
protected void onProgressUpdate(Integer... values) {
mInfo.setProgress(values[0]);
ProgressBar bar = mInfo.getProgressBar();
if(bar != null) {
bar.setProgress(mInfo.getProgress());
bar.invalidate();
}
}
#Override
protected String doInBackground(String... f_url) {
int count;
try {
String root = Environment.getExternalStorageDirectory().toString();
System.out.println("Downloading");
URL url = new URL(mInfo.getFileUrl());
URLConnection conection = url.openConnection();
conection.connect();
// getting file length
int lenghtOfFile = conection.getContentLength();
// input stream to read file - with 8k buffer
// Output stream to write file
File rootdirectory= new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES),"Youtube Videos");
if(!rootdirectory.exists())
{
rootdirectory.mkdirs();
}
String nameoffile= URLUtil.guessFileName(mInfo.getFileUrl(),null, MimeTypeMap.getFileExtensionFromUrl(mInfo.getFileUrl()));
File file= new File(rootdirectory,nameoffile);
file.createNewFile();
mInfo.setDownloadState(DownloadState.DOWNLOADING);
InputStream input = new BufferedInputStream(url.openStream(), 8192);
OutputStream output = new FileOutputStream(file);
byte data[] = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
publishProgress((int)(total*1001)/lenghtOfFile);
// writing data to file
output.write(data, 0, count);
}
// flushing output
output.flush();
// closing streams
output.close();
input.close();
// Intent intent=new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
// intent.setData(Uri.parse(file_url));
// getActivity().sendBroadcast(intent);
} catch (Exception e) {
Log.e("Error: ", e.getMessage());
}
mInfo.setDownloadState(DownloadState.COMPLETE);
return null;
}
protected void onPostExecute(String file_url) {
mInfo.setDownloadState(DownloadState.COMPLETE);
}
#Override
protected void onPreExecute() {
mInfo.setDownloadState(DownloadState.DOWNLOADING);
}
}
DownloadInfo.Java
import android.util.Log;
import android.widget.ProgressBar;
public class DownloadInfo {
private final static String TAG = DownloadInfo.class.getSimpleName();
public enum DownloadState {
NOT_STARTED,
QUEUED,
DOWNLOADING,
COMPLETE
}
private volatile DownloadState mDownloadState = DownloadState.NOT_STARTED;
private String mFilename;
// private final String mFileUrl;
private Integer mFileSize;
private String mFileUrl="";
private volatile Integer mProgress;
// private final Integer mFileSize;
private volatile ProgressBar mProgressBar;
public DownloadInfo(String filename, String FileUrl) {
mFilename = filename;
mProgress = 0;
mFileUrl = FileUrl;
// mFileSize = mFileSize;
// mFileSize = size;
mProgressBar = null;
}
public ProgressBar getProgressBar() {
return mProgressBar;
}
public void setProgressBar(ProgressBar progressBar) {
Log.d(TAG, "setProgressBar " + mFilename + " to " + progressBar);
mProgressBar = progressBar;
}
public void setDownloadState(DownloadState state) {
mDownloadState = state;
}
public DownloadState getDownloadState() {
return mDownloadState;
}
public Integer getProgress() {
return mProgress;
}
public void setProgress(Integer progress) {
this.mProgress = progress;
}
//
// public Integer getFileSize() {
// return mFileSize;
// }
public Integer getFileSize() {
return mFileSize;
}
public void setFileSize(Integer FileSize) {
mFileSize = FileSize;
}
// public void setFileUrl(String FileUrl)
// {
// this.FileUrl = FileUrl;
// }
public String getFilename() {
return mFilename;
}
public String getFileUrl()
{
return mFileUrl;
}
}
DownloadInfoArrayAdapter.Java
public class DownloadInfoArrayAdapter extends ArrayAdapter<DownloadInfo> {
// Simple class to make it so that we don't have to call findViewById frequently
private static class ViewHolder {
TextView textView;
ProgressBar progressBar;
Button button;
DownloadInfo info;
}
private static final String TAG = DownloadInfoArrayAdapter.class.getSimpleName();
public DownloadInfoArrayAdapter(Context context, int textViewResourceId,
List<DownloadInfo> objects) {
super(context, textViewResourceId, objects);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
final DownloadInfo info = getItem(position);
// We need to set the convertView's progressBar to null.
ViewHolder holder = null;
if(null == row) {
LayoutInflater inflater = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = inflater.inflate(R.layout.file_download_row, parent, false);
holder = new ViewHolder();
holder.textView = (TextView) row.findViewById(R.id.downloadFileName);
holder.progressBar = (ProgressBar) row.findViewById(R.id.downloadProgressBar);
holder.button = (Button)row.findViewById(R.id.downloadButton);
holder.info = info;
row.setTag(holder);
} else {
holder = (ViewHolder) row.getTag();
holder.info.setProgressBar(null);
holder.info = info;
holder.info.setProgressBar(holder.progressBar);
}
holder.textView.setText(info.getFilename());
holder.progressBar.setProgress(info.getProgress());
holder.progressBar.setMax(100);
info.setProgressBar(holder.progressBar);
holder.button.setEnabled(info.getDownloadState() == DownloadState.NOT_STARTED);
final Button button = holder.button;
holder.button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
info.setDownloadState(DownloadState.QUEUED);
button.setEnabled(false);
button.invalidate();
FileDownloadTask task = new FileDownloadTask(info);
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
});
//TODO: When reusing a view, invalidate the current progressBar.
return row;
}
}

Custom adapter not updating gridview

I am writing an app to pull movie data from the MovieDB api and display the information in a GridView.
When the app first loads I would expect the view to populate initially, but it does not. I have a sort option in the menu bar and when the sort option is set the first time the GridView is populated by movies in order of popularity, as it should initially, but regardless of what sort criteria is actually selected.
I have used the logs to determine that the correct data is being retrieved from the API and being processed properly, so I have to assume that the adapter is not updating the view properly.
Why isn't the view showing initially or updating as it should?
FilmFragment.java:
public class FilmFragment extends Fragment {
private ArrayList<FilmParcelable> filmParcels = new ArrayList<FilmParcelable>();
private ImageAdaptor mFilmAdaptor;
protected String[] sortOptions = {
"popularity.desc",
"vote_average.desc"
};
protected String sortBy = sortOptions[0];
private final String LOG_TAG = FilmFragment.class.getSimpleName();
public FilmFragment() {
}
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
if (savedInstanceState == null || !savedInstanceState.containsKey("films")){
updateFilms();
mFilmAdaptor = new ImageAdaptor(getActivity(),filmParcels);
} else {
filmParcels = savedInstanceState.getParcelableArrayList("films");
mFilmAdaptor = new ImageAdaptor(getActivity(),filmParcels);
}
// allow fragment to handle menu events
setHasOptionsMenu(true);
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater){
inflater.inflate(R.menu.filmfragment, menu);
}
public boolean onOptionsItemSelected(MenuItem item){
//Handle action bar item clicks. The action bar will
//automatically handle clicks on the Home/Up button, so long
//as you specify a parent activity in AndroidManifest.xml
int id = item.getItemId();
if (id == R.id.action_sort){
showSortDialog();
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public void onSaveInstanceState(Bundle outState){
outState.putParcelableArrayList("films", filmParcels);
super.onSaveInstanceState(outState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
// Find GridView to populate with poster images
GridView gridView = (GridView) rootView.findViewById(R.id.gridView);
// Set the adaptor of the GridView to my ImageAdaptor
gridView.setAdapter(mFilmAdaptor);
updateAdaptor();
return rootView;
}
// Update movie data in case there is a change in the "sort by" option
// Or the fragment is started with no saved data
public void updateFilms(){
new FetchFilmTask().execute();
}
public void updateAdaptor(){
mFilmAdaptor.clear();
mFilmAdaptor.addAll(filmParcels);
mFilmAdaptor.notifyDataSetChanged();
}
// Show dialog sort pop up
public void showSortDialog(){
DialogFragment dialog = new SortDialog();
dialog.setTargetFragment(this, 0);
dialog.show(getActivity().getSupportFragmentManager(), "SortDialog");
}
// If a fragment or activity called by this fragment returns to this fragment,
// Get the information returned via the intent
public void onActivityResult(int requestCode, int resultCode, Intent data){
if (requestCode == 0){
int mSelected = data.getIntExtra("Selected Option", -1);
if (mSelected != -1){
sortBy = sortOptions[mSelected];
updateFilms();
updateAdaptor();
}
}
}
// Class to get JSON data from The Movie Database API
public class FetchFilmTask extends AsyncTask<Void, Void, FilmParcelable[]> {
private final String LOG_TAG = FetchFilmTask.class.getSimpleName();
private final String MOVIE_DB_API_KEY = "e1968ef8ba074d7d5bf07a59de8b2310";
protected FilmParcelable[] doInBackground(Void... params){
// These two need to be declared outside the try/catch
// so that they can be closed in the finally block.
HttpURLConnection urlConnection = null;
BufferedReader reader = null;
// Will contain raw JSON response as a string
String movieDBStr = null;
try {
// Construct URL for Movie DB query
Uri.Builder builder = new Uri.Builder();
builder.scheme("http")
.authority("api.themoviedb.org")
.appendPath("3")
.appendPath("discover")
.appendPath("movie")
.appendQueryParameter("api_key", MOVIE_DB_API_KEY)
.appendQueryParameter("sort_by", sortBy);
String myUrl = builder.build().toString();
Log.d(LOG_TAG, myUrl);
URL url = new URL(myUrl);
// Create the request to The Movie DB, and open the connection
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.connect();
// Read the input stream into a String
InputStream inputStream = urlConnection.getInputStream();
StringBuffer buffer = new StringBuffer();
if (inputStream == null){
return null;
}
reader = new BufferedReader(new InputStreamReader(inputStream));
String line;
while ((line = reader.readLine()) != null) {
// Since it's JSON, adding a newline isn't necessary (it won't affect parsing)
// But it does make debugging a *lot* easier if you print out the completed
// buffer for debugging.
buffer.append(line + "\n");
}
if (buffer.length() == 0) {
return null;
}
movieDBStr = buffer.toString();
} catch (IOException e){
Log.e(LOG_TAG, "Error: ", e);
return null;
} finally {
if (urlConnection != null){
urlConnection.disconnect();
}
if (reader != null){
try{
reader.close();
} catch (final IOException e){
Log.e(LOG_TAG, "Error closing stream", e);
}
}
}
try {
return getFilmDataFromJson(movieDBStr);
} catch (JSONException e){
Log.e(LOG_TAG, e.getMessage(), e);
e.printStackTrace();
}
return null;
}
/**
* Take the String representing the complete forecast in JSON Format and
* pull out the data we need to construct the Strings needed for the wireframes.
*
* Fortunately parsing is easy: constructor takes the JSON string and converts it
* into an Object hierarchy for us.
*/
private FilmParcelable[] getFilmDataFromJson(String movieDBStr)
throws JSONException {
// JSON objects that need to be extracted
final String MDB_RESULTS = "results";
final String MDB_ID = "id";
final String MDB_SYNOPSIS = "overview";
final String MDB_RELEASE = "release_date";
final String MDB_POSTER = "poster_path";
final String MDB_TITLE = "title";
final String MDB_RATING = "vote_average";
JSONObject filmJson = new JSONObject(movieDBStr);
JSONArray filmArray = filmJson.getJSONArray(MDB_RESULTS);
FilmParcelable[] resultFilms = new FilmParcelable[filmArray.length()];
for (int i = 0; i < filmArray.length(); i++){
// Data needed by the FilmParcelable
int id;
String title;
String releaseDate;
String posterUrl;
Double voteAverage;
String plotSynopsis;
JSONObject film = filmArray.getJSONObject(i);
id = film.getInt(MDB_ID);
plotSynopsis = film.getString(MDB_SYNOPSIS);
releaseDate = film.getString(MDB_RELEASE);
posterUrl = "http://image.tmdb.org/t/p/w300" + film.getString(MDB_POSTER);
title = film.getString(MDB_TITLE);
voteAverage = film.getDouble(MDB_RATING);
Log.d(LOG_TAG, title);
Log.d(LOG_TAG, posterUrl);
resultFilms[i] = new FilmParcelable(id, title, releaseDate, posterUrl, voteAverage, plotSynopsis);
}
return resultFilms;
}
#Override
protected void onPostExecute(FilmParcelable[] result){
if (result != null){
filmParcels = new ArrayList<>(Arrays.asList(result));
}
}
}
}
ImageAdaptor.java:
public class ImageAdaptor extends ArrayAdapter<FilmParcelable> {
public ImageAdaptor(Activity context, ArrayList<FilmParcelable> filmParcels){
super(context, 0, filmParcels);
}
public View getView(int position, View convertView, ViewGroup parent){
Context context= getContext();
View gridView;
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
String mUrl = getItem(position).getUrl();
if (convertView == null) {
gridView = inflater.inflate(R.layout.gridview_film_layout, parent, false);
// Find the image view from the gridview_film_layout
ImageView posterView = (ImageView) gridView.findViewById(R.id.grid_item_image);
// Set the image view to contain image located at mUrl
Picasso.with(getContext()).load(mUrl).into(posterView);
} else {
gridView = convertView;
}
return gridView;
}
}
accordingly to the code you posted you are returning over and over the same cell of your GridView. You should have those two lines
ImageView posterView = (ImageView) gridView.findViewById(R.id.grid_item_image);
Picasso.with(getContext()).load(mUrl).into(posterView);
out of the if/else guard:
if (convertView == null) {
// inflate
} else {
// gridView = convertView;
}
ImageView posterView = (ImageView) gridView.findViewById(R.id.grid_item_image);
Picasso.with(getContext()).load(mUrl).into(posterView);
return gridView;
I was attempting to update the adapter after populating the arraylist used for the adapter. However the arraylist was populated and updated in the background so the code:
updateFilms();
updateAdaptor();
was causing the adaptor to update before the data had completed loading in the background.
After fixing that Blackbelt's solution was correct.

saved arrayList<HashMap<String,String>,displaying them without Internet

I have arrayList> in my app.I have this array fro, the Internet,through parsing json data. I want to save this array,then my app can be work without Internet.What can I do? I know how to stored data im SQLite,but response of query is cursor,I know that I can create custom adapter that working with cursor.But maybe I can find easier way for this?
MainActivity:
public class MainActivity extends ListActivity {
private Context context;
SqlHelper dbHelper;
Intent intent;
private static String url = "https://fierce-citadel-4259.herokuapp.com/hamsters";
private static final String TITLE = "title";
private static final String DESCRIPTION = "description";
private static final String IMAGE = "image";
ArrayList<HashMap<String,String>> jsonlist = new ArrayList<HashMap<String, String>>();
ListView lv;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new ProgressTask(MainActivity.this).execute();
lv=(ListView) findViewById(android.R.id.list);
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String title1 = jsonlist.get(position).get("title");
String description1 = jsonlist.get(position).get("description");
String url1 = jsonlist.get(position).get("image");
intent = new Intent(MainActivity.this, DetailInfo.class);
intent.putExtra("title", title1);
intent.putExtra("description", description1);
intent.putExtra("url", url1);
startActivity(intent);
dbHelper = new SqlHelper(MainActivity.this);
try {
dbHelper.open();
} catch (SQLException e) {
e.printStackTrace();
}
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.reload) {
new ProgressTask(MainActivity.this).execute();
}
else if(id == R.id.menu_item_share){
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_TEXT, "Put whatever you want");
startActivity(Intent.createChooser(intent,"Share via"));
}
return super.onOptionsItemSelected(item);
}
private class ProgressTask extends AsyncTask<String,Void,Boolean> {
private ProgressDialog dialog;
private ListActivity activity;
private Context context;
public ProgressTask(MainActivity activity) {
this.activity = activity;
context = activity;
dialog = new ProgressDialog(context);
}
protected void onPreExecute(){
this.dialog.setMessage("Progress start");
this.dialog.show();
}
protected void onPostExecute(final Boolean success){
try{
if((this.dialog != null)&& this.dialog.isShowing()){
this.dialog.dismiss();
}
CustomListAdapter adapter = new CustomListAdapter(MainActivity.this,jsonlist, R.layout.list_item,new String[]{TITLE,DESCRIPTION},new int[]{R.id.title,R.id.description});
lv.setAdapter(adapter);
//setListAdapter(adapter);
}catch (final IllegalArgumentException e){e.printStackTrace();}
}
protected Boolean doInBackground(String... args) {
JSONParser jParser = new JSONParser();
JSONArray json = jParser.getJSONFromUrl(url);
for(int i =0;i<json.length();i++) {
try {
JSONObject c = json.getJSONObject(i);
String vtitle = c.getString(TITLE);
String vdescription = c.getString(DESCRIPTION);
String vimage = c.getString(IMAGE);
/* dbHelper.createEntry(vtitle,vdescription,vimage);
dbHelper.close();*/
HashMap<String, String> map = new HashMap<>();
map.put(TITLE, vtitle);
map.put(DESCRIPTION, vdescription);
map.put(IMAGE, vimage);
jsonlist.add(map);
} catch (JSONException e) {
e.printStackTrace();
}
}
return null;
}
}
/*private void displaysavedlv(){
Cursor cursor = dbHelper.fetchAllCountries();
CustomCursorAdapter adapter1 = new CustomCursorAdapter(MainActivity.this,cursor);
lv.setAdapter(adapter1);
}*/
/* private boolean isNetworkConnected() {
ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo ni = cm.getActiveNetworkInfo();
if (ni == null) {
// There are no active networks.
return false;
} else
return true;
}*/
}
yes you can do this without sqlite. TinyDB will do the trick for you.
checkout here : https://github.com/kcochibili/TinyDB--Android-Shared-Preferences-Turbo
You can create one method in sqlite that returns arrayList with hashmap :
public ArrayList<HashMap<String, String>> getAllData()
{
ArrayList<HashMap<String, String>> array_list = new ArrayList<HashMap<String, String>>();
//hp = new HashMap();
SQLiteDatabase db = this.getReadableDatabase();
Cursor res = db.rawQuery( "select * from tablename", null );
res.moveToFirst();
while(res.isAfterLast() == false){
hashmap = new HashMap<String, String>();
hashmap.put("columnname", res.getString(res.getColumnIndex(columnindex)));
hashmap.put("columnname", res.getString(res.getColumnIndex(columnindex)));
hashmap.put("columnname", res.getString(res.getColumnIndex(columnindex)));
hashmap.put("columnname", res.getString(res.getColumnIndex(columnindex)));
array_list.add(hashmap);
res.moveToNext();
}
return array_list;
}
Cheers!

why BitmapFactory.decodeStream(input) returns null in my code and my photo doesn't show?

I want to read some book's data and show them in a listview and show book's picture using bitmap. I can show other information but I cant show picture and I cant finde why because I did what ever bitmapping needs and befor I use this AsyncTask method my pictures were showing!
and wonderful thing is when I click on an Item, download layout showing book's pic properly and when I Open AllBooksActivity from first place again, it is showing pics properly toO!!!
here is my AllBooksActivity code:
public class AllBooksActivity extends Activity {
public ListItem adapter;
public ListView allbooklist;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_all_books);
new loadingbooks().execute();
}
private class loadingbooks extends AsyncTask<String, String, String> {
private ProgressDialog pDialog;
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(AllBooksActivity.this);
pDialog.setMessage("کتابها در حال بارگذاری، لطفا منتظر بمانید...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.show();
}
#Override
protected String doInBackground(String... args) {
String res = JSONCommands.readData(MainActivity.params);
return res;
}
#Override
protected void onPostExecute(String res) {
if(res != null){
pDialog.dismiss();
AllBooksActivity.this.getActionBar().setTitle(MainActivity.how);
allbooklist = (ListView) findViewById(R.id.list_all);
allbooklist.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent in = new Intent(getApplicationContext(), DownloadActivity.class);
in.putExtra("MyClass", MainActivity.books_array.get(position));
startActivity(in);
}
});
adapter = new ListItem(AllBooksActivity.this, MainActivity.books_array);
allbooklist.setAdapter(adapter);
}
else {
pDialog.dismiss();
AlertDialog.Builder builder = new AlertDialog.Builder(AllBooksActivity.this)
.setTitle("خطا در برقراری ارتباط با سرور")
.setMessage("نمایش کتاب ناموفق :( اتصالات را بررسی کنید.");
builder.create().show();
}
}
}
here is my list adapter code:
public class ListItem extends BaseAdapter {
private int count;
private Context context;
private ArrayList<ShowBook> bookArray;
public ListItem(Context context, ArrayList<ShowBook> bookArray) {
this.count = bookArray.size();
this.context = context;
this.bookArray = bookArray;
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return count;
}
#Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return null;
}
#Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService( Context.LAYOUT_INFLATER_SERVICE );
View row = inflater.inflate(R.layout.list_item, parent, false);
TextView namketabltxt, nevisandeltxt, mozooltxt, qeymatltxt;
ImageView tasvirlimg;
namketabltxt = (TextView) row.findViewById(R.id.ltxt_namketab);
nevisandeltxt = (TextView) row.findViewById(R.id.ltxt_nevisande);
mozooltxt = (TextView) row.findViewById(R.id.ltxt_mozoo);
qeymatltxt = (TextView) row.findViewById(R.id.ltxt_qeymat);
tasvirlimg = (ImageView)row.findViewById(R.id.limg_tasvir);
namketabltxt.setText(MainActivity.books_array.get(position).namketab);
nevisandeltxt.setText(MainActivity.books_array.get(position).nevisande);
mozooltxt.setText(MainActivity.books_array.get(position).mozoo);
qeymatltxt.setText(MainActivity.books_array.get(position).qeymat);
JSONCommands.getpic(MainActivity.books_array.get(position).tasvir, tasvirlimg);
return row;
}
}
here is my DownloadActivity code:
#SuppressLint("ShowToast") public class DownloadActivity extends Activity {
TextView namketabdtxt, nevisandedtxt, mozoodtxt, qeymatdtxt, uplodkonandedtxt;
ImageView tasvirdimg;
Button dlbtn;
RatingBar rb;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_download);
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
namketabdtxt = (TextView) findViewById(R.id.dtxt_namketab);
nevisandedtxt = (TextView) findViewById(R.id.dtxt_nevisande);
mozoodtxt = (TextView) findViewById(R.id.dtxt_mozoo);
uplodkonandedtxt = (TextView) findViewById(R.id.dtxt_uplodkonande);
qeymatdtxt = (TextView) findViewById(R.id.dtxt_qeymat);
tasvirdimg = (ImageView) findViewById(R.id.dimg_tasvir);
dlbtn = (Button)findViewById(R.id.btn_dl);
rb = (RatingBar) findViewById(R.id.ratingBar1);
final ShowBook book = (ShowBook) getIntent().getSerializableExtra("MyClass");
this.getActionBar().setTitle(book.namketab);
namketabdtxt.setText(book.namketab);
nevisandedtxt.setText(book.nevisande);
mozoodtxt.setText(book.mozoo);
uplodkonandedtxt.setText(book.uplodkonande);
qeymatdtxt.setText(book.qeymat);
JSONCommands.getpic(book.tasvir, tasvirdimg);
dlbtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
DownloadFileFromURL downloader = new DownloadFileFromURL();
//downloader.setDownloadedFileName()
String name = book.fileketab.substring(book.fileketab.lastIndexOf("/") + 1);
downloader.setDownloadedFileName(name);
downloader.execute(JSONCommands.firstURL + book.fileketab);
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.download, menu);
return true;
}
private class DownloadFileFromURL extends AsyncTask<String, String, String> {
private String downloadedfileName;
#Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
Toast.makeText(getApplicationContext(), "بارگذاری کتاب باموفقیت انجام شد", Toast.LENGTH_LONG).show();
Toast.makeText(getApplicationContext(), "برای دیدن آن به کتاب‌خانه مراجعه نمایید", Toast.LENGTH_LONG).show();
}
public void setDownloadedFileName(String downloadedfileName){
this.downloadedfileName = downloadedfileName;
}
/**
* Downloading file in background thread
* */
#Override
protected String doInBackground(String... surl) {
int count;
try {
URL url = new URL(surl[0]);
URLConnection conection = url.openConnection();
conection.connect();
// this will be useful so that you can show a typical 0-100%
// progress bar
int lenghtOfFile = conection.getContentLength();
// download the file
InputStream input = new BufferedInputStream(url.openStream(),
8192);
// Output stream
//OutputStream output = new FileOutputStream(Environment
// .getExternalStorageDirectory().toString()
// + "/data/" + downloadedfileName);
OutputStream output = new FileOutputStream(getFilesDir()+File.separator +downloadedfileName);
byte data[] = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
// publishing the progress....
// After this onProgressUpdate will be called
// publishProgress("" + (int) ((total * 100) / lenghtOfFile));
// writing data to file
output.write(data, 0, count);
}
// flushing output
output.flush();
// closing streams
output.close();
input.close();
} catch (Exception e) {
Log.e("Error: ", e.getMessage());
}
return null;
}
}
/**
* After completing background task called
* **/
}
and here is my getpic code using Bitmap(this function is in my JSONCommands class and that is why I called them as "JSONCommands.getpic"):
public static void getpic(String str, ImageView tasvir){
Bitmap bitmap;
if(str != null){
bitmap = getBitmapFromURL(firstURL+ str);
if(bitmap!=null){
tasvir.setImageBitmap(bitmap);
}
else{
tasvir.setImageResource(R.drawable.p3_books);
}
}
else{
tasvir.setImageResource(R.drawable.p3_books);
}
}
public static Bitmap getBitmapFromURL(String src) {
try {
URL url = new URL(src);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream input = connection.getInputStream();
Bitmap myBitmap = BitmapFactory.decodeStream(input);
connection.disconnect();
return myBitmap;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
I cant find the solution and it drives me crazy:) please help, tank you.

Categories

Resources