COOKIES! This blog uses cookies!
I am completely out of control of cookies here, otherwise I would have disabled them (it is controlled by the platform).
If you don't like cookies and being tracked please leave this blog immediately.

Tuesday, 25 August 2015

String manipulations

One my friend asked me how to memorize these string manipulation functions in most of modern programming languages. Why the hek first argument in substring is zero based and second one is one based?

Everything will be easier if you realize that these offsets are not characters but something between characters. Imagine that characters in your string are separated by lines, and numbers are actually indexes of these separators rather than indexes of characters. The picture below will illustrate it well:



So, when you say “substring”, you ask computer to take a string between these separators and (a – b) will be amount of numbers to substring. If a==b, then you substring zero characters. The same about functions like insert, it inserts a string onto the separator, because you usually need to insert the string between characters, not onto them.

Monday, 17 August 2015

Reading XLSX on Android 5+

New Android Build Tools (21+) and Android 5 (ART) seems to easily fix the problem with 65K methods for Apache POI.

All you need to do is to copy the following files into libs dir of your project:
poi-3.12-20150511.jar
poi-ooxml-3.12-20150511.jar
poi-ooxml-schemas-3.12-20150511.jar
stax-1.2.0.jar
stax-api-1.0.1.jar
xmlbeans-2.6.0.jar - the hero of the day, this jar is deffective in maven repo, so it's needed to repack this jar.

See also the repo with repacked POI 3.12 jars and gradle config examples: https://github.com/andruhon/android5xlsx


Add the following into your app/build.gradle to compile your project with multi-dex to fix 65K method's limit and --core-library, to avoid the warning about javax namespace in your libs.
apply plugin: 'com.android.application'

android {
    // ...your other project settings...
    project.tasks.withType(com.android.build.gradle.tasks.Dex) {
        additionalParameters=['--core-library']
    }
}
dependencies {
    // ...deps settings...
    compile 'com.android.support:multidex:1.0.0' //enable multi-dex
}

You still might want to do a 'aavax' hack, to avoid conflicts with future android releases.

If xmlbeans not broken it would be possible to achieve the same results with just adding 'org.apache.poi:poi-ooxml:3.12' into dependencies, however it will not work straighforwardly because xmlbeans jar in maven is defective and contains duplicates of classes, these duplicates are ok for desktop JVM, but android chokes with them. So it is required to add some routine to re-pack xmlbeans and disable preDex. It will work. however the build process will be quite slow, so it is easier just to prepare jars once and put them into libs directory (as described above)

Special thanks to Heiko Johann for pointing onto new Android Build Tools features

Links:
https://github.com/andruhon/android5xlsx - config example
https://developer.android.com/tools/revisions/build-tools.html
https://developer.android.com/tools/building/multidex.html
http://www.docx4java.org/trac/docx4j - another project of reading OpenXML from Java

Previous posts:
http://blog.kondratev.pro/2014/08/reading-xlsx-on-android.html
http://blog.kondratev.pro/2014/09/further-to-my-post-from-yesterday-on.html
http://blog.kondratev.pro/2014/09/reading-xlsx-on-android-3.html

Saturday, 25 July 2015

Calculate particular weekdays in the range of dates in JavaScript

I've created a plugin for Moment JS to calculate particular weekdays in the range of dates:
https://github.com/andruhon/moment-weekday-calc

For example it would work if you need to calculate quantity business days in current financial year. The exclusion option to mind public holidays is also available.

The plugin is available in Bower and NPM as moment-weekday-calc.
npm install moment-weekday-calc
bower install moment-weekday-calc

Thursday, 25 June 2015

A little bit more on git reset and checkout

HEAD Index Workdir WD Safe?
Commit Level
reset --soft [commit] REF NO NO YES
reset [commit] REF YES NO YES
reset --hard [commit] REF YES YES NO
checkout [commit] HEAD YES YES YES
File Level
reset (commit) [file] NO YES NO YES
checkout (commit) [file] NO YES YES NO
*WD Safe means that this action will not affect files in the workdir

The order of underlying actions on HEAD, index and workdir is the following:
The reset command overwrites these three trees in a specific order,
stopping when you tell it to:
  Move the branch HEAD points to (stop here if --soft)
  Make the Index look like HEAD (stop here unless --hard)
  Make the Working Directory look like the Index

git reset file - is actually a shortcut for git reset --mixed HEAD file and does essentially unstage

Discrard all local commits on master:
git fetch --all
git log origin/master
to find the latest commit on the remote, and
git reset --hard c0mm1tID
to reset down to this commit


Source:

This presentation might also be helpful to quicly review some interesting git features:

Thursday, 16 April 2015

Redirect user directly from a webpage to a cordova / phonegap app

There's a Cordova/Phonegap plugin to define custom schemes:
>cordova plugin add https://github.com/EddyVerbruggen/LaunchMyApp-PhoneGap-Plugin.git --variable URL_SCHEME=mycoolapp

The plugin will automatically update a platform config when the platform added or updated.

With this plugin installed custom scheme URLs like two below will invoke the application:
mycoolapp://
mycoolapp://testscreen

It is also possible to handle these URLs in your hybrid app. The handleOpenURL is called when the application is invoked via the custom scheme
/**
 * Custom schema launch plugin callback
 * @param url
 */
var handleOpenURL = function(url) {
    //your code to process the url
};

The example with AngularJS redirecting user to some particular screen of app:
/**
 * Custom schema launch plugin callback
 * @param url
 */
var handleOpenURL = function(url) {
  setTimeout(function(){
    var hash = url.replace("slingshotapp://","");
    var body = document.getElementById("mySlingshotApp");
    var app = angular.element(body);
    var $injector = app.injector();
    var $scope = app.scope();
    var $location = $injector.get('$location');
    $location.path('/'+hash);
    $scope.$apply();
  },300);
};

Please notice that if you install the plugin with the --save flag it will save the URL_SCHEME variable as `prop`, but it should be saved as a `variable` in order to be properly restored on `plugin add` or `update`. Here's the proper feature definition for config.xml:
    <feature name="Custom URL scheme">
        <param name="id" value="nl.x-services.plugins.launchmyapp" />
        <param name="url" value="https://github.com/EddyVerbruggen/LaunchMyApp-PhoneGap-Plugin.git" />
        <variable name="URL_SCHEME" value="mycoolapp" />
    </feature>

Friday, 10 April 2015

Invoke phone Dialer from Cordova / Phonegap

There's a "tel:" schema available to invoke an external dialer from the app.

The usage example:
<a href="tel:0-800-202020">0-800-202020</a>

It works in the same way for other schemas such as "mailto:", "sms:", "geo:" and "market:".

To enable this functionality the following access permissions should be added into the config.xml:
<access origin="tel:*" launch-external="yes"/>
<access origin="geo:*" launch-external="yes"/>
<access origin="mailto:*" launch-external="yes"/>
<access origin="sms:*" launch-external="yes"/>
<access origin="market:*" launch-external="yes"/>

Tuesday, 31 March 2015

My git cheatsheet


Rebase changes from the master onto current branch

Fetch changes first
git fetch

Rebase
git rebase origin/master

Push
git push origin yourbranchname -f

Branches

Rename/move branch
git branch -m <oldname> <newname>


Tags

Add a tag
git tag -a v1.2 -m 'my annotation for v1.2'

Push the tag:
git push origin v1.2


Diverges
Solutions other than normal merge / mergetool workflow

Hard reset to the origin
git reset --hard origin/branchname

Fixing diverge by deleting branch (loosing you changes)
Checkout master:
git checkout master

Delete diverged branch (dispose all local changes):
git branch -D branchname

Checkout branch back:
git checkout branchname

Fixing diverge by hard reset to some particular commit (loosing you changes)
git reset --hard g00dcmid
assume that you're currently at diverged branch and g00dcmid is a last commit before diverge
please be aware that it will revert all files in the INDEX and in the WORKDIR

Reverts

revert a commit
git revert c0mm1tid
notice, that this will revert this particular commit, not revert to this commit

delete local commits
git reset --hard <commit or branch>

Search

search in commit names
git log --all --grep='some stuff'
--all means - search in all branches

search in patches / diffs (Pickaxe)
git log -S "text to find"
it is also possible to add -p option to list actual diffs

Diffs

show staged diff
git diff --cached

add only non white-space changes
git diff -w --no-color | git apply --cached --ignore-whitespace

Local User
Define a user for single repository:
git config user.email "your@mail.com"
git config user.name "Your Name"