Showing posts with label tablet. Show all posts
Showing posts with label tablet. Show all posts

Friday, September 27, 2013

Finally I get to do a tablet only app

We have a dashboard style web page used by our clients. I recently converted the charting side of that from flot to HighCharts. HighCharts gives much nicer looking charts by a long shot and the price was reasonable. All of that work was in JavaScript which I must say I don't miss and am very happy to get back into the mobile side of things.

JavaScript is just barely acceptable on an iPad or Android Tablet. Yes, I tweaked various UI aspects to make them more touch friendly but if we want to be able to look a client in the eye and tell them we have a dashboard that works on their tablet we need to go true native mobile.

All the code I have done in the past has been universal phone and tablet. For this type of dashboard we are going to start tablet only. We really want to design to use the space available. Of course 1024x768 (older iPad and iPad mini current maximum) is not a ton of space but it is what a number of folks run on even older desktop PCs if they only have a 15" LCD.

At this point I am sketching out ideas and have started a framework on the Android side. I am going to start there as this seems a perfect fit for fragments within an activity. Previously I have used fragments to learn about them and knowing it is the proper way to approach the future. Now I will get to exploit so much more of their power. I have not had the need to swap in one fragment for another or to add new ones to an activity, I have only defined them in the XML and let them operate as is.

Since this will target 3.0 and above on large devices I don't even have to worry about the compatibility library. Nice to get to be able to fully use the newer API features.

I am using achartengine for the pie, line and bar charts on the Android side and core-plot on the iOS side of things. The current smaller app just displays a pie chart so I will need to learn my way around the others.

Not sure what approach I will take on the iOS side of things. There is nothing like fragments there so I will get to deal with UI views and manual placement of things. This is why I plan to get it up and running on Android first so I can knock out the initial design without fighting layout issues. I should be able to figure out a number of UI patterns such tab controls, menu options, widget manipulation buttons etc. and run them by beta testers before I begin the iOS conversion.

Saturday, November 24, 2012

Only doing Android work - what a change of pace

At my new position I am only doing Android development where before I was doing Android / iPhone and desktop Java. First off it is a bit weird only having one computer, one IDE, one mouse and one keyboard to deal with. Everything is the same each day. You don't have to mentally switch gears multiple times a week.

What it does make you think about is pushing the one platform you are on even farther than before. I was always in a bit of a rush. I needed this working on both iOS and Android so I got it working on each but maybe not the best on each. Now I can say "I need this working on the Android and I need to to work and look the best possible." I don't care if what I am doing it pain in the behind on iOS, there is another team to worry about that. I don't have to think about desktop Java at all.

I am finding this new mentality is really helping me discover areas of the Android platform I had not had the time or energy to investigate in the past. I have been playing around with animations. We need to swap an image view between the front and back of a check. I started with a simple one, changed it to a fade in / fade out as suggested by another developer then I switched it again on Friday to a simple animation that makes it look the check is flipping. I am pretty happy with the current iteration.

The other bonus is I have the ear of a second Android developer. Being the solo mobile guy at the last place had a number of disadvantages. No one to bounce ideas off of, do code reviews, suggest a better way, a new animation, better color schemes, different layout ideas etc. The other guy has a lot of different Android experience than I do. He had worked with JSON before so got that part running quickly. I had done custom controls and a lot of layouts so I had that handled. We both know to use styles, the string table and other XML files to keep things clean.

The code we inherited looked like it was the first Android project written by this off shore team. We had a lot of general clean up to do before we even wanted to touch the guts as they did not follow any of the general Android guidelines.

We are finishing up the process of making this a real Android app. They locked all the screens into portrait. That may be acceptable for a game but not for a main text based application. The iPhone team locked it all into portrait too because doing both portrait and landscape under iOS can be a pain. Sure, there are some gotchas in Android but it is pretty darn flexible on the layout side of things and it is easy to create the directories you need. Plus we are working on having it look nice on phones and tablets. The iOS team is not doing a universal app so iPad owners will get the less the satisfactory 2x experience.

They are not too worried about Android tablets telling us there is little demand there. Not sure they are looking forward enough. There are going to be a lot of 7" tablets from Google and Amazon under the tree this year along with iPads and iPad minis. I know I use my tablet a lot around the house and I figure more and more people will be using them too. For this battle I am making sure it looks nice and is operational on a tablet. It is not tablet optimized but if you use a tablet I don't want you to scream and run away when you fire up this application.

I would suggest they do a universal app for iOS too but I think that will fall on deaf ears. The current team is very new to iOS, learning it on the fly in fact. Since I sit a converted break room with the other Android developer and two of the iOS team I get to hear their issues. Most of them I know about having done iOS development for a year. At least they are going after iOS 5.x and above and can use the new memory management aspect. The current code does not but all new code can. That will be a huge help. I was using that on the final iPad project I worked on at the old job and I know I could get used to doing it.

The one thing I really miss from the old job is dual 24" monitors. I have a dual screen set up now, the laptop screen and a 21" screen with a less than stellar resolution. The Android emulator barely fits on a screen height wise. Developing means you have a ton of windows open: Outlook, instant messenger, browser, text editor for notes, Eclipse, emulator, music player, command prompt, paint program, etc. These little 1400x900 screens just don't cut it. A a contractor I am considering picking up a bigger screen and hauling it in just to keep my self slightly sane. Companies need to realize how important screen space is to a developer. My dual screen set up at home is a better configuration than I have at work and that is kind of sad.

All in all it has been a good experience so far. They have work lined up so I know there is plenty to do. I am becoming a better Android programmer every day and using more of what the SDK has to offer. As long as I am growing at a job I am happy. The people are friendly and having another Android coder next to me has be a huge help.

Tuesday, September 27, 2011

Converting a phone app to Android tablets and the iPad

Just as I thought I was winding down my Android and iPhone development the Doctors tell us they have bought iPads and Android Tablets to use to enter all the data. Can't blame them as it is much easier to enter data on a tablet. The problem is we were going to target those devices on the next release. Time to quickly switch gears.

The app ran fine on the Xoom but the home screen needed to scale better. I searched the web and found new graphics for that area. With more room using larger fonts also seemed the way to go so I tweaked a few other XML files. I ended up creating a new values-xlarge directory under the res directory to hold a styles.xml file for the tablet. I find the way Android handles this to be super easy. I had to go back into a few of my other XML files to make sure they were using the named styles but that was all. I only have a few files in my layout-xlarge and layout-xlarge-land directories to handle all the changes I wanted to make on the Android Tablet.

Android does handle your app getting kicked out out memory in a way that screwed with our app. We have some global static data (I know wrist slap in order) but I need it for the SQLite database and some other login credentials. When you get booted from memory the OS tries to run your onCreate method of the visible view again. For most apps this would be great, you just pretend you started fresh and go. But with the global variables this is not so fun. I added enough checks that I don't [Force Close] any more but tell the user that the session has expired and they need to login in again. I kick them back to the login screen to get going with a fresh database and session variables.

Initially testing this case was a royal pain. You needed to leave your phone on overnight or run so many apps that it got kicked out of memory. Of course that is stupid and a few internet searches pointed me in the right direction. Fire up the emulator, run your app, use "adb shell" from the command line then "ps" then "kill #id" of your process. This will cause same sequence of events to occur. I brought up each possible activity / view and did that over and over until they all exiting clean to the login screen. You can't do this when running on a device but you can use the DDMS view in Eclipse and hit the red [stop] button to achieve the same results.

Once you start running on a real device, especially a dual core tablet, you hate to go back to the emulator. Of course QA came and took the tablet a few days after I had it in my hot little hands so I am still missing it. So much nicer to type on it and code changes are sent over to it and are up and running in a blink of an eye.

Now for my iPad experience. You can set up a universal binary in Xcode. Once you do that it will automatically switch you to the latest version of iOS as your target which is not a good thing. I wanted to target 3.0x as the minimum iOS version. Since Xcode is smarter than me things quit working on my iTouch until I figured out what it did. Simple enough to change that back.

Initial runs on the iPad looked like initial Android tablet runs. Most things looked pretty good as I was using list views and text editors. The home screen looked crappy though. I was able to use my @2x images for the retina display on the iPad. I used the stretchableImageWIhtLeftCapWidth to simulate the nine-patch image I was using for the shelves on the Android.

topShelf = [[UIImageView alloc] initWithImage:[shelf stretchableImageWithLeftCapWidth:25 topCapHeight:0]];

Worked like a charm and was much easier than I assumed it would be. I had to put in manual positioning code for each of the icons on the shelves for the iPad but there are only 6 images so that was easy enough.

I am adjusting for the height of the status bar in my code too. On the iPhone the status bar height is different between portrait and landscape but it is one height on the iPad. I put code in place to handle those special situations and everything looks pretty darn nice.

Since I have more title bar room I wanted to show the practice name on the home screen. Of course that changed the "back" button on any screen that launched from the home screen which is not what I wanted. Turns out you can do this:

if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {

    self.navigationItem.title = [NSString stringWithFormat:@"Home - %@", [RESTCaller practiceName]];
    UIBarButtonItem *backButton = [[[UIBarButtonItem alloc] initWithTitle:@"Home" style:UIBarButtonItemStylePlain target:nil action:nil] autorelease];
    [self.navigationItem setBackBarButtonItem:backButton];
}

That code allows you to set the title text to one thing but the back button used by all other areas to something else. Not the way my mind thinks but I understand the logic behind it now that it is in place.

I want to increase the font size on various screen on the iPad. Since there is no real layout manager for iOS, everything is hard coded for widths / heights in the XIB file, this is a royal pain. You can either do secondary XIB files where you have to tie everything exactly back to the code via drag and drop or you can try and tweak things in code playing with bounds and what not. Both are sorry excuses for layout editing. I have made slow progress in this area but find the amount of work involved to be stupid.

The iPad cannot use the same call to show the picture gallery as the iPhone. I had to update the code to make the new call to show a pop-up image picker instead of a full screen gallery picker. I hope that is the only API I am using that they changed on me. Rough one to find, good thing we have QA to beat on it.

UIActivitySheets don't exactly work the same on the iPad either. They show up nice and centered but if you rotate the device while you are displaying one it will not stay centered. It stays relative to its original position. Looks ugly but this will be a really rare case so I did not fix it. There are some suggestions on the web as to how to fix it but nothing worked for me. The only thing left to consider is killing the sheet when you get a rotation notice and recreating it so it shows up in new orientation centered again. Of course if you do that really quickly you will have a new set of issues. Not worth it at this point. I see Apple cheated in this respect. Long tap a link on a web page. It pops up a menu. Rotate the screen. The Screen will not rotate until you dismiss the menu. Not what I would call a particularly user friendly way of doing things.

Camera support on iOS devices is totally hit or miss. If you want to determine if a camera is there you need to use iOS 3.2 and above calls. Seems Apple is not very forward thinking on these things and a lot of stuff gets added in later releases but I can't trust a user to be up to date. Instead I am using a call to get the machine name and basing the availability of a camera off of that. Crappy way to do things but it is working for me so far. I know iPad v1 does not have a camera and you have to be up to iPod (the iTouch) version 4 before you have a camera. The simulator never has a camera which sucks. On the Android side it simulates the camera by showing interface then returning a stock image. I had to test camera usage on an actual iOS device and I have to make sure it has a camera otherwise you get a nice crash. I don't even want to show the [Take picture with Camera] button in the UI if you don't have one.

Which brings me to the another WTF? for Apple. Why are Action Sheets index based? If I remove a button from my Action Sheet it shifts the index of all the buttons below that. Hard to write generic code and you always have to edit two places for each action sheet change you make - once where you create the buttons on once where you respond to their presses. Each button should call its own method or at least you should be able to assign tags to them so you can have one case statement. Honestly assigning tags to UI items seems pretty stinking crappy too. I do it where I can to keep track of things but it is not the most object oriented way of programming.

Some of my buttons had the dreaded "..." on them depending on what I ran it on. No device fragmentation here boys, move along. They were working find on the iPad 2 and both iTouch devices but not on the iPad 1 or an iPhone with an older version of iOS. I had to shorten the text on all devices to make sure it fits.

I have no idea if the Doctors will keep their phones up to date. At this point - pre iOS 5 - there are not OTA updates. If a Doctor never connects his iOS device back to a PC running iTunes he will have no idea there is an update out there. Will be interesting to see what iOS versions we have connecting once we roll this thing out into the wild. I have tried to test on as many iOS flavors as possible and each time I seem to find a new issue.

One other big area I can into was the 1 meg blob limit of SQLite. We are taking pictures with the built in cameras and they can easily be over 1 meg on an Android. The lackluster camera on the iPad and the iTouch don't get you into trouble but an iPhone can. I use JPEG compression to shrink the image down as needed to avoid SQLite issues. It is a shame the iPad camera is so limiting in resolution. It is an unusable solution for our doctors, the images of sheets of medical paperwork are not readable with that camera. We also allow you to choose images from the device gallery which could easily be from another device and over the 1 meg limit.

Overall it was not very difficult to get a universal app running on either the Android or iOS platforms. We are not taking full advantage of the tablet form factor but at least we are not just doing a 2X version of our iPhone app, the images scale up nicely without being blurry, you get to utilize the extra space of the device and things look native in general. 

QA is doing final testing then it will be off to the beta clients. It will be really interesting to get their feedback. Now I just need a little time to destress and I get ready to head back into Java + Swing + MigCalendar land to fix some issues in our appointment application.