2013-03-06 77 views
16

我有一個活動wherin我給用戶一個選項,點擊從相機的圖像,然後我把這個圖像存儲在一個字節數組和數據庫。我的代碼似乎但是並沒有對三星Galaxy S3工作,下面是代碼:相機意圖不能與三星Galaxy S3

攝像頭調用的意圖:

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

在相機活動方法:

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的工作,我改變了C頌讚以下,現在它可以與三星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(); 
    } 
} 

這是我的圖像()函數:

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)

+0

我遇到了與此特定設備相同的問題。經過多次反覆試驗,我已經解決了這個問題。你可能會更好地瞭解這個問題從[這裏](http://stackoverflow.com/questions/14495304/camera-force-closing-issue-in-samsung-galaxy-s3-version-4-1-1/14640678 #14640678) – 2013-03-06 13:21:03

+0

上面的引用是同一個伴侶,我從同一個教程中引用了它,而一切看起來都很好,唯一的問題是我丟失了某處不應該發生的聲明。 – Skynet 2013-03-06 13:22:31

+0

你介意鏈接你的項目嗎?我不介意測試一些東西。 – 2013-03-07 00:17:52

回答

16

終於在掙扎三天後,我設計了一個簡單的機制來克服三星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); 
     } 

    } 
} 
+0

親愛的,謝謝你分享你的解決方案!由你決定! – Mateus 2013-03-18 16:30:05

+0

歡迎隊友:) – Skynet 2013-03-19 11:46:53

+0

三星Galaxy S3可以正常工作。但不適用於所有三星設備。 – redestructa 2013-05-17 10:33:12