Android 将相机图像保存到目录中

Android 将相机图像保存到目录中,android,image,directory,android-camera,Android,Image,Directory,Android Camera,我正在开发一个应用程序,在该应用程序中,我必须单击相机中的图像并将其保存到目录中。我可以创建名为MyPersonalFolder的目录,并且图像也将进入其中,但当我试图打开该图像以查看时,它不会打开,并显示无法打开该图像的消息。这是我的密码。谁能告诉我我在这里犯了什么错误 我还提到了清单中的权限 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permi

我正在开发一个应用程序,在该应用程序中,我必须单击相机中的图像并将其保存到目录中。我可以创建名为MyPersonalFolder的目录,并且图像也将进入其中,但当我试图打开该图像以查看时,它不会打开,并显示无法打开该图像的消息。这是我的密码。谁能告诉我我在这里犯了什么错误

我还提到了清单中的权限

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-feature android:name="android.hardware.camera" />





 public class Camera extends Activity{

    private static final String TAG = "Camera";

    private static final int CAMERA_PIC_REQUEST = 1111;
    Button click , share;
    ImageView image;
    String to_send;
    String filename;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.camera);

image = (ImageView)findViewById(R.id.image);

        share = (Button)findViewById(R.id.share);

        click = (Button)findViewById(R.id.click);

        click.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub

                Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);

                startActivityForResult(intent, CAMERA_PIC_REQUEST);

            }
        });

        share.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {

              BitmapDrawable bitmapDrawable = (BitmapDrawable)image.getDrawable();

                Bitmap bitmap = bitmapDrawable.getBitmap();

                // Save this bitmap to a file.
                File cache = getApplicationContext().getExternalCacheDir();
                File sharefile = new File(cache, "toshare.png");
                try {
                FileOutputStream out = new FileOutputStream(sharefile);
                bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
                out.flush();
                out.close();
                } catch (IOException e) {
                }

                // Now send it out to share
                Intent share = new Intent(android.content.Intent.ACTION_SEND);
                share.setType("image/*");
                share.putExtra(Intent.EXTRA_STREAM, Uri.parse("file://" + sharefile.getAbsolutePath()));
                try {
                startActivity(Intent.createChooser(share, "Share photo"));
                } catch (Exception e) {
                }
                 /*Intent share = new Intent(Intent.ACTION_SEND);
                 share.setType("text/plain");
                 //String to_send = null;
                share.putExtra(Intent.EXTRA_TEXT, to_send);

                 startActivity(Intent.createChooser(share, "Share using..."));*/

            }
        });
    }
         protected void onActivityResult(int requestCode, int resultCode, Intent data) {

                FileOutputStream outStream = null;
                if (requestCode == CAMERA_PIC_REQUEST) {
                    //2
                    Bitmap thumbnail = (Bitmap) data.getExtras().get("data"); 
                    image.setImageBitmap(thumbnail);
                    //3
                    share.setVisibility(0);
                    ByteArrayOutputStream bytes = new ByteArrayOutputStream();
                    thumbnail.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
                    //4
                    try {
                    File sdCard = Environment.getExternalStorageDirectory();
                    File dir = new File (sdCard.getAbsolutePath() + "/MyPersonalFolder");
                    dir.mkdirs();   
                    String fileName = String.format("%d.jpg", System.currentTimeMillis());
                    File outFile = new File(dir, fileName);

                    outStream = new FileOutputStream(outFile);
                    //outStream.write(data[0]);
                    outStream.flush();
                    outStream.close();

                    //Log.d(TAG, "onPictureTaken - wrote bytes: " + data.length + " to " + outFile.getAbsolutePath());

                    refreshGallery(outFile);
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {


                    /*try {
                        file.createNewFile();
                        FileOutputStream fo = new FileOutputStream(file);
                        //5
                        fo.write(bytes.toByteArray());
                        fo.close();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();*/
                    }
                }
         }

            private void refreshGallery(File file) {
                Intent mediaScanIntent = new Intent( Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
                mediaScanIntent.setData(Uri.fromFile(file));
                sendBroadcast(mediaScanIntent);
            }   

         }

公共类摄影机扩展活动{
私有静态最终字符串标记=“相机”;
专用静态最终int摄像机图片请求=1111;
点击按钮,分享;
图像视图图像;
要发送的字符串;
字符串文件名;
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.camera);
image=(ImageView)findviewbyd(R.id.image);
share=(按钮)findViewById(R.id.share);
单击=(按钮)findViewById(R.id.click);
单击.setOnClickListener(新建视图.OnClickListener(){
@凌驾
公共void onClick(视图v){
//TODO自动生成的方法存根
Intent Intent=新Intent(android.provider.MediaStore.ACTION\u IMAGE\u CAPTURE);
startActivityForResult(意图、摄像头图片请求);
}
});
share.setOnClickListener(新视图.OnClickListener(){
@凌驾
公共void onClick(视图v){
BitmapDrawable BitmapDrawable=(BitmapDrawable)image.getDrawable();
位图位图=bitmapDrawable.getBitmap();
//将此位图保存到文件中。
文件缓存=getApplicationContext().getExternalCacheDir();
文件共享文件=新文件(缓存,“toshare.png”);
试一试{
FileOutputStream out=新的FileOutputStream(共享文件);
compress(bitmap.CompressFormat.PNG,100,out);
out.flush();
out.close();
}捕获(IOE异常){
}
//现在发送给大家分享
意向共享=新意向(android.content.Intent.ACTION\u SEND);
share.setType(“image/*”);
share.putExtra(Intent.EXTRA_STREAM,Uri.parse(“文件:/”+sharefile.getAbsolutePath());
试一试{
startActivity(Intent.createChooser(共享,“共享照片”));
}捕获(例外e){
}
/*意向共享=新意向(意向.行动\发送);
share.setType(“文本/普通”);
//要发送的字符串=空;
share.putExtra(Intent.EXTRA\u文本,发送);
startActivity(Intent.createChooser(共享,“使用共享…”)*/
}
});
}
受保护的void onActivityResult(int请求代码、int结果代码、意图数据){
FileOutputStream扩展流=null;
if(requestCode==摄像机图片请求){
//2
位图缩略图=(位图)数据.getExtras().get(“数据”);
setImageBitmap(缩略图);
//3
share.setVisibility(0);
ByteArrayOutputStream字节=新建ByteArrayOutputStream();
缩略图.compress(Bitmap.CompressFormat.JPEG,100,字节);
//4
试一试{
文件sdCard=Environment.getExternalStorageDirectory();
File dir=新文件(sdCard.getAbsolutePath()+“/MyPersonalFolder”);
dir.mkdirs();
字符串文件名=String.format(“%d.jpg”,System.currentTimeMillis());
文件输出文件=新文件(目录,文件名);
outStream=新文件OutputStream(输出文件);
//超流写入(数据[0]);
冲水;
exptream.close();
//Log.d(标记“onPictureTaken-写入字节:“+data.length+”到“+outFile.getAbsolutePath()”);
刷新画廊(outFile);
}catch(filenotfounde异常){
e、 printStackTrace();
}捕获(IOE异常){
e、 printStackTrace();
}最后{
/*试一试{
createNewFile();
FileOutputStream fo=新的FileOutputStream(文件);
//5
fo.write(bytes.toByteArray());
fo.close();
}捕获(IOE异常){
//TODO自动生成的捕捉块
e、 printStackTrace()*/
}
}
}
私有空刷新库(文件){
Intent mediaScanIntent=新的Intent(Intent.ACTION\u MEDIA\u SCANNER\u SCAN\u文件);
mediaScanIntent.setData(Uri.fromFile(file));
sendBroadcast(mediaScanIntent);
}   
}

您需要使用MediaScanner通知系统新文件/目录。创建并保存新文件后,您可以尝试以下操作:

/**
 * Adds the new photo/video to the device gallery, else it will remain only visible via sd card
 *
 * @param path
 */
public static void addToGallery(Context context, String path) {
    MediaScanner scanner = new MediaScanner(path, null);
    MediaScannerConnection connection = new MediaScannerConnection(context, scanner);
    scanner.connection = connection;
    connection.connect();
}

/**
 * Scans the sd card for new videos/images and adds them to the gallery
 */
private static final class MediaScanner implements MediaScannerConnection.MediaScannerConnectionClient {
    private final String path;
    private final String mimeType;
    MediaScannerConnection connection;

    public MediaScanner(String path, String mimeType) {
        this.path = path;
        this.mimeType = mimeType;
    }

    @Override
    public void onMediaScannerConnected() {
        connection.scanFile(path, mimeType);
    }

    @Override
    public void onScanCompleted(String path, Uri uri) {
        connection.disconnect();
    }
} 
编辑:

您还忘了将字节数组写入输出流中指定的文件,就像您注释掉的代码一样。在刷新库之前,请在末尾尝试以下操作:

outStream = new FileOutputStream(outFile);
outStream.write(bytes.toByteArray()); //this is the line you had missing
outStream.flush();
outStream.close();

另外请注意,使用Intent.ACTION\u MEDIA\u SCANNER\u SCAN\u文件刷新多媒体资料也会给您带来kitkat上的一些安全问题(记不清问题是什么)。因此,请确保您在kitkat设备上对其进行测试,以确认其正常工作。

嘿,克里斯,谢谢您宝贵的时间。克里斯,我已编辑了我的问题,请您看一下。:)编辑得很好,很高兴看到