0

This is a question about image saving in android app. I am trying to make popular movies app of an udacity project.Link - https://docs.google.com/document/d/1gtXUu1nzLGWrGfVCD6tEA0YHoYA9UNyT2yByqjJemp8/pub?embedded=true

I have picasso library for image downloading in ImageAdapter--
Here is my ImageAdapter code -

package jindal5.mayank.popular_movies_14ce10032_gsc;

public class ImageAdapter extends BaseAdapter {
    private String drawablePrefix;
    private Context mContext;
    private ArrayList<String> mThumbUris;
    private ArrayList<String> mov_id_arr;
    private ArrayList<String> mov_tit_arr;

    public ImageAdapter(Context c) {
        mContext = c;
        String packName=mContext.getPackageName();
        drawablePrefix="android.resource://" +packName+ "/";
        ArrayList<String> mov_id_arr =new ArrayList<>();
        ArrayList<String> mov_tit_arr=new ArrayList<>();
        mov_tit_arr.add("asdf");
        mov_tit_arr.add("asdf");
        mov_tit_arr.add("asdf");
        mov_tit_arr.add("asdf");
        mov_tit_arr.add("asdf");
        mov_tit_arr.add("asdf");

        ArrayList<String> uriPaths=new ArrayList<>();// place your drawables.

        uriPaths.add(drawablePrefix+ R.drawable.sample_0);
        uriPaths.add(drawablePrefix+ R.drawable.sample_0);
        uriPaths.add(drawablePrefix+ R.drawable.sample_0);
        uriPaths.add(drawablePrefix+ R.drawable.sample_0);
        uriPaths.add(drawablePrefix+ R.drawable.sample_0);
        uriPaths.add(drawablePrefix+ R.drawable.sample_0);


        mThumbUris=uriPaths;
    }

    public int getCount() {
        return mThumbUris.size();
    }

    public Object getItem(int position) {
        return mThumbUris.get(position);
    }

    public long getItemId(int position) {
        return 0;
    }

    // create a new ImageView for each item referenced by the Adapter
    public View getView(int position, View convertView, ViewGroup parent) {
        ImageView imageView;
        if (convertView == null) {
            // if it's not recycled, initialize some attributes
            imageView = new ImageView(mContext);
           // imageView.setLayoutParams(new GridView.LayoutParams(85, 85));
           // imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
           // imageView.setPadding(8, 8, 8, 8);
        } else {
            imageView = (ImageView) convertView;
        }
        Uri imgUri=Uri.parse(mThumbUris.get(position));

        Picasso.with(mContext)
                .load(imgUri)
                .placeholder(R.drawable.sample_0)
               .centerCrop()
                .resize(400,400)
                .into(imageView);
       imageView.setImageResource(mThumbIds[position]);
       // imageView.setAdjustViewBounds(true);
        return imageView;
    }

    public ArrayList<String> getUriList(){
        return mThumbUris;
    }
    public ArrayList<String> getidlist(){
        return mov_id_arr;
    }
    public ArrayList<String> gettitlist(){
        return mov_tit_arr;
    }

    // references to our images
    private Integer[] mThumbIds = {
            R.drawable.sample_2, R.drawable.sample_3,
            R.drawable.sample_4, R.drawable.sample_5,
            R.drawable.sample_6, R.drawable.sample_7,
            R.drawable.sample_0, R.drawable.sample_1,
            R.drawable.sample_2, R.drawable.sample_3,
            R.drawable.sample_4, R.drawable.sample_5,
            R.drawable.sample_6, R.drawable.sample_7,
            R.drawable.sample_0, R.drawable.sample_1,
            R.drawable.sample_2, R.drawable.sample_3,
            R.drawable.sample_4, R.drawable.sample_5,
            R.drawable.sample_6, R.drawable.sample_7
    };
}

Now I have two problems -

  1. When I return back to Main Activity from another activity ,local images appear rather than previously downloading images.
  2. When I close my app and open again I see the local images appear rather than downloaded images at last time. Somebody told that you have to save that images after downloading in local memory using File or content provider. But I don't know how to do that ?? .

3.When I change my device orientation I face the same problem.

This is my fragment of main activity-

package jindal5.mayank.popular_movies_14ce10032_gsc;

/**
 * A placeholder fragment containing a simple view.
 */
public class MainActivityFragment extends Fragment {
    public ImageAdapter imag_adap;
    public String movieJsonStr;
    public ArrayList<String > tit_arr = new ArrayList<String>();
    public ArrayList<String > rel_dat_arr = new ArrayList<String>();
    public ArrayList<String > url1_arr = new ArrayList<String>();
    public ArrayList<String > over_arr = new ArrayList<String>();
    public ArrayList<String > id_arr = new ArrayList<String>();
    public String put_ext_tit;
    public String rel_date_ext;
 public  String url_for_pos_ex;
    public String over_ex;
    public String id_ex;
    public MainActivityFragment() {
    }
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // Add this line in order for this fragment to handle menu events.
        setHasOptionsMenu(true);
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        inflater.inflate(R.menu.menu_fragment, menu);
    }

    @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();
        if (id == R.id.action_refresh) {
            //SharedPreferences share = PreferenceManager.getDefaultSharedPreferences();
          //  String order = share.getString()
            getimage imageTask = new getimage();
            imageTask.execute("popularity.desc");
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
       View rootview = inflater.inflate(R.layout.fragment_main, container, false);
        GridView grid = (GridView) rootview.findViewById(R.id.gridView);
        imag_adap = new ImageAdapter(getActivity());
        grid.setAdapter(imag_adap);

        grid.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                String[] tit1 = tit_arr.toArray(new String[tit_arr.size()]);
                String[] rel_date = rel_dat_arr.toArray(new String[rel_dat_arr.size()]);
                String[] url_for_pos = url1_arr.toArray(new String[url1_arr.size()]);
                String[] over = url1_arr.toArray(new String[over_arr.size()]);
                String[] id = id_arr.toArray(new String[over_arr.size()]);
               // Log.v("mayank",tit1[3]);
                try{
                    put_ext_tit = tit1[i];
                    rel_date_ext = rel_date[i];
                    url_for_pos_ex = url_for_pos[i];
                    over_ex = over[i];
                    id_ex =id[i];
                    Intent intent = new Intent(getActivity(),det_mov.class);
                    //.putExtra(Intent.EXTRA_TEXT,put_ext_tit);
                    Bundle extras = new Bundle();
                    extras.putString("title",put_ext_tit);
                    extras.putString("rel_date",rel_date_ext);
                    extras.putString("url_pos",url_for_pos_ex);
                    extras.putString("over_ex",over_ex);
                    extras.putString("id_ex", id_ex);
                    extras.putInt("posit",i);
                    intent.putExtras(extras);
                    startActivity(intent);
                }
                catch (ArrayIndexOutOfBoundsException p){
                    Log.e("mayank","reg",p);
                }
            }
        });

        return rootview;
    }

    public class getimage extends AsyncTask<String, String, String[]> {
        ConnectivityManager conMgr = (ConnectivityManager) getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);


        private final String LOG_TAG = getimage.class.getSimpleName();
        public int count;
        String[] pos_path;
        String[]  mov_id;
        String[] tit;
        String[] rev;
        String[] rel_dat;
        String[] url1;
        String[] over;
        String[] id;
        public ImageAdapter getad(){
            return imag_adap;
        }


        @Override
        protected String[] doInBackground(String... params) {
            HttpURLConnection urlConnection = null;

            BufferedReader reader = null;
            try {
                final String movie_url_str = "http://api.themoviedb.org/3/discover/movie?sort_by="+ params[0] +"&api_key=8d7a48043ba1d3348181e2b6615cedc7";
                URL movie_url = new URL(movie_url_str);
                urlConnection = (HttpURLConnection) movie_url.openConnection();
                urlConnection.setRequestMethod("GET");
                urlConnection.connect();
                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) {
                    buffer.append(line + "\n");
                }
                if (buffer.length() == 0) {
                    return null;
                }
               movieJsonStr = buffer.toString();

                JSONObject movieJson = new JSONObject(movieJsonStr);
                JSONArray movieJsonarray = movieJson.getJSONArray("results");
                 count = movieJsonarray.length();
                pos_path = new String[count];
                mov_id = new String[count];
                tit = new String[count];
                rev = new String[count];
                rel_dat = new String[count];
                url1 = new String[count];
                over = new String[count];
                id = new String[count];
                for(int i=0;i<count;i++){
                    JSONObject sin_movie = movieJsonarray.getJSONObject(i);
                    pos_path[i] = sin_movie.getString("poster_path");
                    over[i] = sin_movie.getString("overview");
                    Uri.Builder url_for_poster = new Uri.Builder();
                    String qw = "t";
                    String as = "p";
                    Uri.Builder url_build =  url_for_poster.scheme("http").authority("image.tmdb.org").appendPath(qw).appendPath(as).appendPath("w500").appendEncodedPath(pos_path[i]);
                     url1[i] = url_build.toString();

                   // mov_id[i] =  sin_movie.getString("id");
                   tit[i] = sin_movie.getString("title");
                    //rev[i] = sin_movie.getString("review");
                    rel_dat[i] = sin_movie.getString("release_date");
                    id[i] = sin_movie.getString("id");
                    publishProgress((String)(tit[i]),(String)(rel_dat[i]),(String)(url1[i]),(String)(over[i]),(String)(id[i]));
                    Log.v(LOG_TAG, "Forecast string: " + id[i]);

                }
            } catch (IOException | JSONException 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);
                    }
                }
            }
            return pos_path;
            }
        @Override
        protected void onProgressUpdate(String... values) {

                tit_arr.add(values[0]);
            rel_dat_arr.add(values[1]);
            url1_arr.add(values[2]);
            over_arr.add(values[3]);
            id_arr.add(values[4]);
        }

        @Override
        protected void onPostExecute(String[] result) {

            ArrayList<String> uriPaths = imag_adap.getUriList();
            uriPaths.clear();
           // ImageView[] im_vi = new ImageView[count];

            for(int j=0;j<count;j++) {

               String  pos_sin_path = pos_path[j];
                String id_mov = id[j];
                Uri.Builder url_for_poster = new Uri.Builder();
                Uri.Builder url_for_rev = new Uri.Builder();
                String qw = "t";
                String as = "p";
              Uri.Builder url_build =  url_for_poster.scheme("http").authority("image.tmdb.org").appendPath(qw).appendPath(as).appendPath("w500").appendEncodedPath(pos_sin_path);
                String url = url_build.toString();
                Uri.Builder url_build_rev = url_for_rev.scheme("http").encodedAuthority("api.themoviedb.org/3/movie").appendPath(id_mov).appendPath("reviews");
                uriPaths.add(url);
               // mov_title.add(tit[j]);
                //mov_id_arr.add(id);
             //   mov_tit_arr.add(title);
             // }
              //catch (UnsupportedEncodingException e){

              //}
                //url_build.clearQuery();

                //Picasso.with(getActivity()).load("http://image.tmdb.org/t/p/w185//nBNZadXqJSdt05SHLqgT0HuC5Gm.jpg").into(im_vi[j]);
                //imag_adap.getItem(j) = im_vi[j];\

            }
            imag_adap.notifyDataSetChanged();
        }
    }
}

Looking for a help As I am new in android.

Mayank Jindal
  • 355
  • 5
  • 15

2 Answers2

1

When I close my app and open again I see the local images appear rather than downloaded images at last time. Somebody told that you have to save that images after downloading in local memory using File or content provider. But I don't know how to do that ?? .

This is expected since you do not have the photos anywhere on your device.Save the image in a database (SQLite) If you want it persisted and available when you return to your app. Or you load them each time you restart your activity, preferably through an AsyncTask.

To store images in the SQLite database, take a look at How to store(bitmap image) and retrieve image from sqlite database in android? Tells you everything you need to know about saving and retrieving images.

Community
  • 1
  • 1
Ojonugwa Jude Ochalifu
  • 26,627
  • 26
  • 120
  • 132
  • I don't know how to save images in database or file . Can u tell me this thing in detail – Mayank Jindal Jul 07 '15 at 19:14
  • Have you used the SQLite database before? – Ojonugwa Jude Ochalifu Jul 07 '15 at 19:20
  • Yes , I saw the course of Udacity . but don't know how to use it with images. – Mayank Jindal Jul 07 '15 at 19:23
  • But in my case how can I get bitmap . because I m loading URL direct in Picasso.load() . – Mayank Jindal Jul 07 '15 at 19:38
  • And what's the format of the image you are loading? – Ojonugwa Jude Ochalifu Jul 07 '15 at 19:41
  • Okay, then Google how to save that in SQLite. The process should be almost similar – Ojonugwa Jude Ochalifu Jul 07 '15 at 19:44
  • And should I write code for storing in image adapter class or main activity fragment as I am populating gridview with imageadapter – Mayank Jindal Jul 07 '15 at 19:47
  • This shouldn't be difficult to figure out. Create a database, Get image through picasso, save it in database, when you load gridview popluate GridView with image. You should create a database helper class with methods to save and retrieve images – Ojonugwa Jude Ochalifu Jul 07 '15 at 19:54
  • OK . and it would be great if u upvote my question because currently I don't have enough reputation to upvote ur answer – Mayank Jindal Jul 07 '15 at 19:57
  • Haha.Am sure that's against Stack Overflow policy.Just upvote when you gain enough reputation.Cheers – Ojonugwa Jude Ochalifu Jul 07 '15 at 20:00
  • OK. Thank you very much – Mayank Jindal Jul 07 '15 at 20:01
  • Sholud I write whole content provider with uri matcher ,sqliteopenhelper and all. Is there any short method for making database and content provider in my case?? – Mayank Jindal Jul 08 '15 at 09:31
  • Just have a separate class that for your database.This call will have methods to add, delete, retrieve and update image.Then, whereever you are there is logic (method) to get image in your app, use the add image method there: `myDatabase.addImage(ImageFormat image)` and then where ever you are getting images to add to your gridview, do `myDatabaseHelper.getImages()` and make that method retrieve a list of all images.You don't have to place everything in one class.I don't know anything about Picasso so I can't really say much more than am saying now – Ojonugwa Jude Ochalifu Jul 08 '15 at 10:18
  • Please have a look at http://stackoverflow.com/questions/31314482/getting-null-pointer-exception-in-sqlitedatabse-query-method – Mayank Jindal Jul 09 '15 at 10:15
  • http://stackoverflow.com/questions/34249254/unable-to-access-changed-value-of-variable-from-another-class-in-android-studio Have a look at this question – Mayank Jindal Dec 13 '15 at 08:27
0

try this,

answer-1:

try to change adapter initialization logic to onCreateView to onCreate. put this line in onCreate.

imag_adap = new ImageAdapter(getActivity());

answer-2:

after download images save that uri paths in database or file or in sharedpreference. and then retrieve that uri's in creation adapter.

ArrayList<String> uriPathsFromDb=getListOfUriFromDatabase();
if(uriPathsFromDb.size()==0){
ArrayList<String> uriPaths=new ArrayList<>();// place your drawables.

        uriPaths.add(drawablePrefix+ R.drawable.sample_0);
        uriPaths.add(drawablePrefix+ R.drawable.sample_0);
        uriPaths.add(drawablePrefix+ R.drawable.sample_0);
        uriPaths.add(drawablePrefix+ R.drawable.sample_0);
        uriPaths.add(drawablePrefix+ R.drawable.sample_0);
        uriPaths.add(drawablePrefix+ R.drawable.sample_0);

        mThumbUris=uriPaths;
}else{
   mThumbUris=uriPathsFromDb;
}
Krishna V
  • 1,801
  • 1
  • 14
  • 16
  • I cut imag_adap from mainactivityfragment.java and paste it to mainactivity.java . Now it is showing error in java. – Mayank Jindal Jul 08 '15 at 08:41
  • I shifted whole code of mainactivityfragment oncreateview in mainactivty oncreate now it compiled but same problem – Mayank Jindal Jul 08 '15 at 08:55
  • not yet. I don't want to save urls I want to save images because I don't want to download them again. And I don't know how to store in database or file – Mayank Jindal Jul 08 '15 at 09:54
  • Picasso.with(this).load(url).into(target); here Target is class it is useful to download the image. – Krishna V Jul 08 '15 at 10:06
  • Please have a look at http://stackoverflow.com/questions/31314482/getting-null-pointer-exception-in-sqlitedatabse-query-method – Mayank Jindal Jul 09 '15 at 10:15
  • after implementing your answer-1 images don't change after returning from phone's back button but changes from app's up button . MAINACTIVITYFRAGMENT.java - public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); imag_adap = new ImageAdapter(getActivity()); // Add this line in order for this fragment to handle menu events. setHasOptionsMenu(true); } – Mayank Jindal Jul 09 '15 at 13:41
  • ya now it worked . I pasted in oncreate - imag_adap = new ImageAdapter(getActivity()); getimage imageTask = new getimage(); imageTask.execute("popularity.desc"); // Add this line in order for this fragment to handle menu events. setHasOptionsMenu(true); – Mayank Jindal Jul 09 '15 at 14:16