[Android] Deployment process, from code to your phone

You may consider yourself an expert Android programmer, and you might even have successful apps published in Google Play Store, but sometimes, IDEs are so easy and helpful, that we forget to worry about what’s happening behind the scenes. This graph extracted from http://developer.android.com/tools/publishing/preparing.html and very well explained by the guys at http://www.bignerdranch.com/, explains every step that is happening when we click on the “Run” button. After understanding it, some technicisms that we often see in the log messages (aapt, zipalign, Dx, dex, dalvik) may sound more familiar for us.

Android App deployment to phone

[iOS] A simple way to move your PDF documents to your iPad without iTunes: Using Google Drive

1.- Upload your PDF document to Google Drive

2.- Download Google Drive App in your iOS device, open your Google Drive Folder

3.- Open the PDF from Google Drive, click on the icon at the top-right corner, select “Open in…“. Select iBooks.

4.- Et voila, your PDF will be downloaded and included to your iBooks library.

 

I know there many more ways of doing that, but most of them are annoying:

– Dropbox is all the time coming with “buy more storage, invite people for more storage, do a handstand for more storage, buy buy BUY BUY” and it’s very annoying.

– iTunes politely invites you to “synchronise your iPhone/iPad”, deleting all the content that Apple might not like, to have their users under control (mmh nice try Apple).

So with that simple steps, you can have your PDF for reading without too many annoying obstacles. We are storing on Google Drive, so make sure your PDF does not contain the words “murder” or “president”, or else the FBI will be knocking your door in a couple of hours 😉

Enjoy!

 

[Android] Usual problem with asnychronous requests: Updating a no-longer-existing Fragment

If you are using asynchronous requests (e.g. AsyncTasks, Services+BroadcastReceivers, android-volley, android-async-http or any other flavour), this scenario may sound familiar to you:

1.- in the Activity’s onCreate() or onResume() method, an asynchronous HTTP request is sent
2.- User quickly destroys the Activity (for example, rotating the phone)
3.- Response to the request made in step 1 arrives, the onResponse/onHandleIntent callback is fired, but the Activity/Fragment is no longer existing, because you have destroyed it in step 2. so BOOM!!! App crashes, giving your users this undesirable “Has stopped unexpectedly” message, and generating such a bad experience with your app.

Typical error message:

java.lang.IllegalStateException Fragment MyFragment not attached to Activity

The simplest and smartest solution for that is using Fragment’s isAdded() method:

if(isAdded()){
mGridView.setVisibility(GridView.INVISIBLE);
// … any other update you need to do in the views
}

So if you reproduce the steps above, isAdded() will return false and application won’t crash.

[Android] Managing Preference screens smoothly

If you are planning to implement a PreferenceActivity (preference screen) in your App, i highly recommend you to have a look at this example App made by CommonsWare. Have a look at the EditPreference class and how it handles headers, then the different kind of SharedPreferences (checkboxes, lists, inputs, etc), without needing to elevate complexity introducing additional Fragment classes (Fragments are private classes inside).

Quite an excellent work 🙂

Have a nice coding day!

[iOS SDK] How to test In-App purchases in your iOS device.

One difficult thing to implement in iOS SDK is an App offering In-App Purchases (from now on, IAPs). There are plenty of tasks to be done in iTunes Connect (Tax, Banking and Contracts, Manage Test Users, Manage Apps, Create App IDs, certificates, provisioning profiles, …), then tasks to be done in Xcode, and also a few more in the iOS device (look well, I said iOS device! and not SIMULATOR!).

The first thing you have to know is that In-App Purchases cannot be tested on the iOS Simulator. If you were trying to do that, or were planning to try, spend your time in something better.

But even in the iOS device, it is not trivial to find the way to test if our IAP implementation is working fine. Here are the steps for doing it. Following them carefully will for sure save you time and headaches 🙂

Prerequisites:

  • iOS App created in iTunes connect, all fields filled and screenshots uploaded. Must have “Ready to upload binary” status.
  • At least one in app purchase created for the iOS App, with its SKU and Bundle ID. I suggest you this tutorial for this point and the previous one.
  • An email account that has no AppleID associated. Immediate access to its inbox.
  • An Xcode project with IAPs implemented. I suggest you this tutorial

Steps:

1.- In iTunes connect, go to Manage Users and create a Test User with the email account mentioned previously. Fill in the rest of the fields (name, secret questions, date of birth, …). Specify a password and take note of it, we’ll need it later.

2.- Get into the mentioned email’s inbox. There should be a mail from Apple with an activation link. Click it to activate the AppleID, note that the email from Apple could be on the Spam folder.

3.- Once the user is created, in your iPhone/iPad and go to Settings > iTunes Store and App Store > Apple ID (on top). Tap on it and select Disconnect in order to logout your AppleID from the iOS device.

4.- Run your iOS App, navigate to your purchase menu, and click on the “Buy” or “Purchase” button. It will ask you for your AppleID, select Use an existing Apple ID and fill in the email and password of the Test User activated in steps 1/2. A message asking you to purchase the item in [Environment: sandbox] will appear. You can buy the item or cancel the transaction and test what happens on each case. After the first purchase, you can try to uninstall the App, reinstall, and purchase the item again to see if your restoration works correctly.  That’s all

Steps 3 and 4 are specially important because this is the only way to make the IAP test work. If you try, for instance, to log in the iPad with the AppleID and password of the Test User, it will come with “This AppleID is not activated in the App Store” and ask you for data / credit card. Also, if you try the step 4 with another Apple ID logged in (not the Test User), it will return a “Can’t connect to iTunes Store” message and IAP won’t work.

 

Hope it helps! Let me know any issues 🙂

[iOS SDK] Useful simulator shortcuts and basic operations

After a while developing iOS Apps, i’ve discovered some frequently used shortcuts that make your life easier:

In iOS Simulator:

Alt+shift: double tap (two-finger tap), for scrolling etc.

Ctrl+Alt: Pinch (zoom-in / zoom-out).

Cmd+Shift+H: Device’s Home button press

Cmd+1, Cmd+2, Cmd+3: Rescale simulator to support different screen sizes

In Xcode:

Cmd+Alt+Shift+Left: Collapse all methods in file

Cmd+Alt+Left: Collapse current code block (Cmd+Alt+Right to expand)

Cmd+7: Shows all breakpoints (Cmd+A selects them all, backspace deletes)

some simple routinary Xcode tasks:

Create segue from an UIButton to another ViewController quickly using Storyboards:

1.- [Storyboard] Place an UIButton inside the current ViewController

2.- [Code] Create the IBOutlet in the .h file, implement it in the .m file

3.- [Storyboard] Ctrl+drag from UIButton to UIVIewController.

Create outlet inside ViewController (UILabel, UIButton, UITextView…)

1.- [Code] Create the property for the outlet in the .h file

Example: @property (weak, nonatomic) IBOutlet UIImageView *img;

2.- [SB] Place the UILabel, UIButton, etc. inside the ViewController (resize it, set its title, etc)

3.- [SB] Ctrl+drag from ViewController (yellow square on the bottom) to the UILabel, UIButton, … , select the attribute defined in step 1.

Create a progress bar (slightly different than the rest of the components)

1.- Place the UIProgressView inside the ViewController

2.- Create the @property in the .h file

3.- ctrl+drag from UIProgressView to an empty zone of the ViewController. Select the attribute specified in step 2

Choose if deploying App to iPhone/iPad or to iOS Simulator:

Select Product > Destination

[iOS SDK] How to integrate Mapbox into your Xcode project, for dummies.

As an iOS dummy i was, i downloaded the mapbox basic tutorial, built & ran it, and it worked perfectly. Now i was wondering how to integrate this example in an Xcode project that i start from zero.

After some research i discovered the way of doing it, and i made myself this little guide:

1.- In your new Xcode project, click on the main target, scroll to the bottom and you’ll find “Linked frameworks and libraries”. Click on the [+] button

Captura de pantalla 2014-08-06 a la(s) 17.09.18 

2.- Now click on Add other, and locate the “Mapbox.framework” file. A copy of it is located inside “mapbox-example-ios” folder.

3.- repeat steps 1 and 2 but now locating and including “libsqlite3.dylib”, “CoreLocation.framework“, and “QuartzCore.framework“. Click on the [+] button, and on the search box type each name, it will appear.

4.- Create a new objC class extending UIViewController. In its .h file, include the #import <Mapbox/Mapbox.h>, and implement the “RMMapViewDelegate” delegate.

#import <Mapbox/Mapbox.h>

@interface MyOfflineMapViewController : UIViewController<RMMapViewDelegate>
@end

5.- copy the .mbtiles map file by dragging and dropping it to the project folder in xcode. IMPORTANT: Do not forget to check “copy items into destination group’s folder”, and to mark all the targets before clicking finish!

Captura de pantalla 2014-08-06 a la(s) 17.11.56

*If you don’t do this, you will get this error: reason: ‘*** -[NSURL initFileURLWithPath:]: nil string parameter’ (luckily, Google searches arrive here and anyone finding this error can fix it)

6.- in the .m file, initialize the TilesSource and the MapView as its done in the Mapbox example

- (void)viewDidLoad
{
[super viewDidLoad];    
RMMBTilesSource *offlineSource = [[RMMBTilesSource alloc] initWithTileSetResource:@“mymbtilesmap" ofType:@"mbtiles"];
RMMapView *mapView = [[RMMapView alloc] initWithFrame:self.view.bounds andTilesource:offlineSource];
mapView.zoom = 2;
mapView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth
mapView.adjustTilesForRetinaDisplay = YES; // these tiles aren't designed specifically for retina, so make them legible
[self.view addSubview:mapView];
mapView.delegate  = self;
}

7.- Build and run your app, navigate to the offline map ViewController. Your map should be visible. Let me know any errors / issues in these instructions.

[iOS SDK] Offline-Mapping first conclusions

After a few days of researching about how to implement offline maps for iOS SDK, i’ve found that OpenStreetMaps seems to be the best choice, though it is difficult to find tutorials or clear documentation about how to implement them. An OSM-based library that suited my needs very well is Mapbox. As we can see in the basic tutorial, Mapbox uses the .mbtiles map format, and here comes the tricky part.

A .mbtiles file is a SQLite database containing two tables: One with metadata (like name of the map, or version) and another with raw tiles, stored in a BLOB field in PNG format, and properly indexed.

So the first challenge is to generate your own .mbtiles file for your custom map. To face this, i’ve found many useful links:

– The TileMill tool, which is basic for generating mbtiles files

– You can open a SQLite connection to the .mbtiles file with your favourite SQLite client (mine is Navicat), and explore its content to understand the structure.

Pedro’s Tech Mumblings, that explains how to do various operations with .mbtiles files

The exporting episode of the crashcourse, which explains how to export a map step by step

– I’ve also found that MOBAC (Mobile Atlas Creator) can manage .mbtiles files. Have a look at my MOBAC tutorial, and use the “mbtiles sqlite format” instead of “OsmDroid ZIP”. Rest of the steps are similar. Do not forget to use PNG tiles!

This post has been useful aswell, because it does an interesting thing (creating the .mbtiles from a hi-res image using self-made a python script), and has a lot of detailed info about the .mbtiles format, and useful scripts for extracting & creating mbtiles files. Helps a lot with the learning.

This example from Mapbox official site, and this one were also helpful to paint markers on the offline map and handle events like single tap, customize the bubble and handle its events, etc.

And that’s pretty much what i’ve discovered after these few days working. I’ll keep on posting my progresses 🙂

[Android] Adding the ActionBarCompat to your project

There are plenty of tutorials like this one that use the ActionBarCompat.

You may have noticed that they all import the ActionBarCompat like this:

import android.support.v7.app.ActionBarActivity;

And here comes the question:

Where is the android-support-v7.jar file?

I’ve seen android-support-v4.jar, and android-support-v13.jar, but not v7.

The solution is:

ANDROID-SDK-ROOT\extras\android\support\v7\appcompat\libs

Copy android-support-v7-appcompat.jar to your project’s libs/ folder, and now you are able to import android.support.v7.app.ActionBarActivity and start working with it.

Sounds stupid, but it took me half an hour to find it.

Hope it saves time for you!!!