0

I have an imageView, that fills with an image selected from the gallery by the user. This image is then used to set the background of another activity when a button called "set background" is clicked. When I choose the image, it shows in the imageView, but when I press the "set background" button, I get a NPE when I scale down the bitmap. Here is the error:

11-22 21:21:14.174: D/AndroidRuntime(24601): Shutting down VM
11-22 21:21:14.194: E/AndroidRuntime(24601): FATAL EXCEPTION: main
11-22 21:21:14.194: E/AndroidRuntime(24601): java.lang.NullPointerException
11-22 21:21:14.194: E/AndroidRuntime(24601):    at com.example.awesomefilebuilderwidget.Personalize.scaleDownBitmap(Personalize.java:119)
11-22 21:21:14.194: E/AndroidRuntime(24601):    at com.example.awesomefilebuilderwidget.Personalize.setBackgroundImageInDragAndDrop(Personalize.java:143)
11-22 21:21:14.194: E/AndroidRuntime(24601):    at com.example.awesomefilebuilderwidget.Personalize.onClick(Personalize.java:88)
11-22 21:21:14.194: E/AndroidRuntime(24601):    at android.view.View.performClick(View.java:2532)
11-22 21:21:14.194: E/AndroidRuntime(24601):    at android.view.View$PerformClick.run(View.java:9308)
11-22 21:21:14.194: E/AndroidRuntime(24601):    at android.os.Handler.handleCallback(Handler.java:587)
11-22 21:21:14.194: E/AndroidRuntime(24601):    at android.os.Handler.dispatchMessage(Handler.java:92)
11-22 21:21:14.194: E/AndroidRuntime(24601):    at android.os.Looper.loop(Looper.java:150)
11-22 21:21:14.194: E/AndroidRuntime(24601):    at android.app.ActivityThread.main(ActivityThread.java:4333)
 11-22 21:21:14.194: E/AndroidRuntime(24601):   at java.lang.reflect.Method.invokeNative(Native Method)
11-22 21:21:14.194: E/AndroidRuntime(24601):    at   com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
11-22 21:21:14.194: E/AndroidRuntime(24601):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
11-22 21:21:14.194: E/AndroidRuntime(24601):    at dalvik.system.NativeStart.main(Native Method)

And here is my Personalize class:

public class Personalize extends Activity implements View.OnClickListener {
    Button button;
    ImageView image;
    ImageView image2;
    Button btnChangeImage;
    Button btnChangeImageForIcon;
    Button btnSetBackground;
    private static final int SELECT_PICTURE = 1;
    private static final int SELECT_PICTURE_2 = 2;
    private static final int RESULT_ICON = 20;
    private String selectedImagePath;
    Bitmap background;
    Bitmap b2;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.personalize);
        Log.d("Personalize", "OnCreate called");

        image = (ImageView) findViewById(R.id.imageView1);
        image2 = (ImageView) findViewById(R.id.imageView2Icon);

        Button btnChangeImage = (Button) findViewById(R.id.btnChangeImage);
        btnChangeImage.setOnClickListener(this);

        Button btnChangeImageForIcon = (Button) findViewById(R.id.btnChangeImageForIcon);
        btnChangeImageForIcon.setOnClickListener(this);

        Button btnSetBackground = (Button) findViewById(R.id.btnSetBackground);
        btnSetBackground.setOnClickListener(this);

        Button btnLinkToFeedback = (Button) findViewById(R.id.btnLinkToFeedback);

        Button btnSetIcon = (Button) findViewById(R.id.btnSetIcon);
        btnSetIcon.setOnClickListener(this);

        // Link to Feedback Screen
        btnLinkToFeedback.setOnClickListener(new View.OnClickListener() {

            public void onClick(View view) {
                Intent i = new Intent(getApplicationContext(), Feedback.class);
                startActivity(i);
                Log.d("Personalize", "LinkToFeedBack called");
                finish();
            }
        });

    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
        case R.id.btnChangeImage:
            launchImageChooser();
            break;
        case R.id.btnChangeImageForIcon:
            launchImageChooser2();
            break;
        case R.id.btnSetBackground:
            setBackgroundImageInDragAndDrop();
            break;
        case R.id.btnSetIcon:
            setIconImageInWidget();
            break;
        }
    }

    private void setIconImageInWidget() {
        // TODO Auto-generated method stub
        Log.d("Personalize", "setIconImageInWidget() called");
        Intent i = getIntent();
        // Convert bitmap to byte array to send back to activity
        // See:
        // http://stackoverflow.com/questions/11010386/send-bitmap-using-intent-android
        scaleDownBitmapForIcon(b2, 500, this.getBaseContext());
        Log.d("Personalize", "Scale Bitmap Chosen For Icon");
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        b2.compress(Bitmap.CompressFormat.PNG, 100, stream);
        byte[] byteArray = stream.toByteArray();

        i.putExtra("myIconBitmap", byteArray);
        setResult(RESULT_ICON, i);
        finish();
    }

    public static Bitmap scaleDownBitmap(Bitmap background, int newHeight, Context c) {

        final float densityMultiplier = c.getResources().getDisplayMetrics().density;

        int h = (int) (500 * densityMultiplier);
        int w = (int) (h * background.getWidth() / ((double) background.getHeight()));

        background = Bitmap.createScaledBitmap(background, w, h, true);
        // TO SOLVE LOOK AT
        // HERE:http://stackoverflow.com/questions/15517176/passing-bitmap-to-other-activity-getting-message-on-logcat-failed-binder-transac
        return background;
    }

    public static Bitmap scaleDownBitmapForIcon(Bitmap b2, int newHeight, Context c) {

        final float densityMultiplier = c.getResources().getDisplayMetrics().density;

        int h = (int) (500 * densityMultiplier);
        int w = (int) (h * b2.getWidth() / ((double) b2.getHeight()));

        b2 = Bitmap.createScaledBitmap(b2, w, h, true);
        // TO SOLVE LOOK AT
        // HERE:http://stackoverflow.com/questions/15517176/passing-bitmap-to-other-activity-getting-message-on-logcat-failed-binder-transac
        return b2;
    }

    private void setBackgroundImageInDragAndDrop() {
        Log.d("Personalize", "setBackgroundImageInDragAndDrop() called");
        Intent i = getIntent();
        // Convert bitmap to byte array to send back to activity
        // See:
        // http://stackoverflow.com/questions/11010386/send-bitmap-using-intent-android
        scaleDownBitmap(background, 500, this.getBaseContext());
        Log.d("Personalize", "Scale Bitmap Chosen");
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        background.compress(Bitmap.CompressFormat.PNG, 100, stream);
        byte[] byteArray = stream.toByteArray();

        i.putExtra("myBackgroundBitmap", byteArray);
        setResult(RESULT_OK, i);
        finish();
    }

    private void launchImageChooser() {
        Intent intent = new Intent();
        intent.setType("image/*");
        intent.setAction(Intent.ACTION_GET_CONTENT);
        intent.addCategory(Intent.CATEGORY_OPENABLE);
        startActivityForResult(intent, SELECT_PICTURE);
        Log.d("Personalize", "launchImageChooser called");
    }

    private void launchImageChooser2() {
        Intent intent = new Intent();
        intent.setType("image/*");
        intent.setAction(Intent.ACTION_GET_CONTENT);
        intent.addCategory(Intent.CATEGORY_OPENABLE);
        startActivityForResult(intent, SELECT_PICTURE_2);
        Log.d("Personalize", "launchImageChooser2 called");
    }

    public String getPath(Uri uri) {
        String[] projection = { MediaStore.Images.Media.DATA };
        Cursor cursor = getContentResolver().query(uri, projection, null, null, null);
        int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
        cursor.moveToFirst();
        String imagePath = cursor.getString(column_index);
        if (cursor != null) {
            cursor.close();
        }
        return imagePath;
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {

        if (resultCode == RESULT_OK) {
            if (requestCode == SELECT_PICTURE) {
                Uri selectedImageUri = data.getData();
                selectedImagePath = getPath(selectedImageUri);
                background = getAndDecodeImage(selectedImagePath);
                if (background != null) {
                    image.setImageBitmap(background);
                }
            } else if (requestCode == SELECT_PICTURE_2) {
                Uri selectedImageUri = data.getData();
                selectedImagePath = getPath(selectedImageUri);
                b2 = getAndDecodeImage(selectedImagePath);
                if (b2 != null) {
                    image2.setImageBitmap(b2);
                }
            }
        }
    }

    @Override
    protected void onPause() {
        SharedPreferences sp = getSharedPreferences("AppSharedPref", 1); // open
                                                                            // shared
                                                                            // preferences
                                                                            // with
                                                                            // name
                                                                            // AppSharedPref
        Editor editor = sp.edit();
        editor.putString("ImagePath", selectedImagePath); // Store
                                                            // selectedImagePath
                                                            // with key
                                                            // "ImagePath". This
                                                            // key will be then
                                                            // used to retrieve
                                                            // data.
        editor.commit();
        super.onPause();
        Log.d("Personalize", "onPause() called and selectedImagePath saved");
    }

    @Override
    protected void onResume() {
        SharedPreferences sp = getSharedPreferences("AppSharedPref", 1);
        selectedImagePath = sp.getString("ImagePath", "");
        super.onResume();
        Log.d("Personalize", "onResume() called and images uploaded");
        Log.d("Personalize", "Now set the image as background");
        background = getAndDecodeImage(selectedImagePath);
        if (background != null) {
            image.setImageBitmap(background);
        }
        if (b2 != null) {
            image2.setImageBitmap(b2);
        }
    }

    private Bitmap getAndDecodeImage(String selectedImagePath) {
        try {
            Log.d("Personalize", "selectedImagePath: " + selectedImagePath);
            FileInputStream fileis = new FileInputStream(selectedImagePath);
            BufferedInputStream bufferedstream = new BufferedInputStream(fileis);
            byte[] bMapArray = new byte[bufferedstream.available()];
            bufferedstream.read(bMapArray);
            Bitmap bMap = BitmapFactory.decodeByteArray(bMapArray, 0, bMapArray.length);

            if (fileis != null) {
                fileis.close();
            }
            if (bufferedstream != null) {
                bufferedstream.close();
            }
            return bMap;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    public boolean saveImageToInternalStorage(Bitmap image) {
        try {
            FileOutputStream fos = this.openFileOutput("desiredFilename.png", Context.MODE_PRIVATE);
            image.compress(Bitmap.CompressFormat.PNG, 100, fos);
            fos.close();
            return true;
        } catch (Exception e) {
            return false;
        }
    }

}

More specifically here are lines

119

int w= (int) (h * background.getWidth()/((double) background.getHeight()));

143

scaleDownBitmap(background, 500, this.getBaseContext());

So apparently background is returning null but I can't figure out why.

Please help!

ADDED:

Here is the LogCat leading up to the NPE:

11-22 21:33:37.650: D/D&D(25036): LinkToPersonalize called
11-22 21:33:37.710: D/Personalize(25036): OnCreate called
11-22 21:33:37.720: D/Personalize(25036): onResume() called and images uploaded
11-22 21:33:37.720: D/Personalize(25036): Now set the image as background
11-22 21:33:37.720: D/Personalize(25036): selectedImagePath: 
11-22 21:33:37.720: D/skia(25036): --- SkImageDecoder::Factory returned null
11-22 21:33:38.300: D/Personalize(25036): launchImageChooser called
11-22 21:33:38.320: D/Personalize(25036): onPause() called and selectedImagePath saved
11-22 21:33:41.593: D/Personalize(25036): selectedImagePath: /mnt/sdcard/paintjoy/112411_143853.png
11-22 21:33:41.643: D/dalvikvm(25036): GC_CONCURRENT freed 80K, 44% free 3178K/5639K, external 3701K/4622K, paused 2ms+2ms
11-22 21:33:41.673: D/dalvikvm(25036): GC_EXTERNAL_ALLOC freed <1K, 44% free 3178K/5639K, external 3701K/4622K, paused 25ms
11-22 21:33:41.693: D/Personalize(25036): onResume() called and images uploaded
11-22 21:33:41.693: D/Personalize(25036): Now set the image as background
11-22 21:33:41.693: D/Personalize(25036): selectedImagePath: 
11-22 21:33:41.693: D/skia(25036): --- SkImageDecoder::Factory returned null
11-22 21:33:42.654: D/Personalize(25036): setBackgroundImageInDragAndDrop() called
11-22 21:33:42.654: D/AndroidRuntime(25036): Shutting down VM

UPDATED: onActivityResult in recieving class:

         @Override 
     protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
     super.onActivityResult(requestCode, resultCode, data); 
     Log.i("Drag_and_Drop_App", "requestCode: " + requestCode + ", resultCode: " + resultCode); 

     if(requestCode == SET_BACKGROUND && resultCode == RESULT_OK){ 
     byte[] byteArray = data.getByteArrayExtra("myBackgroundBitmap"); 
     Bitmap myBackground = BitmapFactory.decodeByteArray(byteArray, 0, byteArray.length); 
     setBackgroundImage(myBackground); 
     } 
     else if(requestCode == RESULT_ICON){
         byte[] byteArray = data.getByteArrayExtra("myIconBitmap"); 
         Bitmap myIcon = BitmapFactory.decodeByteArray(byteArray, 0, byteArray.length); 
         setBackgroundImageForIcon(myIcon); 
         Log.d("Drag_and_Drop_App", "Icon is set");
     }
     } 

setBackgroundImage:

         @SuppressLint("NewApi") 
     private void setBackgroundImage(Bitmap bitmap) { 
     RelativeLayout yourBackgroundView = (RelativeLayout) findViewById(R.id.rl_drag_and_drop_app); 

     Drawable d = new BitmapDrawable(getResources(), bitmap); 

     if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) { 
     yourBackgroundView.setBackgroundDrawable(d); 
     } else { 
     yourBackgroundView.setBackground(d); 
     Log.d("Drag_and_Drop_App", "Background is set");
     } 
     } 

setBackgroundImageForIcon:

         @SuppressLint("NewApi") 
     private void setBackgroundImageForIcon(Bitmap bitmap) { 
         Log.d("Drag_and_Drop_App", "Icon...");
     ImageView ivICON = (ImageView) findViewById(R.id.bwidgetOpen);

     BitmapDrawable dq = new BitmapDrawable(getResources(), bitmap); 

     if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) { 
     // ivICON.setImageDrawable(dq);
         ivICON.setImageResource(R.drawable.pattern1);
     } else { 
    // ivICON.setImageDrawable(dq);
     ivICON.setImageResource(R.drawable.pattern1);
     Log.d("Drag_and_Drop_App", "Icon is set");
     } 
     }

Entire class(without irrelevant things):

package com.example.awesomefilebuilderwidget;

IMPORTS

public class Drag_and_Drop_App extends Activity {
private static final int SET_BACKGROUND = 10;
private static final int RESULT_ICON = 20;

private ListView mListAppInfo;
// Search EditText
EditText inputSearch;
public AppInfoAdapter adapter;
final SwipeDetector swipeDetector = new SwipeDetector();

//For GridView
private int draggedIndex = -1;
private BaseAdapter adapterGV;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // set layout for the main screen
    setContentView(R.layout.drag_and_drop_app);

public Bitmap getThumbnail(String filename) { 
     Bitmap thumbnail = null; 
     try { 
     File filePath = this.getFileStreamPath(filename); 
     FileInputStream fi = new FileInputStream(filePath); 
     thumbnail = BitmapFactory.decodeStream(fi); 
     } catch (Exception ex) { 
     Log.e("getThumbnail() on internal storage", ex.getMessage()); 
     } 
     return thumbnail; 
     } 

public String getPath(Uri uri) {
    String[] projection = { MediaStore.Images.Media.DATA };
    Cursor cursor = getContentResolver().query(uri, projection, null, null, null);
    int column_index = cursor
            .getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
    cursor.moveToFirst();
    String imagePath = cursor.getString(column_index);
    if(cursor != null) {
    cursor.close();
    }
    return imagePath;
}

     @Override 
     protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
     super.onActivityResult(requestCode, resultCode, data); 
     Log.i("Drag_and_Drop_App", "requestCode: " + requestCode + ", resultCode: " + resultCode); 

     if(requestCode == SET_BACKGROUND && resultCode == RESULT_OK){ 
     byte[] byteArray = data.getByteArrayExtra("myBackgroundBitmap"); 
     Bitmap myBackground = BitmapFactory.decodeByteArray(byteArray, 0, byteArray.length); 
     setBackgroundImage(myBackground); 
     } 
     else if(requestCode == RESULT_ICON){
         byte[] byteArray = data.getByteArrayExtra("myIconBitmap"); 
         Bitmap myIcon = BitmapFactory.decodeByteArray(byteArray, 0, byteArray.length); 
         setBackgroundImageForIcon(myIcon); 
         Log.d("Drag_and_Drop_App", "Icon is set");
     }
     } 


     @SuppressLint("NewApi") 
     private void setBackgroundImage(Bitmap bitmap) { 
     RelativeLayout yourBackgroundView = (RelativeLayout) findViewById(R.id.rl_drag_and_drop_app); 

     Drawable d = new BitmapDrawable(getResources(), bitmap); 

     if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) { 
     yourBackgroundView.setBackgroundDrawable(d); 
     } else { 
     yourBackgroundView.setBackground(d); 
     Log.d("Drag_and_Drop_App", "Background is set");
     } 
     } 

     @SuppressLint("NewApi") 
     private void setBackgroundImageForIcon(Bitmap bitmap) { 
         Log.d("Drag_and_Drop_App", "Icon...");
     ImageView ivICON = (ImageView) findViewById(R.id.bwidgetOpen);

     BitmapDrawable dq = new BitmapDrawable(getResources(), bitmap); 

     if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) { 
     // ivICON.setImageDrawable(dq);
         ivICON.setImageResource(R.drawable.pattern1);
     } else { 
    // ivICON.setImageDrawable(dq);
     ivICON.setImageResource(R.drawable.pattern1);
     Log.d("Drag_and_Drop_App", "Icon is set");
     } 
     } 

     } 
user2909006
  • 253
  • 6
  • 22

2 Answers2

0

Try this

Update this method

private Bitmap getAndDecodeImage(String selectedImagePath) {
        try {
            // Decode image size
            BitmapFactory.Options o = new BitmapFactory.Options();
            o.inJustDecodeBounds = true;
            BitmapFactory.decodeFile(selectedImagePath, o);
            // The new size we want to scale to
            final int REQUIRED_SIZE = 500;

            // Find the correct scale value. It should be the power of 2.
            int scale = 1;
            while (o.outWidth / scale / 2 >= REQUIRED_SIZE && o.outHeight / scale / 2 >= REQUIRED_SIZE)
                scale *= 2;

            // Decode with inSampleSize
            BitmapFactory.Options o2 = new BitmapFactory.Options();
            o2.inSampleSize = scale;
            return BitmapFactory.decodeFile(selectedImagePath, o2);
        } catch (Throwable e) {
            e.printStackTrace();
        }
        return null;
    }
Biraj Zalavadia
  • 28,348
  • 10
  • 61
  • 77
0

I think problem is because you save the selectedImagePath before it actually return

Curently, you save the selectedImagePath into SharedPreferences in onPause function, but onPause function will be called before you call the onActivityResult being called, so that mean you saved a empty value into SharedPreferences and get it back in onResume which will lead to NPE.

Just move the save part in onPause to the end of onActivtyResult will make it work.

Hope this help.

justHooman
  • 3,044
  • 2
  • 17
  • 15
  • Ok thank you, that saved the image paths for the imageView...I need help also saving the imagePaths for when I set my background as well (which I will add the coding into the question under "UPDATED") Can you help me with that? – user2909006 Nov 23 '13 at 16:10
  • That fixed the NPE also – user2909006 Nov 23 '13 at 16:16
  • I don't understand your problem here, you want to save the imagePaths and send it back to receive class instead of send the whole bitmap? If that true, because you are already save imagePaths into `SharePreference`, so you can get it back like in `onResume` function of `Personalize` class. Or in `setBackgroundImageInDragAndDrop` of `Personalize`, you can put imagePaths in `Intent` like `i.putExtra("selectedImagePath", selectedImagePath);` and then get it back in `onActivityResult` of `Drag_and_Drop_App` by `String selectedImagePath = data.getStringExtra("selectedImagePath");` – justHooman Nov 24 '13 at 01:44
  • Ok so what I am trying to do is make it so that when I set the background by using `yourBackgroundView.setBackground(d);` in setBackgroundImage, I want to make it so that it keeps that image as the background. I think I can include the second part of what you said above (using imagePath in `Intent`) and then using that somehow? Hopefully this makes sense. – user2909006 Nov 24 '13 at 02:21
  • Currently, I have the imagePaths saved when the user chooses an image and that image is put into an imageView (like a preview), then when they press a button that image in the imageView is set as the background – user2909006 Nov 24 '13 at 02:22
  • I don't find any problem from those code above. Have you debug it yet? Was the `onActivityResult` of `Drag_and_Drop_App` called? the value of `myBackground` before the called of `setBackgroundImage` is null or not? and can you provide yhe logcat after you clicked the set background button – justHooman Nov 24 '13 at 06:33