Exception dispatching input event and but only on first time using the app (Saving Image from Camera)

8 views
0

I am already aware of the what is a NullPointer exception and how do i fix it question and did not find it helped in my instance.

I am trying to take a photo with a camera application and have it saved to a recycerview, however on my first attempt to open the camera and take a photo (and only my first attempt, subsequent attempts work as intended.) the application crashes. The logcat shows that there was an exception dispatching the event, an exception in MessageQueue Callback: handle receive callback and a null pointer exception “Attempt to invoke virtual method ‘java.lang.String java.io.File.getCanonicalPath()’ on a null object reference” at this line

Uri imageUri = FileProvider.getUriForFile(this,authority,photoFile);

within this method

private void takePhotoFromCamera() {
    //Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
    //startActivityForResult(intent, CAMERAB);
    Intent callCameraApplicationIntent = new Intent();
    callCameraApplicationIntent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);

    File photoFile = null;
    try {
        photoFile = createImageFile();

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

    String authority = getApplicationContext().getPackageName()+ ".fileprovider";
    Uri imageUri = FileProvider.getUriForFile(this,authority,photoFile);
    callCameraApplicationIntent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);

    startActivityForResult(callCameraApplicationIntent, CAMERAB);
}

My MainActivityCode is here

public class MainActivity extends AppCompatActivity implements ImageAdapter.Callback {
private Button btn;
private static final String IMAGE_DIRECTORY = "/BingoAppGallery2";
private int GALLERY = 1, CAMERAB = 2;
final int RequestPermissionCode = 0;
private String galleryLocation = "BingoAppGallery";
public File BingoGalleryFolder;
private RecyclerView recycleView;
String mCurrentPhotoPath;



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

    createImageGallery();


    btn = (Button) findViewById(R.id.btn);
    btn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            checkPermissions();
        }
    });

    recycleView = findViewById(R.id.galleryRecyclerView);
    GridLayoutManager layoutManager = new GridLayoutManager(this,2);
    recycleView.setLayoutManager(layoutManager);
    RecyclerView.Adapter imageAdapter = new ImageAdapter(BingoGalleryFolder,this);
    recycleView.setAdapter(imageAdapter);}

private void showPictureDialog(){
    AlertDialog.Builder pictureDialog = new AlertDialog.Builder(this);
    pictureDialog.setTitle("Select Action");
    String[] pictureDialogItems = {
            "Select photo from gallery",
            "Capture photo from camera" };
    pictureDialog.setItems(pictureDialogItems,
            new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    switch (which) {
                        case 0:

                            choosePhotoFromGallary();
                            break;
                        case 1:
                            takePhotoFromCamera();
                            break;
                    }
                }
            });
    pictureDialog.show();
}
private void checkPermissions() {
    if (Build.VERSION.SDK_INT >= 23) {
        if (!checkAllPermission())
            requestPermission();
        else
            showPictureDialog();
    }
    else
        showPictureDialog();
}

private void requestPermission() {
    String[] PERMISSIONS = { Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE,  Manifest.permission.CAMERA};
    ActivityCompat.requestPermissions(MainActivity.this, PERMISSIONS, RequestPermissionCode);

}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    switch (requestCode) {
        case RequestPermissionCode:
            if (grantResults.length > 0) {

                boolean CameraPermission = grantResults[0] == PackageManager.PERMISSION_GRANTED;
                boolean ReadExternalStatePermission = grantResults[1] == PackageManager.PERMISSION_GRANTED;
                boolean ReadWriteStatePermission = grantResults[2] == PackageManager.PERMISSION_GRANTED;
                //



                if (CameraPermission && ReadExternalStatePermission && ReadWriteStatePermission) {

                    showPictureDialog();
                } else {
                    Toast.makeText(MainActivity.this, "You Must Accept Permissions To Add Photos", Toast.LENGTH_LONG).show();
                    requestPermission();

                }
            }

            break;
        default:
            break;
    }
}

public boolean checkAllPermission() {

    int FirstPermissionResult = ContextCompat.checkSelfPermission(getApplicationContext(), CAMERA);
    int SecondPermissionResult = ContextCompat.checkSelfPermission(getApplicationContext(), READ_EXTERNAL_STORAGE);
    int ThirdPermissionResult = ContextCompat.checkSelfPermission(getApplicationContext(), WRITE_EXTERNAL_STORAGE);

    return FirstPermissionResult == PackageManager.PERMISSION_GRANTED &&
            SecondPermissionResult == PackageManager.PERMISSION_GRANTED &&
            ThirdPermissionResult == PackageManager.PERMISSION_GRANTED;
}

public void choosePhotoFromGallary() {
    Intent galleryIntent = new Intent(Intent.ACTION_PICK,
            android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);

    startActivityForResult(galleryIntent, GALLERY);
}

private void takePhotoFromCamera() {
    //Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
    //startActivityForResult(intent, CAMERAB);
    Intent callCameraApplicationIntent = new Intent();
    callCameraApplicationIntent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);

    File photoFile = null;
    try {
        photoFile = createImageFile();

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

    String authority = getApplicationContext().getPackageName()+ ".fileprovider";
    Uri imageUri = FileProvider.getUriForFile(this,authority,photoFile);
    callCameraApplicationIntent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);

    startActivityForResult(callCameraApplicationIntent, CAMERAB);
}


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

    super.onActivityResult(requestCode, resultCode, data);
    if (resultCode == this.RESULT_CANCELED) {
        return;
    }
    if (requestCode == GALLERY) {
        if (data != null) {
            Uri contentURI = data.getData();
            try {
                Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), contentURI);
                String path = saveImage(bitmap);
                Toast.makeText(MainActivity.this, "Image Saved!", Toast.LENGTH_SHORT).show();


            } catch (IOException e) {
                e.printStackTrace();
                Toast.makeText(MainActivity.this, "Failed!", Toast.LENGTH_SHORT).show();
            }
        }

    } else if (requestCode == CAMERAB) {
        //Bitmap thumbnail = (Bitmap) data.getExtras().get("data");
        //saveImage(thumbnail);
        Toast.makeText(MainActivity.this, "Image Saved!", Toast.LENGTH_SHORT).show();
    }

    RecyclerView.Adapter newImageAdapter = new ImageAdapter(BingoGalleryFolder,this);
    recycleView.swapAdapter(newImageAdapter,false);
}



File createImageFile() throws IOException {

    // Create an image file name

    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
    String imageFileName = "IMAGE_" + timeStamp + "_";


    File image = File.createTempFile(imageFileName,".jpg", BingoGalleryFolder);

    return image;}

public String saveImage(Bitmap myBitmap) {
    ByteArrayOutputStream bytes = new ByteArrayOutputStream();
    myBitmap.compress(Bitmap.CompressFormat.JPEG, 90, bytes);
    //File wallpaperDirectory = new File(Environment.getExternalStorageDirectory() + IMAGE_DIRECTORY);
    // have the object build the directory structure, if needed.
   // if (!wallpaperDirectory.exists()) {
        //wallpaperDirectory.mkdirs();
    //}

    try {
        File f = new File(BingoGalleryFolder, Calendar.getInstance()
                .getTimeInMillis() + ".jpg");
        f.createNewFile();
        FileOutputStream fo = new FileOutputStream(f);
        fo.write(bytes.toByteArray());
        MediaScannerConnection.scanFile(this,
                new String[]{f.getPath()},
                new String[]{"image/jpeg"}, null);
        fo.close();
        Log.d("TAG", "File Saved::--->" + f.getAbsolutePath());


        return f.getAbsolutePath();
    } catch (IOException e1) {
        e1.printStackTrace();
    }
    return "";

}
public static boolean checkIfGalleryEmpty(File file)
{
    return file == null;
}


public void createImageGallery()
{
    File storageDirectory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
    BingoGalleryFolder = new File(storageDirectory,galleryLocation);
    if(!BingoGalleryFolder.exists())
        BingoGalleryFolder.mkdirs();


}

@Override
public void onImageClicked(String imagePath)
{
    Intent intent = new Intent(this,ClickedActivity.class);
    intent.putExtra("filepath",imagePath);
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    this.startActivity(intent);
}

@Override
public void onPointerCaptureChanged(boolean hasCapture)
{
    //ignored since not sure how to implememnt and is not used in 
   //program?

 } 
 }  

And my ImageAdapter method (with the callback interface) is here

public class ImageAdapter extends 
RecyclerView.Adapter<ImageAdapter.ViewHolder>
  {
   private static File imagesFile;

public interface Callback
{
    void onImageClicked(String imagePath);
}
Callback mCallback;
public ImageAdapter(File folderFile, Callback callback)
{
    imagesFile = folderFile;
    mCallback = callback;

}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
{
    View view = 

LayoutInflater.from(parent.getContext()).inflate(R.layout.gallery_images_relative_layout,parent,false);
return new ViewHolder(view);

}
@Override
public void onBindViewHolder(ViewHolder holder, int position)
{
    //when i called imagefile in mCallback.onImageClicked it stated imageFile must be final?
    final File imageFile = imagesFile.listFiles()[position];
    Bitmap imageBitmap = BitmapFactory.decodeFile(imageFile.getAbsolutePath());
    holder.getImageView().setImageBitmap(imageBitmap);

    holder.getImageView().setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (mCallback!=null)
            {
                mCallback.onImageClicked(imageFile.getAbsolutePath());
            }
        }
    });


}
@Override
public int getItemCount()
{
  try
  {return imagesFile.listFiles().length;}
  catch (NullPointerException e)
  {
      return 0;
  }

}



public static class ViewHolder extends RecyclerView.ViewHolder
{
    private ImageView imageView;

    public ViewHolder(View view)
    {
        super(view);
        imageView = (ImageView) view.findViewById(R.id.imageGalleryView);


    }
    public ImageView getImageView()
    {
        return imageView;
    }
}



 }

when I reopen the app, the camera works fine, but the image is stored in the second spot in my recyclerview grid. The first spot has a blank image saved inside.I can’t figure out how to handle for this and make the camera not crash, and have the image not be saved as blank. If anyone could help I would appreciate it.