Using multiple processes in Android

Hello everyone!

In Android, when an application’s first component starts, a new process for the application with a single thread of execution called main thread or UI Thread gets created. By default, all components of the same application usually run in the same process. A Service when invoked using the startService method from an Activity runs on the main application thread. However, if the Service performs an intensive task then it may cause your application to become unresponsive eventually resulting in an ANR (Application Not Responding) message.

Memory management plays an important role in applications involving multiple processes. As mentioned on the Android developer’s page, one can specify a separate process for each application component by declaring the android:process attribute for each component in the manifest file. For example, one can specify a service to run in a process separate from the application’s main process by declaring a new process named background as follows.

<service android:name= ".MyBackgroundService"
         android:process= ":background" />

Through this post, we will learn how to manage and use multiple processes in Android.

Pre-requisites: Eclipse IDE, Android SDK

Step 1: Create Service class

In any of your existing Android projects, create two new Service classes named FirstService and SecondService respectively.

FirstService.java

package com.example;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;

public class FirstService extends Service {

	@Override
	public IBinder onBind(Intent intent) {
		// TODO Auto-generated method stub
		return null;
	}
	
	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		// TODO Auto-generated method stub
		Log.i("FirstService", "onStartCommand method is called");
		return Service.START_NOT_STICKY;
	}
	
	@Override
	public void onCreate() {
		// TODO Auto-generated method stub
		Log.i("FirstService","onCreate Method is called");
		super.onCreate();
	}

	@Override
	public void onDestroy() {
		// TODO Auto-generated method stub
		Log.i("FirstService","OnDestroy Method is called");
		super.onDestroy();
	}

	@Override
	public boolean stopService(Intent name) {
		// TODO Auto-generated method stub
		Log.i("FirstService","stopService Method is called");
		return super.stopService(name);
	}

}

SecondService.java

package com.example;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;

public class SecondService extends Service {

	@Override
	public IBinder onBind(Intent intent) {
		// TODO Auto-generated method stub
		return null;
	}
	
	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		// TODO Auto-generated method stub
		Log.i("SecondService", "onStartCommand method is called");
		return Service.START_NOT_STICKY;
	}
	
	@Override
	public void onCreate() {
		// TODO Auto-generated method stub
		Log.i("SecondService","onCreate Method is called");
		super.onCreate();
	}

	@Override
	public void onDestroy() {
		// TODO Auto-generated method stub
		Log.i("SecondService","OnDestroy Method is called");
		super.onDestroy();
	}

	@Override
	public boolean stopService(Intent name) {
		// TODO Auto-generated method stub
		Log.i("SecondService","stopService Method is called");
		return super.stopService(name);
	}

}

Note: Make sure you have registered the above Services in the AndroidManifest.xml file as follows!

AndroidManifest.xml

....
<application
        android:allowBackup="true"
        android:label="@string/app_name"
        android:theme="@style/AppTheme">
        <activity
            android:name="com.example.TestProcessActivity"
            android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
         <service
            android:name="com.example.FirstService"
            android:process=":firstservice">
        </service>
        <service
            android:name="com.example.SecondService"
            android:process=":secondservice">
        </service>
</application>
....

Step 2: Create Activity class

Create a new Activity class called TestProcessActivity that will include certain methods to call the respective Services.

TestProcessActivity.java

package com.example;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;

public class TestProcessActivity extends Activity {

	private Intent m_objServiceIntent = null; 

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_process);
	}

	public void startFirstService(View view){
		m_objServiceIntent = new Intent(TestProcessActivity.this, FirstService.class);
		startService(m_objServiceIntent);
	}

	public void startSecondService(View view){
		m_objServiceIntent = new Intent(TestProcessActivity.this, SecondService.class);
		startService(m_objServiceIntent);
	}
}

activity_process.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="startFirstService"
        android:text="@string/call_first_service"/>

    <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="startSecondService"
        android:text="@string/call_second_service"/>

</LinearLayout>

Finally, make sure no errors are present. Save all changes and run the application on an Android device. If no errors occur then you should be able to see the following output!

output_1

Next, you need to call each Service by clicking the respective button.

first_service

second_service

Now, try switching to the DDMS perspective in order to view the multiple processes running on the Android device.

ddms_output

Reference: Multiple Processes in Android

AngularJS: Custom directives

Hello everyone!

Directives play an important role in AngularJS applications allowing developers to interact and hence simplify DOM manipulation. One of the most important features of a web application is reusability. AngularJS helps us to build custom directives that can in turn modify or even create a totally new behavior in HTML. To call a directive from HTML, we can simple apply the directive in the DOM. At present, there are four different types of directives namely,

1. Element directives

An element directive is activated when AngularJS finds a matching HTML element in the HTML template. Angular normalizes an element’s tag and attribute name to determine which elements match which directives.

2. Attribute directives

In HTML, we mention attributes for a particular tag. This tag holds the code snippet. Attribute directives help to write specific code that such tags can simply include.

3. CSS class directives

4. Comment directives

Note: AngularJS recommends that you try to use element and attribute directives, and leave the CSS class and comment directives (unless absolutely necessary).

Through this tutorial, we will learn how to use the element directive in AngularJS.

Pre-requisites: Eclipse IDE (for Java EE developers), Apache Tomcat 7.0

Step 1: Launch Eclipse IDE and create a new Dynamic Web Project called AngularCustomDirectives with module version 3.0. Create the following index.html page in the WebContent folder.

index.html

<!DOCTYPE html>
<html ng-app="demo">
  <head>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular.min.js"></script>
  </head>
  <body>
	
	<div ng-controller="ListController">
		<customerinfo></customerinfo>
	</div>

	<script type="text/javascript">	
		var app = angular.module("demo",[]);
		app.directive('customerinfo', function() {
			
			var directive = {};
		    directive.restrict = 'E'; /* restrict this directive to elements */
			directive.templateUrl = "html-templates/customerinfo-template.html";
			
			return directive;
			
		});
		
		app.controller("ListController", function($scope){
		    $scope.customers = [
				{ name: 'Hari', city: 'Mumbai', email:'hari@gmail.com',age:'16'},
				{ name: 'Alexander', city: 'Paris', email:'alex@gmail.com',age:'18'}
			];
		});
		
	</script>
	
  </body>
</html>

The restrict field is used to set if the directive should be activated by a matching HTML element, or an element attribute. By setting restrict to E one can specify that only HTML elements named customerinfo should activate the directive.

Step 2: Create a new folder called html-templates under the WebContent folder and create the customerinfo-template.html file as follows.

customerinfo-template.html

	<h2>List of customers</h2>
	<ul>
		<li ng-repeat="customer in customers">
		    Name: {{ customer.name |uppercase}} 
		    Age: {{ customer.age }} 
		    Email: {{ customer.email |lowercase }} 
		    City: {{ customer.city | uppercase}}
		</li>
	</ul>

Save all changes. Make sure no errors are present. Run the project on the Tomcat server to launch the corresponding web page in a browser and you should see the following output!

output

Reference: AngularJS directives

Tutorial #91: Setting up Eclipse for Android Wear Development

The Android Wear SDK was officially launched at Google I/O back in June 2014. Android Wear is a version of Google’s Android operating system designed for smartwatches and other wearables. It helps display notifications and integrates the Google Now functionality by pairing with mobile phones. The Wear SDK includes code samples, documentation required to build applications that directly run on wearable, create custom user interfaces and sync data between mobile phones and wearables.

However, it is important for developers to first setup their environment in order to create wearable applications. This tutorial helps to setup up the Eclipse IDE for Android Wear development.

Pre-requisites: Eclipse IDE, Android Wear SDK

Step 1: Install Android Wear SDK and support repository

Before creating wearable applications, one needs to download and install the Android Wear SDK from the SDK manager as shown below. One also needs to install the Android support repository from the Extras section.

sdk_manager_install_wear_sdk

sdk_manager_support_repository

Step 2: Create support library project

Once the Android Wear SDK has been installed successfully, one will find the wearable folder present under,

{ANDROID_SDK}\extras\google\m2repository\com\google\android\support\

Next, rename the wearable-1.0.0.aar file as wearable-1.0.0.zip and extract the .zip file to obtain the wearable Android project. Now, launch Eclipse IDE and choose File –> Import –> Existing Android code into workspace. Navigate to the path where the project exists and import the same. Finally, create a libs folder and move the classes.jar in the libs folder. Right click the imported project, go to Android, select build target as Android 4.4W.2 and tick the checkbox Is Library. This makes sure that the project is setup as a library project targeting Android API 20.

Create library project

Create library project

Our final project structure would look something like this,

Project Structure

Project Structure

One can now create a new Android Wear project, or import one of the samples that come with the SDK, and add the above Wear support library as a dependency.

That’s it for this tutorial. Stay tuned for more! :)

Android Tools: Zipalign

Hello friends!

Android provides developers the zipalign tool to align your .apk file before distributing to end-users. The tool not only provides better optimization but also ensures that that all uncompressed data starts with a particular alignment relative to the start of the file. It is important to note that the zipalign must only be performed after the .apk file has been signed with your private key. If you perform zipalign before signing, then the signing procedure will undo the alignment.

Through this post, we will learn how to use the zipalign tool in Android.

Pre-requisites: Eclipse IDE, Android SDK

How to export signed apk?

Launch Eclipse IDE and switch to your Android project workspace. Choose any of your existing Android projects for which you need to zipalign the .apk. Before generating the signed apk for your Android project, it is necessary to follow the below steps as per the official documentation for signing an application.

1. Check the AndroidManifest.xml and verify that android:debuggable attribute is set to false. The attribute indicates whether or not the application can be debugged, even when running on a device in user mode.

2. Check the android:versionCode and android:versionName attributes. If it is a new version of an existing apk, make sure these values are larger than the previous apk file.

3. Finally, right click your application, go to Android Tools -> Export Signed Application Package and sign the application using a release key certificate (not debug) as mentioned over here.

Running zipalign

Once you have obtained the signed apk, you can use the zipalign tool for optimization. The following command converts the signed apk to a zipalign signed apk that can be uploaded on the Google Play Store.

zipalign -v 4 AndroidRandomExamples.apk AndroidRandomExamples_aligned.apk

Syntax

zipalign -v 4 your_project_name-unaligned.apk your_project_name.apk

The output of the zipalign process is as follows!

Output

Output

Reference: Android ZipAlign

Tutorial #90: Implement Media Style Notifications in Android

UPDATE: According to the latest release, the createSession() method has now been removed from the MediaSessionManager class. The below tutorial will hence not work as expected. Sorry for the inconvenience. I will try and post a working tutorial soon! :)

Hello everyone!

Even before Google officially launched the Android 5.0 (Lollipop) SDK, a preview to the same was made available to developers to experience the new features. Apart from material design, another interesting feature was Notifications. The Android L (Preview SDK) added a new lock screen notification feature called Notification.MediaStyle. Up until this point lock screen media controls had to be implemented through the use of a RemoteView.

Starting from Android 5.0 (Lollipop), lock screen notifications are now displayed using Notification.MediaStyle template with the addAction() method, which converts actions into clickable icons. Through this tutorial, we will learn how to implement media style notifications in Android.

Pre-requisites: Eclipse IDE, Android SDK (L Preview)

Step 1: Create Android project

Create a new Android application project called AndroidLollipopExamples with both the build target and minimum SDK set to Android L (API level L). Let the package name be com.app.android.lollipop.

Step 2: Create Service class

In order to implement the media style lock screen notification, we need to create a Service class that will contain the various media controls & media session callbacks. Create a new class called MediaPlayerService and write the following code!

MediaPlayerService.java

package com.app.android.lollipop;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.media.MediaPlayer;
import android.media.Rating;
import android.media.session.MediaController;
import android.media.session.MediaSession;
import android.media.session.MediaSessionManager;
import android.os.IBinder;
import android.util.Log;

public class MediaPlayerService extends Service {

    private MediaPlayer m_objMediaPlayer;
    private MediaSessionManager m_objMediaSessionManager;
    private MediaSession m_objMediaSession;
    private MediaController m_objMediaController;

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    private void handleIntent( Intent intent ) {
        if( intent == null || intent.getAction() == null )
            return;

        String action = intent.getAction();

        if( action.equalsIgnoreCase( Constants.ACTION_PLAY ) ) {
            m_objMediaController.getTransportControls().play();
        } else if( action.equalsIgnoreCase( Constants.ACTION_PAUSE ) ) {
            m_objMediaController.getTransportControls().pause();
        } else if( action.equalsIgnoreCase( Constants.ACTION_FAST_FORWARD ) ) {
            m_objMediaController.getTransportControls().fastForward();
        } else if( action.equalsIgnoreCase( Constants.ACTION_REWIND ) ) {
            m_objMediaController.getTransportControls().rewind();
        } else if( action.equalsIgnoreCase( Constants.ACTION_PREVIOUS ) ) {
            m_objMediaController.getTransportControls().skipToPrevious();
        } else if( action.equalsIgnoreCase(Constants.ACTION_NEXT ) ) {
            m_objMediaController.getTransportControls().skipToNext();
        } else if( action.equalsIgnoreCase( Constants.ACTION_STOP ) ) {
            m_objMediaController.getTransportControls().stop();
        }
    }

    private Notification.Action createAction( int icon, String title, String intentAction ) {
        Intent intent = new Intent( getApplicationContext(), MediaPlayerService.class);
        intent.setAction( intentAction );
        PendingIntent pendingIntent = PendingIntent.getService(getApplicationContext(), 1, intent, 0);
        return new Notification.Action.Builder( icon, title, pendingIntent ).build();

    }

    private void buildNotification( Notification.Action action ) {
            Notification.MediaStyle style = new Notification.MediaStyle();
            style.setMediaSession( m_objMediaSession.getSessionToken() );

            Intent intent = new Intent( getApplicationContext(), MediaPlayerService.class );
            intent.setAction( Constants.ACTION_STOP );
            PendingIntent pendingIntent = PendingIntent.getService(getApplicationContext(), 1, intent, 0);
            Notification.Builder builder = new Notification.Builder(this)
                    .setSmallIcon(R.drawable.ic_launcher)
                    .setContentTitle( "Sample Title" )
                    .setContentText( "Sample Artist" )
                    .setDeleteIntent( pendingIntent )
                    .setStyle(style);
            

            builder.addAction( createAction( android.R.drawable.ic_media_previous, "Previous", Constants.ACTION_PREVIOUS ) );
            builder.addAction( createAction( android.R.drawable.ic_media_rew, "Rewind", Constants.ACTION_REWIND ) );
            builder.addAction( action );
            builder.addAction( createAction( android.R.drawable.ic_media_ff, "Fast Foward", Constants.ACTION_FAST_FORWARD ) );
            builder.addAction( createAction( android.R.drawable.ic_media_next, "Next", Constants.ACTION_NEXT ) );

            NotificationManager notificationManager = (NotificationManager) getSystemService( Context.NOTIFICATION_SERVICE );
            notificationManager.notify( 1, builder.build() );
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if( m_objMediaSessionManager == null ) {
            initMediaSessions();
        }

        handleIntent( intent );
        return super.onStartCommand(intent, flags, startId);
    }

    private void initMediaSessions() {
        m_objMediaPlayer = new MediaPlayer();
        m_objMediaSessionManager = (MediaSessionManager) getSystemService(Context.MEDIA_SESSION_SERVICE);
        m_objMediaSession = m_objMediaSessionManager.createSession("sample session");
        m_objMediaController = MediaController.fromToken( m_objMediaSession.getSessionToken() );

        m_objMediaSession.addTransportControlsCallback( new MediaSession.TransportControlsCallback() {
            @Override
            public void onPlay() {
                super.onPlay();
                Log.e( Constants.LOG_TAG, "onPlay");
                buildNotification( createAction( android.R.drawable.ic_media_pause, "Pause", Constants.ACTION_PAUSE ) );
            }

            @Override
            public void onPause() {
                super.onPause();
                Log.e(Constants.LOG_TAG, "onPause");
                buildNotification(createAction(android.R.drawable.ic_media_play, "Play", Constants.ACTION_PLAY));
            }

            @Override
            public void onSkipToNext() {
                super.onSkipToNext();
                Log.e(Constants.LOG_TAG, "onSkipToNext");
                buildNotification( createAction( android.R.drawable.ic_media_pause, "Pause", Constants.ACTION_PAUSE ) );
            }

            @Override
            public void onSkipToPrevious() {
                super.onSkipToPrevious();
                Log.e(Constants.LOG_TAG, "onSkipToPrevious");
                buildNotification( createAction( android.R.drawable.ic_media_pause, "Pause", Constants.ACTION_PAUSE ) );
            }

            @Override
            public void onFastForward() {
                super.onFastForward();
                Log.e(Constants.LOG_TAG, "onFastForward");
            }

            @Override
            public void onRewind() {
                super.onRewind();
                Log.e(Constants.LOG_TAG, "onRewind");
            }

            @Override
            public void onStop() {
                super.onStop();
                Log.e(Constants.LOG_TAG, "onStop");
                NotificationManager notificationManager = (NotificationManager) getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);
                notificationManager.cancel( 1 );
                Intent intent = new Intent( getApplicationContext(), MediaPlayerService.class );
                stopService( intent );
            }

            @Override
            public void onSeekTo(long pos) {
                super.onSeekTo(pos);
            }

            @Override
            public void onSetRating(Rating rating) {
                super.onSetRating(rating);
            }
        });
    }

    @Override
    public boolean onUnbind(Intent intent) {
        m_objMediaSession.release();
        return super.onUnbind(intent);
    }
}

Constants.java

package com.app.android.lollipop;

public class Constants {

	public static final String ACTION_PLAY = "action_play";
	public static final String ACTION_PAUSE = "action_pause";
	public static final String ACTION_REWIND = "action_rewind";
	public static final String ACTION_FAST_FORWARD = "action_fast_foward";
	public static final String ACTION_NEXT = "action_next";
	public static final String ACTION_PREVIOUS = "action_previous";
	public static final String ACTION_STOP = "action_stop";
	public static final String LOG_TAG = "MediaService";
	
}

Step 2: Create Activity class

Create a new Activity class called MediaPlayerActivity that will start the above service.

MediaPlayerActivity.java

package com.app.android.lollipop;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;

public class MediaPlayerActivity extends Activity{

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		Intent intent = new Intent( getApplicationContext(), MediaPlayerService.class );
		intent.setAction( Constants.ACTION_PLAY );
		startService( intent );
	}
}

Step 3: Add permission in Manifest file

It is important for developers to add the new MEDIA_CONTENT_CONTROL permission in the AndroidManifest.xml file in order to implement the media style notification.

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.app.android.lollipop"
    android:versionCode="1"
    android:versionName="1.0">

    <uses-sdk
        android:minSdkVersion="L"
        android:targetSdkVersion="21" />

    <permission android:name="android.permission.MEDIA_CONTENT_CONTROL" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name">
        <activity
            android:name=".MediaPlayerActivity"
            android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name="com.app.android.lollipop.SecondActivity"
            android:label="@string/app_name" />
        
        <service android:name=".MediaPlayerService"/>
   
     </application>
</manifest>

Save all changes. Make sure no errors are present. Run the application on an Android L emulator and you should see the following output!

media style notification

media style notification

Reference: Android Notifications

AngularJS: Form validation

Hello everyone!

In my previous post we learnt how to get started with AngularJS. In general, forms and controls provide validation services so that the end user can be notified of invalid input. As mentioned on the developer’s page, the ng-submit directive prevents the default action (which for form means sending the request to the server and reloading the current page). In Angular, one can submit a form either using a button element with an ng-click attribute or by using the ng-submit directive.

Through this post we will learn how to implement form validation in AngularJS.

Pre-requisites: Windows 7, Notepad or any text editor

Launch Notepad or any text editor and create a new HTML page called form_validation.html as follows.

form_validation.html

<!DOCTYPE html>
<html ng-app="demo">
  <head>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular.min.js"></script>
	
	<style type="text/css">
	    
        .ng-invalid.ng-dirty{
		  border-color: #FA787E;
		}
		
		.ng-valid.ng-dirty{
		  border-color: #78FA89;
		}
	</style>
	
  </head>
  <body>
	
	<div ng-controller="ListController">

	    <h2>List of submissions </h2>  
		<ul>
		   <li ng-repeat="student in students">
		     Name: {{ student.name | uppercase}}
		     Email : {{ student.email | lowercase }}
		     City: {{ student.city | uppercase}}
		  </li>	   
		</ul>
	
		<h2>Please fill the below form</h2>
		
		<form ng-controller="FormController" name="myForm" ng-submit="myForm.$valid && addStudent(student)" novalidate>
		
    	  Name: <input type="text" ng-model="student.name" placeholder="Enter your name" required/> <br>
		  Email: <input type="email" ng-model="student.email" placeholder= "Enter your email addresss" required/> <br>
		  City: <input type="text" ng-model="student.city" placeholder="Enter your city"/> <br>
		  
		 <input type="submit" value="Submit"/>
	
		</form>
		 	
	</div>

	<script type="text/javascript">
		
		var app = angular.module("demo",[]);
		app.controller("ListController", function($scope){
		    $scope.students = [
				{ name: 'Hari', city: 'Mumbai', email:'hari@gmail.com'},
				{ name: 'Alexander', city: 'Paris', email:'alex@gmail.com'}
			];
		});
		
		app.controller("FormController", function($scope){
			$scope.addStudent = function(student){
				$scope.students.push(student);
			};
		});
		
	</script>
	
  </body>
</html>

Open the above page in a web browser. If no errors occur then you should see the following output before and after the form submission!

output_1

output_2

That’s it for this AngularJS tip. Stay tuned for more! :)

Getting started with AngularJS!

The web is constantly evolving. Earlier, when a browser sent a request to the web server, the server would respond with the corresponding webpage & assets required to load the page. However, when a user clicked a link on the page, the browser would download the same files again. AngularJS is an open source web application framework designed to overcome such limitations. It is maintained by Google and the community at large.

AngularJS is by far one of the most popular technologies for developing MVC based web applications. It supports rapid front end development including features such as two way data binding, dependency injection, custom directives etc with the goal of improving testability and performance. Through this post, we will learn how to get started with AngularJS.

Pre-requisites: Windows 7, Notepad or any text editor, JavaScript

Modules

Modules are used to define applications. A module acts as a container for the different parts of an app, including directives, controllers, services etc. All application controllers should belong to a module. For example,

<div ng-app="demo">
 {{ Hello, Angular!}}
</div>

A reference has been made to the demo module using the ng-app directive.

Directives

AngularJS directives are basically extended HTML attributes with the prefix ng-. As mentioned on the developer’s page, directives are markers on a DOM element (such as an attribute, element name, comment or CSS class) that tell AngularJS’s HTML compiler ($compile) to attach a specified behavior to that DOM element or even transform the DOM element and its children.

Controllers

In Angular, a Controller is a JavaScript constructor function that is used to augment the Angular Scope. A Controller is attached to the DOM via the ng-controller directive.

Now, it’s time to implement the above concepts using an example. Let’s create an HTML page called test.html and write the following code.

test.html

<!DOCTYPE html>
<html ng-app="demo">
  <head>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular.min.js"></script>
  </head>
  <body>
	<div>
      <input type="text" ng-model="userName" placeholder="Enter a name here">
        Hello, {{ userName}}!
    </div>
	
	<h2>List of students</h2>
	<div ng-controller="ListController">
		<ul>
		   <li ng-repeat="student in students">{{ student.studentName | uppercase}}</li>	   
		</ul>
	</div>

	<script type="text/javascript">
		
		var app = angular.module("demo",[]);
		app.controller('ListController', function($scope) {
			$scope.students = [
				{ studentName: 'Hari', city: 'Mumbai'},
				{ studentName: 'Alexander', city: 'Paris'},
				{ studentName: 'Zen', city: 'Tokyo'},
				{ studentName: 'Benjamin', city: 'New York'}
			];
		});   
	</script>
	
  </body>
</html>

The above example demonstrates the use of the ng-app and the ng-controller directive. It also explains data binding using AngularJS. If you open the page in a web browser you should see the following output.

output

In the upcoming tutorials we will learn how to use some more features of Angular JS. Till then happy coding! :)

Reference: Angular JS Developer Guide

Implement RecyclerView in Android

Hello friends!

In one of my previous posts, I had talked about a new feature called Activity Transitions introduced in Android 5.0 Lollipop. In addition, Google has also introduced two new views namely RecyclerView and CardView. The RecyclerView widget is used primarily in applications that consists of data collections whose elements change at runtime. The change can occur either due to user action or network events.

As mentioned on the developer’s page, the RecyclerView class simplifies the display and handling of large data sets by providing,

  • Layout managers for positioning items.

  • Default animations for common item operations, such as removal or addition of items.

In order to recycle or reuse a view, a layout manager may ask the adapter to replace the contents of the view with a different element from the dataset. Through this post we will learn how to implement a RecyclerView in Android.

Pre-requisites: Eclipse IDE, Android SDK 5.0

We will be using our existing AndroidLollipopExamples project as mentioned in the previous post in order to implement the RecyclerView.

Step 1: Getting the support library

In order to use the RecyclerView one needs to download and install the latest version of the Android support library from the SDK Manager as seen below.

support_library

Once the support library is installed, navigate to the {ANDROID-SDK}\sdk\extras\android\support\v7\recyclerview directory and copy paste the .jar file present in the libs folder in your Android project. One can also import the same as a library project and add it as a reference to your existing Android project.

Step 2: Create layout for RecyclerView

Create a new XML file called activity_recycler_view.xml and write the following code.

activity_recycler_view.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="${relativePackage}.${activityClass}" >

    <android.support.v7.widget.RecyclerView
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/recyclerView"
        android:scrollbars="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</RelativeLayout>

Step 3: Create Adapter class

Next, we need to create an Adapter class that will bind the data to the View. Let’s call it MyAdapter. It will contain the following code.

MyAdapter.java

package com.app.android.lollipop;

import android.annotation.SuppressLint;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

@SuppressLint("InflateParams")
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {

	private FruitModel[] fruitsData;

	public MyAdapter(FruitModel[] fruitsData) {
		this.fruitsData = fruitsData;

	}

	@Override
	public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,int viewType) {

		//create view and viewholder
		View itemLayoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_fruit, null);
		ViewHolder viewHolder = new ViewHolder(itemLayoutView);
		return viewHolder;
	}

	// Replace the contents of a view 
	@Override
	public void onBindViewHolder(ViewHolder viewHolder, int position) {    
		viewHolder.txtViewTitle.setText(fruitsData[position].getFruitName());
	}

	// class to hold a reference to each item of RecyclerView 
	public static class ViewHolder extends RecyclerView.ViewHolder {

		public TextView txtViewTitle;

		public ViewHolder(View itemLayoutView) {
			super(itemLayoutView);	
			txtViewTitle = (TextView) itemLayoutView.findViewById(R.id.fruit_name);
		}	
	}

	// Returns the size of the fruitsData
	@Override
	public int getItemCount() {
		return fruitsData.length;
	}
}

item_fruit.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center_vertical"
    android:orientation="horizontal"
    android:padding="15dp">

    <TextView
        android:id="@+id/fruit_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</LinearLayout>

The layout that will be used for each item in the RecyclerView contains only one TextView at present. However, one can also add other views (eg. ImageView) if required.

Step 4: Create Activity class

The actual implementation of the RecyclerView happens in the Activity class. Here, we will get the reference to the view and populate the data required.

TestRecyclerViewActivity.java

package com.app.android.lollipop;

import android.app.Activity;
import android.os.Bundle;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
 
public class TestRecyclerViewActivity extends Activity {
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_recycler_view);
        RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
         
        FruitModel fruitsData[] = { new FruitModel("Apple"),
                new FruitModel("Banana"),
                new FruitModel("Orange"),
                new FruitModel("Pineapple"),
                new FruitModel("Mango"),
                new FruitModel("Watermelon"),
                new FruitModel("Strawberry"),
                new FruitModel("Grapes"),
                new FruitModel("Jackfruit"),
                new FruitModel("Carrot"),
                new FruitModel("Fig")};
        
        //set layoutManger
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        MyAdapter mAdapter = new MyAdapter(fruitsData);
        //set adapter
        recyclerView.setAdapter(mAdapter);
        //set item animator to DefaultAnimator
        recyclerView.setItemAnimator(new DefaultItemAnimator());
 
    }
}

No changes are to be made to the AndroidManifest.xml file. Finally, make sure no errors are present. Run the application on an Android emulator and you should see the following output! :)

output_recycler_view

Next, we will look at implementing the CardView in Android.

Reference: Android RecyclerView

Tutorial #89: Execute batch file using Oracle Job Scheduler

Hey everyone!

The Oracle database includes a built-in scheduler that allows scheduling functions and procedures that can be called from any PL/SQL program. The DBMS_SCHEDULER package introduced in Oracle 10g helps to create, run and monitor jobs. In addition, one can also define a job to execute a batch (.bat) file.

In order to run an external job, you need to enable and start the OracleJobScheduler service on the database server. Through this tutorial, we will learn how to execute a batch file using Oracle Job Scheduler.

Pre-requisites: Oracle 11gR2 Enterprise Edition, Windows 7 (64 bit)

Step 1: Create a batch script

Let’s begin by creating a batch script called example1.bat. On Windows, launch any text editor like Notepad and include the following contents.

example1.bat

echo test > F:\programs\calling_job_from_oracle\output\sample.txt

The above batch file will output the word “test” to a text file in the output directory. The batch file will automatically create the text file upon execution.

Step 2: Create Oracle job

Open SQLPlus and log in as a user with highest privileges. Now, let’s create our job definition by executing the below commands in the console.

BEGIN
    SYS.DBMS_SCHEDULER.CREATE_JOB( job_name => 'example_job',
        job_type => 'EXECUTABLE',
        job_action => 'C:\WINDOWS\system32\cmd.exe',
        job_class => 'DEFAULT_JOB_CLASS',
        comments => 'Job to call batch script on Windows',
        auto_drop => FALSE,
        number_of_arguments => 3,
        enabled => FALSE);
 
    SYS.DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE( job_name => 'example_job', argument_position => 1, argument_value => '/q'); 
    SYS.DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE( job_name => 'example_job', argument_position => 2, argument_value => '/c'); 
    SYS.DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE( job_name => 'example_job', argument_position => 3, argument_value => '"F:\programs\calling_job_from_oracle\example1.bat"'); 
    SYS.DBMS_SCHEDULER.ENABLE( 'example_job' ); 
END;
/

As seen above, it is important to note that one can’t directly execute a batch script. Instead, we need to open an instance of the command prompt and pass an argument in order to execute the batch script. For instance, /q is the cmd.exe switch to turn off echo where as /c is the switch to terminate the same after completing the specified command. Finally, you can test the job by executing the below PL/SQL statement.

BEGIN
    DBMS_SCHEDULER.RUN_JOB( 'example_job');
END;
/

If the job is executed successfully, you should see a sample.txt file present in the output folder. That’s it for this tutorial. Hope it helps! :)

Reference:

1. Oracle Job Scheduler

2. Running a Windows batch file from DBMS_SCHEDULER

Activity Transitions using Android 5.0

Hello everyone!

Android 5.0 Lollipop is now officially launched by Google. The new version of Android brings in a lot more features allowing developers to create much better mobile applications. One of the key highlights of this new version includes Material Design. It is basically a comprehensive guide for visual, motion, and interaction design across platforms and devices.

Through material design, developers can also define custom animations. Android 5.0 introduces some default animations for buttons and activity transitions. Through this post, we will learn how to perform an Activity Transition in Android.

Pre-requisites: Eclipse IDE, Android SDK with Android 5.0 Lollipop

Step 1: Create Android project

Launch Eclipse IDE and create a new Android Application Project called AndroidLollipopExamples with package name com.app.android.lollipop. Choose the target SDK as Android 5.0 (API level 21). In case you don’t see the target API level 21 listed, you can download and install the same from the SDK Manager.

android_target_sdk

Step 2: Create Activity class

In order to perform a transition, we need to create two Activities. Let us name our activities as FirstActivity and SecondActivity respectively. The transition will take place while moving from the first to the second activity via an Intent. Our FirstActivity class would be as follows,

FirstActivity.java

package com.app.android.lollipop;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.ActivityOptions;
import android.content.Intent;
import android.os.Bundle;
import android.transition.Explode;
import android.transition.Transition;
import android.view.Window;

@SuppressWarnings("unchecked")
public class FirstActivity extends Activity {

	@SuppressLint("NewApi")
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);	
        //enable window content transition
		getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
        //set the transition
		Transition ts = new Explode();  
		ts.setStartDelay(2000);
        //set the duration
		ts.setDuration(5000);
		getWindow().setEnterTransition(ts);
        //set an exit transition so it is activated when the current activity exits
		getWindow().setExitTransition(ts);
		setContentView(R.layout.activity_first);
		launchSecondActivity();
	}

	//this will call the second activity resulting in an exit transition
	@SuppressLint("NewApi")
	public void launchSecondActivity() {
		Intent intent = new Intent(this, SecondActivity.class);
		startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(this).toBundle());
	}	
}

activity_first.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="${relativePackage}.${activityClass}">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:text="@string/first_activity" />

</RelativeLayout>

We then need to define a transition in our next Activity as well. Here’s how the SecondActivity class will finally look.

package com.app.android.lollipop;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.os.Bundle;
import android.transition.Slide;
import android.transition.Transition;
import android.view.Window;

public class SecondActivity extends Activity {
	
	@SuppressLint("NewApi")
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
        //enable window content transition
		getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
        //set the transition
		Transition ts = new Slide();  
		ts.setDuration(3000);
		getWindow().setEnterTransition(ts);
		getWindow().setExitTransition(ts);
		setContentView(R.layout.activity_second);
	}
}

activity_second.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="${relativePackage}.${activityClass}">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:text="@string/second_activity" />

</RelativeLayout>

strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">AndroidLollipopExamples</string>
    <string name="first_activity">First Activity</string>
    <string name="second_activity">Second Activity</string>    
</resources>

Note:

Make sure you have registered the SecondActivity within the application tag in the AndroidManifest.xml file as follows!

AndroidManifest.xml

....
 <activity
     android:name="com.app.android.lollipop.SecondActivity"
     android:label="@string/app_name" />
....

Finally, make sure no errors are present. Save all changes and run the application on an emulator running Android 5.0 and you should see the activity transition taking place! :)

Reference: Custom Animations in Android