为什么在外部存储中保存位图失败,即使位图已正确创建并且可以在 imageView 中显示?
Why saving a bitmap in external storage failed, even though bitmap is created properly and can be displayed in imageView?
我可以从文件位置 "file:///sdcard/temporary_file.jpg" 成功 运行 意图共享屏幕截图(位图)。但现在我坚持将位图保存到那个位置。
我在清单中包含以下内容
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
还有这个函数来检查权限:
@Override
public void onRequestPermissionsResult(int requestCode,
String[] permissions, int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE:
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// do your stuff
} else {
Toast.makeText(iv_ScoreBoard.this, "GET_ACCOUNTS Denied",
Toast.LENGTH_SHORT).show();
}
break;
default:
super.onRequestPermissionsResult(requestCode, permissions,
grantResults);
}
}
点击分享按钮:
View rootView = getWindow().getDecorView().findViewById(android.R.id.content);
Bitmap bitmaptest = getScreenShot(rootView);
Intent share = new Intent(Intent.ACTION_SEND);
share.putExtra(Intent.EXTRA_TEXT, "@Share from App \"XXYY\"");
share.setType("image/jpeg");
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
bitmaptest.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
File f = new File(Environment.getExternalStorageDirectory() + File.separator + "temporary_file.jpg");
try {
f.createNewFile();
FileOutputStream fo = new FileOutputStream(f);
fo.write(bytes.toByteArray());
} catch (IOException e) {
e.printStackTrace();
}
share.putExtra(Intent.EXTRA_STREAM, Uri.parse("file:///sdcard/temporary_file.jpg"));
startActivity(Intent.createChooser(share, "Share Image"));
return true;
getScreenShot(查看视图)
public static Bitmap getScreenShot(View view) {
View screenView = view.getRootView();
screenView.setDrawingCacheEnabled(true);
Bitmap bitmap = Bitmap.createBitmap(screenView.getDrawingCache());
screenView.setDrawingCacheEnabled(false);
return bitmap;
}
点击分享按钮时,它会产生一个黑色的屏幕帽作为图片...
没有创建文件,没有发现错误。
您至少在问题中提供的代码中没有 requesting/checking 权限。
您的代码仅实现了 onRequestPermissionResult,一旦您请求了权限,就会调用它来通知您结果。
您必须请求许可。
在您的 activity 中实施以下操作。
final int requestCode1 = 100;//this is the constant which you pass while requesting permission.
// this code helps you to identify which permission was requested in onPermissionResultReceived, in case you are dealing with more than one permission groups.
....
onCreate(){
... // your code goes here
...
@Override
public void onClick(View view){
if (ContextCompat.checkSelfPermission(thisActivity,
Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
// Permission is not granted
// request permission
ActivityCompat.requestPermissions(iv_ScoreBoard.this, new String[] {Manifest.permission.WRITE_EXTERNAL_STORAGE}, requestCode1);
} else{
//permission granted
takeScreenShot();
}
你的 onRequestPermissionsResult
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode) {
case requestCode1:
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// do your stuff
takeScreenShot();
} else {
Toast.makeText(iv_ScoreBoard.this, "Permission Denied",
Toast.LENGTH_SHORT).show();
}
break;
default:
super.onRequestPermissionsResult(requestCode, permissions,
grantResults);
}
}
在 onCreate 中或在执行需要这些权限的操作之前添加以上代码。
参考 - https://developer.android.com/training/permissions/requesting#java
将文件共享到另一个应用程序时,您需要提供 Uri
权限。
为此,您首先必须在 Manifest
中创建一个提供程序,如下所示:
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths" />
</provider>
@xml/provider_paths
将如下所示:
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="SavedImages" path="Android/data/com.yourpackagename.yourappname/files/SavedImages/"/>
</paths>
您必须在您的 res
->xml
文件夹中创建以上内容,我将其命名为 provider_paths.xml
如果您没有 xml 文件夹,请创建一个。
然后当您共享文件时,您应该提供权限:
Uri imageUri;
Intent share = new Intent(Intent.ACTION_SEND);
if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
imageUri = Uri.parse("file:///sdcard/temporary_file.jpg");
}else {
File newFile = new File(Environment.getExternalStorageDirectory() + File.separator + "temporary_file.jpg");
imageUri = FileProvider.getUriForFile(getContext(), getContext().getPackageName() + ".provider", newFile);
share.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
}
share.setType("image/jpeg");
share.putExtra(Intent.EXTRA_STREAM, imageUri);
share(Intent.createChooser(share, "Share image using"));
老实说,我不认为您的问题与运行时权限有关。 如果是,您会遇到崩溃并且不会创建文件。正如您在问题中所述 It produces a black screen cap as a picture when share button is clicked... No file is created, no error is found.
.
另一方面,当不提供 Uri
权限时,很可能会产生 Uri 暴露异常。
该文件仍将被创建,但它将是空的。就像你正在经历的那样。
我可以从文件位置 "file:///sdcard/temporary_file.jpg" 成功 运行 意图共享屏幕截图(位图)。但现在我坚持将位图保存到那个位置。
我在清单中包含以下内容
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
还有这个函数来检查权限:
@Override
public void onRequestPermissionsResult(int requestCode,
String[] permissions, int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE:
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// do your stuff
} else {
Toast.makeText(iv_ScoreBoard.this, "GET_ACCOUNTS Denied",
Toast.LENGTH_SHORT).show();
}
break;
default:
super.onRequestPermissionsResult(requestCode, permissions,
grantResults);
}
}
点击分享按钮:
View rootView = getWindow().getDecorView().findViewById(android.R.id.content);
Bitmap bitmaptest = getScreenShot(rootView);
Intent share = new Intent(Intent.ACTION_SEND);
share.putExtra(Intent.EXTRA_TEXT, "@Share from App \"XXYY\"");
share.setType("image/jpeg");
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
bitmaptest.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
File f = new File(Environment.getExternalStorageDirectory() + File.separator + "temporary_file.jpg");
try {
f.createNewFile();
FileOutputStream fo = new FileOutputStream(f);
fo.write(bytes.toByteArray());
} catch (IOException e) {
e.printStackTrace();
}
share.putExtra(Intent.EXTRA_STREAM, Uri.parse("file:///sdcard/temporary_file.jpg"));
startActivity(Intent.createChooser(share, "Share Image"));
return true;
getScreenShot(查看视图)
public static Bitmap getScreenShot(View view) {
View screenView = view.getRootView();
screenView.setDrawingCacheEnabled(true);
Bitmap bitmap = Bitmap.createBitmap(screenView.getDrawingCache());
screenView.setDrawingCacheEnabled(false);
return bitmap;
}
点击分享按钮时,它会产生一个黑色的屏幕帽作为图片... 没有创建文件,没有发现错误。
您至少在问题中提供的代码中没有 requesting/checking 权限。
您的代码仅实现了 onRequestPermissionResult,一旦您请求了权限,就会调用它来通知您结果。
您必须请求许可。
在您的 activity 中实施以下操作。
final int requestCode1 = 100;//this is the constant which you pass while requesting permission.
// this code helps you to identify which permission was requested in onPermissionResultReceived, in case you are dealing with more than one permission groups.
....
onCreate(){
... // your code goes here
...
@Override
public void onClick(View view){
if (ContextCompat.checkSelfPermission(thisActivity,
Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
// Permission is not granted
// request permission
ActivityCompat.requestPermissions(iv_ScoreBoard.this, new String[] {Manifest.permission.WRITE_EXTERNAL_STORAGE}, requestCode1);
} else{
//permission granted
takeScreenShot();
}
你的 onRequestPermissionsResult
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode) {
case requestCode1:
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// do your stuff
takeScreenShot();
} else {
Toast.makeText(iv_ScoreBoard.this, "Permission Denied",
Toast.LENGTH_SHORT).show();
}
break;
default:
super.onRequestPermissionsResult(requestCode, permissions,
grantResults);
}
}
在 onCreate 中或在执行需要这些权限的操作之前添加以上代码。
参考 - https://developer.android.com/training/permissions/requesting#java
将文件共享到另一个应用程序时,您需要提供 Uri
权限。
为此,您首先必须在 Manifest
中创建一个提供程序,如下所示:
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths" />
</provider>
@xml/provider_paths
将如下所示:
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="SavedImages" path="Android/data/com.yourpackagename.yourappname/files/SavedImages/"/>
</paths>
您必须在您的 res
->xml
文件夹中创建以上内容,我将其命名为 provider_paths.xml
如果您没有 xml 文件夹,请创建一个。
然后当您共享文件时,您应该提供权限:
Uri imageUri;
Intent share = new Intent(Intent.ACTION_SEND);
if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
imageUri = Uri.parse("file:///sdcard/temporary_file.jpg");
}else {
File newFile = new File(Environment.getExternalStorageDirectory() + File.separator + "temporary_file.jpg");
imageUri = FileProvider.getUriForFile(getContext(), getContext().getPackageName() + ".provider", newFile);
share.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
}
share.setType("image/jpeg");
share.putExtra(Intent.EXTRA_STREAM, imageUri);
share(Intent.createChooser(share, "Share image using"));
老实说,我不认为您的问题与运行时权限有关。 如果是,您会遇到崩溃并且不会创建文件。正如您在问题中所述 It produces a black screen cap as a picture when share button is clicked... No file is created, no error is found.
.
另一方面,当不提供 Uri
权限时,很可能会产生 Uri 暴露异常。
该文件仍将被创建,但它将是空的。就像你正在经历的那样。