W porządku, problem polega na tym, że użyłem mojego SurfaceView w układzie xml. Gdy zadzwonisz: setContentView (your_layout) -> plik XML jest zawyżony. Oznacza to, że SurfaceView jest również napompowany. To znowu oznacza, że wywoływana jest metoda SurfaceView onSurfaceCreated, która uruchamia otwieranie kamery, itp.
Cały proces trwa trochę dłużej, dlatego Twoja poprzednia czynność (np. Uruchomienie działania z SurfaceView) wydaje się nie odpowiadać ...
Moje rozwiązanie, polegające na utworzeniu CameraView w wątku BG, rozwiązuje problem braku reakcji. Ale nie udało się pokazać wyjścia kamery w SurfaceView.
Rozwiązaniem jest usunięcie SurfaceView z twojego xml. Spowoduje to natychmiastowe rozpoczęcie działania (ponieważ kamera SurfaceView & nie jest tworzona). Po załadowaniu nowego układu Aktywności można programowo dodać nowy ekran SurfaceView do ekranu. Oczywiście, wymaga to czasu, ale twój interfejs użytkownika szybko przełącza się na nową czynność i możesz pokazać program ładujący podczas ładowania SurfaceView i aparatu!
SO: usunąć SURFACEVIEW OD XML -> dodaj ją programowo: uruchamianie Aktywny:
public class Launch extends Activity implements OnClickListener
{
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button btn = (Button)findViewById(R.id.button1);
btn.setOnClickListener(this);
}
@Override
public void onClick(View v) {
Intent intent = new Intent(Launch.this, SurfaceTestActivity.class);
startActivity(intent);
}
}
Main.xml (tylko przycisk, aby rozpocząć nową działalność)
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout android:id="@+id/RelativeLayout1"
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#ff6600">
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button" />
</RelativeLayout>
Oto druga czynność (która zawiera SurfaceView)
public class SurfaceTestActivity extends Activity {
private Context mContext;
private CameraView cameraView;
private Handler mHandler = new Handler();
private final Runnable mLoadCamera = new Runnable()
{
public void run()
{
startCamera();
}
};
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContent();
mContext = getApplicationContext();
}
private void startCamera()
{
RelativeLayout rl = (RelativeLayout)findViewById(R.id.surface_camera);
SurfaceView surfaceView = new SurfaceView(mContext);
final SurfaceHolder mSurfaceHolder = surfaceView.getHolder();
try
{
cameraView = new CameraView();
mSurfaceHolder.addCallback(cameraView);
mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
} catch(Exception e)
{
Log.d("debug", "Another exception");
e.printStackTrace();
}
if(rl != null && surfaceView != null)
rl.addView(surfaceView);
}
private void setContent()
{
setContentView(R.layout.scan);
// Post the Runnable with a Slight delay -> than your layout will be
// shown. Without the delay -> your UI will feel inresponsive
mHandler.postDelayed(mLoadCamera, 100);
}
}
A tu jest t Drugi układ Activity on (bez A SURFACEVIEW)
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout android:id="@+id/RelativeLayout1"
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#ff6600">
<RelativeLayout
android:id="@+id/header"
android:layout_width="fill_parent" android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:text="Explanation Txt"></TextView>
</RelativeLayout>
<RelativeLayout
android:id="@+id/footer"
android:layout_width="fill_parent" android:layout_height="wrap_content"
android:layout_alignParentBottom="true">
<TextView
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:text="Explanation Txt"></TextView>
</RelativeLayout>
<RelativeLayout
android:id="@+id/surface_camera"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:layout_above="@+id/footer"
android:layout_below="@+id/header"
android:background="#ff0066">
</RelativeLayout>
</RelativeLayout>
Na koniec, aby zakończyć odpowiedź, oto kod dla CameraView().To naprawdę jest tylko prosta implementacja, aby otworzyć aparatem i wyświetlać zawartość:
public class CameraView implements SurfaceHolder.Callback{
// Variables
private Camera mCamera = null;
private boolean mPreviewRunning = false;
private boolean mProcessing = false;
private int mWidth = 0;
private int mHeight = 0;
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height)
{
if(mPreviewRunning)
{
mCamera.stopPreview();
}
// Store width and height
mWidth = width;
mHeight = height;
// Set camera parameters
Camera.Parameters p = mCamera.getParameters();
mCamera.setParameters(p);
if(android.os.Build.VERSION.SDK_INT >= 8)
{ // If API >= 8 -> rotate display...
mCamera.setDisplayOrientation(90);
}
try
{
mCamera.setPreviewDisplay(holder);
} catch(IOException e)
{
e.printStackTrace();
}
mCamera.startPreview();
mPreviewRunning = true;
}
@Override
public void surfaceCreated(final SurfaceHolder holder)
{
try {
mCamera = Camera.open();
mCamera.setPreviewDisplay(holder);
} catch (IOException e)
{
mCamera.release();
mCamera = null;
e.printStackTrace();
}
}
@Override
public void surfaceDestroyed(SurfaceHolder holder)
{
if(mCamera != null)
{
mCamera.setPreviewCallback(null);
mCamera.stopPreview();
mCamera.setPreviewCallback(null);
mPreviewRunning = false;
mCamera.release();
mCamera = null;
}
}
}
Przewodnik Android Developers również polecam zadzwonić Camera.open() w WorkerThread aby uniknąć blokowania UI wątek. –
Ten kod działa idealnie dobrze ... co, jeśli chcę dodać do niego mój układ? –
W xml utwórz relatywny obiekt z widokiem powierzchni. Ten surfaceView będzie twoim widokiem "kamery". Oprócz tego możesz dodać wszystkie swoje układy. – Entreco