StartPreview не удалось, но не все устройства

У меня ошибка error startPreview, но не все устройства. В Motorola RAZR и Samsung Galaxy S3 он работает очень хорошо. Некоторые люди сказали мне, что у них такая же проблема на других устройствах (Galaxy SII Lite, Galaxy Ace Duos, Samsung Galaxy Y и т. Д.). Я пытаюсь протестировать в Samsung Galaxy Y, и вот что я получил в Logcat

java.lang.RuntimeException: startPreview failed at android.hardware.Camera.startPreview(Native Method) at br.com.timo.tubagram.CameraSurfaceView.surfaceCreated(CameraSurfaceView.java:47) at android.view.SurfaceView.updateWindow(SurfaceView.java:601) at android.view.SurfaceView.updateWindow(SurfaceView.java:413) at android.view.SurfaceView.dispatchDraw(SurfaceView.java:358) at android.view.View.draw(View.java:7083) at android.view.SurfaceView.draw(SurfaceView.java:344) at android.view.View.buildDrawingCache(View.java:6842) at android.view.View.getDrawingCache(View.java:6628) at android.view.ViewGroup.drawChild(ViewGroup.java:1571) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373) at android.view.View.draw(View.java:7083) at android.widget.FrameLayout.draw(FrameLayout.java:357) at android.view.ViewGroup.drawChild(ViewGroup.java:1646) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373) at android.view.ViewGroup.drawChild(ViewGroup.java:1644) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373) at android.view.ViewGroup.drawChild(ViewGroup.java:1644) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373) at android.view.View.draw(View.java:7083) at android.widget.FrameLayout.draw(FrameLayout.java:357) at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:2108) at android.view.ViewRoot.draw(ViewRoot.java:1540) at android.view.ViewRoot.performTraversals(ViewRoot.java:1276) at android.view.ViewRoot.handleMessage(ViewRoot.java:1878) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:130) at android.app.ActivityThread.main(ActivityThread.java:3770) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:507) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:912) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:670) at dalvik.system.NativeStart.main(Native Method) 

И где мой код

 public class CameraSurfaceView extends SurfaceView implements SurfaceHolder.Callback, PreviewCallback{ private SurfaceHolder holder; private Camera camera; private Camera.Parameters parameters; boolean front = false; public CameraSurfaceView(Context context) { super(context); this.holder = this.getHolder(); this.holder.addCallback(this); } @Override public void surfaceCreated(SurfaceHolder holder) { try { this.holder = holder; camera = Camera.open(); camera.setPreviewDisplay(holder); parameters = parametrosCamera(); camera.setParameters(parameters); camera.setDisplayOrientation(90); camera.startPreview(); } catch (IOException ioe) { } } @Override public void surfaceDestroyed(SurfaceHolder holder) { camera.stopPreview(); camera.release(); camera = null; } private Parameters parametrosCamera(){ Parameters parameters = camera.getParameters(); List<Camera.Size> sizes = parameters.getSupportedPreviewSizes(); if (sizes != null){ Size min = sizes.get(0); for (Size size : sizes){ if (size.width < min.width){ min = size; }else{ parameters.setPreviewSize(min.width, min.height); parameters.setPictureSize(min.width, min.height); } } parameters.set("orientation", "portrait"); parameters.setRotation(90); } if (parameters.getFlashMode() != null){ parameters.setFlashMode(Parameters.FLASH_MODE_AUTO); } return parameters; } } 

И моя Основная деятельность

 public class PrincipalActivity extends Activity{ Camera camera; File sdImageMainDirectory; CameraSurfaceView cameraSurfaceView; Button principalActivity_bt_TirarFoto; Button principalActivity_bt_VirarFoto; Button principalActivity_bt_Aceitar; Button principalActivity_bt_Cancelar; FrameLayout preview; ImageView principalActivity_iv_UltimaFoto; HandlePictureStorage hps; int wid = 0; boolean imageSelected = false; boolean front = false; String caminhoImagens; String url; // File storagePath = new File(Environment.getExternalStorageDirectory() + "/Tubagram/"); @SuppressWarnings("deprecation") @SuppressLint("NewApi") public void onCreate(Bundle savedInstanceState) { Log.i("PrincipalActivity","onCreate"); super.onCreate(savedInstanceState); setContentView(R.layout.principal_activity); principalActivity_bt_TirarFoto = (Button) findViewById(R.id.principalActivity_bt_TirarFoto); setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); cameraSurfaceView = new CameraSurfaceView(principalActivity_bt_TirarFoto.getContext()); cameraSurfaceView.setSoundEffectsEnabled(true); cameraSurfaceView.setDrawingCacheEnabled(true); preview = (FrameLayout) findViewById(R.id.principalActivity_fl_Camera); preview.addView(cameraSurfaceView); principalActivity_bt_TirarFoto.setSoundEffectsEnabled(true); principalActivity_bt_TirarFoto.setOnClickListener(new OnClickListener() { @SuppressLint("NewApi") @Override public void onClick(View v) { Log.i("PrincipalActivity","onClick - TirarFoto"); camera = cameraSurfaceView.getCamera(); camera.takePicture(new ShutterCallback() { @Override public void onShutter() { AudioManager mgr = (AudioManager) getSystemService(Context.AUDIO_SERVICE); mgr.playSoundEffect(AudioManager.FLAG_PLAY_SOUND); } }, null, hps = new HandlePictureStorage()); imageSelected = false; mostrarBotoesConfirma(); } }); principalActivity_bt_Aceitar = (Button) findViewById(R.id.principalActivity_bt_Aceitar); principalActivity_bt_Aceitar.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Log.i("PrincipalActivity","onClick - Aceitar"); if (verificaInstagram()){ ByteArrayOutputStream stream = new ByteArrayOutputStream(); if (imageSelected){ Bitmap bitmap = ((BitmapDrawable)cameraSurfaceView.getBackground()).getBitmap(); bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream); }else{ hps.getBitmap().compress(Bitmap.CompressFormat.PNG, 100, stream); } salvarImagemSelecionada(stream.toByteArray()); Intent shareIntent = new Intent(android.content.Intent.ACTION_SEND); shareIntent.setType("image/*"); caminhoImagens = getRealPathFromURI(Uri.parse(url)); Log.i("Caminho imagem: ", caminhoImagens); shareIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("file://" + caminhoImagens)); shareIntent.setPackage("com.instagram.android"); startActivity(shareIntent); // } }else{ Toast.makeText(v.getContext(), "Você não possui o Instagram no seu smartphone!", Toast.LENGTH_SHORT).show(); } } }); principalActivity_bt_Cancelar = (Button) findViewById(R.id.principalActivity_bt_Cancelar); principalActivity_bt_Cancelar.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Log.i("PrincipalActivity","onClick - Cancelar"); esconderBotoesConfirma(); cameraSurfaceView.setBackgroundColor(Color.TRANSPARENT); cameraSurfaceView.voltarCamera(); } }); int qtdCameras = Camera.getNumberOfCameras(); principalActivity_bt_VirarFoto = (Button) findViewById(R.id.principalActivity_bt_VirarFoto); if(qtdCameras > 1){ principalActivity_bt_VirarFoto.setOnClickListener(new OnClickListener() { public void onClick(View v) { Log.i("PrincipalActivity","onClick - VirarCamera"); Thread t = new Thread(){ @Override public void run() { cameraSurfaceView.flipit(); front = cameraSurfaceView.getFront(); } }; t.start(); } }); }else{ principalActivity_bt_VirarFoto.setVisibility(View.INVISIBLE); } LinearLayout principalActivity_ll_Molduras = (LinearLayout) findViewById(R.id.principalActivity_ll_Molduras); principalActivity_ll_Molduras.setVisibility(View.VISIBLE); List<Integer> listaMoldurasMenores = new ArrayList<Integer>(); final List<Integer> listaMoldurasMaiores = new ArrayList<Integer>(); // listaMoldurasMenores.add(R.drawable.moldura_menor0); listaMoldurasMenores.add(R.drawable.moldura_menor1); listaMoldurasMenores.add(R.drawable.moldura_menor2); listaMoldurasMenores.add(R.drawable.moldura_menor3); listaMoldurasMenores.add(R.drawable.moldura_menor4); listaMoldurasMenores.add(R.drawable.moldura_menor5); listaMoldurasMenores.add(R.drawable.moldura_menor6); listaMoldurasMaiores.add(R.drawable.moldura_maior1); listaMoldurasMaiores.add(R.drawable.moldura_maior2); listaMoldurasMaiores.add(R.drawable.moldura_maior3); listaMoldurasMaiores.add(R.drawable.moldura_maior4); listaMoldurasMaiores.add(R.drawable.moldura_maior5); listaMoldurasMaiores.add(R.drawable.moldura_maior6); for (int i = 0; i < listaMoldurasMenores.size(); i++) { final ImageView imagem_moldura = new ImageView(this); imagem_moldura.setScaleType(ScaleType.FIT_XY); imagem_moldura.setId(i); imagem_moldura.setImageResource(listaMoldurasMenores.get(i)); imagem_moldura.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Log.i("PrincipalActivity","onClick - Molduras"); ImageView imagem_moldura_maior = new ImageView(v.getContext()); imagem_moldura_maior.setImageResource(listaMoldurasMaiores.get(imagem_moldura.getId())); preview.setForeground(imagem_moldura_maior.getDrawable()); } }); principalActivity_ll_Molduras.addView(imagem_moldura,i); } principalActivity_iv_UltimaFoto = (ImageView) findViewById(R.id.principalActivity_iv_UltimaFoto); principalActivity_iv_UltimaFoto.setAdjustViewBounds(false); Uri uri = buscaUltimaFotoAlbum(); Drawable backgroundGaleria; if (uri != null){ String caminhosImagensGaleria = getRealPathFromURI(uri); backgroundGaleria = Drawable.createFromPath(caminhosImagensGaleria); principalActivity_iv_UltimaFoto.setBackgroundDrawable(backgroundGaleria); }else{ principalActivity_iv_UltimaFoto.setBackgroundResource(R.drawable.box_imagem_album); } principalActivity_iv_UltimaFoto.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(Intent.ACTION_PICK,android.provider.MediaStore.Images.Media.INTERNAL_CONTENT_URI); final int ACTION_SELECT_IMAGE = 1; intent.putExtra("crop", "true"); intent.putExtra("aspectX", 10); intent.putExtra("aspectY", 10); intent.putExtra("outputX", 256); intent.putExtra("outputY", 256); intent.putExtra("scale", true); intent.putExtra("return-data", true); startActivityForResult(intent,ACTION_SELECT_IMAGE); } }); } 

EDIT 1 – 06/20/2013

Я немного изменил свой код и теперь работает в своей Галактике Y, но мой FrameLayout с камерой не работает. Я получаю черный экран на FrameLayout. Кто-нибудь знает почему?

Что я меняю:

Я помещаю эту строку в свой конструктор

 this.holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 

Я изменил мою surfaceCreated и surfaceChanged на это

 @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { try { camera.stopPreview(); parameters = parametrosCamera(); camera.setParameters(parameters); camera.setDisplayOrientation(90); camera.setPreviewDisplay(holder); camera.startPreview(); } catch (IOException e) { } catch (Exception e){ } } @SuppressLint("NewApi") @Override public void surfaceCreated(SurfaceHolder holder) { try { camera = Camera.open(0); camera.setPreviewDisplay(this.holder); camera.startPreview(); } catch (IOException ioe) { } catch (Exception e){ } } 

PS

Я поставил несколько журналов, чтобы получить размер, который мой setPreviewSize получает с моим методом

 private Parameters parametrosCamera(){ Parameters parameters = camera.getParameters(); List<Camera.Size> sizes = parameters.getSupportedPreviewSizes(); if (sizes != null){ Size min = sizes.get(0); for (Size size : sizes){ if (size.width < min.width){ min = size; }else{ parameters.setPreviewSize(min.width, min.height); parameters.setPictureSize(min.width, min.height); Log.i("Ultima Camera Width: " + min.width, "Ultima Camera Height: " + min.height); } } parameters.set("orientation", "portrait"); parameters.setRotation(90); } if (parameters.getFlashMode() != null){ parameters.setFlashMode(Parameters.FLASH_MODE_AUTO); } return parameters; } 

И я поместил Log в surfaceChanged чтобы получить ширину и высоту (я не использую эту ширину и высоту), и посмотрите, является ли одно и то же, и я получаю этот результат

Motorola RAZR HD (работает очень хорошо)

SurfaceChanged: 540 x 573 метод parametrosCamera: 640 x 480

Samsung Galaxy Y (не показывать мой просмотр)

SurfaceChanged: Параметр 240 x 162 (W x H) Параметр: 320 x 240

И в моем методе parametrosCamera я использую эти две строки

 parameters.set("orientation", "portrait"); parameters.setRotation(90); 

Я думаю, что ответ на мою проблему в этой части моего кода.

Solutions Collecting From Web of "StartPreview не удалось, но не все устройства"

Кажется, вы ищете минимальный размер предварительного просмотра. Но если этот размер не поддерживается как размер изображения, ваш код инициализирует камеру в неподдерживаемом состоянии. Некоторые устройства могут отказаться от предварительного просмотра в таком состоянии.

Я не уверен, что вам действительно нужен размер изображения, равный размеру предварительного просмотра. Если вы этого не сделаете, вы можете просто перечислить значения по умолчанию из parameters.getSupportedPictureSizes() .

Другая распространенная ошибка (не обязательно применимая к вашему случаю использования) коренится в том, что размеры камеры заднего вида не соответствуют размерам передней камеры. Поэтому при переключении камеры размер всегда должен быть пересчитан.