D'accord, le problème est que j'ai utilisé mon SurfaceView dans la mise en page xml. Le moment de l'appel: setContentView (your_layout) -> le fichier XML est gonflé. Cela signifie que le SurfaceView est également gonflé. Cela signifie que les méthodes SurfaceView onSurfaceCreated sont appelées, ce qui déclenche l'ouverture de la caméra, etc.
Donc, tout ce processus prend du temps, donc votre activité précédente (par exemple celle qui lance l'activité avec SurfaceView) semble pour ne pas répondre ...
Ma solution, de créer le CameraView dans un thread BG résout l'inresponsiveness. Mais n'a pas réussi à afficher la sortie Camera dans SurfaceView.
La solution est d'enlever votre SurfaceView de votre xml. Cela va commencer votre activité immédiatement (puisque les caméras SurfaceView & ne sont pas instanciées). Une fois votre nouvelle mise en page Activités chargée, vous pouvez ajouter un nouveau SurfaceView à votre écran par programmation. Bien sûr, cela prend du temps, mais votre interface utilisateur passe rapidement à la nouvelle activité, et vous pouvez afficher un chargeur pendant le chargement de SurfaceView et Camera!
SO: RETIRER LE SURFACEVIEW DE LA XML -> ADDITIONNEZ Programatically: Activité de lancement:
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 (juste un bouton pour lancer la nouvelle activité)
<?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>
Voilà la deuxième activité (qui contient le 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);
}
}
Et voici t il seconde mise en page de l'activité (SANS 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>
Enfin, pour compléter la réponse, voici le code pour le CameraView().Il est vraiment juste une implémentation simple pour obtenir ouvrir l'appareil photo et afficher le contenu:
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;
}
}
}
Le guide Développeurs Android recommande également appeler Camera.open() dans WorkerThread pour éviter de bloquer l'interface utilisateur fil. –
Ce code fonctionne parfaitement bien ... et si je veux ajouter ma mise en page? –
En XML, créez un relativelayout avec une vue de surface. Cette surfaceView sera votre vue "caméra". En plus, vous pouvez ajouter toutes vos mises en page. – Entreco