문제

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.

도움이 되었습니까?

해결책

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.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top