Hi,
We are now testing activation logic for our subscription based app. I adapted your Java example to our case, where we also check expires custom field of the key. We should perform this check not only when the app launches, but also after user enters the key in activation prompt dialog.
Sometimes (80%) it doesn't activate after you click Activate button saying either key is expired (when it is not), or that system date is not valid on you computer (that is ugly user experience). But after you restart the app it works (date check passes).
Please take a look on source code
Adapted DocumentEditorView constructor...
try{
TurboActivate.SetTurboActivateFolder( "c:/LimeLM-Test/TurboActivate/" ); TurboActivate.SetPDetsLocation(); IsGenuineResult gr = TurboActivate.IsGenuine( 3, 7, true, false ); isActivated = gr == IsGenuineResult.Genuine || gr == IsGenuineResult.GenuineFeaturesChanged || gr == IsGenuineResult.InternetError; if( gr == IsGenuineResult.InternetError ){ } } catch( Exception e ){ JOptionPane.showMessageDialog( null, "Failed to check if activated: " + e.getMessage() ); System.exit( 1 ); }
ShowTrial( !isActivated );
// if this app is activated then you can get a feature value // See: http://wyday.com/limelm/help/license-features/ if(isActivated){
try{
if( !PKey.isKeyDateVaid() ){
JOptionPane.showMessageDialog( null, "This product key is expired." ); //throw new Exception( "This product key is expired." ); //ShowTrial( true ); /*isActivated = false; activateDeactivateMenuClick();*/
}
} catch( Exception ex ){ JOptionPane.showMessageDialog( null, "Failed to check if expired: " + ex.getMessage() ); System.exit( 1 ); }
} else{ //activateDeactivateMenuClick(); }
PKey
private void okButtonActionPerformed(java.awt.event.ActionEvent evt) { try { boolean existingKey = TurboActivate.IsProductKeyValid(); if ((existingKey && !TurboActivate.GetPKey().equals(txtPKey.getText())) || !existingKey) { // save the new key if (!TurboActivate.CheckAndSavePKey(txtPKey.getText())) throw new Exception("The product key is not valid."); }
// try to activate and close the form final String extraData = getSystemExtraData(); TurboActivate.Activate( extraData );
IsGenuineResult gr = TurboActivate.IsGenuine( 0, 1, true, false ); if( gr == IsGenuineResult.Genuine || gr == IsGenuineResult.GenuineFeaturesChanged ){ if( !isKeyDateVaid() ){ throw new Exception( "This product key is expired." ); } } else if( gr == IsGenuineResult.InternetError ){ //TODO: give the user the option to retry the genuine checking immediately //For example a dialog box. In the dialog call IsGenuine() to retry immediately // or throw exception here } else{ // ??? or throw exception here }
doClose(RET_OK); } catch (Exception ex) { JOptionPane.showMessageDialog(null, ex.getMessage()); } }
public static boolean isKeyDateVaid() throws TurboActivateException, UnsupportedEncodingException{
final String expires_date = TurboActivate.GetFeatureValue( "expires" ); return TurboActivate.IsDateValid( expires_date, TurboActivate.TA_HAS_NOT_EXPIRED );
}
So after you click Deactivate menu item in the Java example, and then try to activate again with the new key, or you use another key with valid expiration date it usually says "The product key is not valid.".
We now thinking about 3 options:1) Do not check for expiration date after Activate button click. But in this case user can continue to use the app with the same key and will be just prompted once in 3 days.2) Use timer to check expiration date after 2-5 minutes, because maybe LimeLM servers can't handle the check.3) Restart the app after Activate button click (if the key is valid) to pass the date check.
P.S. Also the java example doesn't honor Java Swing threading and performs network calls via EDT (UI) thread. This should be separated into SwingWorker and EDT threads.