Pergunta

In the setup part of my app, I want to take a picture then display it. I want to display a Progress Dialog while saving the image to disk. My ProgressDialog code works except on a Droid Mini running KitKat.

I have tried a number of approaches, including this blog https://www.workreloaded.com/2011/06/how-to-use-the-android-camera/. I liked the approach but the ProgressDialog did not appear for me.

I think the root of the problem is some timing issue using the UI thread. But I can't precisely diagnose it and definitely can't solve it. My questions: 1. Does camera.takePicture() run on the UI thread?
2. What would prevent a ProgressDialog from appearing? 3. Does someone have a working example (besides the above post) that I could use?

I'm posting code that works but is bad practice and code that doesn't work but would be more maintainable.

The following code with a test for KitKat works, but is bad practice.

public class PreviewTestNextButtonListener implements Button.OnClickListener {
private static final String TAG = "PreviewTestButtonListener";

PreviewTest previewTest;

Camera camera;

public PreviewTestNextButtonListener(PreviewTest context, Camera camera) {
    this.previewTest = context;
    this.camera = camera;

}

public void onClick(View v) {
    Log.v(TAG, "Taking picture");

    try {
        PhotoSaverPreviewTest photoSaver = new PhotoSaverPreviewTest(previewTest);

        if (Build.VERSION.SDK_INT != Build.VERSION_CODES.KITKAT) {
            // don't display the progress dialog in kit kat because my Droid Mini running KitKat has a problem with
            // this. But the Mini is so fast that the save is instantaneous
            previewTest.showProgressDialog();
        }

        // photoSaver will launch the StoredRotationTest
        camera.takePicture(null, null, photoSaver);

    } catch (Exception e) {
        Log.e(TAG, "failed to start Stored Rotation Test because " + e, e);
    }
}
}

In an alternative version, I tried simply calling the ProgressDialog from takePicture() but that doesn't work. I also tried an AsyncTask, but that did not present a ProgressDialog either.

public void onPictureTaken(final byte[] imageData, Camera camera) {

    Log.e(TAG, "starting onPictureTaken");

            // **** this does not present the ProgressDialog
    activity.showProgressDialog();

    if (imageData != null) {

        Log.e(TAG, "got image data");

        camera.startPreview();

        Display display = ((android.view.WindowManager) activity.getSystemService(Context.WINDOW_SERVICE))
                .getDefaultDisplay();

        int displayRotation = display.getRotation();

        try {

            // showProgressDialog();

            // save the image to disk in the background
            RotateAndWriteImageAsync imageWrite = new RotateAndWriteImageAsync(activity, displayRotation, imageData);

            imageWrite.mySpecialMove();

            Intent intent;

            // during set up, launch the stored image rotation test
            intent = new Intent(activity, StoredRotationTest.class);

            activity.startActivity(intent);


            PreviewTest.dismissProgressDialog();

        } catch (Exception e) {
            Log.e(TAG, "error saving image or start rotation test: " + e);
        }
    } else {
        Log.e(TAG, " ");
        Log.e(TAG, "NO IMAGE DATA passed in parameter from camera");
        Log.e(TAG, " ");
    }
}

And finally, the method that presents the ProgressDialog from the PreviewTest Activity.

/** Called by Next Button which is a bit of kludge.*/
public void showProgressDialog() {

    if (progress == null) {
        progress = new ProgressDialog(this);
        progress.setTitle("Saving picture");

    }
    progress.show();
}

/** Called by StoredRotationSetup which is a bit of a kludge.*/
public static void dismissProgressDialog() {
    if (progress != null && progress.isShowing()) {
        progress.dismiss();
    }
}
Foi útil?

Solução

Mark Murphy(aka Commonsware) gave me some guidance during his office hours. ProgressDialogs are bad form: https://ux.stackexchange.com/questions/12637/what-research-is-there-suggesting-modal-dialogs-are-disruptive. My ProgressBar only shows when the user is waiting, but it does not pop up.

ProgressBar solved my problem. Here is the .xml:

<ProgressBar
    android:id="@+id/next_progress_bar"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_above="@+id/rotate_orientation_button"
    style="@android:style/Widget.ProgressBar.Large"
    android:indeterminate="true"
    android:visibility="invisible" />

And the Java:

        // progress bar
    ProgressBar progressBar = (ProgressBar) findViewById(R.id.next_progress_bar);

    progressBar.setVisibility(View.VISIBLE);
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top