AngularJS: Routing

In any web application, navigation is crucial. If users can’t navigate through your application easily, you will quickly lose them. AngularJS provides an out of the box service provider called $routeProvider. Through AngularJS, developers can use routes to create different URLs for different content in an application.

As mentioned in the documentation, the routing functionality in Angular is due to the ngRoute module, which is distributed separately from the core Angular framework. The application’s module needs to declare this dependency in order to use the features provided by the ngRoute module. Through this post, we will learn how to implement routing using AngularJS.

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

Step 1: Launch Eclipse IDE and create a new Dynamic Web Project called AngularRouting. Choose the target runtime as Apache Tomcat 7.0

Step 2: Create HTML page

Create a new HTML page called index.html and place it inside the WebContent folder of your web project. In order to implement routing, the first thing to do is add the extra JavaScript inside the head section as follows!

index.html

....
  <head>
    <title>AngularJS Routing tutorial </title>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular.min.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.5/angular-route.min.js"></script>
  </head>
....

Next, let’s implement our $routeProvider. The $routeProvider is configured in the module’s config() function via calls to the when() and otherwise() functions.

index.html

....
var app = angular.module("demo",['ngRoute']);
app.config(['$routeProvider',
		  function($routeProvider) {
			$routeProvider.
				when('/ShowResult/:id', {
					templateUrl: 'templates/show_result.html',
					controller: 'ShowResultController'
				}).
				otherwise({
					redirectTo: '/'
				});
		}]);
....

We also need to register the ShowResultController and hence navigate to the new page depending upon the request parameter (in this case id). Here’s how our HTML page finally looks,

index.html

<!DOCTYPE html>
<html ng-app="demo">
  <head>
    <title>AngularJS Routing tutorial </title>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular.min.js"></script>
	<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.5/angular-route.min.js"></script>
  </head>
  <body>
	
	<div ng-controller="TableController">

	    <h2>Student data</h2>
		
		<table>
		    <tr>
			  <th> Id </th>
			  <th> Name </th>
			  <th> Age </th>
			  <th> Email </th>
			  <th> City </th>
			  <th> Action </th>
			</tr>
		   <tr ng-repeat="student in students">
		      <td>{{ student.id }} </td>
		      <td>{{ student.name | uppercase}} </td>
			  <td>{{ student.age }} </td>
			  <td>{{ student.email | lowercase }} </td>
		      <td>{{ student.city | uppercase}} </td>
			  <td> <a href="#ShowResult/{{student.id}}">Show Result</a></td>
		  </tr>	   
		</table>
	 	
		<div ng-view></div>

		
	</div>

	<script type="text/javascript">
		
		var app = angular.module("demo",['ngRoute']);
		app.controller("TableController", function($scope){
		    $scope.students = [
				{ id:"101", name: 'Hari', city: 'Mumbai', email:'hari@gmail.com',age:'16'},
				{ id:"102", name: 'Alexander', city: 'Paris', email:'alex@gmail.com',age:'18'}
			];
		});
		
		app.config(['$routeProvider',
		  function($routeProvider) {
			$routeProvider.
				when('/ShowResult/:id', {
					templateUrl: 'templates/show_result.html',
					controller: 'ShowResultController'
				}).
				otherwise({
					redirectTo: '/'
				});
		}]);
		
		app.controller('ShowResultController', function($scope, $routeParams) {
		    $scope.id = $routeParams.id;
		    
		    if($scope.id == 101){
		    	$scope.message = 'The result for student is passed';
		    }else{
		    	$scope.message = 'The result for student is failed';
		    }
		});
	
	</script>
	
  </body>
</html>

Important: Notice the ngView directive in the above page. Inside the div with the ngView directive (can also be written ng-view) the HTML template specific to the given route will be displayed.

show_result.html

<h2>Show Result</h2>
 
{{ message }}

Finally, save all changes and make sure no errors are present. Run the application on the Tomcat server and you should see the following output!

output

Reference: Routing in AngularJS

Tutorial #92: Live Streaming using Vitamio in Android

Hello friends!

Live video streaming is one of the most challenging functionalities to incorporate in an Android application. RTMP (Real Time Messaging Protocol) was developed by Adobe for Flash Player to transmit real-time media (audio, video) between a server and flash player. However, Android does not support RTMP out of the box. Hence, developers need to use third party libraries in order to stream a RTMP video.

Vitamio is an open multimedia framework or library for Android and iOS, with full and real hardware accelerated decoder and renderer. It supports streaming network protocols such as RTSP, RTMP, HLS and can play 720p/1080p HD mp4, mkv, m4v, mov, flv, avi, rmvb and many other video formats in Android and iOS. Through this tutorial, we will learn how to implement live streaming using Vitamio in Android.

Pre-requisites: Eclipse IDE, Android SDK

Step 1: Create Android project

Launch Eclipse IDE and create a new Android application project called AndroidVitamioDemo with package name com.app.vitamio.stream. Choose the target SDK as Android 4.4

Step 2: Add reference to Vitamio bundle (library)

Before creating the streaming Activity class, one needs to download the Vitamio Bundle and add the same as a reference to the above Android project. The Vitamio library will provide the required classes to setup, initialize and play the live stream.

Step 3: Create Activity class

Create a new Activity class called LiveStreamingActivity in order to implement the streaming process. Developers can also add an EditText to obtain the path or URL of the media file. For this tutorial, I have directly provided the URL to the media file.

LiveStreamingActivity.java

package com.app.vitamio.stream;

import io.vov.vitamio.LibsChecker;
import io.vov.vitamio.MediaPlayer;
import io.vov.vitamio.widget.MediaController;
import io.vov.vitamio.widget.VideoView;
import android.app.Activity;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.Toast;

public class LiveStreamingActivity extends Activity {

	private String pathToFileOrUrl= "rtmp://204.107.26.252:8086/live/796.high.stream";
	private VideoView mVideoView;
	
	@Override
	public void onCreate(Bundle icicle) {
		super.onCreate(icicle);
		
		if (!LibsChecker.checkVitamioLibs(this))
			return;
		
		setContentView(R.layout.activity_video_stream);
		mVideoView = (VideoView) findViewById(R.id.surface_view);

		if (pathToFileOrUrl == "") {
			Toast.makeText(this, "Please set the video path for your media file", Toast.LENGTH_LONG).show();
			return;
		} else {

			/*
			 * Alternatively,for streaming media you can use
			 * mVideoView.setVideoURI(Uri.parse(URLstring));
			 */
			mVideoView.setVideoPath(pathToFileOrUrl);
			mVideoView.setMediaController(new MediaController(this));
			mVideoView.requestFocus();

			mVideoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
				@Override
				public void onPrepared(MediaPlayer mediaPlayer) {
					// optional need Vitamio 4.0
					mediaPlayer.setPlaybackSpeed(1.0f);
				}
			});
		}

	}
	
	public void startPlay(View view) {
		if (!TextUtils.isEmpty(pathToFileOrUrl)) {
			mVideoView.setVideoPath(pathToFileOrUrl);
		}
	}

	public void openVideo(View View) {
		mVideoView.setVideoPath(pathToFileOrUrl);
	}

}

activity_video_stream.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">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:orientation="horizontal">

        <Button
            android:id="@+id/start"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="startPlay"
            android:text="@string/play_video"/>
    </LinearLayout>

    <io.vov.vitamio.widget.VideoView
        android:id="@+id/surface_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:onClick="openVideo"
        android:text="@string/open_video"/>

</LinearLayout>

Step 4: Add permissions to Manifest file!

One needs to update the AndroidManifest.xml file in order to include the required permissions.

AndroidManifest.xml

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

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="19" />
 
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    
    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name">
        <activity
            android:name=".LiveStreamingActivity"
            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="io.vov.vitamio.activity.InitActivity"
            android:configChanges="orientation|screenSize|smallestScreenSize|keyboard|keyboardHidden|navigation"
            android:launchMode="singleTop"
            android:theme="@android:style/Theme.NoTitleBar"
            android:windowSoftInputMode="stateAlwaysHidden" />
        
    </application>

</manifest>

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

output_1

output_2

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

Reference: Vitamio Bundle

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