简体   繁体   English

为什么我无法将 bitmap 转换为 .PNG 并将其保存到 Android Oreo Device 中的存储中?

[英]Why I cannot convert bitmap to .PNG and save it into storage in Android Oreo Device?

I want to convert android view to image file and save it to internal storage in Android Oreo device.我想将 android 视图转换为图像文件并将其保存到 Android Oreo 设备的内部存储中。 But my following code is not working.但是我的以下代码不起作用。

Here is XML code:-这是 XML 代码:-

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <LinearLayout
        android:id="@+id/layout1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="20dp"
        android:background="@color/teal_200"
        android:gravity="center"
        android:orientation="horizontal"
        app:layout_constraintBottom_toTopOf="@+id/btnSaveID"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/kohli" />

    </LinearLayout>

    <Button
        android:id="@+id/btnSaveID"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="30dp"
        android:paddingLeft="50dp"
        android:paddingRight="50dp"
        android:text="@string/save"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/layout1" />

</androidx.constraintlayout.widget.ConstraintLayout>

Here is JAVA code:-这是 JAVA 代码:-

public class MainActivity extends AppCompatActivity {
    LinearLayout layout;
    OutputStream outputStream;


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


        findViewById(R.id.btnSaveID).setOnClickListener(v -> {

            if (Build.VERSION.SDK_INT >= 23) {
                String requiredPermission = Manifest.permission.READ_EXTERNAL_STORAGE;
                int checkVal = checkCallingOrSelfPermission(requiredPermission);

                if (checkVal == PackageManager.PERMISSION_GRANTED) {
                    saveImage2(layout, MainActivity.this);

                } else {
                    checkPermission(layout);
                }
            } else {
                saveImage2(layout, MainActivity.this);

            }
        });

    }

    private void saveImage2(LinearLayout layout1, Context context) {
        layout1.setDrawingCacheEnabled(true);
        layout1.buildDrawingCache();
        Bitmap bitmap = Bitmap.createBitmap(layout1.getWidth(), layout1.getHeight(), Bitmap.Config.ARGB_8888);
        if (bitmap != null) {
            Canvas canvas = new Canvas(bitmap);
            layout1.draw(canvas);

            Drawable bgDrawable = layout1.getBackground();

            if (bgDrawable != null) {
                bgDrawable.draw(canvas);
            } else {
                canvas.drawColor(Color.WHITE);
            }

            layout1.draw(canvas);
            String name = System.currentTimeMillis() + ".png";
            try {
                savePng(context, bitmap, name);
            } catch (IOException e) {
                e.printStackTrace();
            }
 }
    }

    public static void savePng(Context context, Bitmap bitmap, @NonNull String name) throws IOException {
        Uri uri;
        OutputStream fileOutputStream;
        String path;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            ContentResolver resolver = context.getContentResolver();
            ContentValues contentValues = new ContentValues();
            contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, name + ".png");
            contentValues.put(MediaStore.MediaColumns.MIME_TYPE, "image/png");
            contentValues.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_PICTURES);
            uri = resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues);
            fileOutputStream = resolver.openOutputStream(Objects.requireNonNull(uri));
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, fileOutputStream);
            fileOutputStream.close();
            Toast.makeText(context, "Saved!", Toast.LENGTH_SHORT).show();
        } else {
            String imagePath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).toString();
            File image = new File(imagePath, name + ".png");
            fileOutputStream = new FileOutputStream(image);
            uri = getUriFromPath(context, imagePath);
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, fileOutputStream);
            fileOutputStream.close();
            Toast.makeText(context, "Saved!", Toast.LENGTH_SHORT).show();
            path = image.getAbsolutePath();
            MediaScannerConnection.scanFile(context, new String[]{path}, new String[]{"image/*"},
                    new MediaScannerConnection.MediaScannerConnectionClient() {
                        public void onMediaScannerConnected() {
                        }
                        public void onScanCompleted(String path, Uri uri) {
                        }
                    });
        }
    }

    private static Uri getUriFromPath(Context context, String imagePath) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
            return FileProvider.getUriForFile(context, "com.noobprogroammer.sampleproject.fileprovider", new File(imagePath));
        return Uri.fromFile(new File(imagePath));
    }

private void checkPermission(LinearLayout layout) {
        PermissionListener permissionListener = new PermissionListener() {
            @Override
            public void onPermissionGranted() {
                saveImage2(layout, MainActivity.this);
            }

            @Override
            public void onPermissionDenied(List<String> deniedPermissions) {
                Toast.makeText(MainActivity.this, "Permission required to download", Toast.LENGTH_SHORT).show();
            }
        };

        TedPermission.with(MainActivity.this)
                .setPermissionListener(permissionListener)
                .setPermissions(Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE)
                .check();
    }

}

I have add path path also:-我还添加了路径路径:-

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-path
        name="external_files"
        path="." />
</paths>

Added meta-data to Manifest file:-将元数据添加到清单文件:-

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

I have also add android:requestLegacyExternalStorage="true" and Internet permissions also:-我还添加了 android:requestLegacyExternalStorage="true"和 Internet 权限:-

<uses-permission
        android:name="android.permission.WRITE_EXTERNAL_STORAGE"
        tools:ignore="ScopedStorage" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

Can anyone find the issue, why this code is not working on Android Oreo Version?谁能找到问题,为什么此代码不适用于 Android Oreo 版本?

XML Code XML 代码

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingHorizontal="15dp"
tools:context=".MainActivity">


<LinearLayout
    android:id="@+id/layout_view"
    android:layout_width="match_parent"
    android:layout_height="200dp"
    android:orientation="vertical"
    android:background="@color/purple_200">

    <ImageView
        android:layout_width="80dp"
        android:layout_height="80dp"
        android:layout_gravity="center_horizontal"
        android:layout_marginTop="30dp"
        android:src="@drawable/ic_launcher_background" />

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">


        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Mizanur Rahaman"
            android:textSize="40dp"
            android:textStyle="bold"
            android:textColor="@color/white"
            android:layout_centerInParent="true"/>


    </RelativeLayout>




</LinearLayout>


<Button
    android:id="@+id/btnConvertToimage"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginVertical="10dp"
    android:text="Convert To Image" />

<ImageView
    android:id="@+id/imgResultImage"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

Java Code Java代码

public class MainActivity extends AppCompatActivity {公共 class MainActivity 扩展 AppCompatActivity {

LinearLayout layout_view;
ImageView imgResultImage;
Button btnConvertToImage;

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

    layout_view = findViewById(R.id.layout_view);
    imgResultImage = findViewById(R.id.imgResultImage);
    btnConvertToImage = findViewById(R.id.btnConvertToimage);


    btnConvertToImage.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
                    convert();
                } else {
                    ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 12545);
                }
            }


        }
    });


}

private void convert() {
    Bitmap image = getBitmapFromView(layout_view);
    imgResultImage.setImageBitmap(image);
    saveImage(image);
}

@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
    switch (requestCode) {
        case 12545:
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                Toast.makeText(this, "Accepted", Toast.LENGTH_SHORT).show();
                convert();
            } else {
                Toast.makeText(this, "Denied", Toast.LENGTH_SHORT).show();
            }
            break;
    }
}




    private Bitmap getBitmapFromView(View view) {
        //Define a bitmap with the same size as the view
        Bitmap returnedBitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888);
        //Bind a canvas to it
        Canvas canvas = new Canvas(returnedBitmap);
        //Get the view's background
        Drawable bgDrawable = view.getBackground();
        if (bgDrawable != null) {
            //has background drawable, then draw it on the canvas
            bgDrawable.draw(canvas);
        } else {
            //does not have background drawable, then draw white background on the canvas
            canvas.drawColor(Color.WHITE);
        }
        // draw the view on the canvas
        view.draw(canvas);
        //return the bitmap
        return returnedBitmap;
    }


private void saveImage(Bitmap bitmap) {
    if (android.os.Build.VERSION.SDK_INT >= 29) {
        ContentValues values = contentValues();
        values.put(MediaStore.Images.Media.RELATIVE_PATH, "Pictures/" + getString(R.string.app_name));
        values.put(MediaStore.Images.Media.IS_PENDING, true);

        Uri uri = this.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
        if (uri != null) {
            try {
                saveImageToStream(bitmap, this.getContentResolver().openOutputStream(uri));
                values.put(MediaStore.Images.Media.IS_PENDING, false);
                this.getContentResolver().update(uri, values, null, null);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }

        }
    } else {
        File directory = new File(Environment.getExternalStorageDirectory().toString() + '/' + getString(R.string.app_name));

        if (!directory.exists()) {
            directory.mkdirs();
        }
        String fileName = System.currentTimeMillis() + ".png";
        File file = new File(directory, fileName);
        try {
            saveImageToStream(bitmap, new FileOutputStream(file));
            ContentValues values = new ContentValues();
            values.put(MediaStore.Images.Media.DATA, file.getAbsolutePath());
            this.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

    }
}


private ContentValues contentValues() {
    ContentValues values = new ContentValues();
    values.put(MediaStore.Images.Media.MIME_TYPE, "image/png");
    values.put(MediaStore.Images.Media.DATE_ADDED, System.currentTimeMillis() / 1000);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
        values.put(MediaStore.Images.Media.DATE_TAKEN, System.currentTimeMillis());
    }
    return values;
}

private void saveImageToStream(Bitmap bitmap, OutputStream outputStream) {
    if (outputStream != null) {
        try {
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream);
            outputStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

} }

Add in manifests添加清单

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM