Fetch That Number Version 1.5.1 Released

Fetch That Number Logo

Fetch That Number

The newest version of Fetch That Number has been released, the Reverse Lookup/Grey Pages search app for Android.

To get the new version, update or install via the Android Market

 

 

New Features:

  • Caller History – You can now see your recently fetched contacts and call, add or ignore them
  • Ice Cream Sandwich support – style and actionbar integrated
  • Tablet Support – you can now search from your Android Tablet.
  • Enable/Disable auto-fetch – going overseas? No problem, just change in the settings.
  • Share Fetch That Number using your favourite social network, email, etc.

 

Posted in Fetch That Number, Products | Tagged , , | Leave a comment

Flex 4 – cut/Copy/Paste context menus not appearing

The right-click context menu for s:TextArea s:RichTextEditor, s:TextEdit, etc. is an expected feature for any sort of form functionality however a bug in s:Panel breaks this functionality whenever the control is inside an s:Panel item.

<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx">
...
    <!-- right-clicking this will show a context with cut/copy/paste -->
    <s:TextArea text="text in app" />
    <!-- right-clicking this will NOT show a context with cut/copy/paste -->
    <s:Panel>
        <s:TextArea text="text in panel" />
    </s:Panel>
...
</application>

Note that this doesn’t affect ctrl+v/p/x keybindings – they work regardless.

There is a hack to get around this –  mark both the s:panel as well as it’s skin as mouseEnabled=”true”. What that means is that EVERY spark panel needs to have a custom skin with that override. This includes cases where there are two enclosing panels.

<!-- this won't work -->
<s:Panel>
    <s:Panel mouseEnabled="true" skinClass="CustomPanel">
        <s:TextArea text="text in panel" />
    </s:Panel>
</s:Panel>

<!-- this won't work -->
<s:Panel skinClass="CustomPanel" mouseEnabled="true">
    <s:Panel>
        <s:TextArea text="text in panel" />
    </s:Panel>
</s:Panel>

<!-- this WILL work -->
<s:Panel skinClass="CustomPanel" mouseEnabled="true">
    <s:Panel skinClass="CustomPanel" mouseEnabled="true">
        <s:TextArea text="text in panel" />
    </s:Panel>
</s:Panel>

It’s a major pain, but it is a workable solution where needed. To create the skin, in eclipse:-

  1. Click ‘file’ > ‘new’ > ‘MXML Skin’
  2. Enter the name for the skin
  3. Set the HostComponent as ‘spark.components.Panel’
  4. Check ‘create as copy of’
  5. Set to copy ‘spark.skins.spark.PanelSkin’
  6. Click ‘finish’
  7. In the ‘<s:SparkSkin ..>’ tag set mouseEnabled=”true”
  8. Set  mouseEnabled=”true” on your ’<s:Panel ..>’ tag
  9. On your ‘<s:Panel ..>’ tag set skinClass=”" to your new skin class

Now cut/copy/paste should appear in your context menu.

Posted in Flex, Programming | Tagged , , , | Leave a comment

Android Developer Labs Melbourne 2012 – Lessons Learnt

I recently attended the Android Developer Labs in Melbourne, which featured talks on how to improve your apps appearance and quality, as well as to show the changes in Android 4.0 – Ice Cream Sandwich.

Android Beam looks to be interesting and I’ve been racking my brains trying to figure out a use for it now!

It was also good to see Google talking on piracy and methods to combat it. The talk on this was certainly interesting.

As a result, there is a big release of Fetch That Number on the horizon with call logs, search and support for tablets (including search services for devices without telephony) and extra large screen sizes such as the Galaxy Nexus. I have also worked to provide some other Ice Cream Sandwich/Honeycomb features such as the Action Bar, utilising the Fragments framework and the new Holo theme.

Posted in Android 2.0, Fetch That Number, mobile | Tagged , , , , | Leave a comment

Formatting Phone Numbers in Java and Android

I needed to format numbers nicely while storing them as a raw string in my database, so I need to turn
0433333333 into 0433 333 333 and 0262195555 into (02) 6219 5555

I couldn’t find something that did this as nicely as I hoped, but this does the job if you know what format your numbers will be as I do (They are all Australian)

My searching didn’t turn up a string mask formatter apart from one in Swing (and I sure don’t want to be importing THAT into an Android project!) so splitting and adding spaces, brackets etc. using  .substring(…) was the nicest way I could think of without writing a whole library.

Make sure the number is a raw numeric string before converting:-

public final class PhoneNumberUtils {

    private PhoneNumberUtils() {

    }

    public static String stripAustralianNumber(String number) {
        if (StringUtils.isEmpty(number)) {
            return null;
        }
        number = stripCountryCode(number);
        // now strip non-numeric
        return number.replaceAll("[^\\d]", "");
    }

    private static String stripCountryCode(String string) {
        if (string.startsWith("+61")) {
            return string.replace("+61", "0");
        } else if (string.startsWith("+")) {
           //handle invalid numbers
        }
        return string;
    }

now the method to format your phone numbers – as noted, this is for Australian numbers, but you can change it easy enough.

 public static String prettyPhoneNumber(String phoneNumber) {

        phoneNumber = stripAustralianNumber(phoneNumber);
        StringBuilder sb = new StringBuilder();

        if (phoneNumber.startsWith("04") || phoneNumber.startsWith("1800")
                || phoneNumber.startsWith("1300")) {
            sb.append(phoneNumber.substring(0, 4)).append(" ")
                    .append(phoneNumber.substring(4, 7)).append(" ")
                    .append(phoneNumber.substring(7, phoneNumber.length()));
        } else if (phoneNumber.length() == 6 && phoneNumber.startsWith("13")) {
            sb.append(phoneNumber.substring(0, 2)).append(" ")
                    .append(phoneNumber.substring(2, 4)).append(" ")
                    .append(phoneNumber.substring(4, phoneNumber.length()));
        } else if (phoneNumber.startsWith("0")) {
            sb.append("(").append(phoneNumber.substring(0, 2)).append(") ")
                    .append(phoneNumber.substring(2, 6)).append(" ")
                    .append(phoneNumber.substring(6, phoneNumber.length()));
        } else {
            sb.append(phoneNumber.substring(0, 4)).append(" ")
                    .append(phoneNumber.substring(4, phoneNumber.length()));
        }

        return sb.toString();
    }
}

I may look at creating a library later on that will do things in a nicer way.

Posted in Android 2.0, Java | Tagged , , | Leave a comment

Fetch That Number Version 1.2.0 Released – Major Update!

The newest version of Fetch That Number for Australia includes new functionality and a brand new style.

Current users should update via the Android Market

New users should check out the product page which also contains links to the app at the Android Market.

New Features:-

  • new styling
  • A Reverse Lookup search activity so you can search for Australian phone numbers without ringing them (of course letting you add their details to your contacts on success!).
  • The Settings screen is now opened via standard Android menu options.
  • Extended info is now an optional search. You can request additional info from the Retrieved Details screen.
  • Added an ‘About’ screen with some handy links

Enjoy!

Also, feedback, suggestions are always welcome either in the comments or via the contact page!

Posted in Android 2.0, Fetch That Number, mobile | Tagged , , | Leave a comment

Inserting and Updating a Contact in Android – Numbers, Addresses and Names – Part 1

I have finally got a working example of inserting and updating contacts using the new ContactsContract API, and I must say, it’s certainly not the prettiest API I’ve used. Sometimes it is downright malignant! I’m sure it made good sense when first created but I have found even the simplest actions like inserting an address somewhat of a chore.

The goal was to populate some values and display to the user the android edit screen. This could be done using the built-in USER_EDIT USER_INSERT or USER_INSERT_OR_UPDATE Activities like this:-

Intent i = new Intent(Intent.ACTION_INSERT);
i.setType(Contacts.CONTENT_TYPE);
i.putExtra(Insert.NAME, "Some Contact Name");
i.putExtra(Insert.EMAIL, "address@email.com");
i.putExtra(Insert.PHONE, "123-456-7890");
context.startActivity(i);

The problem here is that I CAN use Insert.POSTAL to insert an address, but it will insert the whole address on the ‘street’ entry, not break them into suburb etc. which looks rubbish. From memory this is the same with display name, with everything being in the firstname field.

Trawling through the API. there looks to be a new field called ‘data’ which may allow more advanced interaction with contacts however this is only available in honeycomb so at least for the next few years (assuming that it works how I expect it) it isn’t feasable.

So this left me looking for another solution, which was to insert the contact before showing the edit screen. Again, this isn’t optimal, but I figured it was easier for the user to delete an unwanted contact than it was to fix addresses to appear in the correct fields. This on the whole worked well using the ContactsContract API:-

array of contentProviderOperations we wish to run

        ArrayList ops = new ArrayList();

Add a new contact to a selected account (google in this case)

      ops.add(ContentProviderOperation
                    .newInsert(ContactsContract.RawContacts.CONTENT_URI)
                    .withValue(ContactsContract.RawContacts.ACCOUNT_TYPE,
                            "com.google")
                    .withValue(ContactsContract.RawContacts.ACCOUNT_NAME,
                            mAccountName).build());

Add the display name. withValueBackReference is used as the user hasn’t been created yet. It will use the RAW_CONTACT_ID that will be created in the previous operation

ops.add(ContentProviderOperation
                .newInsert(ContactsContract.Data.CONTENT_URI)
                .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
                .withValue(
                        ContactsContract.Data.MIMETYPE,
                        ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)
                .withValue(
                        ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME,
                        mDisplayName).build());

Again using valueBackReference, we are inserting the phone number to the raw contact under a type of work.

        ops.add(ContentProviderOperation
                .newInsert(ContactsContract.Data.CONTENT_URI)
                .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
                .withValue(
                        ContactsContract.Data.MIMETYPE,
                        ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)
                .withValue(ContactsContract.CommonDataKinds.Phone.NUMBER,
                        rci.getNumber())
                .withValue(ContactsContract.CommonDataKinds.Phone.TYPE,
                        ContactsContract.CommonDataKinds.Phone.TYPE_WORK)
                .build());

Now to create the address insert operation. I have marked it as a work address, and we specify each item in the address.

                Log.d(Constants.TAG, address.toString());
                ContentProviderOperation.Builder operationBuilder = ContentProviderOperation
                        .newInsert(ContactsContract.Data.CONTENT_URI);
                    operationBuilder.withValueBackReference(
                            ContactsContract.Data.RAW_CONTACT_ID, 0);

                operationBuilder
                        .withValue(
                                ContactsContract.Data.MIMETYPE,
                                ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_ITEM_TYPE)
                        .withValue(
                                ContactsContract.CommonDataKinds.StructuredPostal.COUNTRY,
                                mCountry)
                        .withValue(
                                ContactsContract.CommonDataKinds.StructuredPostal.REGION,
                                mState)
                        .withValue(
                                ContactsContract.CommonDataKinds.StructuredPostal.POSTCODE,
                                mPostCode)
                        .withValue(
                                ContactsContract.CommonDataKinds.StructuredPostal.CITY,
                                mSuburb)
                        .withValue(
                                ContactsContract.CommonDataKinds.StructuredPostal.STREET,
                                mStreet)
                        .withValue(
                                ContactsContract.CommonDataKinds.StructuredPostal.TYPE,
                                ContactsContract.CommonDataKinds.StructuredPostal.TYPE_WORK);

                ops.add(operationBuilder.build());
            }
        }

Last thing to do is to run the batch operation

Uri contactUri = _context.getContentResolver().applyBatch(
ContactsContract.AUTHORITY, ops);

The URI returned from the batch operation can be used to bring up the Edit User Activity:-

        Intent i = new Intent(Intent.ACTION_EDIT);
        i.setData(contactUri);
        context.startActivity(i);

I also do this within an AsyncTask as the UI will become unresponsive for a few seconds.

I will cover updates in part 2

Any questions, comments or suggestions, feel free to post a comment below.

Posted in Android 2.0, Programming | Tagged , | 2 Comments

Fetch That Number version 1.0.2 released

This is a bugfix release for Fetch That Number Australia.

There were several small bugs fixed around adding a contact after a reverse lookup. There is also some improvements with bug report information.

Any issues, please contact us or check out the product page FAQs.

Posted in Android 2.0, Fetch That Number, mobile, Products | Tagged , , | Leave a comment

Android Market – Authenticating With LVL From a Server

I have been struggling to work out why validation with the Android Market was succeeding with test accounts but with valid market accounts it was failing using code based on android-market-license-verification.

The issue turned out to be that the response data is stripped after verification.
Signed data comes in looking like this if it’s a TEST EMAIL account:-

0|136040138|com.foo.bar|1|ANlOHQOShF3uJUwv3Ql+fbsgEG9FD35Hag==|123456789012

if it is a genuine MARKET account

0|136040138|com.foo.bar|1|ANlOHQOShF3uJUwv3Ql+fbsgEG9FD35Hag==|123456789012:GR=10&VT=0987654321&GT=1234567890

When the signed data is validated, the data after the ‘:’ is stripped, so trying to re-validate the data will fail in the case of the market account, and pass in the case of the test email account.

Posted in Android 2.0, mobile, Programming | Tagged , , , | Leave a comment

Sony – make.believe.ruin

I finally launched my first android app today and as a reward for working all weekend, I decided to buy some downloadable content (DLC) for one of my favorite games Fallout: New Vegas. So after paying, I downloaded the content and installed it. Started Fallout. There was an update for the game itself, so I downloaded and installed that as well. Started the game and…

…strange, no downloadable content listed. Must be something wrong.

I had a quick look online and someone said it may have been due to the game update being installed after installing the DLC. So I deleted the DLC and re-downloaded. I reinstalled, and…

still no content.

Ergh, look on the forums again, and can’t see much. Look on the psn support site… almost zero company support pages, a crappy faq that primarily deals with their new MUBI service, and a community support tab. I hunt around, no contact details on the PSN support page and finally find a contact link on the PS3 support page, hidden in the right sidebar. I click that and…

Site Maintenance Notice

This page is currently down for maintenance.
We apologize for any inconvenience.

Of course it is.

Finally, I trawl through the community support, which interestingly promotes german and spanish results over english (in fact the first 8 results were not english) and read something about DLC being region locked. Now that’s strange because I’m pretty sure regions are more or less abolished for ps3 games… well not quite it seems: While they all WORK on any ps3, the dlc is region specific so if my game comes from the US (as this one apparently is by decifering the codes), I can’t download and install AU content.

Poor form Sony. REALLY poor form.

Surely, this should be something mentioned in FAQ’s? Or god forbid, something they tell you on installation! What a let down. It just goes to show that Sony, even when they do something good like unlock regions on games or provide ‘install other OS’ functionality, you need to think to yourself….

“How can Sony use this to ruin my day…”

because history shows, that given any opportunity, that is exactly what they will do.

Posted in ps3 | Tagged , , | Leave a comment

Fetch That Number launched

Finally, after many months of procrastinating and perfecting, I have launched Fetch That Number into the Android Market.

Cost is $2.99 and available in Australia only at this stage.

Find out more about the app here including links to the market.

Posted in Android 2.0, Fetch That Number, mobile, Products | Tagged , , | Leave a comment