Poor-man's promo check for Android apps.

When I first created Baby’s First Game for Android I gave away a free promotional version. This promotional version was basically to get feedback from people before the real release. I wanted the app to only work for a limited time after which it would disable itself. I suppose I could have just released the full version without any limitations but I didn’t know how well (or poorly as it turns out) my app would do or how a free version floating around would affect it. Plus I wanted to see how one might create a time limited app anyway.


I created a single method called doPromoCheck() that stores the current install date in the app settings and checks them on every start up. I also added a check to alert the user once a day that the application was a promotional version and would expire in x number of days. This message I wanted shown only once a day as to not annoy the users. Here’s the method with some static class variables for configuration:

...
private static final String PROMO_DATE = "promoDate";
private static final String PROMO_DISPLAYED = "promoDisplayed";
private static final long DAYS_MILLIS = 24 * 60 * 60 * 1000;
private static final long PROMO_DURATION = DAYS_MILLIS * 30; // 30 days

private void doPromoCheck() {
  SharedPreferences prefs = getPreferences(Context.MODE_PRIVATE);
  SharedPreferences.Editor editor = prefs.edit();
  long now = System.currentTimeMillis();
  long exp = prefs.getLong(PROMO_DATE, now + PROMO_DURATION);
  editor.putLong(PROMO_DATE, exp);

  // check if the promo period has ended
  if(now > exp) {
    AlertDialog alertDialog;
    String ok = getResources().getString(R.string.label_ok);
    alertDialog = new AlertDialog.Builder(this)
        .setCancelable(false)
        .setPositiveButton(ok, new DialogInterface.OnClickListener() {
          public void onClick(DialogInterface dialog, int id) {
            finish(); // stops the app as soon as the dialog is dismissed.
          }
        }).create();
    String title = "Promo Version";
    alertDialog.setTitle(title);
    String msg = "This promotional version has expired. Please purchase the official version from Google Play.";
    alertDialog.setMessage(msg);
    alertDialog.show();
  } else {
    long disp = prefs.getLong(PROMO_DISPLAYED, now);

    // only display the dialog if it's been one day since the last time it was displayed
    if(now >= disp) {
      // save the next display time for one day from now.
      editor.putLong(PROMO_DISPLAYED, now + DAYS_MILLIS);
      AlertDialog alertDialog;
      String ok = getResources().getString(R.string.label_ok);
      alertDialog = new AlertDialog.Builder(this)
          .setCancelable(false)
          .setPositiveButton(ok, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int id) {
              // do nothing
            }
      }).create();

      String title = "Promo Version";
      alertDialog.setTitle(title);
      long days = (exp - now) / DAYS_MILLIS;
      String msg = "This promotional version will expire in " + days + " days. Please consider purchasing the official version from Google Play.";
      alertDialog.setMessage(msg);
      alertDialog.show();
    }
  }

  editor.commit();
}


The first time this is run it calculates the expiration date and stores it in the private app settings. Each time it is run after, it pulls the expiration out of the app settings. To use this method in your app, put the call as the first thing in your main Activity onCreate() method:

   protected void onCreate(Bundle savedInstanceState) {
      doPromoCheck();
      ...
   }


That’s it. Your application will now only last for 30 days and will simply show the promotional period ended dialog after. Of course, the app can be uninstalled and reinstalled to reset the expiration but it’s annoying and probably not worth the hassle to most people.

Replace Non-Alphanumeric Characters in a C++ String

I needed to replace the non-alphanumeric characters in a std::string. While the Java String class has the replace() and replaceAll() methods for doing this, the std::string class has no such utility methods. Instead you can use the std::replace_if function from the Standard Template Library. Here’s some example code:

#include <iostream>
#include <string>
#include <algorithm>

int isNotAlphaNum(char c)
{
        return !std::isalnum(c);
}

int main(int argc, char* argv[])
{
        std::string s1 = "some/string/with*/nonalpha/characters+1";
        std::cout << s1 << " : ";
        std::replace_if(s1.begin(), s1.end(), isNotAlphaNum, ' ');
        std::cout << s1 << std::endl;
        return 0;
}

The third parameter of the replace_if() function is a pointer to a function that performs the desired check and returns either true or false if the input satisfies the condition. The last parameter is the character to replace the matched character, in this case a space. This program produces the following:

$ ./replace.exe
some/string/with*/nonalpha/characters+1
some string with  nonalpha characters 1

Convert C++ String to Lower Case (or Upper Case)

I don’t usually need to convert string case in C++ so when the need comes up I’ve usually forgotten how to do it and have to Google.

While the Java String class has toLowerCase() and toUpperCase(), C++ std::string does not have such a utility method. Instead, you need to use the std::transform() function. Here’s some example code:

#include <iostream>
#include <string>
#include <utility>

int main(int argc, char* argv[])
{
        std::string s1 = "lowertoupper";
        std::string s2 = "UPPERTOLOWER";
        std::cout << s1 << " : ";
        std::transform(s1.begin(), s1.end(), s1.begin(), ::toupper);
        std::cout << s1 << std::endl;
        std::cout << s2 << " : ";
        std::transform(s2.begin(), s2.end(), s2.begin(), ::tolower);
        std::cout << s2 << std::endl;
        return 0;
}

Produces the following:

$ ./case.exe
lowertoupper : LOWERTOUPPER
UPPERTOLOWER : uppertolower

Note that while the Java toUpperCase() and toLowerCase() methods do not modify the original string, the std::transform function does.

Securing WordPress

In light of the latest attacks on WordPress sites everywhere I thought I should probably step up security a bit here. Not that I thought I had a bad password or anything but I still had the default admin account enabled. This attack is being conducted by a huge botnet of about 90,000 computers trying a large dictionary of passwords against the admin account. I wasn’t too concerned but the fact that it was targeting the admin account and seeing a huge spike in access to wp-login.php I still had an uneasy feeling in my gut.

First, the admin account is now disabled. They can target it all they want! Second, no one should need to access wp-login.php from anywhere in the world. So I updated .htaccess to only allow access from my IP address.

<Files "wp-login.php">
  Order Deny,Allow
  Deny from all
  Allow from xxx.xxx.xxx.xxx/32
  ErrorDocument 403 "https://www.google.com"
</Files>

Third, installed the Limit Login Attempts plugin for WordPress which will automatically block an IP after so many failed login attempts.

Disabling UAC Prompt for Cygwin run.exe in Windows 7

So, every time I try to start Cygwin (actually, the cygwin XWin server) I get that ugly UAC prompt. Very annoying since this is an application I use quite frequently. Unfortunately, changing the properties to always “Run As Administrator” does not fix it.

The only way I’ve successfully managed to get it to work is through the Application Compatibility Toolkit from the Microsoft Download center. Download and install the Application Compatibility Toolkit. Once installed, run ACT as administrator. Right click on its menu entry while holding the Shift key and select Run as Administrator. Note that you have to run the correct version for the architecture of the target program. For instance, Cygwin is 32-bit so the 32-bit version of ACT must be used.

Application Compatibility Toolkit

This will open up a new custom database that we will edit. From here click the Fix icon in the toolbar.

Application Compatibility Toolkit

In the Create new Application Fix dialog, give it a name, the vendor is optional, and select the path to the executable. The executable we want is run.exe on my machine at C:\cygwin\bin\run.exe.

Create new Application Fix

Click next, and next again. From the Compatibility Fixes list, select “RunAsInvoker” and click Finish.

Create new Application Fix

Next save the database by clicking the save icon. You will be prompted to provide a name.

Database Name

Once it is saved we have to install it. Right click on the database in the tree and select Install.

Application Compatibility Toolkit

Installed dialog

Now you should be able to click the Cygwin XWin Server icon and it will start without prompting you. One additional issue I had was that before any of this I had created a Quick Launch icon for the XWin Server. For some reason, these changes do not take affect right away for the Quick Launch icon only. I had to delete and recreate the Quick Launch icon before I could start it that way without being prompted.

Managing MinGW packages with mingw-get

This isn’t meant to be a comprehensive tutorial on everything you can do with mingw-get but rather a place for me to document some tips that I found Googling and felt I should consolidate here. If something here does not work for you or if you have some other useful pointers let me know and I’ll update this post.

MinGW is standard equipment on any new Windows computer I need to use which includes most of the tools I use regularly. I had a need to create zip files recently however zip and unzip are not included in the base MinGW installation. The easiest way to install these utilities is through mingw-get.

$ mingw-get install msys-zip
$ mingw-get install msys-unzip

This lead me to the question, what additional packages are actually available this way? Cygwin provides a nice GUI to pick and choose packages and of course there are the various package managers available for the many Linux distros. There doesn’t seem to be an easy way to list packages that can be installed with mingw-get. One method I found is to look in the catalog file.

$ grep "package name" /mingw/var/lib/mingw-get/data/*.xml

Or to make the output a little nicer:

$ grep "package name=" /mingw/var/lib/mingw-get/data/*.xml |
    sed 's/.*package name="\([^"]*\)".*/\1/'

These commands will show you all the packages available whether they are already installed or not. To list packages that are already installed there is a nifty little script that can be found here. Download mingw-get-info and copy it to /mingw/bin.

$ mingw-get-info installed

This script is not an official MinGW tool and seems to only exist as an attachment to the linked bug report. From the comments on that page the script will generate a number of reports:

$ mingw-get-info all

to see current status for all available packages,

$ mingw-get-info installed

to filter on only those packages which are installed locally, or

$ mingw-get-info index

to see an index for the repository catalogue.

OpenGL Globe Screensaver (Update)

I’ve been running this OpenGL Globe screensaver I wrote for several years now on various machines without any issues. Until the other night when I installed it on my new laptop. So I did a little digging and figured out what was going on. After I installed the screensaver and tried to activate it I got the following error:

LoadLibrary failed with error 1114: A dynamic link library (DLL) initialization routine failed.

Googling for information brought me to this site. Further down in the discussion they start talking about switchable graphics with the AMD drivers (which I have) and the Catalyst control center. It seems that by default screensavers are run in “Power Saving” mode with hardware acceleration disabled. Well, since this is an OpenGL screensaver that just will not do! I open up the Catalyst control center and it’s not listed in the recent applications. I guess since it hadn’t run yet it wouldn’t show up. Of course, the Browse… button on the Other Applications box below won’t allow you to select a .scr file. So I try right clicking the .scr file to try to test it that way:

Explorer context menu | Test

Hey, it starts! So I jump back into the Control Center and there it is!

Catalyst Control Center

I set it to “High Performance” and go back to the screensaver control panel and it starts right up! Interesting. I’m not sure if or how I could update the installer to detect and adjust these settings automatically. I’ve been running this screensaver (or previous builds of it) on various computers for several years now and this is the first time I’ve encountered an issue with it. I’m not sure if I can even consider it an issue with the screensaver or not though I’d argue either the screensaver or the installer need to be updated since I can’t really expect end users to have to jump through hoops to get my software to work. I’m probably not going to do it any time soon however. If you have an idea for fixing this problem in an automated fashion I’d be interested in hearing it. If you’d like to play around with the installer code let me know and I’ll give it to you. In the mean time, if you see this issue, let me know if this fixes it.

Update 3/12/2013

So, I’ve been playing around with the drivers and mucked things up enough that I had to revert. However, when I installed the original version and encountered the same problem with the screensaver described above, the above fix did not work this time! Grrr… To get around it I had to go in and manually add it in the registry. One of the existing screensavers that actually ran without issues was listed in the Switchable Graphics dialog as shown above. I picked ribbons.scr. I opened regedit32.exe and searched for “ribbons.scr”.

Registry Editor

I edited this string value and changed the path to specify “ssglobe.scr” instead of “ribbons.scr”. When I reopened the Switchable Graphics dialog it was listed though it was marked as “Not Assigned”. I’m sure there are other registry settings that can be updated to add it and give it the proper settings all in one shot. However, getting it to show up in the dialog is sufficient for now as the settings can then be changed from there. I set it back to “High Performance” and all is again working.

Disable the Fn + Function Key combo to the use the function keys on HP laptops

Some genius at HP decided the function keys F1 through F12 aren’t important enough and demoted them to second level functions. To access them you now need to pres the Fn + Function key combination to get the normal behavior.

The default behavior for those keys now is what you would normally have had to hold the Fn key to access. Like turning your wireless card on and off, adjusting the display brightness, etc… F5 it looks like enables/disables the backlight on my keyboard. Um no. Setting the display brightness does NOT need to be a top level function, idiot! I’ll set it once and never touch it again.

In the mean time, F3 is used all the time for opening Find/Replace dialogs. I use F5 all the time to refresh web pages, folders, my IDE, etc. I can handle holding the Fn key to toggle my wireless on and off or changing display outputs. In the mean time I want my function keys back.

The fix isn’t a simple control panel setting either. You actually have to go into the computer BIOS to change it. When the computer boots you have to hit F10 to enter the BIOS settings. (Remember to hold the Fn key or you might just be trying to eject your CD-ROM).

Once at the BIOS menu navigate to the “System Configuration” settings. Select “Action Keys Mode” and turn that crap off. Reboot and your sanity and balance in the universe will have been restored.

Java – Failed to download required installation files

Oracle, you’ve outdone yourself! Still not getting this consumer level software thing are you? I got a call at work that my daughter’s laptop was acting funny. Turns out she got hit by a virus. I have her user account set up to run with limited permissions so there wasn’t any real damage and was fairly easy to clean up.

I spent some time trying to figure out how she got infected in the first place since she doesn’t usually venture too far from her game sites, doesn’t have email or facebook, and is pretty closely monitored by us. Her internet history didn’t show anything I didn’t expect, the typical game sites, Google searches for Justin Bieber, etc…

Nothing was out of the ordinary however, some of her game sites make heavy use of Java. Maybe a rogue ad took advantage of the recent Java exploit or something. No, she has Java 6 installed so it wasn’t that particular exploit. I’m not entirely sure it was a Java vulnerability, just covering bases here. Maybe something else?

I figure I’d make sure it was updated anyway and started the Java control panel. Went to the Update tab and clicked Update Now. A new version was available so I clicked Install. The prompt for my administrator password came up (of course, she’s running a limited user account). I enter it and the following error pops up:

Failed to download required installation files.

Hmmm… ok. Not sure why. I check the network settings and tell it to use a direct connection instead of my default browser settings. Same issue. Maybe it’s a permission issue. So I navigate in Explorer to the Java directory, find the javacpl.exe file, right-click and select Run as administrator... Enter my password and try again. Same issue.

I switch user and log into my administrator account. Open the Java control panel and try again. Voila! It works! Looking around the internet, this bug has been around for quite a while and still isn’t fixed. It seems the Java updater won’t work at all unless you are logged into the administrator account. Being a general user and running it as administrator is NOT sufficient. Grrrr…

Creating New Folder in Windows Explorer

Here’s one I forget every so often. What hot key combination will let you create a new folder in Windows Explorer?

In all versions of Windows, with a folder opened in Windows Explorer use Alt + F, W, F. This basically walks you through keyboard navigation of the Explorer menu. Windows 7 has added a hot key combination specifically for this task. Ctrl + Shift + N Thanks to How-To Geek for the tip!