Home > front end >  Error when saving relative layout as bitmap using layout.getDrawingCache() returning null
Error when saving relative layout as bitmap using layout.getDrawingCache() returning null

Time:03-06

How to handle full-sized photo using MediaStore.EXTRA_OUTPUT? First, I need to put the picture AS FULL-SIZED NOT THUMBNAIL on a layout and put text below it like this:

enter image description here

The idea I am using is that I am using layout.getDrawingCache to make it as bitmap.

Below is my camera button:

private void SelectImage(){

    final CharSequence[] items={"Camera", "Cancel"};

    AlertDialog.Builder builder = new AlertDialog.Builder(PickupDrop.this);
    builder.setTitle("Add Image");

    builder.setItems(items, new DialogInterface.OnClickListener() {

        @Override
        public void onClick(DialogInterface dialogInterface, int i) {
            if (items[i].equals("Camera")) {

                Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

                if(cameraIntent.resolveActivity(getPackageManager())!= null){

                    File imageFile = null;
                    try {
                        imageFile = getImageFile();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }

                    if(imageFile!= null){
                         imageUri =FileProvider.getUriForFile(context, "com.example.android.fileprovider", imageFile);


                        cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT,imageUri);
                        cameraIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                        startActivityForResult(cameraIntent,REQUEST_CAMERA);

                       
                    }

                }

            } else if (items[i].equals("Cancel")) {
                dialogInterface.dismiss();
            }
        }
    });
    builder.show();

}

The getImageFile() method:

private File getImageFile(){
    String imageName = "test";
    File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);

    File imageFile = null;
    try {
        imageFile = File.createTempFile(imageName,".jpg",storageDir);
    } catch (IOException e) {
        e.printStackTrace();
    }

    currentImagePath = imageFile.getAbsolutePath();
    return imageFile;
}

As you can see above, I am using EXTRA_OUTPUT with fileprovider to get FULL-SIZED bitmap. Below is my manifests, provider.

Manifest:

<application ...
<provider
        android:authorities="com.example.android.fileprovider"
        android:name="androidx.core.content.FileProvider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_path"/>
    </provider>

file_path.xml:

<?xml version="1.0" encoding="utf-8"?>
<external-path
    name="my images"
    path="Android/data/com.example.luckypasabayapp/files/Pictures"/>

My onActivityResult method:

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

    if(resultCode== Activity.RESULT_OK){

        if(requestCode==REQUEST_CAMERA){

            Bitmap bitmap = BitmapFactory.decodeFile(currentImagePath);


            populateScreenshot(bitmap);

        

        }
    }
}

Now here is where my problem occurs when I try to save the relative layout screenshot to my storage:

public void populateScreenshot(Bitmap bitmapFromPhone){

    LayoutInflater inflater = LayoutInflater.from(PickupDrop.this);
    View v = inflater.inflate(R.layout.information_dialog, null);
    ImageView imageView_profilePic = v.findViewById(R.id.imageview_image);
    TextView txt_item_data = v.findViewById(R.id.txt_item_data);
    Button btn_cancel = v.findViewById(R.id.btn_cancel);
    Button btn_download = v.findViewById(R.id.btn_download);
    screenShot = v.findViewById(R.id.screenShot);
    screenShot.setDrawingCacheEnabled(true);
    screenShot.buildDrawingCache();

    final AlertDialog alertDialog = new AlertDialog.Builder(PickupDrop.this)
            .setView(v)
            .create();

    alertDialog.setOnKeyListener(new DialogInterface.OnKeyListener() {
        @Override
        public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
            // Prevent dialog close on back press button
            return keyCode == KeyEvent.KEYCODE_BACK;
        }
    });
    //alertDialog.setCanceledOnTouchOutside(false);
    
    
    
    
    //SETTING THE IMAGEVIEW OF LAYOUT TAKEN FROM CAMERA
    imageView_profilePic.setImageBitmap(bitmapFromPhone);
    

    btn_download.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

            //GETTING THE RELATIVELAYOUT AS BITMAP
            Bitmap bitmap = screenShot.getDrawingCache();
            

            File filePath = Environment.getExternalStorageDirectory();
            File dir = new File(filePath.getAbsolutePath() "/qrcode/");

            dir.mkdirs();
            File file = new File(dir, "str_specialNumber"   ".png");

            try {
                outputStream = new FileOutputStream(file);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
            
            
            //HERE IS WHERE THE ERROR OCCURS, IT SAYS BITMAP IS NULL!!!
            
            bitmap.setHasAlpha(true);
            bitmap.compress(Bitmap.CompressFormat.PNG, 100,outputStream);

            Toast.makeText(PickupDrop.this,"SCREENSHOT Downloaded",Toast.LENGTH_LONG).show();

            try {
                outputStream.flush();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                outputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

            //notify gallery for a new picture
            galleryAddPic(filePath.getAbsolutePath() "/qrcode/" "str_specialNumber" ".png");


        }
    });

    alertDialog.show();



}

Here in bitmap.setHasAlpha(true); it says bitmap is null from screenshot.getDrawingCache I don't understand why.

How do I handle the EXTRA_OUTPUT properly to be able to do whatever I want with the bitmap?

CodePudding user response:

You can give this answer a try :)

If you want to take the screenshot of any view or your RelativeLayout you can create this method takeScreenShot() : it will return a Bitmap in @Param or parameter in this method, you can pass RelativeLayout

    public static Bitmap takeScreenShot(@NonNull View view) {
    view.setDrawingCacheEnabled(true);
    view.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_AUTO);
    view.buildDrawingCache();

    if (view.getDrawingCache() == null) return null;
    Bitmap snapshot;
    try {
        snapshot = Bitmap.createBitmap(view.getDrawingCache());
        view.setDrawingCacheEnabled(false);
        view.destroyDrawingCache();
    } catch (Exception e) {
        snapshot = null;
    }
    return snapshot;
}

tell me if this helps you :)

CodePudding user response:

So apparently , I needed to write android:requestLegacyExternalStorage="true" on my manifest file for me to store the bitmap to my gallery. Can someone tell me if there's future issues with this request?

  • Related