Android文件未找到异常,但图像已保存
我正在制作一个应用程序,利用相机,并有能力采取的照片使用一个简单的图像识别API上。我可以使用图库上传图片,但是直接从相机上传给我带来了巨大的问题。我基本上只是复制了大部分图像创建的android开发文档,不过可能需要在这里或那里更改一些项目 以下是总代码:Android文件未找到异常,但图像已保存,android,Android,我正在制作一个应用程序,利用相机,并有能力采取的照片使用一个简单的图像识别API上。我可以使用图库上传图片,但是直接从相机上传给我带来了巨大的问题。我基本上只是复制了大部分图像创建的android开发文档,不过可能需要在这里或那里更改一些项目 以下是总代码: private File createImageFile() throws IOException { // Create an image file name String timeStamp = new SimpleDa
private File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + "Image_for_Stack" + "_";
File storageDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_DCIM), "Camera");
File image = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
// Save a file: path for use with ACTION_VIEW intents
currentPhotoPath = "file: " + image.getAbsolutePath();
return image;
}
private void dispatchTakePictureIntent() {
try {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// Ensure that there's a camera activity to handle the intent
if (takePictureIntent.resolveActivity(getActivity().getPackageManager()) != null) {
// Create the File where the photo should go
File photoFile = null;
try {
photoFile = createImageFile();
} catch (IOException ex) {
Log.v(TAG, "IO Exception " + ex);
}
// Continue only if the File was successfully created
if (photoFile != null) {
photoURI = FileProvider.getUriForFile(getContextOfApplication(),
BuildConfig.APPLICATION_ID + ".provider",
photoFile);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
startActivityForResult(takePictureIntent, IMAGE_CAPTURE);
}
}
} catch (Exception e) {
Log.v(TAG, "Exception in dispatch " + e);
}
}
private void galleryAddPic() {
try {
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
File f = new File(currentPhotoPath);
Uri contentUri = Uri.fromFile(f);
mediaScanIntent.setData(contentUri);
getContextOfApplication().sendBroadcast(mediaScanIntent);
} catch (Exception e) {
Log.v(TAG, "Exception " + e);
}
}
在一个单独的类中,这称为:
public static byte[] getByteArrayFromIntentData(@NonNull Context context, @NonNull Intent data) {
InputStream inStream = null;
Bitmap bitmap = null;
try {
inStream = context.getContentResolver().openInputStream(data.getData());
Log.v(TAG, "Instream works");
bitmap = BitmapFactory.decodeStream(inStream);
final ByteArrayOutputStream outStream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outStream);
return outStream.toByteArray();
} catch (FileNotFoundException e) {
Log.v("FileOP Debug", "Exception " + e);
return null;
} finally {
if (inStream != null) {
try {
inStream.close();
} catch (IOException ignored) {
}
}
if (bitmap != null) {
bitmap.recycle();
}
}
}
现在,创建的图像没有问题。我可以转到模拟器,查看照片的应用程序,并获得:
但是,当代码给inStream一个值时,我会遇到这个错误:
java.io.FileNotFoundException:/file:
/存储/模拟/0/DCIM/Camera/JPEG_图像_用于_堆栈_3248071614992872091.jpg
(无此类文件或目录)
我不太明白这是怎么回事。该项目显然存在,并保存在手机上。该应用程序确实请求并被授予写入外部存储的权限,我已经在emulator中检查了它被授予的权限。写也伴随着读,所以就我所知,这也不应该是一个问题
编辑
显示从何处调用此代码
else if (requestCode == IMAGE_CAPTURE) {
galleryAddPic();
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
File f = new File(currentPhotoPath);
Uri contentUri = Uri.fromFile(f);
mediaScanIntent.setData(contentUri);
final ProgressDialog progress = new ProgressDialog(getContextOfApplication());
progress.setTitle("Loading");
progress.setMessage("Identify your flower..");
progress.setCancelable(false);
progress.show();
if (!CheckNetworkConnection.isInternetAvailable(getContextOfApplication())) {
progress.dismiss();
Toast.makeText(getContextOfApplication(),
"Internet connection unavailable.",
Toast.LENGTH_SHORT).show();
return;
}
client = ClarifaiClientGenerator.generate(API_KEY);
final byte[] imageBytes = FileOp.getByteArrayFromIntentData(getContextOfApplication(), mediaScanIntent);
到目前为止,在该方法调用中引发FileNotFound异常时,imageBytes将为null 您可以尝试此代码
public class Images extends Activity
{
private Uri[] mUrls;
String[] mFiles=null;
public void onCreate(Bundle icicle)
{
super.onCreate(icicle);
setContentView(R.layout.images);
File images = Environment.getDataDirectory();
File[] imagelist = images.listFiles(new FilenameFilter(){
@override
public boolean accept(File dir, String name)
{
return ((name.endsWith(".jpg"))||(name.endsWith(".png"))
}
});
mFiles = new String[imagelist.length];
for(int i= 0 ; i< imagelist.length; i++)
{
mFiles[i] = imagelist[i].getAbsolutePath();
}
mUrls = new Uri[mFiles.length];
for(int i=0; i < mFiles.length; i++)
{
mUrls[i] = Uri.parse(mFiles[i]);
}
Gallery g = (Gallery) findViewById(R.id.gallery);
g.setAdapter(new ImageAdapter(this));
g.setFadingEdgeLength(40);
}
public class ImageAdapter extends BaseAdapter{
int mGalleryItemBackground;
public ImageAdapter(Context c) {
mContext = c;
}
public int getCount(){
return mUrls.length;
}
public Object getItem(int position){
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent){
ImageView i = new ImageView(mContext);
i.setImageURI(mUrls[position]);
i.setScaleType(ImageView.ScaleType.FIT_XY);
i.setLayoutParams(new Gallery.LayoutParams(260, 210));
return i;
}
private Context mContext;
}
}
公共类图像扩展活动
{
私有Uri[]mUrls;
字符串[]mFiles=null;
创建公共空间(捆绑冰柱)
{
超级冰柱;
setContentView(R.layout.images);
文件images=Environment.getDataDirectory();
File[]imagelist=images.listFiles(新的FilenameFilter(){
@凌驾
公共布尔接受(文件目录,字符串名称)
{
return((name.endsWith(.jpg))| |(name.endsWith(.png)))
}
});
mFiles=新字符串[imagelist.length];
对于(int i=0;i
不清楚在何处、何时以及如何调用getByteArrayFromIntentData()。请先在NactivityResult()中执行。请告诉data.getData().toString()的值。@greenapps因此该值为“file:///file%3A%20/storage/emulated/0/DCIM/Camera/JPEG_Image_for_Stack_4017640369874084193.jpg",我把它放在第三个代码块的instream行的正上方。错误代码仍然是一样的,尽管数字有点变化,因为它是一个新的图像正在被捕获。@已经从OnActivityResult()调用的greenapps,我将把代码添加到上面的帖子。=FileOp.getByteArrayFromIntentData(getContextOfApplication()),mediaScanIntent);
。您应该像=FileOp.getByteArrayFromIntentData(getContextOfApplication(),data.getData());
那样调用它。