2011-08-18 12 views
0

SurfaceViewをいくつかのコントロールのためにフレームレイアウトに挿入するために、FrameViewにSurfaceViewを配置しようとしています。しかし、私はそれが何であるかわからないInflateExceptionを得ました。カスタムを膨らませるためにしたい場合は以下の私のプレビュークラスのコードと私のmain.xmlFrameViewの問題(InflateException)のSurfaceView

class Preview extends ViewGroup implements SurfaceHolder.Callback { 
private final String TAG = "Preview"; 

SurfaceView mSurfaceView; 
SurfaceHolder mHolder; 
Size mPreviewSize; 
List<Size> mSupportedPreviewSizes; 
Camera mCamera; 

Preview(Context context) { 
    super(context); 
    mSurfaceView = new SurfaceView(context); 
    addView(mSurfaceView); 

    mHolder = mSurfaceView.getHolder(); 
    mHolder.addCallback(this); 
    mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 
} 

public void setCamera(Camera camera) { 
    mCamera = camera; 
    if(mCamera != null) { 
     mSupportedPreviewSizes = mCamera.getParameters().getSupportedPreviewSizes(); 
     requestLayout(); 
    } 
} 

@Override 
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
    final int width = resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec); 
    final int height = resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec); 
    setMeasuredDimension(width, height); 

    if(mSupportedPreviewSizes != null) { 
     mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, width, height); 
    } 
} 

protected void onLayout(boolean changed, int l, int t, int r, int b) { 
    if (changed && getChildCount() > 0) { 
     final View child = getChildAt(0); 

     final int width = r - l; 
     final int height = b - t; 

     int previewWidth = width; 
     int previewHeight = height; 
     if(mPreviewSize != null) { 
      previewWidth = mPreviewSize.width; 
      previewHeight = mPreviewSize.height; 
     } 

     if(width*previewHeight > height * previewWidth) { 
      final int scaledChildWidth = previewWidth * height/previewHeight; 
      child.layout(((width) - scaledChildWidth) /2, 0, ((width) + scaledChildWidth) /2, height); 
     } 
     else { 
      final int scaledChildHeight = previewHeight * width/previewWidth; 
      child.layout(0, ((height)-scaledChildHeight)/2, width, ((height) + scaledChildHeight) /2); 
     } 

    } 

} 

public void surfaceCreated(SurfaceHolder holder) { 
    try { 
     if(mCamera != null) { 
      mCamera.setPreviewDisplay(holder); 
     } 
    } 
    catch (IOException exception) { 

    } 
} 

Camera.PreviewCallback mPreviewCallback = new Camera.PreviewCallback() { 


       public void onPreviewFrame(byte[] data, Camera camera) { 
        int ARRAY_LENGTH = mPreviewSize.width*mPreviewSize.height*3/2; 
        int argb8888[] = new int[ARRAY_LENGTH]; 

        decodeYUV(argb8888, data, mPreviewSize.width, mPreviewSize.height); 
        Bitmap bitmap = Bitmap.createBitmap(argb8888, mPreviewSize.width, mPreviewSize.height, Config.ARGB_8888); 

        FileOutputStream fos; 
        try { 
         fos = new FileOutputStream(String.format("/sdcard/testImage/%d.jpg", System.currentTimeMillis())); 


        BufferedOutputStream bos = new BufferedOutputStream(fos); 
        bitmap.compress(CompressFormat.JPEG, 75, bos); 
      try { 
       bos.flush(); 
      } catch (IOException ex) { 
       Logger.getLogger(Preview.class.getName()).log(Level.SEVERE, null, ex); 
      } 
        bos.close(); 
        fos.close(); 
        } catch (FileNotFoundException ex) { 
         Logger.getLogger(Preview.class.getName()).log(Level.SEVERE, null, ex); 
        } 
        catch (IOException ex) { 
          Logger.getLogger(Preview.class.getName()).log(Level.SEVERE, null, ex); 
         } 

       } 
      }; 

// decode Y, U, and V values on the YUV 420 buffer described as YCbCr_422_SP by Android 
// David Manpearl 081201 
public void decodeYUV(int[] out, byte[] fg, int width, int height) 
    throws NullPointerException, IllegalArgumentException { 
int sz = width * height; 
if (out == null) 
    throw new NullPointerException("buffer out is null"); 
if (out.length < sz) 
    throw new IllegalArgumentException("buffer out size " + out.length 
      + " < minimum " + sz); 
if (fg == null) 
    throw new NullPointerException("buffer 'fg' is null"); 
if (fg.length < sz) 
    throw new IllegalArgumentException("buffer fg size " + fg.length 
      + " < minimum " + sz * 3/2); 
int i, j; 
int Y, Cr = 0, Cb = 0; 
for (j = 0; j < height; j++) { 
    int pixPtr = j * width; 
    final int jDiv2 = j >> 1; 
    for (i = 0; i < width; i++) { 
     Y = fg[pixPtr]; 
     if (Y < 0) 
      Y += 255; 
     if ((i & 0x1) != 1) { 
      final int cOff = sz + jDiv2 * width + (i >> 1) * 2; 
      Cb = fg[cOff]; 
      if (Cb < 0) 
       Cb += 127; 
      else 
       Cb -= 128; 
      Cr = fg[cOff + 1]; 
      if (Cr < 0) 
       Cr += 127; 
      else 
       Cr -= 128; 
     } 
     int R = Y + Cr + (Cr >> 2) + (Cr >> 3) + (Cr >> 5); 
     if (R < 0) 
      R = 0; 
     else if (R > 255) 
      R = 255; 
     int G = Y - (Cb >> 2) + (Cb >> 4) + (Cb >> 5) - (Cr >> 1) 
       + (Cr >> 3) + (Cr >> 4) + (Cr >> 5); 
     if (G < 0) 
      G = 0; 
     else if (G > 255) 
      G = 255; 
     int B = Y + Cb + (Cb >> 1) + (Cb >> 2) + (Cb >> 6); 
     if (B < 0) 
      B = 0; 
     else if (B > 255) 
      B = 255; 
     out[pixPtr++] = 0xff000000 + (B << 16) + (G << 8) + R; 
    } 
} 

} 


public void surfaceDestroyed(SurfaceHolder holder) { 
    if(mCamera != null) { 
     mCamera.stopPreview(); 
    } 
} 

private Size getOptimalPreviewSize(List<Size> sizes, int w, int h) { 
    final double ASPECT_TOLERANCE = 0.1; 
    double targetRatio = (double)w/h; 
    if(sizes==null) { 
     return null; 
    } 
    Size optimalSize = null; 
    double minDiff = Double.MAX_VALUE; 

    int targetHeight = h; 

    for(Size size : sizes) { 
     double ratio = (double) size.width/size.height; 
     if(Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue; 
     if(Math.abs(size.height - targetHeight) < minDiff) { 
      optimalSize = size; 
      minDiff = Math.abs(size.height - targetHeight); 
     } 
    } 

    if(optimalSize == null) { 
     minDiff = Double.MAX_VALUE; 
     for (Size size : sizes) { 
      if(Math.abs(size.height - targetHeight) < minDiff) { 
       optimalSize = size; 
       minDiff = Math.abs(size.height - targetHeight); 
      } 

     } 
    } 
    return optimalSize; 
} 

public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { 
    Camera.Parameters parameters = mCamera.getParameters(); 
    parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height); 
    requestLayout(); 
    //mCamera.setPreviewCallback(mPreviewCallback); 
    mCamera.setParameters(parameters); 
    mCamera.startPreview(); 
} 
} 

私のmain.xml

<?xml version="1.0" encoding="utf-8"?> 

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:layout_width="fill_parent" android:layout_height="fill_parent" 
android:orientation="vertical"> 


    <Button 
    android:id="@+id/showhide" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="Toggle The Another Button Show/Hide" /> 
    <Button 
    android:id="@+id/dummy" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="a Button" /> 
    <FrameLayout 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent"> 
    <camera.test.Preview 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent"/> 
    </FrameLayout> 

Logcat

     08-18 14:01:37.896: ERROR/AndroidRuntime(401): FATAL EXCEPTION: main 
    08-18 14:01:37.896: ERROR/AndroidRuntime(401): java.lang.RuntimeException: Unable to start activity ComponentInfo{camera.test/camera.test.MainActivity}: android.view.InflateException: Binary XML file line #21: Error inflating class camera.test.Preview 
    08-18 14:01:37.896: ERROR/AndroidRuntime(401):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1647) 
    08-18 14:01:37.896: ERROR/AndroidRuntime(401):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663) 
    08-18 14:01:37.896: ERROR/AndroidRuntime(401):  at android.app.ActivityThread.access$1500(ActivityThread.java:117) 
    08-18 14:01:37.896: ERROR/AndroidRuntime(401):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:931) 
    08-18 14:01:37.896: ERROR/AndroidRuntime(401):  at android.os.Handler.dispatchMessage(Handler.java:99) 
    08-18 14:01:37.896: ERROR/AndroidRuntime(401):  at android.os.Looper.loop(Looper.java:123) 
    08-18 14:01:37.896: ERROR/AndroidRuntime(401):  at android.app.ActivityThread.main(ActivityThread.java:3683) 
    08-18 14:01:37.896: ERROR/AndroidRuntime(401):  at java.lang.reflect.Method.invokeNative(Native Method) 
    08-18 14:01:37.896: ERROR/AndroidRuntime(401):  at java.lang.reflect.Method.invoke(Method.java:507) 
    08-18 14:01:37.896: ERROR/AndroidRuntime(401):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839) 
    08-18 14:01:37.896: ERROR/AndroidRuntime(401):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597) 
    08-18 14:01:37.896: ERROR/AndroidRuntime(401):  at dalvik.system.NativeStart.main(Native Method) 
    08-18 14:01:37.896: ERROR/AndroidRuntime(401): Caused by: android.view.InflateException: Binary XML file line #21: Error inflating class camera.test.Preview 
    08-18 14:01:37.896: ERROR/AndroidRuntime(401):  at android.view.LayoutInflater.createView(LayoutInflater.java:508) 
    08-18 14:01:37.896: ERROR/AndroidRuntime(401):  at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:570) 
    08-18 14:01:37.896: ERROR/AndroidRuntime(401):  at android.view.LayoutInflater.rInflate(LayoutInflater.java:623) 
    08-18 14:01:37.896: ERROR/AndroidRuntime(401):  at android.view.LayoutInflater.rInflate(LayoutInflater.java:626) 
    08-18 14:01:37.896: ERROR/AndroidRuntime(401):  at android.view.LayoutInflater.inflate(LayoutInflater.java:408) 
    08-18 14:01:37.896: ERROR/AndroidRuntime(401):  at android.view.LayoutInflater.inflate(LayoutInflater.java:320) 
    08-18 14:01:37.896: ERROR/AndroidRuntime(401):  at android.view.LayoutInflater.inflate(LayoutInflater.java:276) 
    08-18 14:01:37.896: ERROR/AndroidRuntime(401):  at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:207) 
    08-18 14:01:37.896: ERROR/AndroidRuntime(401):  at android.app.Activity.setContentView(Activity.java:1657) 
    08-18 14:01:37.896: ERROR/AndroidRuntime(401):  at camera.test.MainActivity.onCreate(MainActivity.java:45) 
    08-18 14:01:37.896: ERROR/AndroidRuntime(401):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047) 
    08-18 14:01:37.896: ERROR/AndroidRuntime(401):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1611) 
    08-18 14:01:37.896: ERROR/AndroidRuntime(401):  ... 11 more 
    08-18 14:01:37.896: ERROR/AndroidRuntime(401): Caused by: java.lang.NoSuchMethodException: Preview(Context,AttributeSet) 
    08-18 14:01:37.896: ERROR/AndroidRuntime(401):  at java.lang.Class.getMatchingConstructor(Class.java:643) 
    08-18 14:01:37.896: ERROR/AndroidRuntime(401):  at java.lang.Class.getConstructor(Class.java:472) 
    08-18 14:01:37.896: ERROR/AndroidRuntime(401):  at android.view.LayoutInflater.createView(LayoutInflater.java:480) 
    08-18 14:01:37.896: ERROR/AndroidRuntime(401):  ... 22 more 
+0

例外メッセージとスタックトレースを提供した方が良いでしょう。 – Xion

答えて

2

ですXMLからウィジェットを作成するには、2つの引数を持つコンストラクタを実装する必要があります。あなたのケースでは、それは次のようになります。

public Preview(Context context, AttributeSet attrs) { 
    super(context, attrs); 
    // implementation ... 
} 

EDIT:そして、少し外のコンテキストヒント。このようにカメラのプレビューを実装しないでください。これは間違った方法であり、あなたは奇妙なバグをたくさん取るでしょう。私はこれを正確に知っているのは、私が同じアプローチを使って初めてプレビューを実装したからです。 Cameraアプリケーションのソースをご覧ください。これはより良い実装方法です。

+0

それは動作していない、私はプレビュー(コンテキストコンテキスト、AttributeSetのattrs)を実装していたあなたが言ったように。しかし、同じ問題がまだ発生しました。 – chenhou90

+0

あなたが提供したlogcatの出力には、java.lang.NoSuchMethodException:Preview(Context、AttributeSet)というメッセージがあるので、問題は同じにはなりません。そのような方法が必要です。 – Michael

+0

あなたのクラスを 'public'にしてください。 – Michael

関連する問題