Pavan Bilagi
Pavan Bilagi

Reputation: 1617

Caused by java.lang.NullPointerException: Attempt to invoke virtual method 'int android.graphics.Bitmap.getWidth()' on a null object reference

I have BitmapScalingHelper.java:

public class BitmapScalingHelper
{
    public static Bitmap decodeResource(Resources res, int resId, int dstWidth, int dstHeight)
    {
        Options options = new Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeResource(res, resId, options);
        options.inJustDecodeBounds = false;

        options.inSampleSize = calculateSampleSize(options.outWidth, options.outHeight, dstWidth,
                dstHeight);

        Bitmap unscaledBitmap = BitmapFactory.decodeResource(res, resId, options);

        return unscaledBitmap;
    }

    public static Bitmap decodeFile(String filePath, int dstWidth, int dstHeight)
    {
        Options options = new Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(filePath, options);

        options.inJustDecodeBounds = false;
        options.inSampleSize = calculateSampleSize(options.outWidth, options.outHeight, dstWidth,
                dstHeight);

        Bitmap unscaledBitmap = BitmapFactory.decodeFile(filePath, options);

        return unscaledBitmap;
    }


    public static int calculateSampleSize(int srcWidth, int srcHeight, int dstWidth, int dstHeight)
    {
        final float srcAspect = (float)srcWidth / (float)srcHeight;
        final float dstAspect = (float)dstWidth / (float)dstHeight;

        if (srcAspect > dstAspect)
        {
            return srcWidth / dstWidth;
        }
        else
        {
            return srcHeight / dstHeight;
        }
    }

    public static Bitmap createScaledBitmap(Bitmap unscaledBitmap, int dstWidth, int dstHeight)
    {
        Rect srcRect = calculateSrcRect(unscaledBitmap.getWidth(), unscaledBitmap.getHeight());

        Rect dstRect = calculateDstRect(unscaledBitmap.getWidth(), unscaledBitmap.getHeight(),
                dstWidth, dstHeight);

        Bitmap scaledBitmap = Bitmap.createBitmap(dstRect.width(), dstRect.height(),
                Config.ARGB_8888);

        Canvas canvas = new Canvas(scaledBitmap);
        canvas.drawBitmap(unscaledBitmap, srcRect, dstRect, new Paint(Paint.FILTER_BITMAP_FLAG));

        return scaledBitmap;
    }

    public static Rect calculateSrcRect(int srcWidth, int srcHeight)
    {
        System.out.print("Scr" + srcWidth + " " + srcHeight);
        return new Rect(0, 0, srcWidth, srcHeight);
    }

    public static Rect calculateDstRect(int srcWidth, int srcHeight, int dstWidth, int dstHeight)
    {
        final float srcAspect = (float)srcWidth / (float)srcHeight;
        final float dstAspect = (float)dstWidth / (float)dstHeight;

        if (srcAspect > dstAspect)
        {
            return new Rect(0, 0, dstWidth, (int)(dstWidth / srcAspect));
        }
        else
        {
            return new Rect(0, 0, (int)(dstHeight * srcAspect), dstHeight);
        }
    }
}

In this class there is:

createScaledBitmap()

...which returns a scaled bitmap image.

In another class, I have this method:

public Bitmap readSelectedBitmapFromFile(Context context, String fileName)
    {
        DisplayMetrics metrics = new DisplayMetrics();
        WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        windowManager.getDefaultDisplay().getMetrics(metrics);

        Bitmap scaledBitmap = getDefaultBitmap(context);

        try {
            File themeParentDir = context.getDir(THEME_DIRECTORY_NAME, Context.MODE_PRIVATE); //Creating an internal dir;
            File themeSubDir = new File(themeParentDir, THEME_SUB_DIRECTORY_NAME + getThemeBasedDirectoryNumber(m_SelectedTheme));
            themeSubDir.mkdir();

            File themeFileWithinDir = new File(themeSubDir, fileName); //Getting a file within the dir.

            if(themeFileWithinDir.exists())
            {
                // Part 1: Decode image
                Bitmap unscaledBitmap = BitmapScalingHelper.decodeFile(themeFileWithinDir.getPath(), metrics.widthPixels, metrics.heightPixels);

                // Part 2: Scale image
                scaledBitmap = BitmapScalingHelper.createScaledBitmap(unscaledBitmap, metrics.widthPixels, metrics.heightPixels);
                unscaledBitmap.recycle();
            }

            m_SelectedBitmap = scaledBitmap;

        }
        catch (Error e) {
            e.printStackTrace();
        }

        return scaledBitmap;
    }

This code was working fine in many devices. But it was crashing in some devices. Can any one please help me out ?

I am getting a log like this:

Fatal Exception: java.lang.RuntimeException: Unable to start activity ComponentInfo: java.lang.NullPointerException: Attempt to invoke virtual method 'int android.graphics.Bitmap.getWidth()' on a null object reference
       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3254)
       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3350)
       at android.app.ActivityThread.access$1100(ActivityThread.java:222)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1795)
       at android.os.Handler.dispatchMessage(Handler.java:102)
       at android.os.Looper.loop(Looper.java:158)
       at android.app.ActivityThread.main(ActivityThread.java:7229)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
Caused by java.lang.NullPointerException: Attempt to invoke virtual method 'int android.graphics.Bitmap.getWidth()' on a null object reference
       at in.plackal.lovecyclesfree.util.BitmapScalingHelper.createScaledBitmap(SourceFile:62)
       at in.plackal.lovecyclesfree.general.ThemeManager.readSelectedBitmapFromFile(SourceFile:202)
       at in.plackal.lovecyclesfree.activity.SplashActivity.onCreate(SourceFile:70)
       at android.app.Activity.performCreate(Activity.java:6876)
       at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1135)
       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3207)
       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3350)
       at android.app.ActivityThread.access$1100(ActivityThread.java:222)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1795)
       at android.os.Handler.dispatchMessage(Handler.java:102)
       at android.os.Looper.loop(Looper.java:158)
       at android.app.ActivityThread.main(ActivityThread.java:7229)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)

If it's a permissions issue, it should not crash below the Android-M version, but it is crashing in some pre-Android-M devices also.

Upvotes: 35

Views: 76754

Answers (7)

Dhruv Kachhadiya
Dhruv Kachhadiya

Reputation: 21

Simple answer : follow following steps..

  1. press long click on installed APP icon.
  2. Go to the App info section.
  3. now click on app permission section
  4. enable storage permission

now it's working properly

enter image description here

enter image description here

Upvotes: 2

Eng.OsamaYousef
Eng.OsamaYousef

Reputation: 498

For Android 10 , Add this line to manifests:

android:requestLegacyExternalStorage="true"

Note that you must add the required primissions too:

READ_EXTERNAL_STORAGE, WRITE_EXTERNAL_STORAGE

enter image description here

Upvotes: 17

sree_ranjani
sree_ranjani

Reputation: 29

Well, I got this error repeatedly, and my fix for this problem is to make sure you use a .png image as the bitmap image and save it in the drawable folder. Previously I was using it as a vector asset. This worked fine for me.

Upvotes: 1

thatGuy
thatGuy

Reputation: 122

This error can also be caused if you use a poorly created library jar, and have minifyEnabled set to true on your gradle.

Upvotes: 1

Surojit
Surojit

Reputation: 1292

The problem you are facing is that you are trying to getWidth() on your unscaledBitmap in the createScaledBitmap function. Clearly, your unscaledBitmap is null sometimes; and calling getWidth() is causing the Null Pointer exception.

The root cause is that decodeResource is returning you a null for whatever reason.

The reasons can include -

  1. No read permission
  2. The image file is corrupt
  3. There is not enough memory to decode the file
  4. The resource does not exist
  5. Invalid options specified in the options variable.

I'd suggest that you modify your code to include a null-check on the decoded bitmap, log it and debug from there on the specific devices that you see the error occurring.

It may also be that your options variable that you are re-using is being interpreted differently in the second call to decodeResource. You might try passing a null there.

The modified code should be as follows -

public class BitmapScalingHelper
{
    public static Bitmap decodeResource(Resources res, int resId, int dstWidth, int dstHeight)
    {
        Options options = new Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeResource(res, resId, options);
        options.inJustDecodeBounds = false;

        options.inSampleSize = calculateSampleSize(options.outWidth, options.outHeight, dstWidth,
                dstHeight);

        options = new Options(); 
        //May use null here as well. The funciton may interpret the pre-used options variable in ways hard to tell.
        Bitmap unscaledBitmap = BitmapFactory.decodeResource(res, resId, options);

        if(unscaledBitmap == null)
        {
            Log.e("ERR","Failed to decode resource - " + resId + " " + res.toString());
            return null;
        }

        return unscaledBitmap;
    }
}

Upvotes: 26

orzangleli
orzangleli

Reputation: 178

There are some reasons may cause the error.

  1. Lack of the Permission in AndroidManifest.xml. Read or write permission.
  2. The file doesn't exist or you are trying to access to a file that could't be decoded as a bitmap.

From the code you post,I can't find any logic error.Here are my suggestions:

  1. Change another image and test.

  2. Try to use ImageLoader Library like Glide or Fresco and test.

Upvotes: 0

Anis BEN NSIR
Anis BEN NSIR

Reputation: 2555

Your are using: Bitmap decodeFile (String pathName) This method may return null if the decode of file fail. I think that it can be related to permission issue on some device or to image format not supported. If you are using GIF, try https://developer.android.com/reference/android/graphics/Movie.html

Upvotes: 0

Related Questions