Thursday, 10 December 2015

Watstime - We wake up relations


Have you ever felt need of remembering something to remind someone! Have you ever been in situation where you wanted some message to deliver at scheduled time but could not send because of some xyz reason! Have you ever missed to wish someone because of time slippage! And lot of other reasons!
Presenting you World’s first Alarm messenger ‘Watstime’
If I have to sum up Watstime in two lines, it is a message scheduler cum alarm which you can use for yourself OR someone else. It has got context, attachments and meaning as per given situation.You can opt for it to play as Notification OR play as full screen as situation and task demands.
Lets go through its features in detail.
Beauty of Watstime is you can use it for Yourself and Contacts both. We interacted with people like you and figure out what exactly they want.

TYPE — Day, Date and After

  1. Time and Day : When you know what time and what day you want to play (say 6 A:M every wednesday)
  2. Time and Date : When you know exact time and date ( say 12:00 AM — 30 oct, 2016)
  3. After : When you do not know time and all what matters is the event ( say play after 15 minutes, call her after 2 hours etc)

Play — Full screen and Notification

You can not disagree that each task has different priority in your life. Then why let the alarm play full screen and interrupt you when you are in middle of something. Watstime offers you choice between — Full screen play OR Notification Play. You can opt based on task. Not even that, you can switch between both play types when it actually plays.

Custom Snooze

Lets face it, if each task has different priority then why to snooze for same time period. Watstime offers you custom snooze which you can opt at runtime when it plays and decide when next you want Watstime to play again for you. Consider an example of bill payment, you definitely want to snooze it for few hours if you are busy right now. Snooze for 15 minutes might suite for use case like “Call her”

Photograph

A Photo can give emotions and meaning to any conversation. So we thought lets add it to your Watstime and make it more contextual. You can attach a photo when scheduling Watstime of your contacts as well.

Timezone

If you have ever got chance to interact with people in some other country OR need to do something based on some other country timezone; you know the pain point. From now onwards no more timezone calculations; Watstime does all the hard work for you. Simply choose timezone of country you want Watstime to play accordingly and it will come when you need.

Attachments

Contacts

Very simple use case could be “Call her at 7 PM”; simply attach contact with Watstime and initiate call when it rings from there only. No need to switch between apps.

Location

You can attach location with Watstime and schedule it for yourself OR your contacts and when it plays it gives you flexibility to navigate to Maps from there only.

Checklist

Our conversation with people claims that most of us forget one or other task when there are many. Consider example of market shopping, going to gym and taking useful stuff with you, morning routine, before bed routine etc. Our brain works well when we have defined tasks to do. We listened to people pain point and added todo list with Watstime, you can attach a todo list for yourself OR your contacts and it will help you finishing the task on right time. Watstime functionality of switching between Notification and Full screen helps you do finish all the items with right momentum.

A Real life Example

Lets think some real life example which a friend of mine shared. Assume there is a marriage and no doubt bride/groom will be busy that day. On the other side, they want their friends to message as well reminding them they have to visit.
Watstime helps you managing stuff easily, He/She can set Watstime of friends in advance, say she did one week in advance when she was free. She attached a photograph of venue, location where they have to reach and Contact number of person whom they can call once they reach and checklist contains gifts she wants from them :P and tadaa she can relax and Watstime will play its role.
In essence, Watstime is a product which brings so many utilities and you can use in your daily life.
Hold on! This is just the beginning, lot more is on its way.
Catch us at hello@watstime.com
Thank you.

Sunday, 1 November 2015

Android PSD to XML Converter

If you are here, I believe you are in Android development OR want to develop some. You can be developer yourself OR you have developer who can code like breeze. But wait for a second, you are stuck at UI. It is time consuming Job and still results are not satisfactory.

You had already done some basic Google search for PSD to Android xml conversion, some tool which can do it automatically for you but nothing has worked yet.






Your designer gives you a PSD and few assets and you have to convert it to Android xml. At first glance it seems a simple task but once you are into it; you understand hidden complexities. If you were a web developer, believe me it is not your cup of tea. As Android UI components require understanding of Android as a framework and working knowledge of JAVA.

I have been in Android development since a long time and inputs from many people says the same. They find it difficult to do UI job, specially if you are from some other programming background including only Java.

Don't worry, we are here to help. If you have a good design and want to give it life in Android then you are at right place. Steps are very simple :

1) Have a good design from a designer who understand your requirements
2) Send PSD and other Assets to me
3) Lets talk business
3.5) You will get your xml


We charge per screen basis. Charges are as follows :

- $99 * per xml
- $111 * per xml with sample project which integrates xml and give it life

You can reach me here :

in.linkedin.com/in/khannasahab/en
or mail me at   khannasahab.gaurav@gmail.com

[NOTE: If your design requires some third party library OR custom modules, we need to discuss]


Happy Coding!

Wednesday, 19 August 2015

Symfony 2 Production Environment Issue - 405

[Note: This post is my personal experience with Symfony 2 and some strange issues I faced in production environment. Error messages were misleading to some extent. I was stuck with "405 Method Not Allowed" and  "POST request was becoming GET request"  whenever I was trying POST request but GET request was working without any hassle and it was happening only in prod env not in dev]

Here we will be talking about Symfony 2.6 (I believe it applies to other versions as well). Before proceeding, let me shed some light on what exactly happened with me and how did I solve it. I developed some API on my development machine (personal macbook pro) and everything worked perfectly fine. Taking "localhost" example and project "myTestAPI"; So when I was testing in dev environment, my URL was

http://localhost/myTestAPI/web/app_dev.php/myTestRoute
params sent : param1=value1

Above request is POST request and it worked perfectly fine with dev environment. Lets try same in prod environment on localhost itself (I hope you are familiar with environment in symfony see here)

In prod environment, api address became :

http://localhost/myTestAPI/web/myTestRoute
params sent : param1=value1

At first time, it did not work and famous issue was cache clear. I had to run clear cache command in prod environment.

php app/console cache:clear -env=prod

Here we go, it worked like charm. Now it is time to take our awesome API to server, we chose AWS ec2 free service to test our API. Simply installed LAMP stack there and making some changes in httpd.conf as asked for Symfony:


AllowOverride All (in www folder) and we are almost ready here.

Assuming host becomes "ec2-87-52-XX-YY-aws.amazon.com"

So, I tried a GET request after initial set up 

http://ec2-87-52-XX-YY-aws.amazon.com/myTestAPI/web/app_dev.php/myTestRoute  in dev environment and

http://ec2-87-52-XX-YY-aws.amazon.com/myTestAPI/web/app.php/myTestRoute  in prod environment and believe me it worked in first try. I drank a coffee of satisfaction.

But things are not that simple for programmers,  

I tried implementing my first POST api and boom, to my surprise it threw an error with http code "405 - Method not allowed" and I was wondering what exactly happened. On my localhost same code is running perfectly fine but here on ec2 server it was not and here our actual story starts :

First thing came in my mind was routing, so i cross checked routing and no doubt it was fine. I was not sure what to google even, tried few terms

"Symfony -  405 error"  (No luck here)
"Symfony - POST method becomes GET"  (even i was ashamed searching this but no luck here as well)
and few more and finally could not find any solution of this issue.


So this was time to dig down into logs and code myself. Started with Symfony logs and it says:

"request.ERROR: Uncaught PHP Exception Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException: "No route found for "GET /api/v1/user/test": Method Not Allowed (Allow: POST)" at /var/www/html/testAPI/app/cache/prod/classes.php line 2834 {"exception":"[object] (Symfony\\Component\\HttpKernel\\Exception\\MethodNotAllowedHttpException(code: 0): No route found for \"GET /api/v1/user/test\": Method Not Allowed (Allow: POST) at /var/www/html/testAPI/app/cache/prod/classes.php:2834, Symfony\\Component\\Routing\\Exception\\MethodNotAllowedException(code: 0):  at /var/www/html/testAPI/app/cache/prod/appProdUrlMatcher.php:330)"} []"

In short, Symfony was doing its work perfectly saying "you are requesting this api with method GET but routing says POST, so I can not allow you to go further."

But the question arises, we are using POST request then how on earth it is becoming GET. So I thought to check Apache logs and not to my surprise it did same what I was expecting: REDIRECT.

I could see in apache logs that whenever I am making any request in prod environment, it is redirecting it. Point to note here is that it was not about POST or GET but because of 301 redirect and "PRG" (Post Redirect Get) my next request was becoming GET automatically and hence Symfony routing was failed. 

What was causing it : Actually I was using app_dev.php in my path in dev environment and app.php in path for prod environment. There is some rewrite rule in Symfony which redirects to same path without app.php.

SO if you make any request to 

http://{host}/{application}/web/app.php/{route}

Symfony will redirect it to 

http://{host}/{application}/web/{route}

and thus request was transforming from POST to GET. So in essence, do not use app.php in path when you intent to use prod environment.

At last, I believe instead of choosing 301 for this purpose, Symfony must have chosen 307. Feel free to correct if anything you believe is misleading here,

"happy coding"







Tuesday, 11 August 2015

Activity Life Cycle - Twist


To understand this blog basic necessity is knowledge of Activity Life Cycle. Does not it sound weird!!! We are here to learn lifecycle and basic necessity is lifecycle itself. Yes it is, but you will understand in no time :) 

Lets put it this way, this blog puts light on Activity lifecycle in abnormal circumstances. Wait Wait!!! What exactly we mean by this. Don't worry you will understand soon.

Everyone who is working in Android knows this basic diagram , make sure you understand it before you move further :



This is Activity lifecycle in happy environment; when things are in your favour and your requirement is served with normal flags.

But software is not that easy, we get strange requirements all the time. In this post we will be specifically talking about these abnormal situations :

a) Android is running low on memory and it kills your activity
b) You are using FLAG CLEAR TOP while starting Activity OR singleTop in Manifest
c) You are dealing with point b and point a occurs (booooom!!!)

Most of you must be familiar with case a where Android is running low on memory and to make sure device performs well it keeps on clearing memory as soon as possible. So how does it impacts us as developer ?
Documentation of this particular case is pretty clear on the web. So not wasting much time of yours, Android provides you two more lifecycle methods in such scenarios.

i) onSaveInstanceState
ii) onRestoreInstanceState

As name suggests, these methods are simply plugged into your normal lifecycle and system gives you chance to preserve user state for best UX. It is like saying, "Hey dude, I need your space for time being; Could you please pick your belongings for now and when I return you, you can re arrange your items as they were before"

This task is done in onSaveInstanceState method which is called after onPause when Activity is going to destroy which is followed by expected onStop method. We have to fill data (which we want to preserve) in Bundle which is passed to us in parameters. 

Assuming Android is running out of memory and gonna kill your activity, So after onStop method System may Or may not call onDestroy method (However I have seen this method is being called all the time) and woossssss our activity is gone.

Now when user navigates back to our Activity, he expects to see the same state where he left. Nobody like filling those big forms Or even a small email id field if they have already done for you. In this case when system recreates our Activity it simply goes through normal lifecycle which is shown above in diagram with two modifications :

i) It passes the bundle back to us in onCreate method; this is the bundle which we filled in onSaveInstanceState. So we have our data back.
ii) It calls another method named "onRestoreInstanceState" after inStart is called. It too contains same bundle for us to preserve state back for user.


onCreate
onStart
onRestoreInstanceState
OnResume



And at the end of day, we have happy user :)



 - FLAG CLEAR TOP while starting Activity OR singleTop in Manifest -

There are two possibilities, Activity does not exist in task OR it does. If it does not exist, this is similar to starting a new activity with standard flag. Same lifecycle will be called as shown in above diagram.

If Activity instance is already there in task stack (Suppose it was started with Intent i1), in this case Android will simple call method "onNewIntent" followed by "onRestart" and then "onStart" -> "onResume". And from now onwards, getIntent will return you the new Intent which was received recently to start your activity. It sounds simple and believe me it is.


onNewIntent  (with New Intent say i2)
onReStart (i2)
onStart  (i2)
onResume  (i2)


- FLAG CLEAR TOP while starting Activity OR singleTop in Manifest  and Android goes low on memory-


This is the case which was driving me crazy and led me to write this post. Have patience and read, suppose you started an activity A with intent I1 and you navigate to other activity. Assume case a occurs and system is low on  memory and it destroys your activity with normal lifecycle as explained above.

Now if you start another intent (i2) for A1 with either FLAG CLEAR TOP or A1 is singletop; Now as we know our A1 logically exists in backstack but it has been destroyed. So to handle this case, system changes lifecycle a bit:

onCreate (with Intent i1)  - weird
onStart (with Intent i1)  - weird
onRestoreInstanceState   (with Intent i1) - weird
onNewIntent (with Intent i2) and from here onwards, we can show new data as per intent
onResume (with i2)


But the story does not end here, even it goes more complex sometimes. Now we have Activity A1 with Intent i2. Suppose user presses home button and activity goes in background with normal lifecycle.
Assume System is low on memory now, so Android destroys your activity with proper callbacks in onSaveInstanceState (Remember we are dealing with i2).

Now when user navigates back to activity and system re creates activity, it starts Activity with normal lifecycle methods

onCreate  (intent i1)
onStart (intent i1)
onRestoreInstanceState (intent i1)
OnResume (intent i1)

But the strange part here is it calls every thing with Intent i1 (This is intent with which Activity was originally created) But user is expecting to open it with Intent i2 data. 

So in this case, you can utilise onSaveInstance and onRestoreInstanceState to properly fill your data and take actions accordingly.

[NOTE : All this was tested by turning on "Don't keep Activities on" flag in developer options, feel free to correct anything which you believe is misleading]

"happy coding"

Tuesday, 21 April 2015

Propel 2 and Symfony 2.6

Have you ever tried installing Propel 2 with Symfony 2.6 and wondered what the hell is wrong with my machine OR with my code. I am being particular about versions as I am not a full fledged Web developer.

History:
A friend of mine was playing with Symfony and came across Propel (ORM) and after spending some time, he called me to help him in configuring same. It was not as easy as we thought it would be. Here are our findings:

(NOTE : This post is all about my personal experience and these are my viewpoints)

a) Propel2 Documentation on official Symfony site is not up to date, it still shows some old configuration to install propel.

Official Documentation link :

It says use
{
    "require": {
        // ...
        "propel/propel-bundle": "1.2.*"
    }
}
in composer json file (Note: You should change propel version required as per symfony version you are using)

However It never worked for us, It could not download bundle along with it. After spending sometime searching for this (more appropriately struggling for sometime) , We came across some blog post (Do not remember link now) which suggested to try :


"require" : {
                "propel/propel": "~2.0@dev",
                "propel/propel-bundle": "~2.0@dev"
                }

in composer.json and to our surprise it worked for us, No more Bundle Not found error. 

Now Next Step was  not that difficult, we missed entry of Propel Bundle in AppKernel (infact many people does same). Simply Add 

new Propel\PropelBundle\PropelBundle(),

in $bundles array in app/AppKernel.php

Now it should work like charm, So we followed this link and tried to setup DB connection so we can start work happily.

But wait, life is not that simple. It says "dbal is unrecognised under propel". When googled this error, every second page was talking about some multi connections in propel. But we did not have any clue, we wanted only single connection.

As we know, patience always pays. Finally we found propel_link , however no where was mentioned about symfony integration, this is what we tried in our config,yml file:

#Propel ORM configurations
propel:
    database:
        connections:
            con1:
                adapter:   "%database_driver%"
                user:     "%database_user%"
                password: "%database_password%"
                dsn:      "%database_driver%:host=%database_host%;user=root;dbname=%database_name%;password=mysql;charset=%db_charset%"
    runtime:
        defaultConnection: con1
        connections:
            - con1
    generator:
        defaultConnection: con1
        connections:
           - con1

We had to give name to connection (con1 in our case) and had to mention that it is default connection. Finally our first command 

php app/console propel:database:create

executed and database was created.

And this is not good ending of story. My friend had existing database so he wanted to generate xml file from existing tables. So we read propel_existing_db and as given we tried running command :

php app/console propel:database:reverse "mysql:host=localhost;dbname=db;user=root;password=pwd"

and it never worked (probably only for us , thrown some error)

Before quitting, we simply tried to write connection name (like our soul felt to do so) which we gave in config.yml (con1), So tried 
php app/console propel:database:reverse con1


And finally it worked. With default configuration it created a folder named "generated-reverse-database" and a file "schema.xml" inside it (Ofcourse you can rename these by providing parameters to above command). Run

php app/console propel:database:reverse --help

and you will get to know all possible inout parameters.

So we were happy here and thought to generate model classes so that we can start work. We followed propel_build and ran following command :

php app/console propel:model:build 


and we encountered this exception :
No schema files were found (matching your schema fileset definition)
And after google sometime we reached this link propel_issue_schema and following it , we moved our schema.xml to Bundle/Resources/config/schema.xml

Now after running same build command :

Following exception came :

Please define a `package` attribute or a `namespace` attribute for schema `schema.xml`



Here we felt propel is guiding us with proper message in exception, so we did as it asked, added package name in <database> tag so that it applies to all tables as per documentation.

After adding package name, we ran again build command :

php app/console propel:model:build 

But to our surprise it started ignoring our schema file and thrown error :


No schema files were found (matching your schema fileset definition)

Now we could not understand what is exactly causing this, no much clue on internet even. If we remove package attribute from schema file it says "please define package or namespace", if we add package attribute, it started ignoring schema file. One thing was sure that it is able to read schema file from Bundle but second time it was expecting it somewhere else.


After digging into codebase via trace of exception, we realised it is looking for schema file inside cache directory of app folder. 

app/cache/dev/propel/schema_file_name.xml

(here dev is environment)

Now final solution we found was move schema.xml file to propel directory in env(dev/prod/test) inside cache.

And after this we were able to generate model classes with
php app/console propel:model:build 

If you still get error, make sure schema file is only at one position, i.e in your cache directory. Delete from your Resource directory in your bundle.

(One more weird solution we found to above problem, if you do not want to move schema file inside cache yourself, run generate schema command once and then move generated schema to Bundle/Resources/config and then run generate reverse schema command again, propel will automatically create a file name BundleName-schema.xml inside cache directory and you can run build model command -

php app/console propel:database:reverse con1

Now move generated schema.xml to Bundle/Resources/config/
 (Do not forget to add package/namespace attribute) and run

php app/console propel:database:reverse con1

again, propel will generate one file named BundleName-schema.xml in propel directory in cache. Do not forget to delete schema.xml file present in your Bundle/Resources/config

And finally,
php app/console propel:model:build 

Worked but with new welcoming exception :

  Invalid database name: no configured connection named `default`.  

It did not consume much time of ours, we tried replacing name which was default with connection name we had given in our config file under propel (in our case it was con1).

Finally it generated models as expected in given package attribute in file.

Now before using these generated models you need to run following command:
composer dump-autoload -o

P.S This might be very simply configuration to do,it is just some blockers we faced and thought to share, might help someone.


Wednesday, 15 October 2014

Serialization in Android

We use Java Serialization in our day to day activity for use cases like Sending Object Over Network, Save Object to a file, Saving user preferences in Object etc etc.

Note: We will not be learning about Java Serialization here, visit Serialization_Official to learn about same. I assume you have working knowledge of Serialization to proceed.

What is here so special about Serialization in Android. No doubt you can use serialization the same way you do in Java and deserialize it later on.

But point to remember here is Android application is client side code. Many tools are available in market to convert your dex files to java classes and then decompile your classes to java files.

To safeguard our logic/code from malicious programmers we do use some tools like proguard to obfuscate our code. Now these tools change Class names, variable names and assign some not readable names so that even if somebody gets your java files, either they are of no use OR very difficult to read.

Here comes the problematic part which we are interested in, Serialazation + Proguard. Now assume your class (some sound setting which user has personalised)  name is:

com.example.khanna.SoundSetting

Now during development you serialize and deserialize Object of SoundSetting class and it works perfectly fine.

Suddenly at production you start getting exceptions like ClasNotFoundException while deserializing and you start hitting your head WTF happened and those with prior experience in java Serialization start hitting serialVersionUID and in your next releases you find the same problem occurring sometime and working perfectly sometime.

Lets come to point, when we use tool like proguard, there are certain set of guidelines which these tools follows and convert our java files to some unreadable format. Say named java file "com.example.khanna.SoundSetting" to "com.example.khanna.ae"

Now when you serialize OR deserialize it, ae is the class name used by JVM.

Suppose you release your next version and if you are lucky enough that class name was named again "com.example.khanna.ae" and deserialize will work even after upgrade.

But usually if you have changed something in that package and which makes proguard guidelines to change your file name from "com.example.khanna.SoundSetting" to "com.example.khanna.bd"

Now before upgrade you serialize with ae but after upgrade ae does not exist OR even if it does, it is not the class which you are expecting.

Hope you understand problem !!

Solution to this problem is quite simple, either set your file in proguard settings not to change its name, so "SoundSetting" will always be "SoundSetting" even after obfuscation.
Or Use custom Serialization (readObject and writeObject) where you own the process and serialize and deserialize premitives, so your class name is not required.

happy coding :)


Thursday, 20 September 2012

Random Key Generator

Sometimes we do need some sort of random key , say for example :

* Sending some unique password / key for one time authentication
* Generating some random user name
* Generating one time password
* validate email / mobile number

and so on ...

So why to bother every time writing some code for generating random number. Here is solution :

Download Random Generator Jar

Just include this jar file and use utility functions :

Example :


package testing;

import com.affiance.yim.gaurav.random.RandomKeyGenerator;

public class Testing {
public static void main(String[] s) {
System.out.println(RandomKeyGenerator.getRandomAlbhabeticKey(10));
System.out.println(RandomKeyGenerator.getRandomAlphaNumericKey(10));
System.out.println(RandomKeyGenerator.getRandomNumericKey(10));
}
}


Functions take a parameter, length of key you want to generate.

Enjoy Coding !















keywords for SEO  : java j2ee random secret unique key password alphanumeric alphabetic numeric length