Service on android

Service on android

A Service is an application component representing either an application’s desire to perform a longer-running operation while not interacting with the user or to supply functionality for other applications to use. Each service class must have a corresponding declaration in its package’s AndroidManifest.xml. Services can be started with Context.startService() and Context.bindService().

Note that services, like other application objects, run in the main thread of their hosting process. This means that, if your service is going to do any CPU intensive (such as MP3 playback) or blocking (such as networking) operations, it should spawn its own thread in which to do that work. More information on this can be found in Processes and Threads. The IntentService class is available as a standard implementation of Service that has its own thread where it schedules its work to be done.

Service Lifecycle

There are two reasons that a service can be run by the system. If someone calls Context.startService() then the system will retrieve the service (creating it and calling its onCreate() method if needed) and then call its onStartCommand(Intent, int, int) method with the arguments supplied by the client. The service will at this point continue running until Context.stopService() or stopSelf() is called. Note that multiple calls to Context.startService() do not nest (though they do result in multiple corresponding calls to onStartCommand()), so no matter how many times it is started a service will be stopped once Context.stopService() or stopSelf() is called; however, services can use their stopSelf(int) method to ensure the service is not stopped until started intents have been processed.

Example in GitHub

Customizing bashrc, bash aliases, and more – I

If you are used to work with the bash console, probably you have noticed that many tasks/commands are repeated very often. In order to improve the speed/productivity, I’m always customizing bashrc files, bash aliases, and creating helper commands whenever it is possible.

For instance, if you work in many different web projects, and you often need to jump between them, it’s very useful to have an alias that takes you to the root of projects. This can be achieved by adding an entry on your ~/.bash_aliases file. Let’s say all your projects are stored on /data/www, then, adding this line should be enough: www=’cd /data/www’. After that, you can directly move to your projects parent directory, just by typing www.

However, if you are as lazy as me, you may want to go beyond that. Probably, you want to jump directly to an specific project, instead of the parent directory. You cannot  pass a variable to an alias, but you can create your custom function on the ~/.bashrc file. In my particular case, all my web projects are stored like this: “/data/www/dev.SITENAME.(com|es|org)/SITENAME”, so that’s what I did:

#Helper to quickly jump to an specific project
function cdd() {
cd /data/www/dev.$@*/$@
}

Now, you can quickly jump to any project just by typing cdd and the project’s name. However, you still need to write the project name properly, which is a bit painful if the names are very long or even not in your language. Wouldn’t it be perfect if you could type cdd and then hit [TAB] for autocompletion with the list of all the available projects? Yes, we can! 🙂
Basically, we need another function that, given any input characters, outputs all the projects that begin with the specified name (or all, if no character was specified). Then, we will use this function as complete of the cdd previously created:

#Autocomplete for tab key displaying all installed sites
function _sitedirs(){
local curw
COMPREPLY=()
curw=${COMP_WORDS[COMP_CWORD]}
COMPREPLY=($(compgen -W '`ls /var/www/ | cut -d"." -f2`' -- $curw))
return 0}

Basically, I make an ls of the projects folder, then I cut the folder with the dot delimiter, and take just the second field, which contains the names of the projects. Then, I filter by the given input and store the result in COMPREPLY.

Finally, to get this working, just add the following line, that will output the available projects once you hit [TAB] key after typing cdd:

#Assigning the complete method to my custom functions
complete -F _sitedirs -o dirnames cdd

If you want to learn more about how bash completion works, I recommend you to read this articles.

Note: Each time you edit your .bash_aliases or .bashrc, the changes will not take effect until you re-login, but you can reload them just by typing:

source ~/.bashrc

CSV File Validation In PHP (Part I)

Last week, I had to implement a CSV file validation in PHP. It’s a potentially very big file with several columns, where each one has its custom restrictions. For example, the “SKU” field must be an alphanumeric string no longer than 64 characters, the “IMAGES” field must contain image filename(s) and/or image URL(s) (comma separated values), and so on.

Eventually, I came up with a solution, which consists on using a strategy pattern, implementing a custom validation strategy for each field.

In order to fully ensure that the input data is correct, two kinds of validations must be performed:

  • Restrictions regarding the format, like allowed characters or maximun length.
  • Not only the data must be in the proper format, but also it must be valid from a semantical point of view. For instance, the SKUs must exist on the database, or each image URL specified must actually be an online image (an html, or an offline server shouldn’t pass the validation).

So, I split the requirements in two kind of validators: lexical and semantic.

This is how it looks like, hopefully it can be useful if you are in a similar situation:

Base validator:


abstract class Abstract_Validator {

/*
 * Tell whether the data is correct or not
 * Might change (correct) the $input value
 *
 * @return bool
 */
 abstract function validate(&$input);
 /*
 * Return a string with the details of the error and/or the allowed values for the current field.
 *
 * @param $input string|array
 * @return string
 */
 abstract function getErrorMsg($input);

 }

Base lexical validator with an implementation example:

abstract class Abstract_Lexical extends Abstract_Validator {

 protected $tokens;

 function __construct() {
 $this->tokens = array();
 }

 public function getTokens() {
 return $this->tokens;
 }
 public function validate(&$input) {
 $this->tokens[] = $input;
 }

/*
* Return the last part of the error message
* Can be called from a child class to complete the returned message.
*
* @param $input string
* @return string
*/
 public function getErrorMsg($input) {
   return sprintf('but "%s" provided.', $input);
 }
}

/*
 * EAN is an optional field, but if it's not empty, it must be a valid code.
 */
class Lexical_Ean extends Abstract_Lexical {
 protected function checkEAN($fullcode) {
 $code = substr($fullcode, 0, -1);
 $checksum = 0;
 foreach (str_split(strrev($code)) as $pos => $val) {
 $checksum += $val * (3 - 2 * ($pos % 2));
 }
 return (10 - ($checksum % 10)) % 10 == substr($fullcode,-1);
 }
 public function validate(&$input) {
 parent::validate(&$input);
 return strlen($input) == 0 || $this->checkEAN($input);
 }

 public function getErrorMsg($input) {
 return 'allowed values: valid EAN code (13 digits number), ' . parent::getErrorMsg($input);
 }
 }

Base Semantic validator, with an implementation example:

abstract class Abstract_Semantic extends Abstract_Validator {
 protected $dbLink;
 protected $errors;
 protected static $FIELD;
 protected static $QUERY;
 protected static $TYPE = 'validateExisting';

 function __construct($dbLink = null) {
 $errors = array();
 if($dbLink) {
 $this->dbLink = $dbLink;
 }
 }

 /*
 * Default validator
 * Ensure the extended class has defined the required values
 * Perform the query and pass the result to the proper method
 *
 * @param $input simple array with data
 * @return bool
 */
 public function validate(&$input) {

 if (!$this->dbLink || !static::$QUERY || !static::$FIELD || !static::$TYPE) {
 $this->errors[] = 'Error validating ' . get_class($this) . ', incomplete data was provided.';
 return false;
 }
 $field = static::$FIELD;
 $type = static::$TYPE;
 $list = $this->dbLink->query(sprintf(static::$QUERY, implode($input, '","')));
 return $this->$type($list, $field, $input);
 }

 /*
 * Ensure all requested items where present in the database
 * Otherwise, log all not found items
 *
 * @param list mysqli_result
 * @param $field field to check
 * @param $input array with data
 * @return bool
 */
 protected function validateExisting($list, $field, $input) {
 $ret = $list->num_rows == count($input);
 if(!$ret) {
 $found = array();
 while($obj = $list->fetch_object()){
 $found[] = $obj->$field;
 }
 $this->errors = array_diff($input, $found);
 }
 return $ret;
 }

 /*
 * Return the errors found during the validation
 * @return array
 */
 public function getErrors() {
 return $this->errors;
 }

 /**
 * Return the description message for the error.
 *
 * @param $input array
 * @return string
 */
 public function getErrorMsg($input) {
 if (static::$TYPE == 'validateExisting') {
 $exist = 'must exist';
 } else $exist = 'cannot exist';

 return sprintf('%s(s) "%s" %s on the database.', str_replace('Semantic_', '', get_class($this)), implode($input, ', '), $exist);
 }
 }

/**
 * Store field must correspond to an existing store in the database.
 */
class Semantic_Store extends Abstract_Semantic {
 protected static $QUERY = 'SELECT code from stores where code in("%s")';
 protected static $FIELD = 'code';
 }

That’s all for the moment, on next post I’ll explain how I did join all this, iterating over the CSV file, stay tuned!

Intent initial concepts in android

definition

Intents are the way invoke the activities. Otherwise Intent is a class that lets you specify a run Activity

Two forms

There are two primary forms of intents you will use.

Explicit Intents have specified a component (via setComponent(ComponentName) or setClass(Context, Class)), which provides the exact class to be run. Often these will not include any other information, simply being a way for an application to launch various internal activities it has as the user interacts with the application.
Implicit Intents have not specified a component; instead, they must include enough information for the system to determine which of the available components is best to run for that intent.

Intent Structure

A Intent can associate an action, a data and a category.

category — Gives additional information about the action to execute. For example, CATEGORY_LAUNCHER means it should appear in the Launcher as a top-level application, while CATEGORY_ALTERNATIVE means it should be included in a list of alternative actions the user can perform on a piece of data.

type — Specifies an explicit type (a MIME type) of the intent data. Normally the type is inferred from the data itself. By setting this attribute, you disable that evaluation and force an explicit type.

component — Specifies an explicit name of a component class to use for the intent. Normally this is determined by looking at the other information in the intent (the action, data/type, and categories) and matching that with a component that can handle it. If this attribute is set then none of the evaluation is performed, and this component is used exactly as is. By specifying this attribute, all of the other Intent attributes become optional.

extras — This is a Bundle of any additional information. This can be used to provide extended information to the component. For example, if we have a action to send an e-mail message, we could also include extra pieces of data here to supply a subject, body, etc.

SOAP IP Address in PHP

This is an example about how to perform SOAP IP Address petitions over a certain IP address in php.

It can be useful in several situations. For instance, if you have a bunch of server behind a load balancer, all of them hosting the same sites (virtual hosts), and you need to comunicate directly to each of them. If you know the server’s ip address, you can comunicate directly to them by specifying the ip address and the host.
Basically, we need to extend the SoapClient class, overriding the __doRequest method in a way that allows us to specify a custom header in the HTTP petitions.

class HostSoapClient extends SoapClient {

 const DEBUG = true;

/*
 * Override the method __doRequest to perform a custom CURL petition, specifying a host on the header
 *
 * @param $request string
 * @param $location sting
 * @param $action string contain the host and the action in the format url#action
 * @param $version int
 * @param $one_way int
 * @return string
 */
 public function __doRequest($request, $location, $action, $version, $one_way = 0) {
 $url_parts = parse_url($location);
 $ch = curl_init();
 list($host, $action) = explode('#', $action);
 if(self::DEBUG) {
 echo 'Performing request to: ' . $location . "\n";
 echo 'Host specified on the header: ' . $host . "\n";
 echo 'Request:' . $request . "\n";
 }
 curl_setopt($ch,CURLOPT_URL, $location);
 curl_setopt($ch,CURLOPT_POSTFIELDS, $request);
 curl_setopt($ch, CURLOPT_HTTPHEADER, array('Host: ' . $host, 'SoapAction: ' . $action));
 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
 $response = curl_exec($ch);
 curl_close($ch);
 return $response;
 }
}

Usage example:

$server = '11.22.33.44'; //The ip address where the page is hosted
$url = $server . '/api/index/index'; //Path of the api (tested on both v1 and v2)
$host = 'www.yourhost.com'; //An existing hostname on the $server ip
$client = new HostSoapClient(null,
		array('trace' => 1,
			'exceptions' => 1,
			'cache_wsdl' => 0,
			'location'=> $url,
			'uri' => $host));
$session = $client->login('user', 'pass');
//Now you are connected and you can call any resource, ie.
$client->call($session, 'api.method', array('param', 'value'));