开发者

Take photo from android app (not working on Galaxy S / SII)

I am a beginner in Android development, and I have to continue a project started by a former fellow worker. In this application we have customers files, with personal information, and there is a button allowing us to take pictures. But here is the problem : This works fine on HTC Desire and other Android phones, but not on Galaxy S and Galaxy S II.

The algorithm used is basic : When we touch the screen or the center pad, we use the autoFocus method from the "camera" class. Then, we display the picture just taken, and when we push the menu button or the "back" button, a dialog is displayed, asking us if we want to save the picture or not.

Here is the "CameraView.java" code :

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();
    }

}

And the "photoView.java" class :

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();
    }

}

Can anyone help me please ?

Thanks for reading :)


thank you for your answer.

Problem solved ! Here is the answer for anyone who have the same problem :

In these lines :

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

The "intentPhoto.putExtra("laPhoto", data)" method can't be executed because the "data" size is too big. "data" contains the picture taken, and on Galaxy SII, the picture resolution is very big, so this method can't send data (because it's size limited).

So I just used the setPictureSize(width, height) method (Camera.Parameters) on surfaceChanged method to define my own resolution (1024x768), and now it's works fine !

Careful : Before define your own resolution, you HAVE TO verify that it's accepted by your device by using getSupportedPictureSizes() method

Hope this could help someone


Below is the code I used to do the same thing you are trying to do. It creates a SurfaceView and starts the camera preview. Upon tapping anywhere on the screen it takes a picture, shows it and displays two buttons - save and retry (see the onPictureTaken method). The user can click Save, and return the data back to the app, or retry (which from what I can tell I did not finish the retry functionality - it just calls finish()). Hope this helps.

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);
    }

}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜