Category Archives: Technology

How payment systems work, and setting up a payment system – part 1

There are lots of ways to get value for one’s own labour or servicing. That’s the more abstract way of saying “there are lots of ways to get paid”…. Cash, trade/barter, cheques/checks, credit. Most times, money goes into a bank account. That’s if you want to keep the money in a safe place. Also by storing it in a bank, the bank’s communication services can help make it easy for you to pay for stuff. And, for you to be paid, for stuff.

Background of this post
I’m sharing information, trying to make this post a short reference document out of my recent experience.  There are sometimes a lot of fees to chip away at your profit. The fees are most often ignored by people, called “a necessary business expense”. That’s true but they shouldn’t be ignored, or taken lightly. Today I saved one small business client $400, by looking at a different provider of credit card terminals than previously considered. And I’m now on the path to save him another $600 for a separate payment card terminal. I have a merchant account myself, and every month there are more fees, but I’m quickly learning the different fees for everything, so I’ll be saving my own self 400-1000 soon.

What is a payment system
A payment system handles money going from one place to another.  For the purpose of this article, I’m limiting discussion to the moment of payment to the money being in one’s account.

Security and Signatures
Cheques are cheap methods of payment, but the payer has to pay up front for the little pieces of paper, custom printed with security codes and what-have-you, to make the payer and payee/seller more comfortable. And that’s what a lot of the fees go to: comfort. Comfort brought by security. And the security is usually good, but sometimes unnecessary, thus an unnecessary expense. But the most useful security system is the personal identification number (PIN) associated with an account. The account is encoded on a magnetic strip on a swipe card, and read by a stripe reader. I’m ignoring the chip card technology for the moment.

The general retail stores are slowly converting to use a chip with PIN on Visa/Mastercards, and that saves the signature. The signature is being replaced by the PIN at the physical terminal, and the signature is already replaced by the security code on the back of the card, for online transactions. A person can also deposit into a bank account at an ATM/ABM without signing or stamping the cheque because the PIN used with the card represents the signature… that’s the general policy at my bank anyway.

The security is often end-to-end, meaning the merchant is locked-out of the electronic communications between the payment terminal and the payment processor company.

Further sections to be written:

Payment Terminology
Tons of hardware, lots of software, so what is the best approach?
What fees are involved with a payment system?
How is a transaction made?
What are reasonable processing fees of a transaction?
Where the money goes… and how to get it!

 

 

 

 

Posted in Technology, Thoughts | Tagged , , , , | Leave a comment

Do you really want that job? (aka The Incompetent Client)

Here’s a hypothetical situation for you: let’s say an organization wants you to make amazing new signs for a promotion… and you recommend to the buyers/client that they install these new signs in specific locations, but there was a past track record of incompetence, such as previously installing a series of signs all upside down. Would you do the job? (And how does that even happen? Who knows!)

I love the funny pictures that show ridiculous things like that.  Actually working with or for people who would make foolish mistakes, and NOT admit, correct and learn from them, is infuriating, but part of life.

These are things that crossed my mind today.

How does a person guarantee they will get paid? Or how does a person guarantee that his/her own work is respected and used appropriately? If the work is compensated, but trashed, it is not very good to use on a resume or as a client success story for referrals. And if the work is paid, but used or implemented inappropriately, that could be difficult to use for referrals too. Worse yet, someone could see the client’s poor use of the product and conclude the maker/product was at fault, rather than the faulty use by the user/client.

These are all based on a thought of dealing with clients with poor knowledge, attitudes, or behaviour. But again in life, that doesn’t necessarily need to be the case. They could be great people, with good knowledge but the market rejects the work.

Whatever the situation or client, I think the BEST approach is: make a great first impression for yourself and the proposal, be truthful and open and create a very short term plan (a bootstrap plan) and then get up-front retainer fees received and in the bank. Then begin to build momentum, maybe by frequent and productive meetings, and optional ongoing compensation as appropriate.

This is a relatively new business technique to me. But it’s such a great one. The last several clients I have worked with as an independent, I used this technique, to great success. Now in a group with some partners, I am seeing clients coming in who have lots of gusto and excitement to have us do projects, but I’m feeling the risk if their gusto and excitement is not balanced with their budget.

So unfortunately, there is a high risk of loss to the momentum of the business relationship, and to my own business. For example, when loss of a prospective or active client does happen, morale may drop, affecting the ability to get new clients or perform other standard business tasks like proper accounting and invoicing. Really, I am reflecting on an experience that nearly killed my potential right out of the gate, in 2009, a few months before completely dedicating to iPhone and mobile.

Putting a project on hold, or even canceling one for whatever reason, or worse yet losing a client… I cannot let these bother me, and it is much easier to get on with life and other work if I have been paid properly. Then I will just walk on, looking forward to the exciting potential for the next days and the next weeks.

Posted in Technology, Thoughts | Leave a comment

Best Techniques for 360 Panorama on iPhone

360 Panorama is a revolutionary app.  It is made by Occipital (occipital.com) and has been under constant improvement, both the app and the web-site since it was released in late 2010.  Check out the 360Verse web app!

A short history of my use of the app:

I got the app in early December 2010, and captured several Christmas light panoramas.  They were amazing, and the ease at which I could just stand and spin around made me so happy.  Having experience stitching dozens and dozens of photos into 40-80 megapixel panoramas, this made me so happy to save such time. And for better or worse, I am a perfectionist.  Despite how amazing and excited these christmas light panoramas were, I found them flawed. All my attempts were challenged by light intensity, and were full of tilting, so I felt either I needed to figure out some techniques to improve, or the app needed updating or both. And the app has been updated several times with several new features, and greatly improved image blending/stitching! Awesome!

 

Getting a satisfying 360-degree photo is so easy (wahoo!!!), but to add that little extra bit of quality, I’ve come up with a handful of techniques that can be used to improve the finished result.

Quick Bonus Tips! 

  1. Keep the iPhone as close to you as possible, right in front of your face.  Holding it at arms length can confuse it for certain near-by objects.  This tip came directly from Occipital after I finally asked for help in late February 2011.
  2. Also don’t lower it down to your chest or waist when capturing the ground, and don’t stick it way up above your head when capturing the sky.  Only rotate it up and down, right in front of your face, and spin your body to get the side images.

The Best Tips

The following are the most important techniques to solve the most significant problems I found occurring in most panoramas:

  1. Achieving the best camera exposure levels in the first shot
  2. Moving around so the images to blend together properly, primarily to fix broken horizons
  3. Moving so the internal gyroscope does not start to go sideways, resulting in tilted-looking buildings like Leaning Tower of Pisa.. or the horizon on a lake doesn’t tilt.

1. Get Best Exposure for the Environment’s Light

Determining the best exposure is often a bit of a guess, but the best way to get it is aiming the camera toward the brightest point in the 360 environment for light or average environments … obviously the sun, if you’re outside, or some light wall inside, etc.  In a darker environment, aim the camera at the darkest place so it compensates and the rest of the 360 view is easier to see, not all black.  And then, start capturing, and quickly spin around and find any places in the environment that you really like and want to see in the panorama, and if they appear way too dark or too light, then you might want to restart, and aim the camera a bit off from whatever you aimed at initially.  Then you can either assume the camera has a good initial exposure and continue to make the panorama or you can do a quick spot check again.  I usually do one single test and then do the panorama.. Although, I would have done a third on Lake Louise if I had the time (I was annoying family members who were also in the canoe, requesting them to spin the boat around! haha..)

Here are two pairs of panoramas with separate light/dark versions, Lake Louise and Grotto Mountain Pond:

  • Lake Louise light (the water texture is much more detailed than the dark version, but the Fairmont Chateau Lake Louise is farther and harder to see here… the dark one is closer)

 

  • Lake Louise dark (the trees on the mountain are harder to see, and water is darker compared with the light version, but the two landmarks Mount Victoria and Chateau Lake Louise are easy to see)

 

  • Grotto Mountain Pond light (easy-to-see large mountain on left, almost bleached-white mountain on right)

 

  • Grotto Mountain Pond dark (easy-to-see mountain on right, almost total black mountain on left)

I felt rushed for time at Grotto Mountain Pond, so I couldn’t get a well balanced 3rd panorama.  .. Ahem.. Actually, these were the 3rd and 4th. The 1st and 2nd were each destroyed by separate incoming SMS text messages. Bah!! Airplane mode fixed that. hahaha!

This technique was important for the panorama in the field with mountains in Canmore (http://360.io/HkKLEB)  I did 2 or 3 spot checks before I finished the field-with-mountains, because there is a huge amount of dynamic range.

First I aimed at the sun, so the sky was darker and all the clouds were detailed, but the mountains turned totally black.

Then tried lighter a bit, once or twice, until I liked the balance between bright sky clouds and the dark mountains. This was used by Occipital in the 360verse, and a viewer commented on it, inspiring me to write all this information.

 

2. Preventing Broken Horizons

 

Watch the grid when starting, and try to get the horizon in your first image, rather than a total sky image or total ground image.  Then slowly angle the device up and down to get the sky and ground for this initial horizon image, then return to the horizon and start slowly turning around in a circle. The camera decides to take a picture when there is enough new uncaptured environment in the camera view.  When the camera decides to snap a new picture, try to make it so as much of the new image is overlapping the captured images as possible…. so spinning your body slower helps.  Doing this, will greatly reduce the chance of a broken horizon… except in the final stitch-together when you complete the 360 spin.  It’s much more tricky to get the horizon at the end of the 360 spin to be unbroken.  I think it’s a bit of luck, but it’s partly about keeping the iPhone as still as possible, while spinning.  But as I describe in #3 below, the internal gyroscope can get thrown off so sometimes.  Finally, completing the spin around, hopefully there has been very little broken horizons, and there are no trees or buildings or horizon tilted.  Then start spinning slowly again, capturing the sky and ground in the same manner.  I haven’t determined if it makes a difference to capture only the sky in a spin, and only the ground in another spin, or if the second spin can capture both sky and ground perfectly well simply angling up and down as you spin the second time around.

3. Calibrating the Gyroscope Mid-Capture

The fix for the gyroscope, as described above, is important to limit lines both horizontal (like the horizon especially obvious on lakes/oceans) or vertical (like buildings or trees) from tilting left/right.  It’s best, while keeping the iPhone perfectly untilted left or right, to watch the grid on the screen.  If it starts to tilt, then the gyroscope needs calibration.  So, the best way to do that without ruining the panorama is to keeping the iPhone pointed at an image you’ve already captured, and moving the device rapidly back and forth.  I have found various motions work at different times, either outward and inward around 12-24 inches out from your face, or moving the phone in a circle about 12 inches in diameter, or a figure-8 shape, in front of your face.  Alternatively, quickly spin a bit back over the panorama you’ve captured already about 90 degrees, then return and repeat as needed until the grid is straight again.  That is the best technique for calibrating, and at the same time preventing the camera from snapping a new picture for the panorama that you don’t intend.

Now I’ve created almost 30 panoramas, some uploaded and public, and feeling great confidence in the app, and my own improved use of it.  Hope this info can help you get even more enjoyment from the app.

If you want to see some more of mine, click to view my public panoramas occipital account page.

Follow @360panorama on Twitter to hear about the latest news and additions in the 360verse web app.

Posted in Activities & Adventures, Technology, Thoughts | Tagged , , , , , , , , | 4 Comments

Make your iOS apps support public types (like .zip)

It will happen once in a while, when using an iPhone or iPad, a person may get an email with an attachment to be opened, but can’t because there is no app on the device to open it. Or similarly, surfing the web using the Safari mobile browser, and suddenly there is a file to be accessed/downloaded but it isn’t supported in Safari on iOS.

And for app creators/developers, we solve this issue by allowing our apps to open those types of files, to make up for the lack of Apple having an app that does so.

There is much info around the internet about this, but mostly the info is about supporting custom file types (for random example: .my3dimage) it all comes up short for supporting public file types. I mean, types of files that are out there in the world, but the iPhone doesn’t have an app that supports them. A really obvious case is PDF files.  They used to be not supported, but now they can be viewed in Mail or Safari.  One popular type that is not supported in mail or is the zip file type.

An app developer simply adds the CFBundleDocumentTypes key to the app’s Info.plist file, and fills it in with info, and then builds the app to handle the file when another app tries and fails to open a file.

CFBundleDocumentTypes is an Array of Dictionary objects. Each dictionary has a set of keys (and values) and following is a list of recommended keys from Registering the File Types Your App Supports in Document Interaction Programming Topics in the iOS developer library:

CFBundleTypeName specifies the name of the document type. (ie. Zip archive)
CFBundleTypeIconFiles is an array of filenames for the image resources to use as the document’s icon. (could be a picture of a folder with a zipper, like Windows Explorer uses, or anything else)
LSItemContentTypes contains an array of strings with the UTI types that represent the supported file types in this group. (an array of the UTI types.. this is the confusing part for quickly supporting public types that I deal with in a moment).
LSHandlerRank describes whether this application owns the document type or is merely able to open it. (This is another interesting part that I talk about)

More can be added (and SHOULD be added), and they’re found in Table 2 Keys for type-definition dictionaries, of the CFBundleDocumentTypes section, in the Core Foundation Keys page of iOS Information Property Key Reference.  But BEWARE!  Several of these keys are not for iOS, but Mac OSX, and some are deprecated, while still remaining in the list.

There is more information on the meaning of each specific value that can be assigned to each key. Check out below Table 2, in CFBundleDocumentTypes section, for Document Roles and Document Icons.

After Document Roles and Document Icons sub-sections, is a relatively section of some importance, Recommended Keys.  I say “some” importance because it’s a very important section naturally, but contains out-of-date recommendations.  This list contains 1 valid key for iOS and 3 that are Mac OSX only, plus those 3 are deprecated:

LSItemContentTypes
CFBundleTypeExtensions (not in iOS)
CFBundleTypeMIMETypes (not in iOS)
CFBundleTypeOSTypes (not in iOS)

The following are strongly recommended, but optional:

CFBundleTypeIconFile
CFBundleTypeName
CFBundleTypeRole

These 7 recommended keys, partly overlap with the 4 I listed above from the Registering the File Types Your App Supports section. The overlapping items are:

LSItemContentTypes
CFBundleTypeName

It can be confusing then, which to use… I think this is just a case of some instructions not being updated with the latest best-practices. So try support as many non-deprecated keys as possible!

Now for a list of the strings that can go into the all-important LSItemContentTypes section:

System-declared Uniform Type Identifiers (UTIs)

 

The table on this page lists a whole bunch of system and public file types that aren’t necessarily supported in the iPhone or iPad.  Zip is in the list, and happens to have the com.pkware.zip-archive valiue.

I won’t discuss the icon, but please see Document Icons  within Custom Icon and Image Creation Guidelines for info about them.

Info about the Role is in iOS library.

There is a possible issue with the Rank, if two apps declare themselves as the Owner of a type, then one of them is given precidence for the button that appears on the right-side in Mobile Safari, as seen in this picture:

 

 

 

 

 

 

 

 

 

I don’t know much about dealing with this yet, but it should not be a huge problem because a user can click on the “Open In..” button and see other apps that open it, like in the following picture:

Hope that helps someone.

Posted in Technology | Tagged , , , , , , , , , | 2 Comments

Design updates on Google Calendar

Google Calendar’s visual design was updated recently.

The changes and reasons are explained here:
http://www.google.com/support/calendar/bin/answer.py?answer=1351806&&hl=en

I want to just point out some interesting part of that, the part that is always the most interesting/relevant to my own self:

Why we made these changes

The way people use and experience the web is evolving, and our goal is to give you a more seamless and consistent online experience — one that works no matter which Google product you’re using or what device you’re using it on. The new Google experience that we’re working toward is founded on three key design principles:

Focus: With the design changes in the coming weeks and months, we’re bringing forward the stuff that matters to you and getting all the other clutter out of your way.
Elasticity: The new design will soon allow you to seamlessly transition from your desktop computer to your mobile phone to your tablet, while keeping a consistent visual experience. We aim to bring you this flexibility without sacrificing style or usefulness.
Effortlessness: Our design philosophy is to combine power with simplicity. We want to keep our look simple and clean. But behind the seemingly simple design, the changes use new technologies to make sure you have all the power of the web behind you.

Here are some shrunk images that demonstrate the before-after differences:

Posted in Technology, Thoughts | Tagged , , , , | Leave a comment

Google Android cheap devices

A friend and I walked by a Rogers Wireless reseller recently, and discussed a promotional poster we saw in the window. It showed a bunch of Android phones, and the cost for these was advertised around $80, brand new (on contract, of course… )

Soon, most or all North-American mobile phones will be smartphones. Android is free, and so manufacturers are not obligated to spend any money for including it on their devices. Except, in order to properly manufacture a phone that includes Android installed from the factory, the phones must have certain abilities/features.

As phone prices drop, perhaps the cost to include a touch-screen will become too great for the manufacturer (relative to the cost of the phone itself) and the manufacturer may choose to use a trackball or touchpad like the BlackBerry phones. The possibility of any major manufacturer producing any android phone without a touch screen is a very bad thought. It would wreck most apps, and make the experience of using the phone very terrible. Maybe then it would not matter if it had no touch screen, because no one would buy it!

So, it was a pleasant when I was looking for a list of permanently-available buttons (home, back, search, menu, volume, lock, etc) and I discovered the following, part of the Android Compatibility Definition Document, available in the side column at http://source.android.com/compatibility/index.html

7.2.3. Navigation keys
The Home, Menu and Back functions are essential to the Android navigation paradigm. Device implementations MUST make these functions available
to the user at all times, regardless of application state. These functions SHOULD be implemented via dedicated buttons. They MAY be implemented
using software, gestures, touch panel, etc., but if so they MUST be always accessible and not obscure or interfere with the available application display
area.
Device implementers SHOULD also provide a dedicated search key. Device implementers MAY also provide send and end keys for phone calls.

7.2.4. Touchscreen input
Device implementations:17
• MUST have a touchscreen
• MAY have either capacitive or resistive touchscreen
• MUST report the value of android.content.res.Configuration [Resources, 30] reflecting corresponding to the type of the specific
touchscreen on the device
• SHOULD support fully independently tracked pointers, if the touchscreen supports multiple pointers

7.2.4 says all Android phones MUST have a touch screen. That’s a great discovery! So the touchscreen part of an android phone is not optional.

That’s all for now.

Posted in Technology | Tagged , , , , , , | Leave a comment

Tablet screens: Playbook vs Galaxy Tab vs iPad

This is just a bit of technical numbers trivia.
I made these calculations to have a reference for comparing things.

Platform

BlackBerry
Playbook

Samsung
Galaxy Tab
Apple
iPad
Resolution
(pixels)
1024 x 600
1024 x 600
1024 x 768
Diagonal size
(pixels)
1186 diag
1186 diag
1280 diag
Diagonal size
(inches)
7"
7"
9.7"

pixels-per-inch
(dots per inch)

169 ppi/dpi
169 ppi/dpi
132ppi/dpi
App icon width (pixels)
90px
(90 x 90)
72px
(72 x 72)
72px
(72 x 72)
(divided by ppi)
169 ppi
169 ppi
132 ppi
App icon width
(inches)
0.53"
0.43"
0.55"
Posted in Technology | Tagged , , , , , , , , , , , | Leave a comment

BlackBerry vs iPhone (iOS): the fundamental UI “view”

Here’s some info for developers… Not so useful for a regular app user.  This will be an updated document/post!

There are usually counterparts in competitive things. Blackberry’s OS and iOS and Android, they all have common things that are simply changed a bit, most frequently by name, but maintaining a common set of traits, as I’m going to begin describing. There is much too much documentation on various things to do a comprehensive common comparison, unless I were getting paid to do such an article by someone who wanted it (which I’m open to doing for the right price!). The purpose of constructing this is to give a platform to launch a person into their own research and discovery.

The basic foundational user-interface concepts are what you see, and what you do with it.
The foundational “what you see” element is generally called the “view”. In iOS, this is called UIView and in BlackBerry, it is called Field. For the record, in Google Android, it is called View.
Temporary note: this is comparing BB and iOS, not including Android right now.
What foundational “what you do with it” element is generally a user action. In iOS, the most basic is a UITouch (and derivatives, like UIGestureRecognizer), and in BlackBerry, I think it’s called a trackballClick. Then there are more actions a user can do, like dragging… Sorry if this is too basic, just being well-rounded.

The specific web address for the documentation of each of the view elements are:
http://www.blackberry.com/developers/docs/3.6api/net/rim/device/api/ui/Field.html
http://developer.apple.com/library/ios/#documentation/uikit/reference/UIView_Class/UIView/UIView.html

BB iOS
Quick description (from official docs):
A field represents a rectangular region contained by a manager. The field sizes itself according to its needs in layout. The manager, rather than the contained fields, completely handles scrolling.
Quick description (from official docs):
The UIView class defines a rectangular area on the screen and the interfaces for managing the content in that area. At runtime, a view object handles the rendering of any content in its area and also handles any interactions with that content.
.isFocusable (UIResponder)canBecomeFirstResponder
.onFocus (UIResponderDelegate) becomeFirstResponder
.onUnFocus (UIResponderDelegate) resignFirstResponder
.layout(req) layoutSubviews
.paint(req) drawView
.invalidate setNeedsDisplay
.updateLayout setNeedsLayout
.trackwheelClick (UIResponder)touchesBegan:withEvent:
.trackwheelUnclick (UIResponder)touchesEnded:withEvent:
(UIResponder)touchesCancelled:withEvent:

Manager vs UIViewController
http://www.blackberry.com/developers/docs/3.6api/net/rim/device/api/ui/Manager.html
http://developer.apple.com/library/ios/#documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html

BB iOS
Quick description (from official docs):
The system uses manager objects to contain fields. The various manager subclasses handle specific kinds of field layout. This Manager class itself deals with scrolling internally.
Quick description (from official docs):
The UIViewController class provides the fundamental view-management model for iPhone applications. The basic view controller class supports the presentation of an associated view, support for managing modal views, and support for rotating views in response to device orientation changes
Relationship to Field: extended from Field class
Contains a bit of UIScrollView code for handling scrolling…
Relationship to Field: contains a UIView property ( .view)
Posted in Technology, Thoughts | Leave a comment

Which is better: to embed images or link images in HTML emails?

Early this morning, and later in the evening, I was working on a PHP script that composes HTML emails with extra files included, but rather than making images as attachments, the script embeds the images so they don’t actually appear as attachments, but appear instantly within the email.

It works fine for <img> tags, but the big issue comes when trying to use CSS.

<img src=”cid:20110212231111.1we615e” />

This works in Thunderbird, immediately.  And it works in Gmail’s web-interface.
BUT…

body { background-image: url(cid:20110212231111.1we615e); }

This DOES NOT work in Thunderibrd, and NOT in Gmail’s web interface.  These items do however appear as attachments.  So that defeats the purpose of having everything appear instantly and properly.

And given client demands, I need to make everything as perfectly seamless AND painless as possible.

So, I believe I’m going to simply link ALL images.  That will save on bandwidth, plus any email client that has image security will simply display a link that says something sounding like “Do you want to display images in this email?”.  If the recipient clicks to say yes they want to see, then everything will appear, instead of just the <img> tags, but no background.

This is an example of the far-out strange places I go in my work.

Trying to embed and compose HTML emails is difficult on a Windows machine since Thunderbird’s only HTML composing feature is old and not updated to work with the latest version, and Outlook only works (so I’ve read) with HTML composed from within Frontpage (not going to touch that with a 10-foot pole!!).  A few days ago I created an automated emailer that attaches vCard files, and in order to do this, I had to learn about MIME boundaries, content-type, content-disposition (inline vs attachment) and a whole lot of extra stuff.  Lots of technical stuff.  In the end, I’m here wasting time figuring out embedding images, just because Gmail’s web interface doesn’t operate to the most ideal level possible.

Oh well.  So I’ll just link every image.  And that’s a wrap! … several wasted hours later.

Posted in Activities & Adventures, Technology | Tagged , , , , , , , , , | 2 Comments

Mobile web problem on the Blackberry Torch/Tour/Style

One of the benefits of having smartphone is surfing the internet with a high-quality web browser while you’re driving down a high-speed highway.  Then, often if you’re looking for information on a destination, anything from a restaurant or hospital or mechanic or astrophysicist, you’ll discover a phone number.

And magically, any android phone or apple iphone, will see the phone numbers and make them clickable.  Even the Opera browser I have on the iPhone 4 does this.

But NOT the built-in browser in the OS 6 phones from RIM.. the Blackberry Torch, Blackberry Style and Blackberry Tour.

Unfortunately, there is no solution for that personlooking up a contact phone number on their Blackberry phone. HOWEVER, that does not mean it is impossible.  The solution rests completely on the shoulders of the creator of the web page.
For a web designer/developer, instead of putting a line of text within HTML in your page like

Call me!  1-800-123-4567

simply change the HTML code to

Call me! <a href=”tel:1-800-123-4567″>1-800-123-4567</a>

I’ve downloaded all the emulators for these devices, to verify the solution.  Yep, works. Very, very simple.

Posted in Technology | Tagged , , , , , , , , , , | Leave a comment