If you are building iOS applications and using SVN you may have had issues getting your @2x resources for Retina Display Support added to svn. I used the command line on Mac OSX and I figured I could just use the standard backspace escape.. no dice. This turns out to be caused by internal path recognizers in svn. It expects the last at symbol to specify a revision. You can get around this by adding the symbol at the end of your file name. So if you are trying to add Default@2x.png you would do it like this

$ svn add Default@2x.png@

If you have a number of files to add you can save your self some time by taking advantage of the unix tools available. The following command would add all the images in the directory

$ svn status | grep '^?' | grep @2x | sed -e 's/.png/.png@/' | awk '{print $2}' | xargs svn add

You can than commit them all by using this

$ svn status | grep -v '^?' | grep @2x | sed -e 's/.png/.png@/' | awk '{print $2}' | xargs svn commit -m "add images"

Hope this helps..

Post to Twitter Tweet This Post

Android 2.2 on HTC Hero via Cyanogenmod 6

Posted November 6th, 2010. Filed under Applications

I recently got tired of constantly running out of space on my HTC Hero. So rather than deal with the continued frustration, I finally flashed my Hero with the new Android 2.2 ROM from Cyanogenmod. I have to say I could not be happier! Everything worked after the ROM flash, that is right, no problems! Currently, my Hero is overclocked to 768 MHZ and the performance boost is definitely noticeable. The ability to move the applications to the SD card has solved my constant issue with space on the Hero and Android 2.2-only apps like Chrome to Phone, Google Goggles, and others are now available. The Cyanogenmod ROM comes rooted and I verified wireless tether worked perfectly as well as ROM manager and setCPU.  With this ROM you can utilize the setCPU application and overclock the CPU; which is how I set the Hero’s Cpu to 768 MHZ vs the stock 528 MHZ.  As I mentioned above, this is a considerable speed boost and if you are willing to take the risk, flashing your ROM for this reason alone is worth it. Below, I will briefly outline the steps I took to make my HTC Hero virtually a new phone.

DISCLAIMER:  Follow the guide below at YOUR OWN RISK.  TwistByte, LLC its affiliates, assigns, advertisers, hosts, or other entity related to TwistByte, LLC will not be held responsible for any damage to personal or other property as a result of following this guide. Further THIS PROCESS WILL ERASE ALL YOUR DATA. You will need to backup your application data, emails, sms, etc.. that you want to keep. This process could BRICK THE PHONE which may leave it in an unusable state.  Finally, flashing your ROM may VOID your manufacturer warranty.

As you are aware from the disclaimer above, this process could brick your phone and result in data loss if you haven’t backed everything up.  Now, I had a recent backup of all my data and followed the steps below carefully and didn’t have a problem on my Hero, but that might not be the case for everyone.  Basically, be careful when flashing ROMs, especially if flashing your main device.

1 ) If you have the most up to date software from sprint than you will not be able to root your phone, so I flashed the original 2.1 update provided from sprint back to my phone. If you dont have this download I think you can get it on the web. The file is called HTC Sprint Hero MR 2.27.651.5 2.exe

2 ) After a clean install of the original 2.1 ROM go to http://unrevoked.com and download unrevoked for HTC Hero.  Open the application and click on button to root your device

3 ) Install ROM Manager from the android market

4 ) Back up your existing ROM

5 ) Download Cyanogenmod 6 from the site here for HTC Hero CDMA

6 ) Copy the zip file you downloaded to the SD Card, open ROM Manager and click ‘Install ROM from SD card’. Then choose your zip file you copied there

7 ) If you want all the google apps and market then copy one of these ROMs here to your SD Card and install the same way you did in 6. Make sure you uncheck clear the data check boxes.

8 ) Now install setCPU from the market and accept the defaults. It will dynamically overclock to 768 mhz. Note that overclocking your phone will likely reduce battery life and increase overall heat output of the Cpu, as such, monitor your phone carefully when overclocking.

Some of the applications I installed:

Sprint Visual Voice Mail from xda-forums

Pure Grid Calendar -- replacement for htc calendar widget

Fancy Widget -- replacement for main clock/weather widget

Wireless Tether -- wireless router

Memory Usage Plus -- The widget you see on the home screen is from memory usage plus. displays active, avail, free memory

CPU Usage Plus -- Nice to see which processes are running and using CPU

I created the following video when I was running Cyanogenmod 6.1 RC1 I had some issues with this experimental ROM (force closes) so I flashed the Cyanogenmod 6.0 stable release and this version is much better, no force closes, better performance over all. This ROM only allows setCPU to over clock to 691 mhz but if you use the interactive scaling and the 691 mhz max it really performs well. More information on interactive governor can be found here

Here is a real short video with my HTC Hero running Cyanogenmod 6.0. As you can see the screen is very responsive and the applications start up quickly. I removed the live wallpaper because that was slowing down the phone in general and was just not worth it IMO

Post to Twitter Tweet This Post

Using the Android licensing service step by step

Posted October 28th, 2010. Filed under Tutorial

Google has deprecated the copy protection on paid apps and is recommending everybody use the new licensing service instead. One of the big benefits you get by removing the copy protection and using the license service is the ability to enable the move to sd card for your application. This is more important if you are developing a game with images and sounds as these files can quickly make your application very large.

I recently modified all our applications to use the licensing server and it was a lot easier than I expected. I have created a Intellij IDEA .iml module for the licensing service and I just need to include this my application that I want to use it in. So here are the steps that I took to add this to my application

1. First you have to use the Android SDK manager and choose ‘Available Packages’ on left, than select the android repository and click refresh. You should see ‘Market Licensing package, revision 1′ . You will need to go ahead with the install of this package. After this is complete you should see it in the list of Installed Packages as shown in the image below

2. Now you will have a new directory called market_licensing in your android SDK folder. Copy this folder to a new location where you will create a module for it.

NOTE: You only have to do this part one time…

3. Open your Android application and from the menu choose File -> New Module. Choose create module from scratch. Choose the location of your market_licensing/library directory you copied from the SDK.  Once you import the new module you will need to go to the properties of your application and add the library module as a dependency.

4. Add these values to your project in res/values/strings.xml

<string name="check_license">Check license</string>
<string name="checking_license">Checking license...</string>
<string name="dont_allow">Don\'t allow the user access</string>
<string name="allow">Allow the user access</string>
<string name="application_error">Application error: %1$s</string>
<!-- Unlicensed dialog messages -->
<string name="unlicensed_dialog_title">Application not licensed</string>
<string name="unlicensed_dialog_body">This application is not licensed. Please purchase it from Android Market.</string>
<string name="buy_button">Buy app</string>
<string name="quit_button">Exit</string>

5. Add the following permission to your AndroidManifest.xml. In addition I have an example here of how you enable the move to sdcard with the android:installLocation. You also have to target at least API level 3 in in the android:minSdkVersion

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="your.package.name"
          android:versionCode="1"
          android:versionName="1.0.0"
        android:installLocation="auto">
 
    <uses-sdk android:minSdkVersion="3"/>
 
    <uses-permission android:name="com.android.vending.CHECK_LICENSE" />
 
</manifest>

6. Create a new java class in your project called LicenseCheckActivity. Below is the code that will go in that class. This is just a slightly modified version that is provided by the google example

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Handler;
import android.provider.Settings;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.widget.TextView;
import com.android.vending.licensing.*;
 
public abstract class LicenseCheckActivity extends Activity {
 
    static boolean licensed = true;
    static boolean didCheck = false;
    static boolean checkingLicense = false;
    static final String BASE64_PUBLIC_KEY = "REPLACE WITH YOUR KEY FROM PUBLISHER CONSOLE";
 
    LicenseCheckerCallback mLicenseCheckerCallback;
    LicenseChecker mChecker;
 
    Handler mHandler;
 
    SharedPreferences prefs;
 
    // REPLACE WITH YOUR OWN SALT , THIS IS FROM EXAMPLE
    private static final byte[] SALT = new byte[]{
            -46, 65, 30, -128, -103, -57, 74, -64, 51, 88, -95, -45, 77, -117, -36, -113, -11, 32, -64,
            89
    };
 
    private void displayResult(final String result) {
        mHandler.post(new Runnable() {
            public void run() {
 
                setProgressBarIndeterminateVisibility(false);
 
            }
        });
    }
 
    protected void doCheck() {
 
        didCheck = false;
        checkingLicense = true;
        setProgressBarIndeterminateVisibility(true);
 
        mChecker.checkAccess(mLicenseCheckerCallback);
    }
 
    protected void checkLicense() {
 
        Log.i("LICENSE", "checkLicense");
        mHandler = new Handler();
 
        // Try to use more data here. ANDROID_ID is a single point of attack.
        String deviceId = Settings.Secure.getString(getContentResolver(), Settings.Secure.ANDROID_ID);
 
        // Library calls this when it's done.
        mLicenseCheckerCallback = new MyLicenseCheckerCallback();
        // Construct the LicenseChecker with a policy.
        mChecker = new LicenseChecker(
                this, new ServerManagedPolicy(this,
                        new AESObfuscator(SALT, getPackageName(), deviceId)),
                BASE64_PUBLIC_KEY);
 
//        mChecker = new LicenseChecker(
//                this, new StrictPolicy(),
//                BASE64_PUBLIC_KEY);
 
        doCheck();
    }
 
    protected class MyLicenseCheckerCallback implements LicenseCheckerCallback {
 
        public void allow() {
            Log.i("LICENSE", "allow");
            if (isFinishing()) {
                // Don't update UI if Activity is finishing.
                return;
            }
            // Should allow user access.
            displayResult(getString(R.string.allow));
            licensed = true;
            checkingLicense = false;
            didCheck = true;
 
        }
 
        public void dontAllow() {
            Log.i("LICENSE", "dontAllow");
            if (isFinishing()) {
                // Don't update UI if Activity is finishing.
                return;
            }
            displayResult(getString(R.string.dont_allow));
            licensed = false;
            // Should not allow access. In most cases, the app should assume
            // the user has access unless it encounters this. If it does,
            // the app should inform the user of their unlicensed ways
            // and then either shut down the app or limit the user to a
            // restricted set of features.
            // In this example, we show a dialog that takes the user to Market.
            checkingLicense = false;
            didCheck = true;
 
            showDialog(0);
        }
 
        public void applicationError(ApplicationErrorCode errorCode) {
            Log.i("LICENSE", "error: " + errorCode);
            if (isFinishing()) {
                // Don't update UI if Activity is finishing.
                return;
            }
            licensed = false;
            // This is a polite way of saying the developer made a mistake
            // while setting up or calling the license checker library.
            // Please examine the error code and fix the error.
            String result = String.format(getString(R.string.application_error), errorCode);
            checkingLicense = false;
            didCheck = true;
 
            //displayResult(result);
            showDialog(0);
        }
    }
 
    protected Dialog onCreateDialog(int id) {
        // We have only one dialog.
        return new AlertDialog.Builder(this)
                .setTitle(R.string.unlicensed_dialog_title)
                .setMessage(R.string.unlicensed_dialog_body)
                .setPositiveButton(R.string.buy_button, new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        Intent marketIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(
                                "http://market.android.com/details?id=" + getPackageName()));
                        startActivity(marketIntent);
                        finish();
                    }
                })
                .setNegativeButton(R.string.quit_button, new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        finish();
                    }
                })
 
                .setCancelable(false)
                .setOnKeyListener(new DialogInterface.OnKeyListener(){
                    public boolean onKey(DialogInterface dialogInterface, int i, KeyEvent keyEvent) {
                        Log.i("License", "Key Listener");
                        finish();
                        return true;
                    }
                })
                .create();
 
    }
 
    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mChecker != null) {
            Log.i("LIcense", "distroy checker");
            mChecker.onDestroy();
        }
    }
 
}

7. Now change your starting activity to extend LicenseCheckActivity. Modify  the  onCreate(Bundle savedInstanceState) by adding  the following code after you set the content view.

public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.main);
 
            Toast.makeText(this, "Checking Application License", Toast.LENGTH_SHORT).show();
            // Check the license
            checkLicense();
 
.........

Now for any future projects all you will need to do is:
- include the module, which has already created so when you go to File -> New Module you will choose import existing module and point to the IDEA .iml file
- Add the LicenseCheckActivity and extend it
- Add the call to checkLicense() in the onCreate method

Now you can test on your device or emulator

Post to Twitter Tweet This Post

Updated Shut the Box for Android

Posted October 23rd, 2010. Filed under Applications

We have updated our Shut the Box game with a new addition of a 12 tile game of classic and high 5. We have added new leaderboards on openfeint for the new games also. The 12 tile games are a bit more of a challenge, it can be very difficult to roll the 12 and this can leave you with big points!!

Post to Twitter Tweet This Post

Shut the Box for Android (With OpenFeint)

Posted October 16th, 2010. Filed under Applications

We have created the classic Shut the Box game and High 5 game for Android with integration with OpenFeint game network. This game is a popular pub game and is also the basis of the popular TV quiz show High Rollers. High 5 game is a more modern twist on the classic game that includes bonus rolls for rolling a double, multiplier values for clearing all the tiles and you shoot for the highest score, not the lowest, like you do in the classic game. We have added 2d animation and physics ( usingandengine) into this game for the dice rolling to make it appear more realistic. One of the things we are really excited about is the integration with openfeint game network. This adds a whole new level to this classic game. You can post your high/low scores to openfeint leader board to compete with friends. We also display the top 5 scores in the game with real time updates.  In addition to this we have added achievements you can unlock during the game. You get points for each achievement which allows yet another way you can compete with your friends on openfeint game network. This is a great game for kids ( practice their math!) and adults. We plan on updating the game with new achievements from time to time so check back for updates!!

Search for shut the box in the market or scan this barcode below to go directly to the game

Post to Twitter Tweet This Post

Halloween Kids Application

Posted September 30th, 2010. Filed under Applications IPad

Celebrate the spooky season with Spooky Halloween! A simple yet fun touch and sound application for kids or anyone else that is ready for a “scare”. Hear spooky sound effects and watch eye-catching animations. A great way to get ready for this Halloween season!

Check out the application in itunes

Post to Twitter Tweet This Post

SMS Receptionist for Android

Posted September 21st, 2010. Filed under Applications

We have released SMS Receptionist for Android. This application will add a menu bar to the bottom of the incoming call screen with buttons you can touch to decline the call and send the caller a predefined SMS Message. You can define the name of the buttons as well as the SMS text that will be sent to the caller. You can also touch any place on the incoming call screen to dismiss SMS Receptionist and answer or decline the call as you normally would. This is perfect for meetings, driving, or when you are out with friends and dont want to answer the phone but you want to let the caller know you will call back in a few minutes.

We also provide a widget for this application to allow you to quickly and easily enable or disable the SMS Receptionist button bar.

Scan the barcode below to go directly to the app in the market.

Post to Twitter Tweet This Post

Wedding Dinger for IPhone

Posted September 20th, 2010. Filed under Applications

The Wedding Dinger simplifies your wedding experience by providing you with several virtual glassware options that you can tap, thus recreating that great “spoon on glassware” sound. Use it for toasts, use it to get that new bride and groom to show their love, use it to protect your glassware or even to annoy others around you! The Wedding Dinger is great fun and free to boot! If you would like to see additional glassware added contact us and we will do what we can!

Click here to see the app in iTunes

Post to Twitter Tweet This Post

Android Wedding Dinger

Posted August 29th, 2010. Filed under Applications

The Wedding Dinger simplifies your wedding experience by providing you with several virtual glassware options that you can tap, thus recreating that great “spoon on glassware” sound. Use it for toasts, use it to get that new bride and groom to show their love, use it to protect your glassware or even to annoy others around you! The Wedding Dinger is great fun and free to boot! If you would like to see additional glassware added contact us and we will do what we can!

Download from the market and let us know what you think!!

Scan this barcode with barcode scanner app to go directly to the app in the market

Post to Twitter Tweet This Post

Shut the Box for iPad

Posted June 18th, 2010. Filed under Applications

The same great game you have enjoyed on iPhone is now available on iPad with the addition of high definition graphics. We are also working on a head 2 head version of the game that will allow two players to play with the same dice and see who makes the better decisions on which tiles to remove.  Below are some screen shots of our iPad app

Click here to see our app in the app store

Post to Twitter Tweet This Post