Question

I'm writing a password protection type thing where basically the app prompts you to create a gesture, stores it somewhere (this is where I'm having the problem) then later retrieves it and matches it against what you enter as your "password".

For the gesture creation, what I have is as follows:

public class GestureUnlock extends Activity {
private static final float LENGTH_THRESHOLD = 120.0f;
private Gesture mGesture;
private View mConfirmButton;
private final File mStoreFile = new File(Environment.getExternalStorageDirectory(), "gestures");

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.gesture_unlock);

    mConfirmButton = findViewById(R.id.confirmButton);

    GestureOverlayView overlay = (GestureOverlayView)findViewById(R.id.gestureOverlayView);
    overlay.addOnGestureListener(new GesturesProcessor());
}

protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    if (mGesture != null) {
        outState.putParcelable("gesture", mGesture);
    }
}
protected void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);

    mGesture = savedInstanceState.getParcelable("gesture");
    if (mGesture != null) {
        final GestureOverlayView overlay =
                (GestureOverlayView) findViewById(R.id.gestureOverlayView);
        overlay.post(new Runnable() {
            public void run() {
                overlay.setGesture(mGesture);
            }
        });
        mConfirmButton.setEnabled(true);
    }
}

public void confirm(View v) {
    if (mGesture != null) {

        GestureLibrary store = GestureLibraries.fromFile(mStoreFile);
        store.addGesture("Gesture Password", mGesture);
        store.save();

        setResult(RESULT_OK);

        Intent intent = new Intent(this, GestureConfirm.class);
        startActivity(intent);

    } else {
        setResult(RESULT_CANCELED);
    }
}

public void clear(View v) {
    GestureOverlayView overlay = (GestureOverlayView)findViewById(R.id.gestureOverlayView);
    overlay.cancelClearAnimation();
    overlay.clear(true);
}

private class GesturesProcessor implements GestureOverlayView.OnGestureListener {
    public void onGestureStarted(GestureOverlayView overlay, MotionEvent event) {
        mConfirmButton.setEnabled(false);
        mGesture = null;
    }
    public void onGesture(GestureOverlayView overlay, MotionEvent event) {
    }

    public void onGestureEnded(GestureOverlayView overlay, MotionEvent event) {
        mGesture = overlay.getGesture();
        if (mGesture.getLength() < LENGTH_THRESHOLD) {
            overlay.clear(false);
        }
        mConfirmButton.setEnabled(true);
    }
    public void onGestureCancelled(GestureOverlayView overlay, MotionEvent event) {
    }
}
}

This is the first code, the one responsible for creating the gesture in the first place. Things to note: the layout is a gesture overlay, two buttons, one resets the gesture, the other is associated with the confirm method.

public class GestureConfirm extends Activity implements OnGesturePerformedListener {

private final File mStoreFile = new File(Environment.getExternalStorageDirectory(), "gestures");
private GestureLibrary store = GestureLibraries.fromFile(mStoreFile);

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.gesture_confirm);

    GestureOverlayView gesturesView = (GestureOverlayView) findViewById(R.id.gestureOverlayViewConfirm);
    gesturesView.addOnGesturePerformedListener(this);
    store.load();

}

public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture) {
    ArrayList<Prediction> predictions = store.recognize(gesture);
    for (Prediction prediction : predictions) {
        if (prediction.score > 1.0) {
            Toast.makeText(this, prediction.name, Toast.LENGTH_SHORT).show();
        }
    }
}
}

Here is what I have for the code responsible for reading the gestures.

Était-ce utile?

La solution

Your code looks fine. I'm afraid save() takes some time and when you load it in the new Activity it not saved yet. You could solve using a singleton class:

import java.io.File;

import android.content.Context;
import android.gesture.GestureLibraries;
import android.gesture.GestureLibrary;

public class PasswordGesturesLibrary {

    private static GestureLibrary sStore;

    public static GestureLibrary getStore(Context c) {

        if (sStore == null) {
            File storeFile = new File(c.getFilesDir(), "gestures");
            sStore = GestureLibraries.fromFile(storeFile);
            sStore.load();
        }

        return sStore;
    }

}

And when you want to take a reference to that just call:

GestureLibrary store = PasswordGesturesLibrary.getStore(this);

Make sure you use it in both activities.

Also, take a looks at how sms templates with gestures works in CyanogenMod sms app.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top