相机意图不适用于三星 Galaxy S3
Posted
技术标签:
【中文标题】相机意图不适用于三星 Galaxy S3【英文标题】:Camera intent not working with Samsung Galaxy S3 【发布时间】:2013-02-21 07:09:19 【问题描述】:我有一个活动,我让用户可以选择单击相机中的图像,然后将此图像存储在字节数组和数据库中。但是我的代码似乎不适用于三星 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));
finallymyCursor.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));
finallymyCursor.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 中)
【问题讨论】:
我在使用这个特定设备时遇到了同样的问题。经过多次反复试验,我已经解决了这个问题。你可能会从here 那里得到关于这个问题的更好的想法 您介意链接您的项目吗?我不介意测试一些东西。 当然@Daniel Smith,让我知道在哪里以及如何做到这一点? 只需压缩项目并将其加载到您想要在线的任何位置并在此处链接。我使用谷歌驱动器。其他人使用 mediafire。 【参考方案1】:经过三天的挣扎,我终于设计了一个简单的机制来克服三星 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 );
【讨论】:
适用于三星 Galaxy S3。但并非适用于所有三星设备。 哪个特定设备?我已经改进了代码,很快就会发布更新! S3 也有同样的问题 我有一个只能通过 android:screenOrientation="portrait" 进行纵向活动的活动但是 S3 在切换到相机时总是强制改变方向。因此,添加 android:configChanges="keyboardHidden|orientation|screenSize" 可以防止它破坏底层活动。感谢您的帖子,它帮助我弄清楚了! Samsung Note 3 with Lolipop 仍然有这个问题。请使用@J_Sizzle 的答案来修复此错误。 这根本不是一个解决方案,它不是一个通用的解决方案,也不适用于所有设备。考虑为所有设备制定解决方案。问题在于方向没有查询不同的MediaStore
列。如果您将configChanges
设置为android:configChanges="keyboardHidden|orientation|screenSize"
,它将工作一次,但之后,相同的行为将再次出现【参考方案2】:
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);
【讨论】:
以上是关于相机意图不适用于三星 Galaxy S3的主要内容,如果未能解决你的问题,请参考以下文章
三星 Galaxy S3、S4、S5 的 Android 相机/图片方向问题
三星 Galaxy S3 4.1.1 版中的相机强制关闭问题
Android 三星 Galaxy S4 自定义相机预览失真