2

My goal is to create an application which after clicking on it, an activity will be displayed and all the photos from the phone gallery and SD card will be placed on this activity. Unfortunately, I have an error which I am unable to locate. Below I am posting my .java file and the error log.

package com.example.androidgridview;

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

import android.os.Bundle;
import android.os.Environment;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.Toast;

public class MainActivity extends Activity {

    public class ImageAdapter extends BaseAdapter {

        private Context mContext;
        ArrayList<String> itemList = new ArrayList<String>();

        public ImageAdapter(Context c) {
            mContext = c;   
        }

        void add(String path){
            itemList.add(path); 
        }

        @Override
        public int getCount() {
            return itemList.size();
        }

        @Override
        public Object getItem(int arg0) {
            // 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) {
            ImageView imageView;
            if (convertView == null) {  // if it's not recycled, initialize some attributes
                imageView = new ImageView(mContext);
                imageView.setLayoutParams(new GridView.LayoutParams(220, 220));
                imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
                imageView.setPadding(8, 8, 8, 8);
            } else {
                imageView = (ImageView) convertView;
            }

            Bitmap bm = decodeSampledBitmapFromUri(itemList.get(position), 220, 220);

            imageView.setImageBitmap(bm);
            return imageView;
        }

        public Bitmap decodeSampledBitmapFromUri(String path, int reqWidth, int reqHeight) {

            Bitmap bm = null;
            // First decode with inJustDecodeBounds=true to check dimensions
            final BitmapFactory.Options options = new BitmapFactory.Options();
            options.inJustDecodeBounds = true;
            BitmapFactory.decodeFile(path, options);

            // Calculate inSampleSize
            options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

            // Decode bitmap with inSampleSize set
            options.inJustDecodeBounds = false;
            bm = BitmapFactory.decodeFile(path, options); 

            return bm;      
        }

        public int calculateInSampleSize(

            BitmapFactory.Options options, int reqWidth, int reqHeight) {
            // Raw height and width of image
            final int height = options.outHeight;
            final int width = options.outWidth;
            int inSampleSize = 1;

            if (height > reqHeight || width > reqWidth) {
                if (width > height) {
                    inSampleSize = Math.round((float)height / (float)reqHeight);    
                } else {
                    inSampleSize = Math.round((float)width / (float)reqWidth);      
                }   
            }

            return inSampleSize;    
        }

    }

    ImageAdapter myImageAdapter;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        GridView gridview = (GridView) findViewById(R.id.gridview);
        myImageAdapter = new ImageAdapter(this);
        gridview.setAdapter(myImageAdapter);

        String ExternalStorageDirectoryPath = Environment
                .getExternalStorageDirectory()
                .getAbsolutePath();

        String targetPath = ExternalStorageDirectoryPath + "/test/";

        Toast.makeText(getApplicationContext(), targetPath, Toast.LENGTH_LONG).show();
        File targetDirector = new File(targetPath);

        File[] files = targetDirector.listFiles();
        for (File file : files){
            myImageAdapter.add(file.getAbsolutePath());
        } 
    }
}

and this is the error log:

      java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.androidgridview/com.example.androidgridview.MainActivity}: java.lang.NullPointerException: Attempt to get length of null array
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2694)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2759)
            at android.app.ActivityThread.access$900(ActivityThread.java:178)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1449)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:145)
            at android.app.ActivityThread.main(ActivityThread.java:5944)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)
     Caused by: java.lang.NullPointerException: Attempt to get length of null array
            at com.example.androidgridview.MainActivity.onCreate(MainActivity.java:129)
            at android.app.Activity.performCreate(Activity.java:6289)
            at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1119)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2647)
           
XeniaSis
  • 2,192
  • 5
  • 24
  • 39

2 Answers2

0

I have run the code you pasted above, and i find out that your target Path is ExternalStorageDirectoryPath + "/test/";.

If the path ExternalStorageDirectoryPath + "/test/" in my device is not null, the code can work correctly no matter the folder ExternalStorageDirectoryPath + "/test/" has pictures or not. However, if the path ExternalStorageDirectoryPath + "/test/" is null, NullPointerException error will occur in the line for (File file : files){.

So we can try this way: if the path is null , we create the path to avoid this error. My change is :

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    GridView gridview = (GridView) findViewById(R.id.gridview);
    myImageAdapter = new ImageAdapter(this);
    gridview.setAdapter(myImageAdapter);

    String ExternalStorageDirectoryPath = Environment
            .getExternalStorageDirectory()
            .getAbsolutePath();

    String targetPath = ExternalStorageDirectoryPath + "/test/";
    System.err.println(isFolderExists(targetPath));

    Toast.makeText(getApplicationContext(), targetPath, Toast.LENGTH_LONG).show();
    File targetDirector = new File(targetPath);

    File[] files = targetDirector.listFiles();
    for (File file : files){
        myImageAdapter.add(file.getAbsolutePath());
    } 
}

private boolean isFolderExists(String strFolder) {
    File file = new File(strFolder);        
    if (!file.exists()) {
        if (file.mkdirs()) {                
            return true;
        } else {
            return false;

        }
    }
    return true;
}

I invoked isFolderExists() method to create the path ExternalStorageDirectoryPath + "/test/" so it is not null before we traverse the pictures in the folder.

Zoe
  • 27,060
  • 21
  • 118
  • 148
LinaInverce
  • 166
  • 3
  • 13
0

According to documentation

listFiles Returns an array of files contained in the directory represented by this file. The result is null if this file is not a directory.

File[] files = targetDirector.listFiles(); 
    if(files!=null){
                for (File file : files){
                    myImageAdapter.add(file.getAbsolutePath());
                } 
            }else{
                // do something if directory is null 
            }

add a check for null. Because listfiles returns an array of files or null. Hope it works for you.

and also add a check if the directory exists or not.

Deepak Goyal
  • 4,747
  • 2
  • 21
  • 46