Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Android Android Data Persistence File Storage Displaying Images in a Grid

Jun Kakeno
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Jun Kakeno
iOS Development with Swift Techdegree Graduate 24,842 Points

Grid created but image is not displayed

When I run the app I can see the grids with the name for each jpg on the emulator screen but there's no image displayed. I've follow the video and checked that my code is exactly as explained in the video. Also I'm using the starter files provided by Evan, and checked that the .jpg files are actually images and that they are under the assets folder. I've found old post reporting the same issue but I couldn't find a solution. Please help.

Mahmoud Amin
Mahmoud Amin
Courses Plus Student 6,269 Points

If you can please share your code and if their is any error please clarify

Jun Kakeno
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Jun Kakeno
iOS Development with Swift Techdegree Graduate 24,842 Points
package com.teamtreehouse.mememaker.utils;

import android.content.Context;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Environment;

import com.teamtreehouse.mememaker.MemeMakerApplicationSettings;

import java.io.File;
import java.io.FileFilter;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class FileUtilities {

    public static void saveAssetImage(Context context, String assetName) {

//java.io is an abstraction of an actual file once instantiated you have access to methods that can be used on a file (Eg. check if it exist in the file system, delete its content in the file system)
//        File fileDirectory = context.getFilesDir();
        File fileDirectory = getFileDirectory(context);
//Create location to write a file
        File fileToWrite = new File(fileDirectory,assetName);
//Get access to asset files to read the file
        AssetManager assetManager = context.getAssets();
        try {
//Create a input file stream so we can read the file, open() throws exception so rounded with try catch to handle exception
            InputStream in = assetManager.open(assetName);
//Create an output file stream so we can write the file, FileOutputStream throws exception so rounded with try catch to handle exception
            OutputStream out = new FileOutputStream(fileToWrite);
//Add right to internal storage

            in.close();
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static File getFileDirectory (Context context){
        MemeMakerApplicationSettings settings = new MemeMakerApplicationSettings(context);
//        String storageType = StorageType.INTERNAL;
        String storageType = settings.getStoragePreference();
        if(storageType.equals(StorageType.INTERNAL)) {
            return context.getFilesDir();
        } else {
            if (isExternalStorageAvailable()){
                if(storageType.equals(StorageType.PRIVATE_EXTERNAL)) {
                    return context.getExternalFilesDir(null);
                }else {
                    return Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
                }
            } else {
                return context.getFilesDir();
            }
        }
    }

    public static boolean isExternalStorageAvailable(){
        String state = Environment.getExternalStorageState();
        if(Environment.MEDIA_MOUNTED.equals(state)){
            return true;
        }
        return false;
    }

//Read data thru input stream and write that data to a buffer until there's nothing left to read
//This exception is getting catch in saveAssetImage()
    private static void copyFile(InputStream in, OutputStream out) throws IOException {
        byte[] buffer = new byte[1024];
        int read;
        while((read = in.read(buffer)) != -1) {
            out.write(buffer, 0, read);
        }
    }

//Create method to return array of files
    public static File [] listFiles (Context context){
//        File fileDirectory = context.getFilesDir();
        File fileDirectory = getFileDirectory(context);
//List files by applying filer in the directory; list files which directory contains .jpg
        File [] filteredFiles = fileDirectory.listFiles(new FileFilter() {
            @Override
            public boolean accept(File file) {
                if (file.getAbsolutePath().contains(".jpg")){
                    return  true;
                } else {
                    return false;
                }
            }
        });
        return filteredFiles;
    }

    public static Uri saveImageForSharing(Context context, Bitmap bitmap,  String assetName) {
        File fileToWrite = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), assetName);

        try {
            FileOutputStream outputStream = new FileOutputStream(fileToWrite);
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream);
            outputStream.flush();
            outputStream.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            return Uri.fromFile(fileToWrite);
        }
    }


    public static void saveImage(Context context, Bitmap bitmap, String name) {
//        File fileDirectory = context.getFilesDir();
        File fileDirectory = getFileDirectory(context);
        File fileToWrite = new File(fileDirectory, name);

        try {
            FileOutputStream outputStream = new FileOutputStream(fileToWrite);
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream);
            outputStream.flush();
            outputStream.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}
Jun Kakeno
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Jun Kakeno
iOS Development with Swift Techdegree Graduate 24,842 Points
package com.teamtreehouse.mememaker.ui.fragments;

import android.app.AlertDialog;
import android.app.Fragment;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.GridView;

import com.teamtreehouse.mememaker.R;
import com.teamtreehouse.mememaker.adapters.GridViewAdapter;
import com.teamtreehouse.mememaker.models.ImageGridItem;
import com.teamtreehouse.mememaker.ui.activities.CreateMemeActivity;
import com.teamtreehouse.mememaker.ui.activities.MemeSettingsActivity;
import com.teamtreehouse.mememaker.utils.FileUtilities;

import java.io.File;
import java.util.ArrayList;

public class ImageGridFragment extends Fragment {

    private GridView mGridView;
    private GridViewAdapter mGridAdapter;
    public static int RESULT_LOAD_IMAGE = 1000;

    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_image_grid, container, false);
        mGridView = (GridView) rootView.findViewById(R.id.gridView);
        mGridAdapter = new GridViewAdapter(this.getActivity(), R.layout.view_grid, extractFiles());
        mGridView.setAdapter(mGridAdapter);
        mGridView.setOnItemClickListener(mOnItemClickListener);
        mGridView.setOnItemLongClickListener(mOnItemLongClickListener);
        this.setHasOptionsMenu(true);
        return rootView;
    }

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

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if(item.getItemId() == R.id.import_action) {
            Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
            startActivityForResult(intent, RESULT_LOAD_IMAGE);
        } else {
            if (item.getItemId() == R.id.settings_action) {
                Intent intent = new Intent(this.getActivity(), MemeSettingsActivity.class);
                startActivity(intent);
            }
        }

        return super.onOptionsItemSelected(item);
    }

    private ArrayList extractFiles() {
        final ArrayList imageItems = new ArrayList();
//Get the file array from FileUtilities class
        File [] filteredFiles = FileUtilities.listFiles(this.getActivity());
        for (File filteredFile : filteredFiles){
//Decode the file to bipmap
            Bitmap bitmap = BitmapFactory.decodeFile(filteredFile.getAbsolutePath());
//Create file item variable
            ImageGridItem item = new ImageGridItem(bitmap, filteredFile.getName(), filteredFile.getAbsolutePath());
//Attach the file item to the array list
            imageItems.add(item);
        }
        return imageItems;
    }

    private void resetGridAdapter() {
        mGridAdapter = new GridViewAdapter(this.getActivity(), R.layout.view_grid, extractFiles());
        mGridView.setAdapter(mGridAdapter);
    }

    protected AdapterView.OnItemClickListener mOnItemClickListener = new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
            ImageGridItem imageGridItem = (ImageGridItem) adapterView.getAdapter().getItem(i);
            Intent intent = new Intent(ImageGridFragment.this.getActivity(), CreateMemeActivity.class);
            intent.putExtra(CreateMemeActivity.EXTRA_IMAGE_FILE_PATH, imageGridItem.getFullPath());
            Log.d("FILE:", imageGridItem.getFullPath());
            ImageGridFragment.this.getActivity().startActivity(intent);
        }
    };

    protected AdapterView.OnItemLongClickListener mOnItemLongClickListener = new AdapterView.OnItemLongClickListener() {
        @Override
        public boolean onItemLongClick(AdapterView<?> adapterView, View view, int i, long l) {
            final ImageGridItem imageGridItem = (ImageGridItem) adapterView.getAdapter().getItem(i);

            AlertDialog.Builder builder = new AlertDialog.Builder(ImageGridFragment.this.getActivity());
            builder.setTitle(R.string.dialog_confirm)
                    .setMessage(R.string.dialog_message_delete_file)
                    .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialogInterface, int i) {
                            File fileToDelete = new File(imageGridItem.getFullPath());
                            boolean deleted = fileToDelete.delete();
                            if (deleted) {
                                ImageGridFragment.this.resetGridAdapter();
                            }
                        }
                    })
                    .setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialogInterface, int i) {

                        }
                    });
            builder.create().show();
            return true;
        }
    };
}
Jun Kakeno
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Jun Kakeno
iOS Development with Swift Techdegree Graduate 24,842 Points
package com.teamtreehouse.mememaker;

import android.preference.Preference;
import android.preference.PreferenceManager;
import com.teamtreehouse.mememaker.utils.FileUtilities;

public class MemeMakerApplication extends android.app.Application {
    @Override
    public void onCreate() {
        super.onCreate();

        FileUtilities.saveAssetImage(this, "dogmess.jpg");
        FileUtilities.saveAssetImage(this, "excitedcat.jpg");
        FileUtilities.saveAssetImage(this, "guiltypup.jpg");
    }
}