Free Online Courses for Software Developers - MrBool
× Please, log in to give us a feedback. Click here to login
×

You must be logged to download. Click here to login

×

MrBool is totally free and you can help us to help the Developers Community around the world

Yes, I'd like to help the MrBool and the Developers Community before download

No, I'd like to download without make the donation

×

MrBool is totally free and you can help us to help the Developers Community around the world

Yes, I'd like to help the MrBool and the Developers Community before download

No, I'd like to download without make the donation

Android Intents: Activating App Components and Implement Debugging

See in this article how to activate App Components with Intents and Implement Debugging in Android.

Consider the example of an Android app that contains multiple activities. During the execution of the app, you may be required to invoke one activity from another activity. For example, you may want that when a user clicks a button on one activity, another activity should be launched. To implement this requirement, you need to use intents.

Intents are messages used to activate app components, such as activities, services, and broadcast receivers. To understand intents, let us consider the example of a Contact Manager app. This app contains an Add Contact activity that allows you to add a new contact to your Android device. Once you fill up the details of a new contact and clicks the save button, the following two actions are performed:

  • Details of the newly added contact are stored in the Contacts database.
  • A new activity, Show Contacts, is launched that displays the details of the newly added contact along with all previously stored contacts in the form of a list.

In the preceding example, the Add Contact activity sends an intent to the Show Contacts activity to activate it.

Components of Intent

An intent object contains information for the app component that receives the intent, such as the action to be initiated and the data to be acted upon. It also contains information for the Android system, such as the category of component that should handle the intent and instructions on how to launch the target activity. The various components of an intent are:

Component name:Specifies the name of the component that should handle the intent. It is a ComponentNameobject, which identifies an app component, such as an activity, service, broadcast receiver, or content provider. This object specifies a fully qualified class name of the target component, such as com.exampleapp.demo.app.ExampleAc tivity.

Action:Specifies the action that needs to be performed. In the case of broadcast intents, it specifies the action that took place and is being reported. This part of an intent can take some constant values. Some standard constants are predefined in the Intent class. However, you can also define your own constants.

Let us consider an example:

Intent i = new Intent (Intent.ACTION_CALL,Uri.parse("tel:123456");

The preceding code will make a call on the number 123456, as shown in the following figure:

Figure 1: The Activity for Initiating a Call

Data:Specifies the data to operate on. For example, the statement below will launch the dialer activity with the number to be dialed set to 5553333. The action is specified as ACTION_DIAL and the data is the number that needs to be dialed.

Intent dialIntent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:5553333"));

Category:Specifies the behaviour of the target app component. For example, CATEGORY_LAUNCHER indicates that the activity can be the initial activity of an app. This component of an intent can take some constant values. Some standard constants are predefined in the Intent class. However, you can also define your own constants.

Extras:Contains extra information in the form of key-value pairs that must be delivered to the components that handle the intent. For example, if the action is specified as ACTION_TIMEZONE_CHANGED, the extras field should contain a time-zone value that specifies the new time zone.

Flags:Includes flags that control various aspects related to activating a new component. For example, the flag, FLAG_FROM_BACKGROUND, indicates that the intent is coming from a background operation and not from a direct user interaction. Similarly, the flag, FLAG_GRANT_READ_URI_PERMISSION, indicates that the recipient of the intent should be granted read permission on the data specified in the intent.

Types of Intents

  • Explicit intents
  • Implicit intents

Explicit Intents

Explicit intents specify the name of the target component in order to activate that component. Such intents are used to start an activity or a service within the same app. Consider the example of an app that contains two activities, MyFirstActivityand MySecondActivity. To invoke the MySecondActivity activity from the MyFirstActivity activity, the following code snippet can be used: Intent mExplicitIntent = new Intent (MyFirstActivity.this, MySecondActivity.class); startActivity(mExplicitIntent); The preceding code snippet can be written in the click event handler of a button or in the handler of any other event that should trigger the display of the second activity. In the preceding code snippet, the first parameter to the Intent constructor specifies the context in which the new activity is started. The second parameter specifies the name of the class (component name) to be invoked in order to start the new activity.

Implicit Intents

Implicit intents are used to activate the components of other apps. Implicit intents do not specify the target components by their name. The Android system must find the components that can handle the implicit intents. These components advertise their capability to do a job by using intent filters. A component that needs to invoke another component simply needs to express its requirement to do a job by issuing intent. The Android system automatically invokes an appropriate component to do the job by comparing the contents of the intent to the intent filters of various existing components. In this case, both the components are not aware of each other’s existence but are still able to work together.

An intent filter has fields equivalent to the action, data, and category components of an intent. Comparison of an implicit intent with an intent filter is done in all these three areas. If a match is found in all the three areas, the intent is delivered to the component that owns the filter. If two components declare the same intent filters, both of them can respond to the same intent. In such a case, both the options are presented to the user and the user is allowed to select one of the two. The Android system must know about the capabilities of a component before it can launch that component. Therefore, intent filters of a component are generally declared in the AndroidManifest.xml file.

The following markup illustrates how to declare intent filters in the AndroidManifest.xml file:

<?xml version="1.0"encoding="utf-8"?>
   <manifest xmlns:android="http:// schemas.android.com/apk/res/android" package="com.example.helloworld" android:versionCode="1"android:versionName="1.0"> 
  <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17"/> <application android:allowBackup="true" android:icon="@drawable/icon" android:label="@string/app_name"android:theme="@style/AppTheme">
  <activityandroid:name="com.example.helloworld.M ainActivity" android:label="@string/app_name" >
   <intent-filter> 
  <action android:name="android.intent.action.MAIN" />
  <category android:name="android.intent.category.LAUNCHER" />
   </intent-filter> </activity> </application> </manifest>

Let us now look at a few examples to understand how implicit intents are used. The following example illustrates how to launch an activity that can dial a telephone number:

Intent mImplicitIntent = new Intent (Intent.ACTION_DIAL,Uri.parse ("tel:555-3333")); startActivity(mImplicitIntent);

In the preceding code snippet, the first statement creates an Intent object by using a constructor that accepts the action and data attributes of the intent. The second statement invokes an activity whose action and data attributes match the action and data attributes specified in the intent.

Similarly, the following code will launch an activity that has the ability to display the native contacts of your Android device:

Intent mImplicitIntent = new Intent (Intent.ACTION_VIEW,Uri.parse ("content://contacts/people/"));
   mImplicitIntent.setFlags (Intent.FLAG_GRANT_READ_URI_PERMISSION ); startActivity(mImplicitIntent);

The following code will invoke an activity that can be used to edit the details of a single contact, in this case the one with ID 2:

Intent mImplicitIntent = new Intent (Intent.ACTION_EDIT,Uri.parse ("content://contacts/people/2")); 
  startActivity(mImplicitIntent);

The following code will invoke an activity that allows a user to view a Web page, which appears in the application launcher of the device:

Intent mImplicitIntent = new Intent (Intent.ACTION_VIEW); 
  mImplicitIntent.setData(Uri.parse ("http://www.niit.com")); 
  mImplicitIntent.addCategory (Intent.CATEGORY_LAUNCHER); 
  startActivity(mImplicitIntent);

Implicit intents are helpful when you want to add functionalities of third party or native apps in your app. This will allow you to share functionalities from other apps. For example, you can add telephony support in your apps by launching an intent for a dialer app. This will save you from creating a dialer especially for your app.

How to Pass Data between App Components Using Intents

Consider a scenario where you have two activities, Activity1 and Activity2. You want to invoke Activity2 from Activity1 and while doing it, you also want to pass some data to Activity2. This data can be packaged in an object of the Bundle class and attached with the intent used for activating Activity2.

Consider the following code written in Activity1:

Intent intent1 = new Intent (Activity1.this, Activity2.class); 
  // Creates and initializes a bundle object.
   Bundle b1 = new Bundle();
  // Puts values in the bundle object
  // In this case, double values are put for keys key1 and key2 
  b1.putDouble("key1", 10); b1.putDouble("key2", 20);
  // Adds the bundle to the intent object that is passed to the other 
  // app component. 
  intent1.putExtras(b1); startActivity(intent1);

The preceding code packages two key-value pairs in a bundle object and attaches it with an intent. The intent is then used to start another activity. Now, consider the following code in Activity2 that retrieves the two values sent by Activity1:

// Initializes the intent object 
  Intent intent2 = getIntent(); 
  // Get values from the intent and add them to a bundle object 
  Bundle b2 = intent2.getExtras();
  // Retrieves double values from the bundle object 
  Double v1 = b2.getDouble("key1"); Double v2 = b2.getDouble("key2");

Let us now consider another example where Activity1 needs to send two values to Activity2. Activity2 needs to add the two values and return the result back to Activity1. Consider the following code written in Activity1 to invoke Activity2:

Intent intent1 = new Intent (Activity1.this, Activity2.class); 
  Bundle b1 = new Bundle(); 
  b1.putDouble ("num1", 10);
   b1.putDouble ("num2", 20);
  intent1.putExtras(b1);
  // Starts an activity with request code 123. This request code is  required for retrieving the result from the activity. 
  startActivityForResult(intent1, 123);

In the preceding code, the new activity is invoked by using the startActivityForResult()method. This method is used to invoke an activity that is expected to return a result. The method accepts two parameters, an object of the Intent class and a request code. When Activity2 returns a result, this request code will be used to match the response sent by Activity2 with the relevant request.

Now, consider the following code written in Activity2 to extract the data sent with the intent and to send the response:

// Obtains a reference to the intent sent from Activity1 Intent intent2 = getIntent();
  // Extracts the data from the intent
   Bundle b2 = intent2.getExtras(); 
  Double v1 = b2.getDouble("num1");
   Double v2 = b2.getDouble("num2");
  // Calculates the result 
  Double v3 = v1 + v2;
  // Stores the result in a bundle
   b2.putDouble ("result", v3);
  // Attaches the bundle to the intent 
  intent2. putExtras(b2);
  // Returns result with an OK signal to the calling activity setResult (Activity.RESULT_OK, intent2);

In the preceding code, the getIntent()method is used to obtain a reference to the intent sent from Activity1. Data is then extracted from the intent and the result is calculated. The result is stored in a bundle and attached with the intent. Finally, the intent is returned to Activity1 with an OK signal.

Once Activity2 sends the intent containing the result to Activity1, Activity1 needs to extract the result from the intent. Consider the following code written in Activity1 to extract the result:

protected void onActivityResult(int requestCode, int resultCode, Intent data)
  {
   super.onActivityResult(requestCode, resultCode, data);
   try{
   /* Checks whether the request code of the result matches that of the original request, and whether Activity2 has sent an OK signal indicating that the result was successfully computed */ 
  if ((requestCode == 123 ) && (resultCode == Activity.RESULT_OK))
  {
   // Extracts the bundle from the intent sent from Activity2 
  Bundle b3 = data.getExtras();
  / / Extracts the data from the bundle 
  Double vresult = b3.getDouble ("result"); 
  }
   }
   catch (Exception e) { // Exception handling code }

In the preceding code, the onActivityResult() method is automatically invoked when Activity2 returns a result to Activity1.

Debugging Android Apps

Mobile app development has a lot of similarities with programming for the desktop and the Web. Developers at times, assume that programming logics/techniques that work best for the desktop and Web environments generally work in the mobile environment as well. It is important for mobile app developers to program the code in a modular approach and be careful of not over-stretching resources, such as memory and persistent storage. Mobile app development and traditional development platforms diverge in earnest areas of app testing and debugging. Debugging is the process of detecting errors or bugs in an app. To help you create error-free apps, the Android development environment provides you with various easy-to-use debugging tools. An important aspect related to debugging is logging. At times, a developer needs to generate and examine logs to identify bugs in an app. Debugging Android apps is an interesting activity and involves a few command-line/GUI tools available through the Android SDK. Consider an example where a developer needs to create a PDF reader app. While executing the app, the developer encounters an error stating that the app is not parsing the text in the correct format. In such a big app, it would be difficult to search each and every line of code to detect the error. In such scenarios, Android debugging tools along with logs can be used to detect the erroneous code in the app quickly and easily.

Following figure displays various tabs in Debug Prospective

Figure 2: Debug Prospective

Identifying Android Debugging Tools

The Android SDK provides various tools that can be used to debug an Android app. If you want to step through code, view variable values, and pause execution of an app, you need a JDWP-compliant debugger. This debugger is already included in the Eclipse IDE. The main components of the Android debugging environment are:

Android Debug Bridge (ADB):ADB is a versatile command-line tool that allows you to communicate with an emulator instance or connected Android-enabled mobile device. ADB acts as a communication medium between the development hardware and the device/emulator. It lets you install apps, push and pull files, and run Linux shell commands on the target device. By using the device’s Linux shell, you can manage certain device settings and query or modify databases available on the device/emulator. The ADB tool lets you manage the state of an emulator or Android device so that you can debug your app or interact with the device at a higher level.

Dalvik Debug Monitor Server (DDMS):DDMS is a program with a GUI that communicates with the emulator/device through ADB. If you are using the Eclipse IDE with ADT plug-in, DDMS is integrated into the IDE. If you are not using Eclipse with ADT plug-in, you can run DDMS from the command line and it will automatically connect you to the available emulator that is running. You can find the DDMS tool in the tools directory of the Android SDK.

Device/AVD:An AVD emulates a real Android device. It is an ideal tool for debugging and testing your Android apps especially if the real device is not available. By using an AVD, you can simulate how the apps will appear and behave on a real Android-enabled mobile device. It provides you with several alternative UIs to represent different hardware configurations each with different screen sizes, resolutions, orientations, and hardware features to simulate a variety of mobile device types. While debugging apps, an AVD provides full network connectivity along with the ability to tweak the Internet connection speed and latency. It also allows you to simulate placing and receiving voice calls and SMS messages. In addition, multiple AVDs with different configurations can be created to test and debug an app on devices with different configurations. The ADT plug-in integrates the AVD with Eclipse. As a result, an AVD is automatically launched when you run or debug your Android application projects.

JDWP debugger:The JDWP protocol, which is supported by DVM, allows debuggers to attach to a Java Virtual Machine (JVM). Each app runs in a Virtual Machine (VM) and provides a unique port for attaching a debugger via DDMS.

The AVD may not implement all the mobile hardware features supported by an actual Android device including camera, vibration, LEDs, actual phone calls, accelerometer, USB connections, Bluetooth, audio capture, battery charge level, and SD card insertion and ejection.

In addition to the main debugging tools, the following tools can be used to debug and profile apps:

Hierarchy Viewer:This tool is used to debug issues related to layout. It enables you to debug and optimize UI of your app. It provides a visual representation of the layout’s view hierarchy with details about the performance of each node in the layout. In addition, it provides a magnified view of the display to analyze the pixels in the layout closely.

Conclusion

While developing Android apps, a developer may encounter bugs or errors. It is important to create apps that do not contain any bugs. This process of finding and resolving is called debugging.



Certified Trainer for Windows 8 Mobile App Development, IBM CE Project Trainer With IBM DB2, RAD, RSA, Certified Trainer for ZEND (PHP), Certified PHP and MySql trainer, Certified trainer of Diploma in Oracle 10g (DBA) as per Orac...

What did you think of this post?
Services
[Close]
To have full access to this post (or download the associated files) you must have MrBool Credits.

  See the prices for this post in Mr.Bool Credits System below:

Individually – in this case the price for this post is US$ 0,00 (Buy it now)
in this case you will buy only this video by paying the full price with no discount.

Package of 10 credits - in this case the price for this post is US$ 0,00
This subscription is ideal if you want to download few videos. In this plan you will receive a discount of 50% in each video. Subscribe for this package!

Package of 50 credits – in this case the price for this post is US$ 0,00
This subscription is ideal if you want to download several videos. In this plan you will receive a discount of 83% in each video. Subscribe for this package!


> More info about MrBool Credits
[Close]
You must be logged to download.

Click here to login