17

我有一个活动,我让用户可以选择单击相机中的图像,然后将此图像存储在字节数组和数据库中。但是我的代码似乎不适用于三星 Galaxy S3,下面是代码:

摄像头调用意图:

if (i == 0) {
    Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE); 
    startActivityForResult(cameraIntent, CAMERA_PIC_REQUEST); 
}

关于相机的 Activity 方法:

protected void onActivityResult(int requestCode, int resultCode, Intent data) {  
    if (requestCode == 1337 && resultCode == RESULT_OK) {
        Bundle extras = data.getExtras();
        if (extras != null) {   
            BitmapFactory.Options options = new BitmapFactory.Options();
            thumbnail = (Bitmap) extras.get("data");
            image(thumbnail);
        } else {
            Toast.makeText(CreateProfile.this, "Picture NOt taken", Toast.LENGTH_LONG).show();
        }

        super.onActivityResult(requestCode, resultCode, data);     
    }
}

我的图像(位图缩略图)功能:

public void image(Bitmap thumbnail) {
    Bitmap photo = thumbnail; 
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    photo.compress(Bitmap.CompressFormat.PNG, 100, bos);
    b = bos.toByteArray();
    ImageView imageview = (ImageView)findViewById(R.id.imageView1);
    Bitmap bt = Bitmap.createScaledBitmap(photo, 100, 80, false);  
    imageview.setImageBitmap(bt);
}

但是这不适用于三星 S3,我将代码更改为以下代码,现在它适用于三星 S3,但它不适用于任何其他设备。

相机意图:

Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

结果活动:

startActivityForResult(intent, CAMERA_IMAGE_CAPTURE);
protected void onActivityResult(int requestCode, int resultCode, Intent data) {  
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == CAMERA_IMAGE_CAPTURE && resultCode == Activity.RESULT_OK) {
        // Describe the columns you'd like to have returned. Selecting from the Thumbnails location gives you both the Thumbnail Image ID, as well as the original image ID
String[] projection = {
 MediaStore.Images.Thumbnails._ID,  // The columns we want
 MediaStore.Images.Thumbnails.IMAGE_ID,
 MediaStore.Images.Thumbnails.KIND,
 MediaStore.Images.Thumbnails.DATA};
 String selection = MediaStore.Images.Thumbnails.KIND + "="  + // Select only mini's
 MediaStore.Images.Thumbnails.MINI_KIND;

 String sort = MediaStore.Images.Thumbnails._ID + " DESC";

//At the moment, this is a bit of a hack, as I'm returning ALL images, and just taking the latest one. There is a better way to narrow this down I think with a WHERE clause which is currently the selection variable
Cursor myCursor = this.managedQuery(MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI, projection, selection, null, sort);

long imageId = 0l;
long thumbnailImageId = 0l;
String thumbnailPath = "";

try{
 myCursor.moveToFirst();
imageId = myCursor.getLong(myCursor.getColumnIndexOrThrow(MediaStore.Images.Thumbnails.IMAGE_ID));
thumbnailImageId = myCursor.getLong(myCursor.getColumnIndexOrThrow(MediaStore.Images.Thumbnails._ID));
thumbnailPath = myCursor.getString(myCursor.getColumnIndexOrThrow(MediaStore.Images.Thumbnails.DATA));
}
finally{myCursor.close();}

 //Create new Cursor to obtain the file Path for the large image

 String[] largeFileProjection = {
 MediaStore.Images.ImageColumns._ID,
 MediaStore.Images.ImageColumns.DATA
 };

 String largeFileSort = MediaStore.Images.ImageColumns._ID + " DESC";
 myCursor = this.managedQuery(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, largeFileProjection, null, null, largeFileSort);
 String largeImagePath = "";

try{
 myCursor.moveToFirst();

//This will actually give yo uthe file path location of the image.
largeImagePath = myCursor.getString(myCursor.getColumnIndexOrThrow(MediaStore.Images.ImageColumns.DATA));
}
finally{myCursor.close();}
 // These are the two URI's you'll be interested in. They give you a handle to the actual images
 Uri uriLargeImage = Uri.withAppendedPath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, String.valueOf(imageId));
 Uri uriThumbnailImage = Uri.withAppendedPath(MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI, String.valueOf(thumbnailImageId));

// I've left out the remaining code, as all I do is assign the URI's to my own objects anyways...
// Toast.makeText(this, ""+largeImagePath, Toast.LENGTH_LONG).show();
// Toast.makeText(this, ""+uriLargeImage, Toast.LENGTH_LONG).show();
// Toast.makeText(this, ""+uriThumbnailImage, Toast.LENGTH_LONG).show();

    if (largeImagePath != null) {
        // Toast.makeText(this, "" + largeImagePath, Toast.LENGTH_LONG).show();

        BitmapFactory.Options opts = new BitmapFactory.Options();
        opts.inSampleSize = OG;
        // thumbnail = (BitmapFactory.decodeFile(picturePath));
        thumbnail = BitmapFactory.decodeFile((largeImagePath), opts);
        System.gc();
        if (thumbnail != null) {
            Toast.makeText(this, "Success", Toast.LENGTH_LONG).show();
        }

        image(thumbnail);

    }

    if (uriLargeImage != null) {
        Toast.makeText(this, "" + uriLargeImage, Toast.LENGTH_LONG).show();
    } 

    if (uriThumbnailImage != null) {
        Toast.makeText(this, "" + uriThumbnailImage, Toast.LENGTH_LONG).show();
    }
}

这是我的 image() 函数:

public void image(Bitmap thumbnail) {
    b = null;

    Bitmap photo = thumbnail; 
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    photo.compress(Bitmap.CompressFormat.PNG, 100, bos);
    b = bos.toByteArray();

    if (b != null) {
        Toast.makeText(this, "Success Yeah" + b, Toast.LENGTH_LONG).show();
    }
}

虽然这三个 1)uriLargeImage 2)largeImagePath 3)uriThumbnailImage 返回我的路径或 URI,但我无法将创建的位图设置为我的 ImageView。然而,这仅适用于三星 S3,如果我在任何其他设备上运行上述编辑的代码,程序就会崩溃。

在我用过的清单中

android:configChanges="keyboardHidden|orientation"

基于教程: http: //kevinpotgieter.wordpress.com/2011/03/30/null-intent-passed-back-on-samsung-galaxy-tab/

但是,如果我在横向模式下拍照,一切正常!我很困惑!!(在三星 S3 中)

4

2 回答 2

17

经过三天的挣扎,我终于设计了一个简单的机制来克服三星 S3 Saga。

下面是代码,代码的快速总结是我首先检查设备的制造商,并在此基础上调用相机的不同意图。

public class MainActivity extends Activity {

    private static int RESULT_LOAD_IMAGE = 1;
    private static final int PICK_FROM_GALLERY = 2;
    int CAMERA_PIC_REQUEST = 1337;
    Bitmap thumbnail = null;
    private static final int OG = 4;

    private static final int CAMERA_IMAGE_CAPTURE = 0;
    Uri u;
    ImageView imgview;
    // int z=0;
    String z = null;
    byte b[];
    String largeImagePath = "";
    Uri uriLargeImage;
    Uri uriThumbnailImage;
    Cursor myCursor;

    public void imageCam(Bitmap thumbnail) {
        Bitmap photo = thumbnail;
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        photo.compress(Bitmap.CompressFormat.JPEG, 70, bos);
        b = bos.toByteArray();
        ImageView imageview = (ImageView) findViewById(R.id.imageView1);
        imageview.setImageBitmap(photo);
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button bt = (Button) findViewById(R.id.button1);
        bt.setOnClickListener(onBTN);
        if (savedInstanceState != null) {

            Bitmap Zatang;
            String B1 = savedInstanceState.getString("message");
            Toast.makeText(this, "SavedYeah" + B1, Toast.LENGTH_LONG).show();
            BitmapFactory.Options opts = new BitmapFactory.Options();
            opts.inSampleSize = OG;
            Zatang = BitmapFactory.decodeFile((B1), opts);
            System.gc();
            if (Zatang != null) {
                Toast.makeText(this, "Success Zatang" + B1, Toast.LENGTH_LONG)
                .show();
                imageCam(Zatang);
            }
        }
    }

    private View.OnClickListener onBTN = new View.OnClickListener() {
        public void onClick(View v) {
            openNewGameDialog();
        }
    };

    String[] B = { "Cam", "Gallery" };

    private void openNewGameDialog() {
        new AlertDialog.Builder(this).setItems(B,new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialoginterface,int i) {
                if (i == 0) {
                    String BX1 =  android.os.Build.MANUFACTURER;

                    if(BX1.equalsIgnoreCase("samsung")) {
                        Toast.makeText(getApplicationContext(), "Device man"+BX1, Toast.LENGTH_LONG).show();
                        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                        startActivityForResult(intent, CAMERA_IMAGE_CAPTURE);

                    } else {
                        Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE); 
                        startActivityForResult(cameraIntent, CAMERA_PIC_REQUEST); 
                    }
                } else if (i == 1) {
                    Intent intent = new Intent(Intent.ACTION_PICK);
                    intent.setType("image/*");
                    startActivityForResult(intent, RESULT_LOAD_IMAGE);
                }
            }).show();
        }

        protected void onActivityResult(int requestCode, int resultCode, Intent data) {  
            super.onActivityResult(requestCode, resultCode, data);
            if(requestCode==CAMERA_IMAGE_CAPTURE && resultCode==Activity.RESULT_OK){

                // Describe the columns you'd like to have returned. Selecting from the Thumbnails location gives you both the Thumbnail Image ID, as well as the original image ID
                String[] projection = {
                        MediaStore.Images.Thumbnails._ID,  // The columns we want
                        MediaStore.Images.Thumbnails.IMAGE_ID,
                        MediaStore.Images.Thumbnails.KIND,
                        MediaStore.Images.Thumbnails.DATA};
                String selection = MediaStore.Images.Thumbnails.KIND + "="  + // Select only mini's
                        MediaStore.Images.Thumbnails.MINI_KIND;

                String sort = MediaStore.Images.Thumbnails._ID + " DESC";

                //At the moment, this is a bit of a hack, as I'm returning ALL images, and just taking the latest one. There is a better way to narrow this down I think with a WHERE clause which is currently the selection variable
                myCursor = this.managedQuery(MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI, projection, selection, null, sort);

                long imageId = 0l;
                long thumbnailImageId = 0l;
                String thumbnailPath = "";

                try {
                    myCursor.moveToFirst();
                    imageId = myCursor.getLong(myCursor.getColumnIndexOrThrow(MediaStore.Images.Thumbnails.IMAGE_ID));
                    thumbnailImageId = myCursor.getLong(myCursor.getColumnIndexOrThrow(MediaStore.Images.Thumbnails._ID));
                    thumbnailPath = myCursor.getString(myCursor.getColumnIndexOrThrow(MediaStore.Images.Thumbnails.DATA));
                } finally {
                    myCursor.close();
                }

                //Create new Cursor to obtain the file Path for the large image

                String[] largeFileProjection = {
                        MediaStore.Images.ImageColumns._ID,
                        MediaStore.Images.ImageColumns.DATA
                };

                String largeFileSort = MediaStore.Images.ImageColumns._ID + " DESC";
                myCursor = this.managedQuery(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, largeFileProjection, null, null, largeFileSort);
                largeImagePath = "";

                try {
                    myCursor.moveToFirst();

                    //This will actually give yo uthe file path location of the image.
                    largeImagePath = myCursor.getString(myCursor.getColumnIndexOrThrow(MediaStore.Images.ImageColumns.DATA));
                } finally {
                    myCursor.close();
                }
                // These are the two URI's you'll be interested in. They give you a handle to the actual images
                uriLargeImage = Uri.withAppendedPath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, String.valueOf(imageId));
                uriThumbnailImage = Uri.withAppendedPath(MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI, String.valueOf(thumbnailImageId));

                // I've left out the remaining code, as all I do is assign the URI's to my own objects anyways...
                // Toast.makeText(this, ""+largeImagePath, Toast.LENGTH_LONG).show();
                // Toast.makeText(this, ""+uriLargeImage, Toast.LENGTH_LONG).show();
                // Toast.makeText(this, ""+uriThumbnailImage, Toast.LENGTH_LONG).show();


                if (largeImagePath != null) {
                    Toast.makeText(this, "LARGE YES"+largeImagePath, Toast.LENGTH_LONG).show();

                    BitmapFactory.Options opts = new BitmapFactory.Options();
                    opts.inSampleSize = OG;
                    thumbnail = BitmapFactory.decodeFile((largeImagePath), opts);
                    System.gc();
                    if (thumbnail != null) {
                        Toast.makeText(this, "Try Without Saved Instance", Toast.LENGTH_LONG).show();
                        imageCam(thumbnail);
                    }
                }
                if (uriLargeImage != null) {
                    Toast.makeText(this, ""+uriLargeImage, Toast.LENGTH_LONG).show();
                }
                if (uriThumbnailImage != null) {
                    Toast.makeText(this, ""+uriThumbnailImage, Toast.LENGTH_LONG).show();
                }
            }
            if( requestCode == 1337 && resultCode== RESULT_OK){
                Bundle extras = data.getExtras();
                if (extras.keySet().contains("data") ){
                    BitmapFactory.Options options = new BitmapFactory.Options();
                    thumbnail = (Bitmap) extras.get("data");
                    if (thumbnail != null) {
                        Toast.makeText(this, "YES Thumbnail", Toast.LENGTH_LONG).show();
                        BitmapFactory.Options opt = new BitmapFactory.Options();
                        thumbnail = (Bitmap) extras.get("data");
                        imageCam(thumbnail);
                    }
                } else {
                    Uri imageURI = getIntent().getData();
                    ImageView imageview = (ImageView)findViewById(R.id.imageView1);
                    imageview.setImageURI(imageURI);

                    if(imageURI != null){
                        Toast.makeText(this, "YES Image Uri", Toast.LENGTH_LONG).show();
                    }
                }
                super.onActivityResult(requestCode, resultCode, data);  
            }
            if (requestCode == RESULT_LOAD_IMAGE && resultCode == RESULT_OK && null != data) {
                Uri selectedImage = data.getData();

                String[] filePathColumn = { MediaStore.Images.Media.DATA };
                Cursor cursor = getContentResolver().query(selectedImage,filePathColumn, null, null, null);
                cursor.moveToFirst();
                int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
                String picturePath = cursor.getString(columnIndex);
                cursor.close();
                BitmapFactory.Options opts = new BitmapFactory.Options();
                thumbnail = BitmapFactory.decodeFile((picturePath), opts);
                System.gc();
                imageCam(thumbnail);             
            }
        }
        @Override
        public void onSaveInstanceState(Bundle outState) {
            super.onSaveInstanceState(outState);
            outState.putString("message",largeImagePath );
        }

    }
}
于 2013-03-08T05:12:51.787 回答
0
Above ans with some correction for normal samsung device and orientaton issue problem


private void cameraIntent() {
        new AlertDialog.Builder(this).setItems(B,new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialoginterface,int i) {
                if (i == 0) {

                    String manufacturer_Type =  android.os.Build.MANUFACTURER;

                    if(manufacturer_Type.equalsIgnoreCase("samsung")) {
                        Toast.makeText(getApplicationContext(), "Device man"+manufacturer_Type, Toast.LENGTH_LONG).show();
                        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                        startActivityForResult(intent, CAMERA_IMAGE_CAPTURE);

                    } else {
                        Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE); 
                        startActivityForResult(cameraIntent, CAMERA_PIC_REQUEST); 
                    }
                } else if (i == 1) {
                    Intent intent = new Intent(Intent.ACTION_PICK);
                    intent.setType("image/*");
                    startActivityForResult(intent, RESULT_LOAD_IMAGE);
                }
            }
        }).show();


    }

protected void onActivityResult(int requestCode, int resultCode, Intent data) {  
        super.onActivityResult(requestCode, resultCode, data);
        if(requestCode==CAMERA_IMAGE_CAPTURE && resultCode==Activity.RESULT_OK){

            // Describe the columns you'd like to have returned. Selecting from the Thumbnails location gives you both the Thumbnail Image ID, as well as the original image ID
            String[] projection = {
                    MediaStore.Images.Thumbnails._ID,  // The columns we want
                    MediaStore.Images.Thumbnails.IMAGE_ID,
                    MediaStore.Images.Thumbnails.KIND,
                    MediaStore.Images.Thumbnails.DATA};
            String selection = MediaStore.Images.Thumbnails.KIND + "="  + // Select only mini's
                    MediaStore.Images.Thumbnails.MINI_KIND;

            String sort = MediaStore.Images.Thumbnails._ID + " DESC";

            //At the moment, this is a bit of a hack, as I'm returning ALL images, and just taking the latest one. There is a better way to narrow this down I think with a WHERE clause which is currently the selection variable
            myCursor = CameraActivity.this.managedQuery(MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI, projection, selection, null, sort);

            long imageId = 0l;
            long thumbnailImageId = 0l;
            String thumbnailPath = "";

            try {
                int cursor_size = myCursor.getCount();
                if(cursor_size>0){
                    myCursor.moveToFirst();
                    imageId = myCursor.getLong(myCursor.getColumnIndexOrThrow(MediaStore.Images.Thumbnails.IMAGE_ID));

                    thumbnailImageId = myCursor.getLong(myCursor.getColumnIndexOrThrow(MediaStore.Images.Thumbnails._ID));
                    thumbnailPath = myCursor.getString(myCursor.getColumnIndexOrThrow(MediaStore.Images.Thumbnails.DATA));
                    myCursor.close();
                    //Create new Cursor to obtain the file Path for the large image

                    String[] largeFileProjection = {
                            MediaStore.Images.ImageColumns._ID,
                            MediaStore.Images.ImageColumns.DATA
                    };

                    String largeFileSort = MediaStore.Images.ImageColumns._ID + " DESC";
                    Cursor mCursor = CameraActivity.this.managedQuery(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, largeFileProjection, null, null, largeFileSort);
                    largeImagePath = "";

                    try {
                        mCursor.moveToFirst();

                        //This will actually give you the file path location of the image.
                        largeImagePath = mCursor.getString(mCursor.getColumnIndexOrThrow(MediaStore.Images.ImageColumns.DATA));
                    }finally{
                        mCursor.close();
                    }

                    // These are the two URI's you'll be interested in. They give you a handle to the actual images
                    uriLargeImage = Uri.withAppendedPath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, String.valueOf(imageId));
                    uriThumbnailImage = Uri.withAppendedPath(MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI, String.valueOf(thumbnailImageId));

                    // I've left out the remaining code, as all I do is assign the URI's to my own objects anyways...
                    // Toast.makeText(this, ""+largeImagePath, Toast.LENGTH_LONG).show();
                    // Toast.makeText(this, ""+uriLargeImage, Toast.LENGTH_LONG).show();
                    // Toast.makeText(this, ""+uriThumbnailImage, Toast.LENGTH_LONG).show();


                    if (largeImagePath != null) {
                        Toast.makeText(this, "LARGE YES"+largeImagePath, Toast.LENGTH_LONG).show();

                        BitmapFactory.Options opts = new BitmapFactory.Options();
                        opts.inSampleSize = OG;
                        thumbnail = BitmapFactory.decodeFile((largeImagePath), opts);
                        System.gc();
                        if (thumbnail != null) {
                            Toast.makeText(this, "Try Without Saved Instance", Toast.LENGTH_LONG).show();
                            Bitmap rotatedImage = exifImage(thumbnail, largeImagePath);
                            //                        imageCam(thumbnail);

                            if(imageview!=null){
                                imageview.setImageBitmap(rotatedImage);
                            }
                        }
                    }
                    if (uriLargeImage != null) {
                        Toast.makeText(this, ""+uriLargeImage, Toast.LENGTH_LONG).show();
                    }
                    if (uriThumbnailImage != null) {
                        Toast.makeText(this, ""+uriThumbnailImage, Toast.LENGTH_LONG).show();
                    }
                }else{
                    requestCode=CAMERA_SAMSUNG_NORMAL_PIC_REQUEST;
                    normalDeviceCamera(requestCode, resultCode, data);
                }
            } catch(Exception e){
                e.printStackTrace();

            }finally {
                if(!myCursor.isClosed()){
                    myCursor.close();
                }
            }


        }
        if( requestCode == CAMERA_PIC_REQUEST && resultCode== RESULT_OK){
            normalDeviceCamera(requestCode, resultCode, data);
        }

    }

    private void normalDeviceCamera(int requestCode, int resultCode, Intent data){
        if( requestCode == CAMERA_PIC_REQUEST && resultCode== RESULT_OK){
            Bundle extras = data.getExtras();
            if (extras.keySet().contain`enter code here`s("data") ){
                BitmapFactory.Options options = new BitmapFactory.Options();
                thumbnail = (Bitmap) extras.get("data");
                if (thumbnail != null) {
                    Toast.makeText(this, "YES Thumbnail", Toast.LENGTH_LONG).show();
                    /*  BitmapFactory.Options opt = new BitmapFactory.Options();*/
                    thumbnail = (Bitmap) extras.get("data");

                    if(imageview!=null){
                        imageview.setImageBitmap(thumbnail);
                    }
                }
            } else {
                Uri imageURI = getIntent().getData();
                //                ImageView imageview = (ImageView)findViewById(R.id.imgCam);
                if(imageview!=null){
                    imageview.setImageURI(imageURI);
                }
                if(imageURI != null){
                    Toast.makeText(this, "YES Image Uri", Toast.LENGTH_LONG).show();
                }
            }
            super.onActivityResult(requestCode, resultCode, data);  
        }
    }
于 2018-05-25T05:30:13.210 回答