jjzjj

android - startPreview 失败但不是所有设备

coder 2023-11-19 原文

我收到错误 startPreview failed 但不是所有设备。 在摩托罗拉 RAZR 和三星 Galaxy S3 中,它运行良好。 有人告诉我他们在其他设备(Galaxy SII Lite、Galaxy Ace Duos、Samsung Galaxy Y 等)中遇到了同样的问题 我正在尝试在三星 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;
    }
}

还有我的PrincipalActivity

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

编辑 1 - 2013 年 6 月 20 日

我稍微更改了我的代码,现在可以在我的 Galaxy Y 中运行,但我的 FrameLayout 和相机无法正常工作。我在 FrameLayout 上出现黑屏。 谁知道为什么?

我改变了什么:

我在构造函数中添加了这一行

this.holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

我将 surfaceCreatedsurfaceChanged 更改为此

@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){
    }
}

附言

我添加了一些日志来获取我的 setPreviewSize 正在使用我的方法获取的大小

private Parameters parametersCamera(){
    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;
}

然后我在 surfaceChanged 中添加了一个 Log 以获取宽度和高度(我不使用此宽度和高度)并查看是否相同,我得到了这个结果

摩托罗拉 RAZR HD(运行良好)

表面已更改:540 x 573 方法参数相机:640 x 480

Samsung Galaxy Y(不要显示我的预览)

表面已更改:240 x 162(宽 x 高) 方法参数相机:320 x 240

在我的方法 parametersCamera 中我使用了这两行

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

我认为我的问题的答案在我的这部分代码中。

最佳答案

您似乎在寻找支持的最小预览尺寸。但是,如果不支持此尺寸作为图片尺寸,您的代码会将相机初始化为不受支持的状态。某些设备可能会选择在这种状态下无法打开预览。

我不确定您是否真的需要图片大小等于预览帧大小。如果不这样做,您可以简单地分别迭代 parameters.getSupportedPictureSizes() 的值。

另一个常见错误(不一定适用于您的用例)是因为后置摄像头的尺寸与前置摄像头的尺寸不匹配。因此,切换相机时必须始终重新计算尺寸。

关于android - startPreview 失败但不是所有设备,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17141421/

有关android - startPreview 失败但不是所有设备的更多相关文章

  1. ruby - 如何以所有可能的方式将字符串拆分为长度最多为 3 的连续子字符串? - 2

    我试图获取一个长度在1到10之间的字符串,并输出将字符串分解为大小为1、2或3的连续子字符串的所有可能方式。例如:输入:123456将整数分割成单个字符,然后继续查找组合。该代码将返回以下所有数组。[1,2,3,4,5,6][12,3,4,5,6][1,23,4,5,6][1,2,34,5,6][1,2,3,45,6][1,2,3,4,56][12,34,5,6][12,3,45,6][12,3,4,56][1,23,45,6][1,2,34,56][1,23,4,56][12,34,56][123,4,5,6][1,234,5,6][1,2,345,6][1,2,3,456][123

  2. ruby-on-rails - 跳过状态机方法的所有验证 - 2

    当我的预订模型通过rake任务在状态机上转换时,我试图找出如何跳过对ActiveRecord对象的特定实例的验证。我想在reservation.close时跳过所有验证!叫做。希望调用reservation.close!(:validate=>false)之类的东西。仅供引用,我们正在使用https://github.com/pluginaweek/state_machine用于状态机。这是我的预订模型的示例。classReservation["requested","negotiating","approved"])}state_machine:initial=>'requested

  3. ruby - Nokogiri 剥离所有属性 - 2

    我有这个html标记:我想得到这个:我如何使用Nokogiri做到这一点? 最佳答案 require'nokogiri'doc=Nokogiri::HTML('')您可以通过xpath删除所有属性:doc.xpath('//@*').remove或者,如果您需要做一些更复杂的事情,有时使用以下方法遍历所有元素会更容易:doc.traversedo|node|node.keys.eachdo|attribute|node.deleteattributeendend 关于ruby-Nokog

  4. ruby - 即使失败也继续进行多主机测试 - 2

    我已经构建了一些serverspec代码来在多个主机上运行一组测试。问题是当任何测试失败时,测试会在当前主机停止。即使测试失败,我也希望它继续在所有主机上运行。Rakefile:namespace:specdotask:all=>hosts.map{|h|'spec:'+h.split('.')[0]}hosts.eachdo|host|begindesc"Runserverspecto#{host}"RSpec::Core::RakeTask.new(host)do|t|ENV['TARGET_HOST']=hostt.pattern="spec/cfengine3/*_spec.r

  5. ruby - 获取模块中定义的所有常量的值 - 2

    我想获取模块中定义的所有常量的值:moduleLettersA='apple'.freezeB='boy'.freezeendconstants给了我常量的名字:Letters.constants(false)#=>[:A,:B]如何获取它们的值的数组,即["apple","boy"]? 最佳答案 为了做到这一点,请使用mapLetters.constants(false).map&Letters.method(:const_get)这将返回["a","b"]第二种方式:Letters.constants(false).map{|c

  6. 【鸿蒙应用开发系列】- 获取系统设备信息以及版本API兼容调用方式 - 2

    在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList​()Obt

  7. 【Java 面试合集】HashMap中为什么引入红黑树,而不是AVL树呢 - 2

    HashMap中为什么引入红黑树,而不是AVL树呢1.概述开始学习这个知识点之前我们需要知道,在JDK1.8以及之前,针对HashMap有什么不同。JDK1.7的时候,HashMap的底层实现是数组+链表JDK1.8的时候,HashMap的底层实现是数组+链表+红黑树我们要思考一个问题,为什么要从链表转为红黑树呢。首先先让我们了解下链表有什么不好???2.链表上述的截图其实就是链表的结构,我们来看下链表的增删改查的时间复杂度增:因为链表不是线性结构,所以每次添加的时候,只需要移动一个节点,所以可以理解为复杂度是N(1)删:算法时间复杂度跟增保持一致查:既然是非线性结构,所以查询某一个节点的时候

  8. ruby-on-rails - 创建 ruby​​ 数据库时惰性符号绑定(bind)失败 - 2

    我正在尝试在Rails上安装ruby​​,到目前为止一切都已安装,但是当我尝试使用rakedb:create创建数据库时,我收到一个奇怪的错误:dyld:lazysymbolbindingfailed:Symbolnotfound:_mysql_get_client_infoReferencedfrom:/Library/Ruby/Gems/1.8/gems/mysql2-0.3.11/lib/mysql2/mysql2.bundleExpectedin:flatnamespacedyld:Symbolnotfound:_mysql_get_client_infoReferencedf

  9. 安卓apk修改(Android反编译apk) - 2

    最近因为项目需要,需要将Android手机系统自带的某个系统软件反编译并更改里面某个资源,并重新打包,签名生成新的自定义的apk,下面我来介绍一下我的实现过程。APK修改,分为以下几步:反编译解包,修改,重打包,修改签名等步骤。安卓apk修改准备工作1.系统配置好JavaJDK环境变量2.需要root权限的手机(针对系统自带apk,其他软件免root)3.Auto-Sign签名工具4.apktool工具安卓apk修改开始反编译本文拿Android系统里面的Settings.apk做demo,具体如何将apk获取出来在此就不过多介绍了,直接进入主题:按键win+R输入cmd,打开命令窗口,并将路

  10. ruby - 正则表达式在哪个位置失败? - 2

    我需要一个非常简单的字符串验证器来显示第一个符号与所需格式不对应的位置。我想使用正则表达式,但在这种情况下,我必须找到与表达式相对应的字符串停止的位置,但我找不到可以做到这一点的方法。(这一定是一种相当简单的方法……也许没有?)例如,如果我有正则表达式:/^Q+E+R+$/带字符串:"QQQQEEE2ER"期望的结果应该是7 最佳答案 一个想法:你可以做的是标记你的模式并用可选的嵌套捕获组编写它:^(Q+(E+(R+($)?)?)?)?然后你只需要计算你获得的捕获组的数量就可以知道正则表达式引擎在模式中停止的位置,你可以确定匹配结束

随机推荐