我一直在使用外部存储器来保存其他类型的文件。该文件必须对用户可见。现在,从Android Q方法FutureBuilder
开始,getExternalStoragePublicDirectory(docs)被取消了。
我使用了以下代码:
getExternalStoragePublicDirectory()
还有另一种方法来保存对用户可见的文件吗?
答案 0 :(得分:5)
您需要添加针对Android Q的支票。假设您要将图片保存在公共下载文件夹中。
try{
OutputStream fos;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
ContentResolver resolver = context.getContentResolver();
ContentValues contentValues = new ContentValues();
contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, fileName);
contentValues.put(MediaStore.MediaColumns.MIME_TYPE, "image/jpg");
contentValues.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_DOWNLOADS);
Uri imageUri = resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues);
fos = resolver.openOutputStream(Objects.requireNonNull(imageUri));
} else {
String imagesDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).toString();
File image = new File(imagesDir, fileName);
fos = new FileOutputStream(image);
}
finalBitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
Objects.requireNonNull(fos).close();
}catch (IOException e) {
// Log Message
}
答案 1 :(得分:2)
将捕获位图保存在android Q及以下版本中
private class AsyncTaskExample extends AsyncTask<String, String, Bitmap> {
Bitmap icon = null;
ByteArrayOutputStream bytes;
@Override
protected void onPreExecute() {
super.onPreExecute();
mBitmap = BaseApplication.getInstance().getBitmap();
((BaseActivity)mContext).showFullScreenProgressLoader(((BaseActivity)mContext), ((BaseActivity)mContext).getString(R.string.please_wait), ((BaseActivity)mContext).getString(R.string.we_are_processing_your_request));
}
@Override
protected Bitmap doInBackground(String... strings) {
try {
String imageFileName = "picture_" + System.currentTimeMillis() + ".jpg";
File directory = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) + "/" + Constants.INTERNAL_FOLDER_NAME + "/");
directory.mkdirs();
mFile = new File(directory, imageFileName);
if (!mFile.isFile()) {
try {
mFile.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.Q) {
final ContentResolver resolver = ((CameraFaceDetectionActivity) mContext).getContentResolver();
insertImage(resolver, mBitmap, mFile.getAbsolutePath(), "");
} else {
FileOutputStream out = new FileOutputStream(mFile);
try {
// mBitmap = modifyOrientation(mBitmap,mFile.getAbsolutePath());
OutputStream output = new FileOutputStream(mFile);
mBitmap.compress(Bitmap.CompressFormat.JPEG, 100, output);
output.flush(); // Not really required
output.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
} catch(Exception e){
e.printStackTrace();
}
return mBitmap;
}
@Override
protected void onPostExecute(Bitmap bitmap) {
super.onPostExecute(bitmap);
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
try {
OutputStream output = new FileOutputStream(mFile);
Bitmap b = modifyOrientation(mBitmap, mFile.getAbsolutePath());
b.compress(Bitmap.CompressFormat.JPEG, 100, output);
} catch (IOException e) {
e.printStackTrace();
}
startActivity(new Intent(mContext, SelfiePreviewForgetPsdActivity.class)
.putExtra(Constants.KEY_MOBILE, mMobileNumber)
.putExtra(Constants.KEY_COUNTRY_CODE, mCountryCode)
.putExtra(KEY_ID_NUMBER, idNumber)
.putExtra(Constants.KEY_USER_DETAIL, mVerifyUserDetailResponse)
.putExtra(KEY_ID_TYPE, idType)
.putExtra(Constants.IMAGE_PATH, mFile.getAbsolutePath()));
}
}, 500);
}
}
以下是用于在Android Q上保存位图以指定文件夹的方法
public static String insertImage(ContentResolver cr,
Bitmap source,
String title,
String description) {
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.TITLE, title);
values.put(MediaStore.Images.Media.DISPLAY_NAME, title);
values.put(MediaStore.Images.Media.DESCRIPTION, description);
values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpg");
// Add the date meta data to ensure the image is added at the front of the gallery
values.put(MediaStore.Images.Media.DATE_ADDED, System.currentTimeMillis());
values.put(MediaStore.Images.Media.DATE_TAKEN, System.currentTimeMillis());
Uri url = null;
String stringUrl = null; /* value to be returned */
try {
url = cr.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
if (source != null) {
OutputStream imageOut = cr.openOutputStream(url);
try {
source.compress(Bitmap.CompressFormat.JPEG, 100, imageOut);
} finally {
imageOut.close();
}
long id = ContentUris.parseId(url);
// Wait until MINI_KIND thumbnail is generated.
Bitmap miniThumb = MediaStore.Images.Thumbnails.getThumbnail(cr, id, MediaStore.Images.Thumbnails.MINI_KIND, null);
// This is for backward compatibility.
storeThumbnail(cr, miniThumb, id, source.getWidth(), source.getHeight(), MediaStore.Images.Thumbnails.MICRO_KIND);
} else {
cr.delete(url, null, null);
url = null;
}
} catch (Exception e) {
if (url != null) {
cr.delete(url, null, null);
url = null;
}
}
if (url != null) {
stringUrl = url.toString();
}
return stringUrl;
}
保存位图方法
private static final Bitmap storeThumbnail(
ContentResolver cr,
Bitmap source,
long id,
float width,
float height,
int kind) {
// create the matrix to scale it
Matrix matrix = new Matrix();
float scaleX = width / source.getWidth();
float scaleY = height / source.getHeight();
matrix.setScale(scaleX, scaleY);
Bitmap thumb = Bitmap.createBitmap(source, 0, 0,
source.getWidth(),
source.getHeight(), matrix,
true
);
ContentValues values = new ContentValues(4);
values.put(MediaStore.Images.Thumbnails.KIND, kind);
values.put(MediaStore.Images.Thumbnails.IMAGE_ID, (int) id);
values.put(MediaStore.Images.Thumbnails.HEIGHT, thumb.getHeight());
values.put(MediaStore.Images.Thumbnails.WIDTH, thumb.getWidth());
Uri url = cr.insert(MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI, values);
try {
OutputStream thumbOut = cr.openOutputStream(url);
thumb.compress(Bitmap.CompressFormat.JPEG, 100, thumbOut);
thumbOut.close();
return thumb;
} catch (Exception ex) {
return null;
}
}
答案 2 :(得分:1)
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
替换为此:
requireContext().getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS)!!.absolutePath