Thursday 30 October 2014

Video search in Android using Youtube Data api

This post is about how to use Youtube's data api to search youtube videos in android. Unlike all the other youtube api's like Player api there is not an android client to leverage those api's into the app.

But there is a Java client provided access to data api which we can use to search videos in our case.
Following post will allow you to make you better use of the Java client to get the required result.

Since in this post we will be presenting to you how to search youtube videos by keywords but using the java client to search videos gets a little confusing as Java client contains a number of jars required for various functionalities ranging from posting a channel bulletin, uploading a video, updating an video, searching videos etc.

A lot of other dependencies (Google OAuth client etc.) are also added in the client library which simply of no use in a case like current where we only want to search videos for a particular keyword.

Assumptions :
1. Registered your application in Google API console to be able to use Google Services like Youtube Data API etc.
Please follow the link

https://developers.google.com/youtube/v3/getting-started#before-you-start

2. Create a browser key under your project's OAuth and Credentials menu.

The API supports two types of credentials. Create whichever credentials are appropriate for your project:
-> OAUTH
-> API KEY

Since we are presenting a demo for the videos search, so we won't need any user level authentication hence avoiding OAUTH, instead we will be using API KEY to authenticate app to use Youtube data api.

YOUTUBE Data Api :
Best part of the youtube data api is that it provides an efficient way to fetch the partial resources with employed filtering of unneeded data. Hence makes better use of network, CPU and memory resources.

The filtering as cited in the above sentence is implemented by using two parameters to each request we make to fetch the youtube reosurce. It simply means that a particular youtube resource which is completely defined by a large number of properties can be filtered down based upon the properties required by a user.


1. part : this parameter ensures that a required group of properties is returned by the user. It is the one of the important top-level non-nested properties that should be added into the api response . For example : snippet, contentDetails, statistics etc.

2. fields : this filters the API response to return only specific properties within the requested resource parts.
example for representing filtering of nested properties is as follows :
-> fields=items/id,playlistItems/snippet/title,playlistItems/snippet/position {identify a nested property}
-> fields=items(id,snippet/title,snippet/position)
-> fields=items(id,snippet(title,position)) {group of nested properties }



NOTE : Alternative for accessing Youtube data is to fetch the data using REST API url with defined parameters
https://www.googleapis.com/youtube/v3/videos?id=7lCDEYXw3mM&key=YOUR_API_KEY&fields=items(id,snippet(channelId,title,categoryId),statistics)&part=snippet,statistics


Gradle dependencies required are : 


 dependencies {
 compile fileTree(dir: 'libs', include: ['*.jar'])
 compile 'com.android.support:appcompat-v7:21.0.+'
 compile 'com.google.android.gms:play-services:+'

 // Library for using Youtube data api
 compile 'com.google.apis:google-api-services-youtube:v3-rev120-1.19.0'
 compile 'com.google.http-client:google-http-client-android:+'
 compile 'com.google.api-client:google-api-client-android:+'
 compile 'com.google.api-client:google-api-client-gson:+'

 // Library for using CardView
 compile 'com.android.support:cardview-v7:21.0.+'

 // Image loading library
 compile 'com.squareup.picasso:picasso:2.3.+'
}


Issue :
We will create a browser key instead of android key with allowed HTTP referrers field set empty. With Android key it was giving service config errors (Error code : 403)

References :
https://developers.google.com/youtube/v3/getting-started
https://developers.google.com/youtube/v3/code_samples/java#search_by_keyword



Please find Source Code here.

Monday 27 October 2014

Gradle Configuration for an Android Studio project with Android 5.0 or L or Lollipop

This post is only about configuring an android project in Android Studio with compile and target versions set as  android L or 5.0 or Lollipop. 

    I am writing this post with the sample gradle as I faced a lot of problems while configuring Lollipop's preview version.
    I will write the sample gradle as well as the screen shot of android sdk manager to represent most basic requirements required for a project setup with target version as Lollipop.
   
    So to be able to use any feature of the Android 5.0, here is the sample gradle with support library for Android L features :



apply plugin: 'com.android.application'

android {
    compileSdkVersion 21
    buildToolsVersion "21.0.1"

    defaultConfig {
        applicationId "your app's packagename"
        minSdkVersion 10
        targetSdkVersion 21
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            runProguard false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:21.0.+'
 // Not compulsory just added 
    compile 'com.google.android.gms:play-services:+'
 // Support for L features for devices with lower OS versions
    compile 'com.android.support:cardview-v7:21.0.+'
    compile 'com.android.support:recyclerview-v7:21.0.+'
}

Also see the following attached screenshots to get the required SDK, various support dependencies, platforms etc to be downloaded :

Android Tools :


Android SDK 5.0(L or Lollipop)

 Minimum Android SDK (as per above gradle 2.3.3 or API level 10)

Support Libraries for L features for older devices

Please provide your comment in case of any issues.

Monday 20 October 2014

Git Submodules

This blog post is a very simple description on how to use a very important feature of GIT i.e submodules.

Requirement:
How to use a third party library into your app without keeping the source code for library project inside your repository ?There are multiple ways to include a third party code into your app. Either copy the entire source code into your app or get it installed using some tool like Ruby gem or CPAN install.

Or else you could import the remote third party repository into your code without getting its actual code by using git submodule feature. This is also used to include a third party repository without making your own repository getting heavier in size.
This approach also allows you to contribute back to the third party repository.


Submodules:
Submodules allow you to keep a Git repository as a sub-directory of another Git repository. This lets you clone another repository into your project and keep your commits separate.

 What you need to get the library :
Add the external repository under your project in a sub-directory. You can do this by the calling following git command from the project's repository


        git submodule add <remote url> <subdirectory name>  
        example :
        git submodule add https://github.com/couchbase/couchbase-lite-android.git  mylibs

Now you will have the library project under subdirectory folder. and will see that you have a new file in your project directory
        new file:   .gitmodules
        new file:  <subdirectory name> (in example mylibs which will contain the external lib project)
 

   
.gitmodules is a configuration file that contains the mapping between the library project's url and the subdirectory to which it is pulled into. 



What git thinks of and does with submodules :
Although <subdirectory name> is a subdirectory in your working directory, Git sees it as a submodule and doesn’t track its contents when you’re not in that directory. Instead, Git records it as a particular commit from that repository.
When you make changes and commit in that subdirectory, the superproject notices that the HEAD there has changed and records the exact commit you’re currently working off of; that way, when others clone this project, they can re-create the environment exactly.

All the Git commands work independently in the two directories.



What other users need to do to get your repository along with submodules : 
1. Clone the repository.
       $ git clone <repository_url>
2. Navigate to root of the project directory

       $ cd <repo_name>
2. call following command from project's root

       $ git submodule init && git submodule update
      
You must run above two commands: git submodule init to initialize your local configuration file, and git submodule update to fetch all the data from that project.


Now you are ready to Clean, Build and Run.


Monday 13 October 2014

Couchbase Sync Gateway : Installation and Running

Sync Gateway is a sync server that syncs data to and from the mobile clients and the couchbase server. Sync Gateway can be implemented using a 100 lines of code implementing all the functionalities like network connections handling , push and pull of data between servers and devices
It makes the JSON document stored on Couchbase server available to mobile devices over the internet. 
It provide features for routing data to users, authentication, change validation and access control.

Now in this blog we will try to get the sync gateway installed and running up using the following procedure:

Running the Sync Gateway :
Since couchbase is used easily along the multiple OS. We will try to demo it on Windows. This involves a number of important steps to get couchbase running.

-> Installing of Couchbase Sync Gateway in Windows
Get the download from the following for the respective operating system.

-> Connecting Couchbase Sync gateway to Couchbase sync server
1. Open Couchbase server console and signin to the app.
      2. From the menu choose the option to create a new bucket with name sync_gateway.
      3. Accessing and modifying sync gateway : Sync Gateway is similar to an application server in that it considers itself the owner of its bucket, and stores data in the bucket using its own schema. Even though the documents in the bucket are the ones stored there by clients, the Gateway adds its own metadata to them to track their sync status and revision history.



 -> Starting Sync Gateway : There are multiple ways to start Sync Gateway in windows once it is successfully installed.

a. One option to start Sync gateway from the command line using -url option. 
You start Sync Gateway by running sync_gateway with the -url option. The argument for the -url option is the HTTP URL of the Couchbase server to which you want Sync Gateway to connect. If you do not include any additional command-line options, the default values are used.

The following command starts Sync Gateway on port 4984, connects to the default bucket named sync_gateway in the Couchbase Serving running on localhost, and starts the admin server on port 4985.

$ ./sync_gateway -url http://localhost:8091
or 
C:\Users\ravikumar>sync_gateway -url http://localhost:8091

If you used a different name for the Couchbase Server bucket or want to listen on a different port, you need to include those parameters as command-line options. For information about the available command-line options, see the Configuration options guide.

b. Other option to start sync gateway is to click start Sync Gateway exe from the Window's Startup menu.


Note : This won't run if the sync_gateway installation directory's path is not added to the environment variable.

-> Stopping Sync Gateway :
There is no specific procedure to stop the sync gateway. Use the Ctrl C to stop the running the sync gateway.

Tuesday 7 October 2014

Attachments to a Document


Apart from the trivial storage facilities for text there is huge requirement for the storage of  the non-textual data like media files. Couchbase lite provides a mechanism to store the content of the media files as an attachments rather as a part of the document's JSON content.

Attachments store data associated with a document but are not the part of document's JSON object. Their primary purpose is to make it efficient to store large binary data in a document. Binary data stored in JSON has to be base64-encoded into a string, which inflates its size by 33%. Also, binary data blobs are often large (think of camera images or audio files), and big JSON documents are slow to parse. 

A document can have any number of attachments, each with a different name. The MIME type information of the attachment is also stored which is only relevant for the app for interpreting its content.

In native api an attachment to a document is represented by class Attachment.


Major operations on attachment to a document are :

1. Creating or updating an attachment : 
To create an attachment, first create a mutable UnsavedRevision object by calling createRevision on the document's currentRevision. Then call setAttachment on the new revision to add an attachment. (You can of course also change the JSON by modifying the revision's properties.) Finally you call save to save the new revision.

Updating an attachment's content (or type) works exactly the same way.

final Document currentDocument = mCouchbaseDatabase.getDocument(iDocId);
UnsavedRevision newRev = currentDocument.getCurrentRevision().createRevision();
if (is == null)
{
   is = getAssets().open("droid.jpg");
   newRev.setAttachment("droid.jpg", "image/jpg", is);
   newRev.save();
}


2. Reading an attachment :
An attachment can be accessed by Revision object which in turn is accessed by Document's currentRevision. And then call getAttachment on the Revision object

final Document currentDocument = mCouchbaseDatabase.getDocument(iDocId);
final SavedRevision savedRevision = currentDocument.getCurrentRevision();
Attachment att = savedRevision.getAttachment("droid.jpg");
if (att != null)
{
 InputStream is = att.getContent();
 Drawable attachDrawable = Drawable.createFromStream(is, "droid.jpg");

 ImageView imv = new ImageView(this);
 imv.setImageDrawable(attachDrawable);
 LayoutParams pars = new LayoutParams(WIDTH_HEIGHT, WIDTH_HEIGHT);
 imv.setLayoutParams(pars);

 // Set ImageView to the Toast
 Toast testToast = new Toast(this);
 testToast.setView(imv);
 testToast.setDuration(Toast.LENGTH_LONG);
 testToast.show();
}



3. Deleting an attachment
An attachment can be deleted by calling removeAttachment on Revision object


final Document currentDocument = mCouchbaseDatabase.getDocument(iDocId);
UnsavedRevision newRev = currentDocument.getCurrentRevision().createRevision();
newRev.removeAttachment("droid.jpg");
newRev.save();


Storage without any Duplication
Attachments aren't stored in the database file itself. Instead they are individual files, contained in a directory right next to the database file. Each attachment file has a cryptic name that is actually a SHA-1 digest of its contents.

As a consequence of the naming scheme, attachments are de-duplicated: if multiple attachments in the same database have exactly the same contents, the data is only stored once in the filesystem.

                                       
Please find the complete source code here SourceCode