Monday, January 26, 2015

Features Available in Crittercism That we use less

Loggin Transactions

Transactions allows companies to track key interactions or user flows in their app such as login, account registration and in app purchase. By default, the SDK will automatically track application load time as a transaction. A developer can specify additional transactions by adding a few more lines of code to the application. 

Developers must add code to specify where a transaction starts and where it ends. Below is an example of tracking transactions 

[Crittercism beginTransaction:@“Login”];
BOOL didLogin = [self runMyLoginCode];
if(didLogin)
{
[Crittercism endTransaction:@“Login”];
}
else 
{
[Crittercism failTransaction:@“Login”];
}

Transaction can be nested. But transaction with the same group cannot be multiple. A transaction group is identified by the name given in the beginTransaction method. 

to end the transaction, code can use the endTransaction API. To modify the value of transaction, one can use setValue:forTransaction valueForTransaction 

Logging Breadcrumbs
Developers can use leaveBreadcrumb method to write to a chronological log that is reported with the crashes and handled exceptions 

A breadcrumb is a developer-defined text string upto 140 characters that allows developers to capture app runtime information. 

[Crittercism leaveBreadcrubmb:@“User reached login screen”]; 

by default the breadcrumbs are written on to the file immediately. in order to force the breadcrumbs to use the background thread, below method can be called 

[Crittercism setAsyncBreadcrumbMode:YES]

Handled Exceptions
Application can use logHandledException method to track NSException that do not cause a crash. An example is like below 

@try 
{
[NSException raise:NSINvalidArgumentException format:@“foo must not be nil”];
}
@catch (NSException *exception)
{
[Crittercism logHandledException:exception];
}

Logging Errors 
for logging errors, use logError method. Error may be used for tracking NSError errors returned by the Apple and 3rd party library errors. 

Handling Offline Crashes
library caches upto 3 crashes on the device when offline. But this value can be altered using the setMaxOfflineCrashReports method. 

Detecting that a Crash occurred
CrittercismDelegate protocol gives a method, below method can be overridden 

- (void) crittercismDidCrashOnLastLoad
{
}


 References:
http://docs.crittercism.com/ios/ios.html

Sunday, January 25, 2015

Setting up Google Play Services


To develop an app using the Google Play Services APIs, one need to setup the projects with the Google Play services SDK. 

In order to add the Google Play services SDK package, below steps can be followed. 

Open SDK Manager, Open the Extras directory and select the Google Play Services and Google Repository. Google Play services are not available on every device, but available on all devices with Google Play Store.  An Android devices that run on 2.3 OS or later, Or Android emulator with an AVD that runs Google APIs platform based on Android 4.2.2 or higher will have the Google Play services available. 

Next Step is to add Play Services to The Project
1. Open the build.gradle file in the Application module directory 
2. Add a new build rule under dependancies for the version of play-services.

For e.g. 
apply plugin ‘com.android.application’

dependancies{
compile : ‘com.google.android.gms:play-services:6.5.87’
}

We need to be sure to update this version number everytime Google Play service is updated. 

3. Save the changes and Click Sync Project with Gradle files in the tool bar 
4. Open the app’s manifest file and add the following tag as child for application element 

android:value=“@integer/google_play_services_version”/>

Now one can begin developing with Google Play services! 


References:

Friday, January 23, 2015

What is Big Data




Big data is a popular terms used to describe exponential growth and availability of data, both structured and unstructured. And big data may be as important to business - and society - as the internet has become. Why? More data may lead to more accurate analysis. 

More accurate analysis leads to more confident decision making. And better decisions can mean greater operational efficiencies, cost reductions and reduced risk.

The three Vs of big data are: 

Volume: Volume denotes the data volume. There are many sources for data, transaction - based data stored for many years, unstructured data from social media networks, data collected from sensors. Recently, the data storage costs have been reduced and storing large amount of data can be done now with less cost. Even though decreasing the storage cost, the other issue emerging is how to make out meaningful information from these data. 

Velocity :data is streaming in an unprecedented speed and must be dealt with in timely manner. RFID tags, sensors and smart metering are driving the need to deal with torrents of data in near real time.  Reacting quickly enough to deal with the data velocity is a challenge for many organisations. 

Variety: Data today comes in all types of formats. Structured numeric data in traditional databases. Info created from line of business apps. Unstructured text documents such as email video, audio, stock ticker data and financial transactions. Managing, merging and governing different varieties of data is something many organisations still grapple with.  

What is matters with the Big Data? 
The real issue is not about collecting the data, it is about how to interpret the data. For instance: by combining big data and high powered analytics, it is possible to 

1. Determine root causes of failures, issues and defects in near-real time, potentially saving millions of dollars annually. 

2. Optimise routes for many thousands of package delivery vehicles while they are on the road. 

3. Analyse millions of SKUs to determine prices that maximise profit and clear inventory. 

4. Generate retain coupons at the point of sale based on customers current and past purchases. 

5. Send tailored recommendations to mobile devices while customers are in the right area to take advantage of offers. 

6. Recalculate entire risk portfolios in minutes

7. Quickly identify customers who matter the most 

8. Use clickstream and data mining to detect the fraudulent behaviour. 

References: 

Wednesday, January 21, 2015

Android Setting Cookie to WebView

In order to set the cookie into the Android WebView, below code can be used.

                        CookieManager.getInstance().setAcceptCookie(true);
                        CookieManager.getInstance().setCookie("myhttp.info","testcookie=cookietest");

                        webView.setWebViewClient(new WebViewClient());
                        webView.loadUrl("http://myhttp.info/");


the web page http://myhttp.info/ is a good tool to know what headers the request is containing.
In the above code, it is trying to pass the cookie as cookietest for the key testcookie. The appearance of this page is something like below



References:
http://myhttp.info/

Tuesday, January 20, 2015

UIWebView cookie setting from hosting app

It is possible to set cookies to the iOS layer so that the UIWebview displayed within the app can pick it up and apply the session value. Below code tries to set a session key to the google.com domain. 

 NSMutableDictionary *cookieProperties = [NSMutableDictionary dictionary];
                [cookieProperties setObject:@"authToken" forKey:NSHTTPCookieName];
                NSString *sessionID = [userdetails.sessionId stringByReplacingOccurrencesOfString:@"Wayfarer=" withString:@""];
                [cookieProperties setObject:sessionID forKey:NSHTTPCookieValue];
                [cookieProperties setObject:@"www.google.com" forKey:NSHTTPCookieDomain];
                [cookieProperties setObject:@"www.google.com" forKey:NSHTTPCookieOriginURL];
                [cookieProperties setObject:@"/" forKey:NSHTTPCookiePath];
                [cookieProperties setObject:@"0" forKey:NSHTTPCookieVersion];
                [cookieProperties setObject:[[NSDate date] dateByAddingTimeInterval:2629743] forKey:NSHTTPCookieExpires];
                NSHTTPCookie *cookie = [NSHTTPCookie cookieWithProperties:cookieProperties];
                

                [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookie];

Even though application sets the cookie information, it is not possible that Safari or other application pick up this value in the request they make. 

Friday, January 16, 2015

Android Managing System UI - Hiding the Navigation Bar

In Android system bars are screen areas dedicated to the display of notifications, communication of device status, and device navigation. These are displayed concurrently with the application. Apps that display immersive content, such as images or movies can temporarily dim the system bar icons for a less distractng experience, or temporarily hide the bars for a fully immersive experience. 

Hiding the Navigation Bar
Navigation bar was introduced in Android System 4.0. Normally, it is better to hide the status bar and the navigation bar together. 

Below code can hide the navigation bar. 

super.onCreate(savedInstanceState);
        View decorView = getWindow().getDecorView();
        int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                | View.SYSTEM_UI_FLAG_FULLSCREEN;
        decorView.setSystemUiVisibility(uiOptions);
        setContentView(R.layout.activity_main);

Few notes:

- In this approach, touching anywhere on the screen will cause the navigation bar and the status bar to reappear again.  i.e. User interaction makes the elements re-appear again and the already set flags will be cleared. 

- Application can listen to the UI Visibility state changes to listen to the ui activity events and then can decide to make it reappear again, 

- Application needs to call the flags at specific points in the application, OnCreate is one place, onResume is another, onWindowFocusChanged should also be overriden to listen to the system event and then hide the system ui components again 

- The methods have effect only if the calls is from a View that is visible

- Navigating away from the view causes the flag set with the setSystemUiVisibility to be cleared. 

with the below few lines of code, application is able to show a full screen Activity

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        View decorView = getWindow().getDecorView();
        int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                | View.SYSTEM_UI_FLAG_FULLSCREEN;
        decorView.setSystemUiVisibility(uiOptions);
        setContentView(R.layout.activity_main);
        ActionBar ab = getActionBar();
        if(ab != null) {
            ab.hide();
        }
        android.support.v7.app.ActionBar sab = getSupportActionBar();
        if(sab != null) {
            sab.hide();
        }
    }


References:


Thursday, January 8, 2015

GridView with android Hands On

When decided to learn about GridView, thought will look at the Android Sample itself. Found the sample at the link given in Android website very useful.

The code was pretty simple. First had to add the grid view to the layout xml file

The code was like the below

        android:id="@+id/gridview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:columnWidth="90dp"
        android:numColumns="auto_fit"
        android:verticalSpacing="10dp"
        android:horizontalSpacing="10dp"
        android:stretchMode="columnWidth"
        android:gravity="center"
        />

Now, in the main activity on create, below code needs to be added

GridView gridview = (GridView) findViewById(R.id.gridview);
        gridview.setAdapter(new ImageAdapter(this));

        gridview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            public void onItemClick(AdapterView parent, View v, int position, long id) {
                Toast.makeText(GridViewSampleActivity.this, "" + position, Toast.LENGTH_SHORT).show();
            }
        });

Just create the subclass of BaseAdapter and override the getView function

 public View getView(int position, View convertView, ViewGroup parent) {
        ImageView imageView;
        if (convertView == null) {  // if it's not recycled, initialize some attributes
            imageView = new ImageView(mContext);
            imageView.setLayoutParams(new GridView.LayoutParams(200, 200));
            imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
            imageView.setPadding(8, 8, 8, 8);
        } else {
            imageView = (ImageView) convertView;
        }

        imageView.setImageResource(mThumbIds[position]);
        return imageView;
    }

I gave the layout param as 200 x 200 gave a good looking grid view, however, on orientation chagne, all the grid items were overlapping without any gap. Need to check this. 

Reference:
http://developer.android.com/guide/topics/ui/layout/gridview.html

Home Automation System Protocols



Just like other electronic systems, smart devices all run on variety of different protocols. That is, sets of rules and standards for communication between electronic devices. 
If we got a device which speaks ZigBee and another speaking ZWave, and they don’t communicate each other, then the fully automated environment can’t be achieved.
There are only few devices which can be multi lingual 

X10 
This is grand daddy of home automation protocols. X10 has been around since mid 70s. It started as a power line based system (meaning, it is hard wired into the walls) but eventual went wireless. 
If someone is just beginning home automation, then better start with devices which are compatible with newer standards, as X10 systems are typically more difficult to install in comparison. 

UPB
Universal Powerline Bus is a power line only communication protocol designed to use a higher voltage and put out a stronger signal than X10. The only problem is that since it is power line only, it is rather expensive and hard to install. 
We don’t need to worry much about this one, because it is not baked into many of our devices, and there are better options out there. 

INSTEON
Insteon is a home automation protocol designed to bridge gap between power line based and wireless protocols, so it uses both. It is also compatible with X10 devices. So, it is not a bad choice if we got home filled with X10 based devices and trying to transition to the Wireless ones. 
There seems to be a good range of products available with INSTEON and it can be browsed through their website, link given in the reference section 

Z-Wave
Z-Wave is a home automation protocols that runs on the 908.42 MHz frequency band. it is relatively new in terms of home automation protocols. but has grown quite rapidly in past few years. The group behind it, Z-Wave Alliance now boasta about 1000+ devise are compatible with it. 
One of the key features of ZWave is that it uses a mesh network. The advantage of mesh network is that, one unit will transmit the signal to the other until it reaches the final destination. This relay mechanism extend the range of the protocol and device. IT is also extremely low power one, and is ideally for device that rely on battery power. 

ZIGBEE
Zigbee is an IEEE 802 standard built by IEEE. Much like ZWave, this has significant growth in recent years and can be found relatively large number of devices. It also consumes less power and uses mesh network structure to offer excellent range and speedy communication between devices. However, some users have noted that Zigbee devices frequently have difficulty in communicating with those made by different manufacturers. So, it may not be the best option if looking for seamless interoperability. 

WiFi 
WiFi is fairly ubiquitous, so, it is not surprising that a broad range of manufacturers have begun making smart home devices that work with it. If we already have a wireless router, then we don’t need to pick up a hub/access point in order for the compatible devices to connect to it. 
This has a bandwidth issue because if the house if already connected full of WiFi devices, then smart devices will have low bandwidth and potentially slower to respond. WiFi also consumes lot of power, it is not ideal for battery operated devices. 

BLE
BLE doesn’t use much power, but also has fairly limited range compared to other networking protocols. So, it is treated as not a great stuff that needs to stay connected all the time like security sensors and motion sensors. 

Conclusion,
As far the reading goes, the better one looks to be ZIGBEE or ZWave, while if we have lot of older X10 compatible devices, then ISTEON could be an option as well. 

Reference:

Tuesday, January 6, 2015

What is Internet Of Me


Looks like some of the new devices at display at CES 2015, use apps that monitor nearly all aspects of personal life, including sleep. The new technologies are getting so personal that it is moving to connect and analyse our movements, our health, our brains, and our everyday devices. This is called internet of Me. 

One of the major themes at the international Consumer electronics show in Las Vegas is connecting thousands of objects that people use each day — clothing, cars, light bulbs and home appliances. 

The purpose of this interconnectivity is to make one’s life easier and less complicated. Instead of ignoring those preferences we set in our smartphones, tablets and wearables, they will now become more global, anticipatory, and refined, Smart Devices will “Know” us, at least sense that they will sense our daily patterns, habits, and rituals. 

Smart devices will know if you are buying on Lolly wolly Doodle, when soccer camp is (so, they’ will buy all the supplies from Target and have them drop-shipped to your location), and how frequently you buy Cherry Gracia etc. 

They will suggest new wines listed on Wine Advocate. If one like black sand beaches and 78-degree mean temperatures, they will come up with fresh new vacation suggestion a world away from regular vacation spot. 

This is not just a change in lifestyle, It is also a change in the way people look at the markets and new business opportunities. Big data will play a major part in this transformation. So will logistics and delivery services of all shapes and sizes. Most of all, every merchant will have deeper understanding of how the consumer is. 

Reference:

Android Writing into Files

I had to write few contents into the file and for this, below is the code followed public void logToFile(String message)
    {
        boolean isFreshLogFile = false;
        String openStr = "-- Open Str --";
        if(fout == null)
        {
            isFreshLogFile = true;
            Log.v("RR:--","File Dir ="+getApplicationContext().getFilesDir().getPath());
            Log.v("RR:--","Cache Dir ="+getApplicationContext().getCacheDir().getPath());
            Log.v("RR:--","Ext Cache Dir ="+getApplicationContext().getExternalCacheDir().getPath());
            Log.v("RR:--","Ext Files Dir ="+getApplicationContext().getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS).getPath());

            File file = new File(getApplicationContext().getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS),"locationtrace.txt");
            try {
                Log.v("RR:---","creating new file");
                file.createNewFile();
                Log.v("RR:---","created new file");
            } catch (IOException e) {
                Log.v("RR:---","New file create exception");
                e.printStackTrace();
            }
            openStr = "===== Creation time ===" + new Date().toString();
            try {
                fout = new FileOutputStream(file,true) ;//openFileOutput(file.getName(),Context.MODE_APPEND);

            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if(fout != null)
        {
            Log.v("RR:--","output stream is not null, going to write into");
            try
            {
                if(isFreshLogFile)
                {
                    fout.write(openStr.getBytes());
                }
                fout.write(message.getBytes());
//                fout.close();
            }
            catch (Exception ex)
            {
                ex.printStackTrace();;
            }
        }
    }


The logs were printed like the below 

/RR:--   ( 2056): File Dir =/data/data/mportal.mybuddy/files
V/RR:--   ( 2056): Cache Dir =/data/data/mportal.mybuddy/cache
V/RR:--   ( 2056): Ext Cache Dir =/storage/sdcard0/Android/data/mportal.mybuddy/cache
V/RR:--   ( 2056): Ext Files Dir =/storage/sdcard0/Android/data/mportal.mybuddy/files/Documents


References:

Addressbook Reading in iOS

To get the basic fields, below few code can be used. 

ABAddressBookRef addressBookRef = ABAddressBookCreateWithOptions(NULL, error);

Now get the permission if we have not already

 if (ABAddressBookRequestAccessWithCompletion != NULL) {
                dispatch_semaphore_t sema = dispatch_semaphore_create(0);
                ABAddressBookRequestAccessWithCompletion(addressBookRef, ^(bool granted, CFErrorRef error) {
                    dispatch_semaphore_signal(sema);
                });
                dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
}

//Now get the array of all people. 
CFArrayRef allPeople =
            ABAddressBookCopyArrayOfAllPeople(addressBookRef);
            CFIndex nPeople = ABAddressBookGetPersonCount(addressBookRef);
if (allPeople != nil)
{
    for ( int i = 0; i < nPeople; i++ )
    {
         ABRecordRef ref = CFArrayGetValueAtIndex(allPeople, i);
         ABRecordID recordId = ABRecordGetRecordID(ref);
         CFStringRef lastNameMultiValueCF = ABRecordCopyValue(ref, kABPersonLastNameProperty);
         CFStringRef firstNmaeMultiValueCF = ABRecordCopyValue(ref, kABPersonFirstNameProperty);
         CFStringRef companyNameMultiValueC = ABRecordCopyValue(ref, kABPersonOrganizationProperty);
         CFStringRef nickNameMultiValueC = ABRecordCopyValue(ref, kABPersonNicknameProperty);
     }
}

Each of these CFStringRef can be converted to NSString using the type casting. Given below 

NSString *firstName =  (__bridge NSString *)firstNmaeMultiValueCF;

Getting all phone numbers:

ABMultiValueRef phoneNumsRef= ABRecordCopyValue(ref,kABPersonPhoneProperty);
if(phoneNumsRef)
{
NSArray *phNumbers = (__bridge_transfer NSArray*)ABMultiValueCopyArrayOfAllValues(phoneNumsRef);
if(phNumbers)
{
for(int j = 0; j < [phNumber count]; j++)
        {
//get the phone number
NSString *ph = [phNumber objectAtIndex:j];
//Now get the label for this address book item
NSString *label = nil;
CFStringRef unlocalizedLabel = ABMultiValueCopyLabelAtIndex(phoneNumbarsRef, j);
           if (unlocalizedLabel)
           {
               label = CFBridgingRelease(ABAddressBookCopyLocalizedLabel(unlocalizedLabel));
                                    CFRelease(unlocalizedLabel);
           }

    }
}
}

Getting all email values
Reading all emails is similar way as reading the phone number and the code is like below 

ABMultiValueRef emailRef= ABRecordCopyValue(ref,kABPersonEmailProperty);
NSArray *emails = (__bridge_transfer NSArray*)ABMultiValueCopyArrayOfAllValues(emailRef);
//individual emails can be iterated and found out like in code below.
for(int j = 0; j < [emailCount count]; j++)
{
NSString *ph = [emails objectAtIndex:j];
}

Similar to the Phone numbers, we can get the email labels using the below lines
CFStringRef unlocalizedLabel = ABMultiValueCopyLabelAtIndex(emailRef, j);
if (unlocalizedLabel)
{
     label = CFBridgingRelease(ABAddressBookCopyLocalizedLabel(unlocalizedLabel));
     CFRelease(unlocalizedLabel);
}

Getting Address components for a person contact
ABMultiValueRef addessRef= ABRecordCopyValue(ref,kABPersonAddressProperty);
NSArray *addressArray = (__bridge_transfer NSArray*)ABMultiValueCopyArrayOfAllValues(addessRef);

Now, we can iterate through the address array items and we can get the individual components for it. 


for(int j = 0; j < [addressArray count]; j++)
{
     Address *add = [[Address alloc] init];
     NSDictionary *addressDic = [addressArray objectAtIndex:j];
     if([addressDic objectForKey:@"City"])
         add.city =[addressDic objectForKey:@"City"];
     if([addressDic objectForKey:@"CountryCode"])
         add.country = [addressDic objectForKey:@"CountryCode"];
     if([addressDic objectForKey:@"State"])
         add.state = [addressDic objectForKey:@"State"];
     if([addressDic objectForKey:@"Street"])
         add.street = [addressDic objectForKey:@"Street"];
     if([addressDic objectForKey:@"ZIP"])
         add.zipCode = [addressDic objectForKey:@"ZIP"];
      contact.addresses addObject:add];
}


Reading Image Data: 

To know whether the person item having the image data, the ABPersonHasImageData API can be used. 
NSData *imageData = (__bridge NSData*)ABPersonCopyImageDataWithFormat(ref, kABPersonImageFormatThumbnail);
image = [UIImage imageWithData:imageData];
if(image)
{
//do something with the image
}    
CFRelease((__bridge CFTypeRef)(imageData)); 


Monday, January 5, 2015

Android: Distance between two Geo Locations

In order to find the distance between two geo locations, the below code can be used

This does not give the traffic route distance, instead gives the geographical distance. 
But this is good enough to know whether the user is somewhere near the vicinity of the tagged location etc. 

public double getDistance (double lat1, double lon1, double lat2, double lon2)
    {
        double distance = 0;
        Location locationA = new Location("A");
        locationA.setLatitude(lat1);
        locationA.setLongitude(lon1);
        Location locationB = new Location("B");
        locationB.setLatitude(lat2);
        locationB.setLongitude(lon2);
        distance = locationA.distanceTo(locationB);
        return distance;
    }




References:
http://stackoverflow.com/questions/18310126/get-the-distance-between-two-locations-in-android

Friday, January 2, 2015

Android Location Notification - Practical Scenario

The intention was to create an app that can send an SMS when some one is near vicinity of a location for e.g. Home or Office. Basic requirements were like below

- When user reach in office from home, send out a message saying reached in the Office vicinity
- When user start from office, then send a message saying started from office.
- When reached home, send a message saying reached Home.

Below was the algorithm designed for it.


This was working okay for most part, but was failing in some practical scenarios:

1. The phone sometimes does not connect to the WiFi automatically. This makes the mechanism unreliable because even if user reach office, since the WiFi doesnt get associated, instead stay in the dormant state, the connection change notification doesnt get fired to the application.

2. App was getting notifications when just travelling, as it passes by the WiFi networks. this situation is handled in the app itself. but makes the logic run un-necessarily.

This makes me to think that some other mechanism is really needed to make it really work well. Probably say a complete location monitoring based code and define vicinity etc.