【问题标题】:Why I cannot convert bitmap to .PNG and save it into storage in Android Oreo Device?为什么我无法将位图转换为 .PNG 并将其保存到 Android Oreo 设备中的存储中?
【发布时间】:2021-02-17 06:19:07
【问题描述】:

我想将 android 视图转换为图像文件并将其保存到 Android Oreo 设备的内部存储中。但我的以下代码不起作用。

这是 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>

这里是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();
    }

}

我也添加了路径路径:-

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

向 Manifest 文件添加元数据:-

<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>

我还添加了 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" />

谁能找到问题,为什么这段代码在 Android Oreo 版本上不起作用?

【问题讨论】:

  • 请删除所有代码和xml等。仅发布 savePng() 函数的代码,并说明什么不起作用。
  • 也不需要互联网许可和请求旧的外部存储,因此您也可以将其删除。

标签: android scope storage android-8.0-oreo


【解决方案1】:

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 代码

公共类 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();
        }
    }
}

}

添加清单

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-18
    • 1970-01-01
    • 1970-01-01
    • 2021-02-03
    相关资源
    最近更新 更多