【发布时间】:2020-09-23 11:36:40
【问题描述】:
我正在尝试将我的位图文件写入我在 androids 外部存储中创建的目录中的文件路径,但是当我运行我的代码时,我从bitmap.compress (bitmap.CompressFormat.JPEG, 0, outputStream) 收到了一个null pointer exception。通过调试,我发现我的bitmap 对象不为空,并且outputStream 对象为空,因此当我创建outputStream 对象并收到java.io.FileNotFoundException 时,null pointer exception 正在发生。从调试中我知道java.io.FileNotFoundException 正在发生,因为dir.mkdir () 返回false,所以没有为我的位图文件创建目录。
我不明白为什么 dir.mkdir () 返回 false,因为我实例化了 dir 并检查外部存储是否可写入 isExternalStorageWritable() 并在我的清单文件中添加 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 并创建了 askPermission()、@987654335 @& isStoragePermissionGranted () 请求用户对外部存储的许可。所以我不明白为什么dir.mkdir ()返回false并且没有创建目录。
这是发生异常的类:
public class BitmapFiles {
public String imagePath;
public String name;
private Bitmap bitmap;
private int resourceId;
private Context context;
private OutputStream outputStream;
private File file;
public BitmapFiles (Context context, int resourceId, String name) {
this.resourceId = resourceId;
this.name = name;
this.context = context;
convertToBitmap();
saveBitmap();
setImagePath();
}
public void convertToBitmap () {
bitmap = BitmapFactory.decodeResource(context.getResources(), resourceId);
}
public void saveBitmap () {
File filePath = Environment.getExternalStorageDirectory ();
File dir = new File (filePath.getAbsolutePath() + "/Items");
if (isExternalStorageWritable()) {
Log.d ("red", "external storage is writable");//I recieve this in the log cat
}
if (!dir.exists ()) {
try {
boolean direct = dir.mkdir();//Returns false
if (dir.exists()) {
Log.d ("blue", "directory exists now");//I don't recieve this in the log cat
}
if (!direct) {
Log.d ("green", "the directory was not created");//I recieve this in the log cat
}
} catch (SecurityException e) {
e.printStackTrace();
}
} else {
Log.d ("yellow", "the directory already exists");
}
file = new File (dir, name + ".jpg");
try {
outputStream = new FileOutputStream(file);
} catch (FileNotFoundException e) {
e.printStackTrace ();
}
if (outputStream == null) {
Log.d ("grey", "outputstream is null");//I recieve this in log cat
}
bitmap.compress (Bitmap.CompressFormat.JPEG, 0, outputStream);
}
public boolean isExternalStorageWritable () {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals (state)) {
return true;
}
return false;
}
}
这是我请求用户许可的类:
public class GroceryItem extends AppCompatActivity {
private static final int STORAGE_PERMISSION_CODE = 101;
protected void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_grocery_item);
askForPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE, STORAGE_PERMISSION_CODE);
}
public void askForPermission (String permission, int requestCode) {
if (isStoragePermissionGranted()) {
ActivityCompat.requestPermissions(this, new String [] {permission}, requestCode);
} else {
Toast.makeText (this, "Permission already granted", Toast.LENGTH_SHORT)
.show();
}
}
public void onRequestPermissionsResult (int requestCode, String [] permissions, int [] grantResults) {
super.onRequestPermissionsResult (requestCode, permissions, grantResults);
if (requestCode == STORAGE_PERMISSION_CODE) {
if (grantResults.length > 0 && grantResults [0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, "Storage Permission Granted", Toast.LENGTH_SHORT)
.show();
} else {
Toast.makeText(this, "Storage Permission Denied", Toast.LENGTH_SHORT)
.show();
}
}
}
public boolean isStoragePermissionGranted () {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, "permission granted", Toast.LENGTH_SHORT)
.show();
return true;
}
return false;
}
}
这是我收到的例外情况:
2020-09-23 10:18:20.829 32212-32263/com.myapp.groceryapp W/System.err: java.io.FileNotFoundException: /storage/emulated/0/Items/faan.jpg: open failed: ENOENT (No such file or directory)
2020-09-23 10:18:20.829 32212-32263/com.myapp.groceryapp W/System.err: at libcore.io.IoBridge.open(IoBridge.java:496)
2020-09-23 10:18:20.829 32212-32263/com.myapp.groceryapp W/System.err: at java.io.FileOutputStream.<init>(FileOutputStream.java:235)
2020-09-23 10:18:20.830 32212-32263/com.myapp.groceryapp W/System.err: at java.io.FileOutputStream.<init>(FileOutputStream.java:186)
2020-09-23 10:18:20.830 32212-32263/com.myapp.groceryapp W/System.err: at com.myapp.groceryapp.BitmapFiles.saveBitmap(BitmapFiles.java:82)
2020-09-23 10:18:20.830 32212-32263/com.myapp.groceryapp W/System.err: at com.myapp.groceryapp.BitmapFiles.<init>(BitmapFiles.java:30)
2020-09-23 10:18:20.830 32212-32263/com.myapp.groceryapp W/System.err: at com.myapp.groceryapp.MyDatabaseHelper.createBitmapFiles(MyDatabaseHelper.java:42)
2020-09-23 10:18:20.830 32212-32263/com.myapp.groceryapp W/System.err: at com.myapp.groceryapp.MyDatabaseHelper.upgradeDatabase(MyDatabaseHelper.java:37)
2020-09-23 10:18:20.830 32212-32263/com.myapp.groceryapp W/System.err: at com.myapp.groceryapp.MyDatabaseHelper.onCreate(MyDatabaseHelper.java:33)
2020-09-23 10:18:20.830 32212-32263/com.myapp.groceryapp W/System.err: at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:412)
2020-09-23 10:18:20.830 32212-32263/com.myapp.groceryapp W/System.err: at android.database.sqlite.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:341)
2020-09-23 10:18:20.830 32212-32263/com.myapp.groceryapp W/System.err: at com.myapp.groceryapp.GroceryItem.accessDataBase(GroceryItem.java:44)
2020-09-23 10:18:20.830 32212-32263/com.myapp.groceryapp W/System.err: at com.myapp.groceryapp.GroceryItem$StartDatabase.doInBackground(GroceryItem.java:101)
2020-09-23 10:18:20.830 32212-32263/com.myapp.groceryapp W/System.err: at com.myapp.groceryapp.GroceryItem$StartDatabase.doInBackground(GroceryItem.java:93)
2020-09-23 10:18:20.830 32212-32263/com.myapp.groceryapp W/System.err: at android.os.AsyncTask$3.call(AsyncTask.java:378)
2020-09-23 10:18:20.830 32212-32263/com.myapp.groceryapp W/System.err: at java.util.concurrent.FutureTask.run(FutureTask.java:266)
2020-09-23 10:18:20.830 32212-32263/com.myapp.groceryapp W/System.err: at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:289)
2020-09-23 10:18:20.830 32212-32263/com.myapp.groceryapp W/System.err: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
2020-09-23 10:18:20.830 32212-32263/com.myapp.groceryapp W/System.err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
2020-09-23 10:18:20.830 32212-32263/com.myapp.groceryapp W/System.err: at java.lang.Thread.run(Thread.java:919)
2020-09-23 10:18:20.830 32212-32263/com.myapp.groceryapp W/System.err: Caused by: android.system.ErrnoException: open failed: ENOENT (No such file or directory)
2020-09-23 10:18:20.830 32212-32263/com.myapp.groceryapp W/System.err: at libcore.io.Linux.open(Native Method)
2020-09-23 10:18:20.830 32212-32263/com.myapp.groceryapp W/System.err: at libcore.io.ForwardingOs.open(ForwardingOs.java:167)
2020-09-23 10:18:20.830 32212-32263/com.myapp.groceryapp W/System.err: at libcore.io.BlockGuardOs.open(BlockGuardOs.java:252)
2020-09-23 10:18:20.830 32212-32263/com.myapp.groceryapp W/System.err: at libcore.io.ForwardingOs.open(ForwardingOs.java:167)
2020-09-23 10:18:20.830 32212-32263/com.myapp.groceryapp W/System.err: at android.app.ActivityThread$AndroidOs.open(ActivityThread.java:7581)
2020-09-23 10:18:20.830 32212-32263/com.myapp.groceryapp W/System.err: at libcore.io.IoBridge.open(IoBridge.java:482)
2020-09-23 10:18:20.830 32212-32263/com.myapp.groceryapp W/System.err: ... 18 more
2020-09-23 10:18:20.830 32212-32263/com.myapp.groceryapp D/outty: outputstream is null
2020-09-23 10:18:20.836 32212-32263/com.myapp.groceryapp E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #1
Process: com.myapp.groceryapp, PID: 32212
java.lang.RuntimeException: An error occurred while executing doInBackground()
at android.os.AsyncTask$4.done(AsyncTask.java:399)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:383)
at java.util.concurrent.FutureTask.setException(FutureTask.java:252)
at java.util.concurrent.FutureTask.run(FutureTask.java:271)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:289)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:919)
Caused by: java.lang.NullPointerException
at android.graphics.Bitmap.compress(Bitmap.java:1407)
at com.myapp.groceryapp.BitmapFiles.saveBitmap(BitmapFiles.java:95)
at com.myapp.groceryapp.BitmapFiles.<init>(BitmapFiles.java:30)
at com.myapp.groceryapp.MyDatabaseHelper.createBitmapFiles(MyDatabaseHelper.java:42)
at com.myapp.groceryapp.MyDatabaseHelper.upgradeDatabase(MyDatabaseHelper.java:37)
at com.myapp.groceryapp.MyDatabaseHelper.onCreate(MyDatabaseHelper.java:33)
at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:412)
at android.database.sqlite.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:341)
at com.myapp.groceryapp.GroceryItem.accessDataBase(GroceryItem.java:44)
at com.myapp.groceryapp.GroceryItem$StartDatabase.doInBackground(GroceryItem.java:101)
at com.myapp.groceryapp.GroceryItem$StartDatabase.doInBackground(GroceryItem.java:93)
at android.os.AsyncTask$3.call(AsyncTask.java:378)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:289)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:919)
【问题讨论】:
-
那是因为您的设备运行的是 Android 10。
标签: java android nullpointerexception filenotfoundexception android-external-storage