2011-08-03 97 views
0

我是Android開發的初學者,我必須繼續一個由前同事開始的項目。 在這個應用程序中,我們有客戶文件和個人信息,並且有一個按鈕允許我們拍照。 但問題在於:HTC Desire和其他Android手機可以正常工作,但不適用於Galaxy S和Galaxy S II。從android應用拍攝照片(不適用於Galaxy S/SII)

使用的算法是基本的:當我們觸摸屏幕或中心墊時,我們使用「camera」類中的autoFocus方法。然後,我們顯示剛剛拍攝的圖片,當我們按下菜單按鈕或「後退」按鈕時,會顯示一個對話框,詢問我們是否要保存圖片。

這裏是 「CameraView.java」 代碼:

public class CameraView extends Activity implements Callback, AutoFocusCallback 
{ 
    private Camera camera; 
    private FrameLayout layout; 
    private SurfaceView surface; 

    private String idPatient; 
    private boolean start; 
    private int click; 

    public void onCreate(Bundle savedInstanceState) 
    { 
     super.onCreate(savedInstanceState); 
     requestWindowFeature(Window.FEATURE_NO_TITLE); 
     getWindow().setBackgroundDrawable(null); 
     getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); 

     setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); 
     layout = new FrameLayout(this); 
     surface = new SurfaceView(this); 
     surface.getHolder().addCallback(this); 
     surface.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 
     layout.addView(surface); 
     setContentView(layout); 

     idPatient = (String) this.getIntent().getStringExtra("lePatient"); 
     start = false; 
     click = 0; 
    } 

    @Override 
    public boolean onKeyDown(int keyCode, KeyEvent event){ 
     if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) 
     { 
      click++; 
      if((!start)&&(click==1)) 
      { 
       camera.autoFocus(this); 
       return true; 
      } 
     } 
     if (keyCode == KeyEvent.KEYCODE_BACK) 
     { 
      finish(); 
     } 
     return false; 
    } 


    @Override 
    public boolean onTouchEvent(MotionEvent event) 
    { 
     if(event.getAction() == MotionEvent.ACTION_DOWN) 
     { 
      click++; 
      if((!start)&&(click==1)) 
      { 
       camera.autoFocus(this); 
       return true; 
      }  
     } 
     return false; 
    } 

    public void onAutoFocus(boolean success, Camera camera) 
    { 
     start = true; 
     PictureCallback picture = new PictureCallback() 
     { 
      @Override 
      public void onPictureTaken(byte[] data, Camera camera) 
      { 
       Intent intentPhoto = new Intent(CameraView.this, PhotoView.class); 
       intentPhoto.putExtra("lePatient", idPatient); 
       intentPhoto.putExtra("laPhoto", data); 
       CameraView.this.startActivityForResult(intentPhoto, 101); 

       camera.startPreview(); 
       start = false; 
       click = 0; 
      } 
     }; 
     camera.takePicture(null, null, picture); 
    } 

    @Override 
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) 
    { 
     Camera.Parameters params = camera.getParameters(); 
     params.setPictureFormat(PixelFormat.JPEG); 
     params.setPreviewSize(width, height); 
     camera.setParameters(params); 
     camera.startPreview(); 
    } 

    @Override 
    public void surfaceCreated(SurfaceHolder holder) 
    { 
     try 
     { 
      camera = Camera.open(); 
      camera.setPreviewDisplay(holder); 
     } 
     catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 

    @Override 
    public void surfaceDestroyed(SurfaceHolder holder) { 
     camera.stopPreview(); 
     camera.release(); 
     camera = null; 
    } 

    /** 
    * Fermeture de l'activity 
    */ 
    protected void onDestroy() 
    { 
     super.onDestroy(); 
    } 

} 

與 「photoView.java」 類:

public class PhotoView extends Activity 
{ 
    private static final int DIALOG_ENREGISTRER = 10; 

    private ImageView photo; 
    private byte[] data; 
    private String idPatient; 
    private DBAdapter db; 

    /** 
    * Creation de l'activity 
    */ 
    public void onCreate(Bundle savedInstanceState) 
    { 
     super.onCreate(savedInstanceState); 
     setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); 
     requestWindowFeature(Window.FEATURE_NO_TITLE); 
     getWindow().setBackgroundDrawable(null); 
     getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); 
     setContentView(R.layout.photoview); 

     db = new DBAdapter(this); 
     db.open(); 

     idPatient = (String) this.getIntent().getStringExtra("lePatient"); 
     data = (byte[]) this.getIntent().getByteArrayExtra("laPhoto"); 
     photo = (ImageView) this.findViewById(R.id.photo); 

     Bitmap bmp = BitmapFactory.decodeByteArray(data, 0, data.length);  

     int w = bmp.getWidth(); 
     int h = bmp.getHeight(); 
     Matrix mtx = new Matrix(); 
     mtx.postRotate(90); 
     Bitmap rotatedBMP = Bitmap.createBitmap(bmp, 0, 0, w, h, mtx, true); 

     WindowManager manager = (WindowManager) this.getSystemService(Context.WINDOW_SERVICE); 
     Display display = manager.getDefaultDisplay(); 
     int height= display.getHeight(); 
     int width= display.getWidth(); 
     Bitmap bmpFullScreen = Bitmap.createScaledBitmap(rotatedBMP, width, height, true); 

     photo.setImageBitmap(bmpFullScreen); 
    } 

    /** 
    * Permet de récuperer un évènement de click de touche 
    */ 
    public boolean onKeyUp(int keyCode, KeyEvent event) { 
     if((keyCode==KeyEvent.KEYCODE_BACK) ||(keyCode==KeyEvent.KEYCODE_MENU))// zoom in 
     { 
      showDialog(DIALOG_ENREGISTRER); 
     } 
     //return super.onKeyUp(keyCode, event); 
     return false; 
    } 

    /** 
    * Permet de créer des boites de dialog 
    */ 
    protected Dialog onCreateDialog(int id) 
    { 
     switch (id) 
     { 
      case DIALOG_ENREGISTRER: 
       return new AlertDialog.Builder(PhotoView.this) 
        .setIcon(android.R.drawable.ic_menu_info_details) 
        .setTitle("Enregistrer ?") 
        .setPositiveButton("OUI", new DialogInterface.OnClickListener() { 
         public void onClick(DialogInterface dialog, int whichButton) 
         { 
          String title = PhotoView.this.savePhotoDB(); 
          PhotoView.this.savePhotoFS(title); 

          finish(); 
         } 
        }) 
        .setNegativeButton("NON", new DialogInterface.OnClickListener() { 
         public void onClick(DialogInterface dialog, int whichButton) 
         { 
          finish(); 
         } 
        }) 
        .create(); 
     } 
     return null; 
    } 

    /** 
    * Permet de sauvegarder une photo dans la base de données 
    * @param title 
    */ 
    private String savePhotoDB() 
    { 
     Log.i("","idPatient : " +idPatient); 
     String comment = "Note : "; 
     Log.i("","comment : " + comment); 

     Date maintenant = new Date(System.currentTimeMillis()); 

     SimpleDateFormat formatDateJour = new SimpleDateFormat("yyyyddMM"); 
     String date = formatDateJour.format(maintenant); 
     Log.i("","Date formatée : " + date); 
     SimpleDateFormat formatHeure = new SimpleDateFormat("mmss"); 
     String heure = formatHeure.format(maintenant); 
     Log.i("","Heure formatée : " + heure); 

     String fileName = "photo"+date+heure+".jpeg"; 
     Log.i("","fileName : " + fileName); 

     String title = "photo"+date+heure+".jpeg"; 
     Log.i("","title : " + title); 
     String userDefined = "1"; 
     Log.i("","userDefined : " + userDefined); 

     db.insererPhoto(idPatient, comment, date, fileName, title, userDefined); 
     return title; 
    } 

    /** 
    * Permet de sauvegarder une photo sur le file system 
    * @param title 
    */ 
    private void savePhotoFS(String title) { 
     try 
     { 
      File fs = new File(PhotoView.this.getFilesDir()+"/"+title); 
      FileOutputStream fos = new FileOutputStream(fs); 
      fos.write(data); 
      fos.flush(); 
      fos.close(); 
      //Toast.makeText(PhotoView.this, ""+fs.getAbsolutePath(), Toast.LENGTH_LONG).show(); 
     } 
     catch (Exception e) 
     { 
      e.printStackTrace(); 
     } 
    } 

    /** 
    * Fermeture de l'activity 
    */ 
    protected void onDestroy() 
    { 
     db.close(); 
     super.onDestroy(); 
    } 

} 

誰能幫助我嗎?

感謝您的閱讀:)

+0

後除外。發生什麼事?它崩潰了嗎?或者在拍攝照片後沒有數據被返回? – Jack

+0

噢對不起,我忘了那部分^^。好吧,當我觸摸屏幕時,我想會拍攝一張照片(我聽到了聲音,並且有自動對焦),但是之後,我們不再向我顯示剛剛拍攝的照片,而是「回到」相機查看,所以我無法保存我的照片。我檢查了我的手機相冊,這張照片不在這裏。我猜這個問題來自於「onAutoFocus」方法,它應該調用「PhotoView」類(在其他設備上正常工作,但不是像我說的那樣在Galaxy S上)。 =>對不起,如果我的英語不好,這不是我的母語^^ – Vince

+0

Up?任何人都可以幫助我嗎? :(:( – Vince

回答

1

下面是我用來做你正在嘗試做同樣的事情的代碼。它創建一個SurfaceView並啓動相機預覽。在屏幕上的任何地方點擊它會拍攝一張照片,顯示它並顯示兩個按鈕 - 保存和重試(請參閱onPictureTaken方法)。用戶可以單擊保存,然後將數據返回到應用程序,或者重試(從我所能告訴的我沒有完成重試功能 - 它只是調用finish())。希望這可以幫助。

public class SnapShot extends Activity implements OnClickListener, 
     SurfaceHolder.Callback, Camera.PictureCallback { 

    SurfaceView cameraView; 
    SurfaceHolder surfaceHolder; 
    Camera camera; 
    LayoutInflater inflater; 
    Uri imageFileUri; 
    Button save; 
    Button retry; 
    View viewControl; 
    LayoutParams layoutParamsControl; 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.view_camera); 

     cameraView = (SurfaceView) this.findViewById(R.id.CameraView); 
     surfaceHolder = cameraView.getHolder(); 
     surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 
     surfaceHolder.addCallback(this); 

     cameraView.setFocusable(true); 
     cameraView.setFocusableInTouchMode(true); 
     cameraView.setClickable(true); 
     cameraView.setOnClickListener(this); 

     inflater = LayoutInflater.from(getBaseContext()); 
     viewControl = inflater.inflate(R.layout.camera_control, null); 
     save = (Button) viewControl.findViewById(R.id.vc_btn_keep); 
     retry = (Button)viewControl.findViewById(R.id.vc_btn_discard); 
     layoutParamsControl = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT); 



    } 

    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { 
     camera.startPreview(); 
    } 

    public void surfaceCreated(SurfaceHolder holder) { 
     camera = Camera.open(); 
     try { 
      Camera.Parameters parameters = camera.getParameters(); 
      if (this.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE) { 
       // This is an undocumented although widely known feature 
       parameters.set("orientation", "portrait"); 
       // For Android 2.2 and above 
       camera.setDisplayOrientation(90); 
       // Uncomment for Android 2.0 and above 
       // parameters.setRotation(90); 
      } else { 
       // This is an undocumented although widely known feature 
       parameters.set("orientation", "landscape"); 
       // For Android 2.2 and above 
       camera.setDisplayOrientation(0); 
       // Uncomment for Android 2.0 and above 
       // parameters.setRotation(0); 
      } 
      camera.setParameters(parameters); 
      camera.setPreviewDisplay(holder); 
     } catch (IOException exception) { 
      camera.release(); 
      Log.v("surfaceCreated", exception.getMessage()); 
     } 
     camera.startPreview(); 
    } 

    public void surfaceDestroyed(SurfaceHolder holder) { 

     camera.stopPreview(); 
     camera.release(); 
    } 

    @Override 
    public void onPictureTaken(final byte[] data, Camera camera) { 


     this.addContentView(viewControl, layoutParamsControl); 



      save.setOnClickListener(new Button.OnClickListener() { 

       @Override 
       public void onClick(View v) { 

        insertImage(data); 
        Intent i = new Intent(); 
        i.putExtra("data", imageFileUri.toString()); 
        setResult(-1, i); 
        finish(); 
       }}); 


     retry.setOnClickListener(new Button.OnClickListener() { 

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


    } 

    public void insertImage(byte[] data) 
    { 

     Bitmap b = null; 
     try { 
      b = GeneralUtils.decodeFile(data, this); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     ByteArrayOutputStream bos = new ByteArrayOutputStream(); 
     b.compress(Bitmap.CompressFormat.JPEG, 80, bos); 
     //b = null; 
     Bitmap bitmap = BitmapFactory.decodeByteArray(bos.toByteArray(), 0, bos.size()); 
     Matrix m = new Matrix(); 
     if (b.getWidth() > b.getHeight()) 
     { 
      m.postRotate(90); 
      bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), m, true); 

     } 
     String result = MediaStore.Images.Media.insertImage(getContentResolver(), bitmap, "", ""); 
     b.recycle(); 
     data = null; 
     b = null; 
     m = null; 

     imageFileUri = Uri.parse(result); 

    } 


    @Override 
    public void onClick(View arg0) { 
     // TODO Auto-generated method stub 
     camera.takePicture(null, null, null, this); 
    } 

} 
3

謝謝你的回答。

問題解決! 這裏是誰的人有同樣的問題的答案:

在這些線路:

Intent intentPhoto = new Intent(CameraView.this, PhotoView.class); 
intentPhoto.putExtra("lePatient", idPatient); 
intentPhoto.putExtra("laPhoto", data); 
startActivityForResult(intentPhoto, 101); 

的「intentPhoto.putExtra(」 laPhoto「數據)」方法不能因爲執行「數據」的大小太大了。 「數據」包含拍攝的圖片,而在Galaxy SII上,圖片分辨率非常大,所以此方法無法發送數據(因爲它的尺寸有限)。

所以我只是用setPictureSize(寬,高)方法(Camera.Parameters)上surfaceChanged方法來定義自己的分辨率(1024×768),現在它的正常工作!

小心:在定義自己的分辨率,您必須驗證它是由您的設備接受使用getSupportedPictureSizes()方法

希望能幫助別人