Linked Lists- C

Posted: October 9, 2011 in Uncategorized

Introduction

Linked list is one of the fundamental data structures, and can be used to implement other data structures. In a linked list there are different numbers of nodes. Each node is consists of two fields. The first field holds the value or data and the second field holds the reference to the next node or null if the linked list is empty.

 

 

Figure: Linked list

Pseudocode:

Collapse | Copy Code
Linkedlist Node {
    data // The value or data stored in the node
    next // A reference to the next node, null for last node
 }

 

The singly-linked list is the easiest of the linked list, which has one link per node.

Pointer

To create linked list in C/C++ we must have a clear understanding about pointer. Now I will explain in brief what is pointer and how it works.

A pointer is a variable that contains the address of a variable. The question is why we need pointer? Or why it is so powerful? The answer is they have been part of the C/C++ language and so we have to use it. Using pointer we can pass argument to the functions. Generally we pass them by value as a copy. So we cannot change them. But if we pass argument using pointer, we can modify them. To understand about pointers, we must know how computer store variable and its value. Now, I will show it here in a very simple way.

 

Let us imagine that a computer memory is a long array and every array location has a distinct memory location.

 

Collapse | Copy Code
 int a = 50 // initialize variable a

 

 

Figure: Variable value store inside an array

 

It is like a house which has an address and this house has only one room. So the full address is-

Name of the house: a

Name of the person/value who live here is: 50

House Number: 4010

 

If we want to change the person/value of this house, the conventional way is, type this code line

Collapse | Copy Code
 a = 100    // new initialization

 

But using pointer we can directly go to the memory location of ‘a’ and change the person/value of this house without disturbing ‘a’. This is the main point about pointer.

 

Now the question is how we can use pointer. Type this code line:

 

Collapse | Copy Code
 int *b;    // declare pointer b

 

We transfer the memory location of a to b.

 

Collapse | Copy Code
 b = &a;    // the unary operator & gives the address of an object

 

Figure: Integer pointer b store the address of the integer variable a

 

Now, we can change the value of a without accessing a.

 

Collapse | Copy Code
 *b = 100;  // change the value of 'a' using pointer ‘b’
  cout<<a;  // show the output of 'a'

 

When you order the computer to access to access *b, it reads the content inside b, which is actually the address of a then it will follow the address and comes to the house of a and read a`s content which is 50.

 

Now the question is, if it is possible to read and change the content of b without accessing b? The answer is affirmative. We can create a pointer of pointer.

 

Collapse | Copy Code
 int **c;   //declare a pointer to a pointer
 c = &b;    //transfer the address of ‘b’ to ‘c’

 

So, we can change the value of a without disturbing variable a and pointer b.

 

Collapse | Copy Code
 **c = 200;  // change the value of ‘a’ using pointer to a pointer ‘c’
  cout<<a;  // show the output of a

 

Now the total code is:

Collapse | Copy Code
#include<iostream>
using namespace std;

int main()
{
      int a = 50;       // initialize integer variable a
      cout<<"The value of 'a': "<<a<<endl; // show the output of a

      int * b;          // declare an integer pointer b
      b = &a;           // transfer the address of 'a' to pointer 'b'
      *b = 100;         // change the value of 'a' using pointer 'b'
      cout<<"The value of 'a' using *b: "<<a<<endl;// show the output of a

      int **c;          // declare an integer pointer to pointer 'c'
      c = &b;           // transfer the address of 'b' to pointer to pointer 'c'
      **c = 200;        // change the value of 'a' using pointer to pointer 'c'
      cout<<"The value of 'a' using **c: "<<a<<endl;// show the output of a

      return 0;
}

 

Output:

 

 

This program will give you the inside view of the pointer.

Collapse | Copy Code
#include<iostream>
using namespace std;

int main()
{
      int a = 50;       // initialize integer variable a
      cout<<"Value of 'a' = "<<a<<endl;          // show the output of a
      cout<<"Memory address of 'a': "<<&a<<endl; // show the address of a
      cout<<endl;

      int * b;             // declare an integer pointer b
      b = &a;              // transfer the address of 'a' to pointer 'b'
      cout<<"Value of Pointer 'b': "<<*b<<endl;  // show the output of *b
      cout<<"Content of Pointer 'b': "<<b<<endl; // show the content of *b
      cout<<"Memory address of Pointer 'b': "<<&b<<endl; // show the address of *b
      cout<<endl;

      int **c;                // declare an integer pointer to a pointer
      c = &b;                 // transfer the address of 'b' to 'c'
      cout<<"Value of Pointer 'c': "<<**c<<endl; // show the output of **c
      cout<<"Content of Pointer 'c': "<<c<<endl;  // show the content of **c
      cout<<"Memory address of Pointer 'c': "<<&c<<endl; // show the address of **c
      cout<<endl;
      return 0;
}

 

Output:

 

We can observe that the memory address of a and the content of pointer b is same. The content of pointer c and the memory address of b is same.

 

Linked list operation

Now we have a clear view about pointer. So we are ready for creating linked list.

 

Linked list structure

Collapse | Copy Code
typedef struct node                                                
{                                                               
      int data;               // will store information
      node *next;             // the reference to the next node
};

 

First we create a structure “node”. It has two members and first is int data which will store the information and second is node *next which will hold the address of the next node. Linked list structure is complete so now we will create linked list. We can insert data in the linked list from ‘front’ and at the same time from ‘back’. Now we will examine how we can insert data from front in the linked list.

1) Insert from front

At first initialize node type.

Collapse | Copy Code
node *head = NULL;             //empty linked list

 

Then we take the data input from the user and store in the node info variable. Create a temporary node node *temp and allocate space for it.

Collapse | Copy Code
node *temp;             //create a temporary node 
temp = (node*)malloc(sizeof(node)); //allocate space for node

 

Then place info to temp->data. So the first field of the node *temp is filled. Now temp->next must become a part of the remaining linked list (although now linked list is empty but imagine that we have a 2 node linked list and head is pointed at the front) So temp->next must copy the address of the *head (Because we want insert at first) and we also want that *head will always point at front. So *head must copy the address of the node *temp.

 

Figure: Insert at first

 

Collapse | Copy Code
temp->data = info;             // store data(first field)
temp->next=head;  // store the address of the pointer head(second field)
head = temp;                  // transfer the address of 'temp' to 'head'

 

2) Traverse

Now we want to see the information stored inside the linked list. We create node *temp1. Transfer the address of *head to *temp1. So *temp1 is also pointed at the front of the linked list. Linked list has 3 nodes.

 

We can get the data from first node using temp1->data. To get data from second node, we shift *temp1 to the second node. Now we can get the data from second node.

 

Collapse | Copy Code
while( temp1!=NULL )
{
 cout<< temp1->data<<" ";// show the data in the linked list
 temp1 = temp1->next;   // tranfer the address of 'temp->next' to 'temp'
}

 

Figure: Traverse

 

This process will run until the linked list’s next is NULL.

3) Insert from back

Insert data from back is very similar to the insert from front in the linked list. Here the extra job is to find the last node of the linked list.

 

Collapse | Copy Code
node *temp1;                         // create a temporary node
temp1=(node*)malloc(sizeof(node));   // allocate space for node
temp1 = head;                  // transfer the address of 'head' to 'temp1'
while(temp1->next!=NULL) // go to the last node
      temp1 = temp1->next;//tranfer the address of 'temp1->next' to 'temp1'

 

 

Now, Create a temporary node node *temp and allocate space for it. Then place info to temp->data, so the first field of the node node *temp is filled. node *temp will be the last node of the linked list. For this reason, temp->next will be NULL. To create a connection between linked list and the new node, the last node of the existing linked list node *temp1`s second field temp1->next is pointed to node *temp.

 

 

Figure: Insert at last

 

 

Collapse | Copy Code
node *temp;                           // create a temporary node
temp = (node*)malloc(sizeof(node));  // allocate space for node
temp->data = info;                   // store data(first field)
temp->next = NULL;                   // second field will be null(last node)
temp1->next = temp;                  // 'temp' node will be the last node

4) Insert after specified number of nodes

Insert data in the linked list after specified number of node is a little bit complicated. But the idea is simple. Suppose, we want to add a node after 2nd position. So, the new node must be in 3rd position. The first step is to go the specified number of node. Let, node *temp1 is pointed to the 2nd node now.

 

Collapse | Copy Code
cout<<"ENTER THE NODE NUMBER:";
cin>>node_number;                   // take the node number from user 

node *temp1;                        // create a temporary node
temp1 = (node*)malloc(sizeof(node)); // allocate space for node
temp1 = head;

for( int i = 1 ; i < node_number ; i++ )
{
      temp1 = temp1->next;           // go to the next node

      if( temp1 == NULL )
      {
            cout<<node_number<<" node is not exist"<< endl;
            break;
      }
}

 

Now, Create a temporary node node *temp and allocate space for it. Then place info to temp->next , so the first field of the node node *temp is filled.

Collapse | Copy Code
node *temp;                          // create a temporary node
temp = (node*)malloc(sizeof(node));  // allocate space for node
temp->data = info;                   // store data(first field)

 

 

To establish the connection between new node and the existing linked list, new node’s next must pointed to the 2nd node’s (temp1) next . The 2nd node’s (temp1) next must pointed to the new node(temp).

Collapse | Copy Code
temp->next = temp1->next;            //transfer the address of temp1->next to temp->next
temp1->next = temp;     //transfer the address of temp to temp1->next

 

Figure: Insert after specified number of nodes

 

 

5) Delete from front

Delete a node from linked list is relatively easy. First, we create node *temp. Transfer the address of *head to *temp. So *temp is pointed at the front of the linked list. We want to delete the first node. So transfer the address of temp->next to head so that it now pointed to the second node. Now free the space allocated for first node.

 

Collapse | Copy Code
node *temp;                                      // create a temporary node
temp = (node*)malloc(sizeof(node));  // allocate space for node
temp = head;                   // transfer the address of 'head' to 'temp'
head = temp->next;      // transfer the address of 'temp->next' to 'head'
free(temp);

 

Figure: Delete at first node

 

 

6) Delete from back

The last node`s next of the linked list always pointed to NULL. So when we will delete the last node, the previous node of last nodeis now pointed at NULL. So, we will track last node and previous node of the last node in the linked list. Create temporary node * temp1 and *old_temp.

Collapse | Copy Code
// create a temporary node
node *temp1;
temp1 = (node*)malloc(sizeof(node)); // allocate space for node
temp1 = head;                        //transfer the address of head to temp1
node *old_temp;                     // create a temporary node
old_temp = (node*)malloc(sizeof(node));    // allocate space for node

while(temp1->next!=NULL)             // go to the last node
{
      old_temp = temp1; // transfer the address of 'temp1' to 'old_temp'
      temp1 = temp1->next;       // transfer the address of 'temp1->next' to 'temp1'
}

 

Now node *temp1 is now pointed at the last node and *old_temp is pointed at the previous node of the last node. Now rest of the work is very simple. Previous node of the last node old_temp will be NULL so it become the last node of the linked list. Free the space allocated for last lode.

Collapse | Copy Code
old_temp->next = NULL;         // previous node of the last node is null
free(temp1);

 

Figure: Delete at first last

 

7) Delete specified number of node

To delete a specified node in the linked list, we also require to find the specified node and previous node of the specified node. Create temporary node * temp1, *old_temp and allocate space for it. Take the input from user to know the number of the node.

Collapse | Copy Code
node *temp1;                         // create a temporary node
temp1 = (node*)malloc(sizeof(node)); // allocate space for node
temp1 = head;                  // transfer the address of 'head' to 'temp1'

node *old_temp;                     // create a temporary node
old_temp = (node*)malloc(sizeof(node));    // allocate space for node
old_temp = temp1;       // transfer the address of 'temp1' to 'old_temp'

 

Collapse | Copy Code
cout<<"ENTER THE NODE NUMBER:";
cin>>node_number;                    // take location

 

Collapse | Copy Code
for( int i = 1 ; i < node_number ; i++ )
{
      old_temp = temp1;                    // store previous node
      temp1 = temp1->next;                 // store current node

}

 

Now node *temp1 is now pointed at the specified node and *old_temp is pointed at the previous node of the specified node. The previous node of the specified node must connect to the rest of the linked list so we transfer the address of temp1->next to old_temp->next. Now free the space allocated for the specified node.

Collapse | Copy Code
old_temp->next = temp1->next;  // transfer the address of 'temp1->next' to 'old_temp->next'
free(temp1);

 

 

8) Sort nodes

Linked list sorting is very simple. It is just like ordinary array sorting. First we create two temporary node node *temp1, *temp2 and allocate space for it. Transfer the address of first node to temp1 and address of second node to temp2. Now check if temp1->data is greater than temp2->data. If yes then exchange the data. Similarly, we perform this checking for all the nodes.

 

Collapse | Copy Code
node *temp1;                         // create a temporary node
temp1 = (node*)malloc(sizeof(node)); // allocate space for node

node *temp2;                         // create a temporary node
temp2 = (node*)malloc(sizeof(node)); // allocate space for node

int temp = 0;                        // store temporary data value

for( temp1 = head ; temp1!=NULL ; temp1 = temp1->next )
{
      for( temp2 = temp1->next ; temp2!=NULL ; temp2 = temp2->next )
      {
            if( temp1->data > temp2->data )
            {
                  temp = temp1->data;
                  temp1->data = temp2->data;
                  temp2->data = temp;
            }
      }
}

 

Conclusion

From the above discussions, I hope that everybody understands what linked list is and how we can create it. Now we can easily modify linked list according to our program requirement and try to use it for some real tasks. Those who still have some confusion about linked list, for them I will now tell you a story.

Once upon a time, an old man lived in a small village. The old man was very wise and knew many solutions about different problems. He had also special powers so he could talk to genie and spirits, and sometimes they granted his wish by using their special powers. Oneday a witch with a broom came to talk with him and ask difficult and complex issues about global warming. He was very surprised but patiently explained her about green house model and gave her advice about using biofuel in her broom. The witch was very rude and greedy but she always liked to preach her nobility. So at the time of her departure, she wanted to grant only two wishes. The old man asked her why she only granted two wishes. He also reminded her that whenever genie comes he granted two wishes.” What I am look like” the witch asked angrily,” A blank check?” The old man brewed a plan. He told her that his first wish was to get a super computer.” It is granted”, the witch announced loudly.” Then my second wish is to have another two wishes”, the old man said very slowly. The witch was shell shocked. “It is also granted”, the witch said and left the place very quickly with her broom.

You may ask yourself why the witch was surprised. First, the witch granted two witches. One was fulfilled and for the second wish, the old man wanted another two wish. “What’s the big idea?” you can ask me,” The witch can also fulfill this wish”. Certainly, the witch can grant his wish. But what will happen if the old man wants to extend his second wish to another two wish set. So, the process will never end unless, the old man want to stop. The idea is same for linked list. First you have a node where you can imagine that data is the first wish and node*next is the second wish by which you can create second node just like first. This process will continue until you put NULL in the *next.

 

Figure: It looks like the old man had lots of wish.

References

  1. Wikipedia, the free encyclopedia.
  2. Pointer in C, from P. Kanetkar.

 

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Nasif M.

 

Reference

http://www.codeproject.com/KB/cpp/linked_list.aspx

------------------------------------------------
         "Understanding Hash Tables"
------------------------------------------------
  C/O :: arp of DynamicHell Development Team
------------------------------------------------
  http://dynamichell.org | irc.dynamichell.org
------------------------------------------------

This tutorial is aimed at users with a basic understanding of C, pointers, and
more importantly linked lists.  This technique, like linked lists, is portable
and can be used on any operating system with a standard C library and compiler.

There are many data structures available to the programmer.  The most common
being the linked-list.  However, linked-list traversal can become quite slow
with large lists.  A hash tables provides a means of storing and accessing data
much more efficiently.

Essentially, a hash table is an array of linked-lists, with each list indexed
by the hash of a common variable stored in a node.

For large amounts of data, in which hashing is possible, hash tables become
faster to traverse than a standard linked-list.  Rather than traversing one
large list, the program tests the data to be added, generates a hash index and
inserts it into the array of linked-lists at that index.  Meaning that the 
linked-list to be traversed is much shorter; saving time.

The following diagram shows a visual representation of a hash table:

Node    : ===
Pointer : ---

 Index
  [0]---===---===---===---===---===---===---NULL
  [1]---NULL
  [2]---===---===---===---NULL
  [3]---===---===---===---===---===---NULL
  [4]---===---NULL
  ...

As you can see once the index is found, the number of nodes to traverse is much
smaller than a traditional long linked-list.

Implementing a Hash Table (C)
=============================

The traditional structure for a node in a hash table is identical to that of a
linked list:

struct node {
       char *data;
       struct node *next;
};

Now our table must be defined, remembering to define a size which is 
accessible by all parts of our program (this will become clearer later.)

#define TABLE_SIZE 100

struct node *hashtable[TABLE_SIZE];

We must now define a method of creating a new node.  It is identical to the 
function typically used in a linked-list:

struct node *hashtable_alloc(void)
{
	struct node *tmp = calloc(1, sizeof(struct hash));
	if(tmp == NULL) {
	       fprintf(stderr, "Error: calloc()\n");
	       exit(EXIT_FAILURE);
	}

	tmp->next = NULL;	

	return tmp;       
}

The next step is important--easy to forget--and involves initialising the array
of linked lists.  There are various ways to do this, though for simplicity we
will allocate one root node for each list.

void hashtable_init(void)
{
	int x;

	for(x = 0; x <TABLE_SIZE; x++) {
	      hashtable[x] = hashtable_alloc();
	}

}

Before adding to our table, we need a means of finding an index into our array;
a hashing function.  Our hashing function will take our value, a string, and
convert it into an index into our hash table (array of linked lists).

unsigned int hash_gen(char *string)
{
	unsigned int num = 0;

	while(*string++ != '')
			num += *string;

	return num % TABLE_SIZE;
}

Now able to find the correct index into the hash table, we are ready to add 
data to it.  A typical function for adding data to a hash table follows.  
Notice the double traversal. The first checks the whole list, up to the NULL 
pointer and acts appropriately--in this case returning.  The second traversal
ends when node->next equals NULL, so we know that the current node exists, and
thus, using its pointer will result in a successful link.

void hashtable_add(char *data)
{
	unsigned int x = hash_gen(data);
	struct node *tmp;
	char *strdup(const char *s);

	/* Our first loop checks to see the data doesn't already exist */

	for(tmp = hashtable[x]; tmp != NULL; tmp = tmp->next) {

		if(tmp->data != 0) { /* for our root node */

			if(!strcmp(data, tmp->data))
					 return; /* Exists already */

		}
	}

	for(tmp = hashtable[x]; tmp->next != NULL; tmp = tmp->next);

	if(tmp->next == NULL) { 
		     tmp->next = hashtable_alloc();
		     tmp = tmp->next;
		     tmp->data = strdup(data);
		     tmp->next = NULL;
	} else
		exit(EXIT_FAILURE); 
}

With our functions for creating nodes, generating a hash and adding data to 
the hash table, we are now ready to write a function to read the data from the
list.  This entails looping through the table and traversing each list as you
would a linked-list.

void hashtable_list(void)
{
	int x = 0;
	struct node *tmp;

	for(x = 0; x < TABLE_SIZE; x++) {

		for(tmp = hashtable[x]; tmp != NULL; tmp = tmp->next) {
			if(tmp->name != 0) {
		                printf("Index is %d, Data is %s\n", x, 
							     tmp->data);
			}
		}

	}
}

We are almost complete.  The only thing that remains to be done is to clean up
once we have finished with our hash table.  We use two temporary pointers in 
order to reconnect to the list once one node has been freed.

void hashtable_free(void)
{
	struct node *tmp;
	struct node *fwd;
	int x;

	for(x = 0; x < TABLE_SIZE; x++) {

	      tmp = hashtable[x];
	      while(tmp != NULL) {
	              fwd = tmp->next;
		      free(tmp->data);
		      free(tmp);
		      tmp = fwd;

	      }
	}
}

Again as with linked lists we never modify the pointer to a root node as this
would break our lists.

Final Code
==========

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define TABLE_SIZE 100

struct node {
       char *data;
       struct node *next;
};

struct node *hashtable[TABLE_SIZE]; /* Our hash table */

struct node *hashtable_alloc(void);
void hashtable_init(void);
unsigned int hash_gen(char *string);
void hashtable_add(char *data);
void hashtable_list(void);
void hashtable_free(void);

int main(void)
{
	hashtable_init();

	hashtable_add("David");
	hashtable_add("Goliath");
	hashtable_add("Alan");

	hashtable_list();

	hashtable_free();

	return EXIT_SUCCESS;
}

void hashtable_list(void)
{
	int x = 0;
	struct node *tmp;

	for(x = 0; x < TABLE_SIZE; x++) {

		for(tmp = hashtable[x]; tmp != NULL; tmp = tmp->next) {
			if(tmp->data != 0) {
		                printf("Index is %d, Data is %s\n", x, 
							     tmp->data);
			}
		}

	}
}

void hashtable_add(char *data)
{
	unsigned int x = hash_gen(data);
	struct node *tmp;
	char *strdup(const char *s);

	/* Our first loop checks to see the data doesn't already exist */

	for(tmp = hashtable[x]; tmp != NULL; tmp = tmp->next) {

		if(tmp->data != 0) { /* for our root node */

			if(!strcmp(data, tmp->data))
					 return;
		}
	}

	for(tmp = hashtable[x]; tmp->next != NULL; tmp = tmp->next);

	if(tmp->next == NULL) { 
		     tmp->next = hashtable_alloc();
		     tmp = tmp->next;
		     tmp->data = strdup(data);
		     tmp->next = NULL;
	} else
		exit(EXIT_FAILURE); 
}

unsigned int hash_gen(char *string)
{
	unsigned int num = 0;

	while(*string++ != '')
			num += *string;

	return num % TABLE_SIZE;
}

void hashtable_init(void)
{
	int x;

	for(x = 0; x <TABLE_SIZE; x++) {
	      hashtable[x] = hashtable_alloc();
	}

}

struct node *hashtable_alloc(void)
{
	struct node *tmp = calloc(1, sizeof(struct node));
	if(tmp == NULL) {
	       fprintf(stderr, "Error: calloc()\n");
	       exit(EXIT_FAILURE);
	}

	tmp->next = NULL;	

	return tmp;       
}

void hashtable_free(void)
{
	struct node *tmp;
	struct node *fwd;
	int x;

	for(x = 0; x < TABLE_SIZE; x++) {

	      tmp = hashtable[x];
	      while(tmp != NULL) {
	              fwd = tmp->next;
		      free(tmp->data);
		      free(tmp);
		      tmp = fwd;

	      }
	}
}

Improvements
============

There are various improvements which could be made to this design.  Firstly, 
the hash table could be larger to avoid unnecessary collisions.  Secondly,
instead of wasting memory by allocating one root node for each array of linked
lists, we could allocate on demand, instead initialising by setting each 
linked-list to NULL.  Another suggestion is to use a bitmap for defining used
and unused lists.  The program could quickly check the bits and decide whether
to allocate or to traverse.  

Summary
=======

Hash tables are faster than large linked lists.  They--like linked lists--are 
used throughout the software industry.  

The root node of any list is never directly modified, only pointers to it, so
not to damage the list's structure.

There are various ways to improve hash table efficiency.

Copright (c) 2006.  Alastair Poole.

Verbatim copying and distribution of this entire article are permitted
worldwide, without royalty, in any medium, provided this notice, and the
copyright notice, are preserved.

Reference
http://web.textfiles.com/hacking/DYNAMICHELL/hashtables.txt

Passing array with intents

Posted: September 12, 2011 in Android

 

 

I have an array of integers in the activity A:

int array[] = {1,2,3};

And i want to send that variable to the activity B, so i create a new intent and use the putExtra method:

Intent i = new Intent(A.this, B.class);
i.putExtra("numbers", array);
startActivity(i);

In the activity B i get the info:

Bundle extras = getIntent().getExtras();
int arrayB = extras.getInt("numbers");

But this is not really sending the array, i just get the value ‘0’ on the arrayB. I’ve been looking for some examples but i didnt found anything so… Can anybody help me here?😀

Thanxs!

 

 

8down voteaccepted

You are setting the extra with an array. You are then trying to get a single int.

Your code should be:

int[] arrayB = extras.getIntArray("numbers");

Reference

http://stackoverflow.com/questions/3848148/sending-information-with-intent-putextra

Intents

Posted: September 11, 2011 in Android

Android folds multiple ideas, (to name some: invoking other applications, invoking other components, events, actions, publish and subscribe), in to what is called an “Intent”.

At the simplest level you can use an intent to start an application that you write. Imagine you write an application whose startign screen or activity is called MY_SCREEN. Then you can have other programs invoke that screen by calling this function:

 public static invokeMyApplication(Activity parentActivity) { String actionName= "com.your-company.your-app.intent.action.MY_SCREEN"; Intent intent = new Intent(actionName); parentActivity.startActivity(intent); } 

The name of an action follows Java-style naming convention. For built in android actions such as Intent.ACTION_VIEW you would put android.intent.action.VIEW here. Or you can use the defined constant in your code: Intent.ACTION_VIEW. Custom actions should generally use a prefix matching the package name.

However the comes after your java package name is arbitrary but if you were to follow the android convention then it should “.intent.action.YOUR_ACTION_NAME”.

To make this work your application have to announce in androidmanifest.xml that it can be invoked for this action. Here is an example

 <activity android:name="MyApplication" android:label="@string/my_application_label"> <intent-filter> <action android:name="com.your-company.your-app.intent.action.MY_SCREEN" /> </intent-filter> </activity> 

Available Intents in Android

As Android comes with a predefined set of applications, it is reasonable to assume that there are some prefabricated applications out there that we can quickly invoke and test our understanding of intents. That is indeed the case. The following url

 http://code.google.com/android/reference/available-intents.html 

documents the available intents. These include

  • A browser application to open a browser window
  • An application to call a telephone number
  • An application to present the dialer to type in the numbers and then call through the UI
  • A mapping application to show the map of the world at a given lat long
  • A detailed mapping application that can show google street views

Here is some sample code that exercises each of these applications

 public class IntentsUtils { public static void invokeWebBrowser(Activity activity) { Intent intent = new Intent(Intent.ACTION_VIEW); intent.setData(Uri.parse("http://www.google.com")); activity.startActivity(intent); } public static void invokeWebSearch(Activity activity) { Intent intent = new Intent(Intent.ACTION_WEB_SEARCH); intent.setData(Uri.parse("http://www.google.com")); activity.startActivity(intent); } public static void dial(Activity activity) { Intent intent = new Intent(Intent.ACTION_DIAL); activity.startActivity(intent); } public static void call(Activity activity) { Intent intent = new Intent(Intent.ACTION_CALL); intent.setData(Uri.parse("tel:904-905-5646")); activity.startActivity(intent); } public static void showMapAtLatLong(Activity activity) { Intent intent = new Intent(Intent.ACTION_VIEW); //geo:lat,long?z=zoomlevel&q=question-string intent.setData(Uri.parse("geo:0,0?z=4&q=business+near+city")); activity.startActivity(intent); } public static void tryOneOfThese(Activity activity) { IntentsUtils.call(activity); } } 

Intents and Data Uris

we have covered simplest of the intents where all we need is the name of an action. The ACTION_DIAL activity above falls under this criteria just like the “MY_SCREEN” example we started with. So to invoke the dialler all we need is the action of the dialler and nothing else. So let us reconsider that example:

 public static void dial(Activity activity) { Intent intent = new Intent(Intent.ACTION_DIAL); activity.startActivity(intent); } 

However if you notice other intents above you will see that they take an additional parameter called “Data” which normally points to a Uri. Let us take a look at the CALL activity

 public static void call(Activity activity) { Intent intent = new Intent(Intent.ACTION_CALL); intent.setData(Uri.parse("tel:904-905-5646")); activity.startActivity(intent); } 

For example one can not call a phone number unless they know what the phone number is. So invoking a “ACTION_CALL” would be useless unless we tell what number to call. This is what gets passed through the Data uri. so we now know that an “intent” has atleast two parts

  1. Action
  2. Data

Action is pointed by a string constant as we discussed earlier usually prefixed by the java package name. The Data portion is always a string representing a uri. The format of this uri could be specific to each Activity that is invoked by that action. In this case the “CALL” action decides what kind of data uri it would expect. From the Uri it extracts the telephone number.

The activity can also use the Uri as a pointer to a data source and extract the data from the data source and use that data instead. This would be the case for media such as audio and video or images.

Generic Actions

The actions Intent.ACTION_CALL and Intent.ACTION_DIAL could easily lead us to a wrong assumption that there is a one to one relationship between an action and what it invokes. To disprove this let us extract a counter example from the sample code above:

 public static void invokeWebBrowser(Activity activity) { Intent intent = new Intent(Intent.ACTION_VIEW); intent.setData(Uri.parse("http://www.google.com")); activity.startActivity(intent); } 

If you notice, the action is simply stated as ACTION_VIEW. How does Android know which activity to invoke in response to such a generic action. Well android under these cases rely more heavily on the nature of the Uri. In this case it looks at the scehme of the uri which happens to be “http” and inquires all the registered activities to see which ones understand this scheme. Out of these it inquires which ones can handle the “VIEW” and then invokes that activity. For this to work the browser activity should have registered a VIEW intent against the data scheme of “http”. That intent declaration may look like

 <intent-filter> <action android:name="android.intent.action.VIEW" /> <data android:scheme="http"/> <data android:scheme="https"/> </intent-filter> 

You can learn more about the data options by looking at the XML definition for the Data element at

 http://code.google.com/android/reference/android/R.styleable.html#AndroidManifestData 

The child elements or attributes of data include

 host mimeType path pathPattern pathPrefix port scheme 

The one that is often used is the mime type. For example the following IntentFilter for the activity that displays (views) a list of notes indicate the mime type as a directory of notes.

 <intent-filter> <action android:name="android.intent.action.VIEW" /> <data android:mimeType="vnd.android.cursor.dir/vnd.google.note" /> </intent-filter> 

Where as the screen that displays a single note declares its intent filter as handling of type “a single note item”

 <intent-filter> <action android:name="android.intent.action.INSERT" /> <data android:mimeType="vnd.android.cursor.dir/vnd.google.note" /> </intent-filter> 

Using Extra Info

Intent provides another facility to pass data between senders and receivers of an intent. This data is sometimes refered as “Extra” data. This “extra” data that an “Intent” carries with it is a set of key value pairs. The keys are recommended to start with the package name. The value can be any fundamental data type or an arbitrary object as long as it implements the Parcelable interface. So in that sense a bundle is a maping from string keys to various Parcelable type values.

A Parcelable interface allows classes to write their instances to and restored from a Parcel. A Parcel is a container for a message (data and object references) that can be sent through an IBinder. A Parcel can contain both flattened data that will be unflattened on the other side of the IPC (using the various methods here for writing specific types, or the general Parcelable interface), and references to live IBinder objects that will result in the other side receiving a proxy IBinder connected with the original IBinder in the Parcel.

Parcel is not a general-purpose serialization mechanism. This class (and the corresponding Parcelable API for placing arbitrary objects into a Parcel) is designed as a high-performance IPC transport. As such, it is not appropriate to place any Parcel data in to persistent storage: changes in the underlying implementation of any of the data in the Parcel can render older data unreadable.

There are a number of methods available on the “Intent” class to set and get this extra open ended data. Underneath an “Intent” stores this extra data as a single “Bundle”. With that information most of the methods related to “extra” information would make sense.

start with

 public static void exerciseExtraInfo(Intent intent) { //Get the Bundle from this intent Bundle extraBundle = intent.getExtras(); // Bundle anotherBundle = new Bundle(); ... intent.putExtras(anotherBundle); } 

Here is what “putExtras” does. It checks to see if there is currently a bundle in the intent. If it is there it adds the additional keys and values from the new bundle to this existing bundle. If the bundle doesn’t exist it will create a new one and adds the stuff from the new bundle to that bundle. So it is important to note that it doesn’t reference the incoming bundle rather replicates it. Which means if you were to change the passed in bundle it won’t change the bundle inside the Intent.

A number of methods exist to add fundamental types to the bundle. Here is a sample that adds simple data types to the “extra” data

 putExtra(String name, boolean value); putExtra(String name, int value); putExtra(String name, double value); putExtra(String name, String value); .... .... and more 

And here are some not so simple extras

 //simple array support putExtra(String name, int[] values); putExtra(String name, float[] values); //Serializable objects putExtra(String name, Serializable value); //Parcelable support putExtra(String name, Parcelable value); //Add another bundle at a given key //Bundles in bundles putExtra(String name, Bundle value); //Add bundles from another intent //copy of bundles putExtra(String name, Intent anotherIntent); //Explicit Array List support putIntegerArrayListExtra(String name, ArrayList arrayList); putParcelableArrayListExtra(String name, ArrayList arrayList); putStringArrayListExtra(String name, ArrayList arrayList); 

On the receiving side there are equivalent methods that start with “get” to get retrieve information from the extra bundle based on key names.

The “Intent” class defines a number of Extra key strings that go with certain actions. Here are some examples

EXTRA_ALARM_COUNT: Used as an int extra field in AlarmManager intents to tell the application being invoked how many pending alarms are being delievered with the intent. For one-shot alarms this will always be 1. For recurring alarms, this might be greater than 1 if the device was asleep or powered off at the time an earlier alarm would have been delivered. Constant Value: “android.intent.extra.ALARM_COUNT”

EXTRA_EMAIL: A String[] holding e-mail addresses that should be delivered to. Constant Value: “android.intent.extra.EMAIL”

EXTRA_SUBJECT: A constant string holding the desired subject line of a message. Constant Value: “android.intent.extra.SUBJECT”

EXTRA_BCC: A String[] holding e-mail addresses that should be blind carbon copied. Constant Value: “android.intent.extra.BCC”

EXTRA_CC: A String[] holding e-mail addresses that should be carbon copied. Constant Value: “android.intent.extra.CC”

EXTRA_DONT_KILL_APP: Used as an boolean extra field in ACTION_PACKAGE_REMOVED or ACTION_PACKAGE_CHANGED intents to override the default action of restarting the application. Constant Value: “android.intent.extra.DONT_KILL_APP”

EXTRA_INTENT: An Intent describing the choices you would like shown with ACTION_PICK_ACTIVITY. Constant Value: “android.intent.extra.INTENT”

EXTRA_KEY_EVENT: A KeyEvent object containing the event that triggered the creation of the Intent it is in. Constant Value: “android.intent.extra.KEY_EVENT”

EXTRA_PHONE_NUMBER: A String holding the phone number originally entered in ACTION_NEW_OUTGOING_CALL, or the actual number to call in a ACTION_CALL. Constant Value: “android.intent.extra.PHONE_NUMBER”

EXTRA_SHORTCUT_ICON: The name of the extra used to define the icon, as a Bitmap, of a shortcut. Used in conjunction with ACTION_CREATE_SHORTCUT action. Constant Value: “android.intent.extra.shortcut.ICON

EXTRA_SHORTCUT_ICON_RESOURCE: The name of the extra used to define the icon, as a ShortcutIconResource, of a shortcut. Constant Value: “android.intent.extra.shortcut.ICON_RESOURCE”

EXTRA_SHORTCUT_INTENT: The name of the extra used to define the Intent of a shortcut. Constant Value: “android.intent.extra.shortcut.INTENT”

EXTRA_SHORTCUT_NAME: The name of the extra used to define the name of a shortcut. Constant Value: “android.intent.extra.shortcut.NAME”

EXTRA_STREAM: A content: URI holding a stream of data associated with the Intent, used with ACTION_SEND to supply the data being sent. Constant Value: “android.intent.extra.STREAM”

EXTRA_TEXT: A constant CharSequence that is associated with the Intent, used with ACTION_SEND to supply the literal data to be sent. Note that this may be a styled CharSequence, so you must use Bundle.getCharSequence() to retrieve it. Constant Value: “android.intent.extra.TEXT”

EXTRA_TEMPLATE: The initial data to place in a newly created record. Use with ACTION_INSERT. The data here is a Map containing the same fields as would be given to the underlying ContentProvider.insert() call. Constant Value: “android.intent.extra.TEMPLATE”

EXTRA_TITLE: A CharSequence dialog title to provide to the user when used with a ACTION_CHOOSER. Constant Value: “android.intent.extra.TITLE”

EXTRA_UID: Used as an int extra field in ACTION_UID_REMOVED intents to supply the uid the package had been assigned. Also an optional extra in ACTION_PACKAGE_REMOVED or ACTION_PACKAGE_CHANGED for the same purpose. Constant Value: “android.intent.extra.UID”

Using components to directly invoke an Activity

In Android Activity, Service, ContentProvider and Application are considered application components. They all implement ComponentCallbacks. As an implementer of ComponentCallbacks they are expected to support two call back apis: onConfigurationChanged and onLowMemory.

The signatures of these methods are

 public void onConfigurationChanged(Configuration newConfig); public void onLowMemory(); 

onConfigurationChanged is called by the system when the device configuration changes while that component is running. Note that, unlike activities, other components are never restarted when a configuration changes: they must always deal with the results of the change, such as by re-retrieving resources.

onLowMemory() is called when the overall system is running low on memory, and would like actively running process to try to tighten their belt. While the exact point at which this will be called is not defined, generally it will happen around the time all background processes have been killed, that is before reaching the point of killing processes hosting service and foreground UI that we would like to avoid killing. Applications that want to be nice can implement this method to release any caches or other unnecessary resources they may be holding on to. The system will perform a gc after returning from this method.

An Activity being a component we can specify the name of this component or class name as an argument to the Intent and use start activity on the intent to start the target activity identified by the component name.

In a similar manner a target service component can be started using the “startService” method on the context class.

There are a number of methods available on the Intent class to specify a component.

 setComponent(ComponentName name); setClassName(String packageName, String classNameInThatPackage); setClassName(Context context, String classNameInThatContext); setClass(Context context, Class classObjectInThatContext); 

Ultimately they are all shortcuts for calling one method

 setComponent(ComponentName name); 

Curiously ComponentName is a class which basically wraps a package name and a classname together. Although a component name is expected to point to a component implementing a “component” contract, the constructor of ComponentName does not do any particular checks to ensure that.

For example the following code invokes the “contacts” activity that gets shipped with the emulator

 Intent intent = new Intent(); intent.setComponent(new ComponentName( "com.android.contacts" ,"com.android.contacts.DialtactsContactsEntryActivity"); intent.setFlags(....) startActivity(intent) 

Notice that the package name and the classname are fully qualified and used in turn to construct the ComponentName before passing to the intent class.

However it must be noted that this is not the recommended way to invoke other appications. The approach is fine for activities that are are inside an application. But for applications or activities that need to be invoked from outside they should go through the action and data uri route.

Best practice for component designers

If you look at the design for the contacts application in Android you will notice some patterns for designing with intents. In the example above we have used an explicit way to invoke the contacts application.

To make this easier the “android.provider.contacts” package defines three Intent related classes. These are

 contacts.Intents contacts.Intents.Insert //nested class contacts.Intents.UI //nested class 

The top level class “Intents” defines the primary Intents that the contacts application will respond to and also the events it generates as it does its work.

The nested class Intents.Insert defines the supporing intents and other constants to insert new records. The Intents.UI nested class defines a number of ways invoking the UI. The intents here also clarifies the extra information needed to invoke the intents including key names and their expected value types.

As you design your own content providers and activites that act upon those content providers you may want to follow this pattern for making intents explicit.

What are categories and how are they used

Categories is a way to classify activities. As activities are designed, they may have certain capabilities that will restrict them or enable them under some circumstances. These common characteristics of these activities are declared through categories. Let us look at some known categories

 CATEGORY_DEFAULT CATEGORY_BROWSABLE CATEGORY_TAB CATEGORY_ALTERNATIVE CATEGORY_SELECTED_ALTERNATIVE CATEGORY_LAUNCHER CATEGORY_HOME CATEGORY_PREFERENCE CATEGORY_GADGET CATEGORY_TEST CATEGORY_EMBED 

let us examine a few of these categories whose meaning is obvious. Take for insnace GADGET category. Activities enabled for this category, can be embedded inside of another activity that is hosting gadgets. The implication is that such an activity needs to be bound by certain contracts. In a similar manner The EMBED category declares that an activity is capable of being embedded in a parent activity.

Here is an explanation for each of these categories.

CATEGORY_DEFAULT:Set if the activity should be an option for the default action (center press) to perform on a piece of data. Setting this will hide from the user any activities without it set when performing an action on some data. Note that this is normal -not- set in the Intent when initiating an action — it is for use in intent filters specified in packages. Constant Value: “android.intent.category.DEFAULT”

CATEGORY_BROWSABLE: Activities that can be safely invoked from a browser must support this category. For example, if the user is viewing a web page or an e-mail and clicks on a link in the text, the Intent generated execute that link will require the BROWSABLE category, so that only activities supporting this category will be considered as possible actions. By supporting this category, you are promising that there is nothing damaging (without user intervention) that can happen by invoking any matching Intent. Constant Value: “android.intent.category.BROWSABLE”

CATEGORY_TAB: Intended to be used as a tab inside of an containing TabActivity.

CATEGORY_ALTERNATIVE: Set if the activity should be considered as an alternative action to the data the user is currently viewing. See also CATEGORY_SELECTED_ALTERNATIVE for an alternative action that applies to the selection in a list of items. Supporting this category means that you would like your activity to be displayed in the set of alternative things the user can do, usually as part of the current activity’s options menu. You will usually want to include a specific label in the of this action describing to the user what it does.

The action of IntentFilter with this category is important in that it describes the specific action the target will perform. This generally should not be a generic action (such as ACTION_VIEW, but rather a specific name such as “com.android.camera.action.CROP. Only one alternative of any particular action will be shown to the user, so using a specific action like this makes sure that your alternative will be displayed while also allowing other applications to provide their own overrides of that particular action.

CATEGORY_EMBED: Capable of running inside a parent activity container. However this is being removed in favor of more explicit categories such as CATEGORY_GADGET

CATEGORY_SELECTED_ALTERNATIVE: Set if the activity should be considered as an alternative selection action to the data the user has currently selected. This is like CATEGORY_ALTERNATIVE, but is used in activities showing a list of items from which the user can select, giving them alternatives to the default action that will be performed on it.

CATEGORY_LAUNCHER: Should be displayed in the top-level launcher.

CATEGORY_HOME: This is the home activity, that is the first activity that is displayed when the device boots.

CATEGORY_PREFERENCE: This activity is a development preference panel.

CATEGORY_GADGET: This activity can be embedded inside of another activity that is hosting gadgets.

CATEGORY_TEST: To be used as a test (not part of the normal user experience).

CATEGORY_MONKEY: This activity may be exercised by the monkey or other automated test tools.

CATEGORY_OPENABLE: Used to indicate that a GET_CONTENT intent only wants URIs that can be opened with ContentResolver.openInputStream. Openable URIs must support the columns in OpenableColumns when queried, though it is allowable for those columns to be blank.

Categories and Intents

When you use an intent to start an activity, you can specify the kind of activity to choose by specifying a category. Or you can also search for activites that match a certain category.

Here is an example to retrieve a set of main activities that match the category of CATEGORY_SAMPLE_CODE. PackageManager is a key class that allows discovery of activities that match a certain intent with out invoking them. A programmer can cycle through the received activities and invoke them as see fit based on the ResolveInfo api.

 Intent mainIntent = new Intent(Intent.ACTION_MAIN, null); mainIntent.addCategory(Intent.CATEGORY_SAMPLE_CODE); PackageManager pm = getPackageManager(); List<ResolveInfo> list = pm.queryIntentActivities(mainIntent, 0); 

Following the same logic we can also get a list of all launchable applications by populating an intent with a category of CATEGORY_LAUNCHER. The sample code for this is below

 //Get me all launchable applications Intent mainIntent = new Intent(Intent.ACTION_MAIN, null); mainIntent.addCategory(Intent.CATEGORY_LAUNCHER); List mApps = getPackageManager().queryIntentActivities(mainIntent, 0); 

In fact we can do better. Let us go ahead and start an activity based on the Intent above. There are going to be more than one activity matching the intent. Which activity is Android going to start? Android instead presents a chooser dialog listing all possible activities. The title of this dialog says “Complete action using”.

 public static void invokeAMainApp(Activity activity) { Intent mainIntent = new Intent(Intent.ACTION_MAIN, null); mainIntent.addCategory(Intent.CATEGORY_LAUNCHER); activity.startActivity(mainIntent); } 

Here is another example of using an intent to go to a home page.

 //Go to home screen Intent mainIntent = new Intent(Intent.ACTION_MAIN, null); mainIntent.addCategory(Intent.CATEGORY_HOME); startActivity(mainIntent); 

You can also write your own home page instead of one that comes with Android and declare that activity to be of category HOME and then the code above will give you an option to open your home activity as there are now more than one home activities registered.

 //Replace the home screen with yours <intent-filter> <action android:value="android.intent.action.MAIN" /> <category android:value="android.intent.category.HOME"/> <category android:value="android.intent.category.DEFAULT" /> </intent-filter> 

Also note that when we launch these intents, they are still being launched as a new instance that is part of the same task/stack. If we want to launch it as a separate task (or bring the currently running instance of the app to the foreground) like the home app does, then we need to set the NEW_TASK_LAUNCH flag in the Intent.

The rules for resolving Intents to their components

So far we have discussed a number of aspects about intents. To recap we talked about actions, data uris, extra infos, and finally categories. Given these aspects Android uses the following algorithm to resolve the intents to activities or more specifically components:

At the top of the hierarchy, with an air of exclusivity, is the Component name attached to an intent. If this is set, then every other aspect or attribute of the intent is ignored and that component is chosen for execution.

If an intent indicates an action then the target activity must have that action listed as one it supports in the manifest file.

If an intent specifies a data uri, the type is retrieved from this uri, if not already supplied in the Intent. Like the action, if a type is included in the intent (either explicitly or implicitly in its data), then this must be listed by the component as one it handles.

For data that is not a content: URI and where no explicit type is included in the Intent, instead the scheme of the intent data (such as http: or mailto:) is considered. Again like the action, if we are matching a scheme it must be listed by the component as one it can handle.

The categories, if supplied, must all be listed by the activity as categories it handles. That is, if you include the categories CATEGORY_LAUNCHER and CATEGORY_ALTERNATIVE, then you will only resolve to components with an intent that lists both of those categories. Activities will very often need to support the CATEGORY_DEFAULT so that they can be found by Context.startActivity().

How should your applications declare intents

As you write new applications for Android you will want to declare intents for each of the activities you have in that application. Let us examine the notepad application to draw a pattern of these intent declarations.

 <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.notepad"> <application android:icon="@drawable/app_notes" android:label="@string/app_name"> <provider android:authorities="com.google.provider.NotePad" /> <activity android:label="@string/title_notes_list"> <intent-filter> <action android:value="android.intent.action.MAIN" /> <category android:value="android.intent.category.LAUNCHER" /> </intent-filter> <intent-filter> <action android:value="android.intent.action.VIEW" /> <action android:value="android.intent.action.EDIT" /> <action android:value="android.intent.action.PICK" /> <category android:value="android.intent.category.DEFAULT" /> <type android:value="vnd.android.cursor.dir/vnd.google.note" /> </intent-filter> <intent-filter> <action android:value="android.intent.action.GET_CONTENT" /> <category android:value="android.intent.category.DEFAULT" /> <type android:value="vnd.android.cursor.item/vnd.google.note" /> </intent-filter> </activity> <activity android:label="@string/title_note"> <intent-filter android:label="@string/resolve_edit"> <action android:value="android.intent.action.VIEW" /> <action android:value="android.intent.action.EDIT" /> <category android:value="android.intent.category.DEFAULT" /> <type android:value="vnd.android.cursor.item/vnd.google.note" /> </intent-filter> <intent-filter> <action android:value="android.intent.action.INSERT" /> <category android:value="android.intent.category.DEFAULT" /> <type android:value="vnd.android.cursor.dir/vnd.google.note" /> </intent-filter> </activity> <activity android:label="@string/title_edit_title" android:theme="@android:style/Theme.Dialog"> <intent-filter android:label="@string/resolve_title"> <action android:value="com.android.notepad.action.EDIT_TITLE" /> <category android:value="android.intent.category.DEFAULT" /> <category android:value="android.intent.category.ALTERNATIVE" /> <category android:value="android.intent.category.SELECTED_ALTERNATIVE" /> <type android:value="vnd.android.cursor.item/vnd.google.note" /> </intent-filter> </activity> </application> </manifest> 

As you can see there are three activities in this application that are exposed for public consumption. They are

 NotesList NoteEditor TitleEditor 

NotesList is the main entry point of the application listing all the notes in the database of notes. NoteEditor is the screen that allows you the content of a given note. A TitleEditor is the screen that allows you to edit the title of a note. You will want to put an icon in the launcher of android so that the notes application can be invoked. To facilitate this the main activity NotesList declares an intent as follows:

 <intent-filter> <action android:value="android.intent.action.MAIN" /> <category android:value="android.intent.category.LAUNCHER" /> </intent-filter> 

This allows Android to add this activity as a launchable activity. List activity is can also be invoked explicitly by some other program to view or edit a collection of notes in the notepad.

 <intent-filter> <action android:value="android.intent.action.VIEW" /> <action android:value="android.intent.action.EDIT" /> <action android:value="android.intent.action.PICK" /> <category android:value="android.intent.category.DEFAULT" /> <type android:value="vnd.android.cursor.dir/vnd.google.note" /> </intent-filter> 

By declaring a “PICK” action the NotesList activity is allowing the user to pick an item from the collection and return to the caller. This activity is also capable of returning the data for a given note item by allowing the user to pick one of the items of a note using the following intent. As you can see for these generic supported actions the main key is the mime type of the data. So an activity defines a set of allowed actions for each mime type in a separate filter.

 <intent-filter> <action android:value="android.intent.action.GET_CONTENT" /> <category android:value="android.intent.category.DEFAULT" /> <type android:value="vnd.android.cursor.item/vnd.google.note" /> </intent-filter> 

Let’s look at the NotesEditor activity to see how it defines its intent filters

 <activity android:label="@string/title_note"> <intent-filter android:label="@string/resolve_edit"> <action android:value="android.intent.action.VIEW" /> <action android:value="android.intent.action.EDIT" /> <category android:value="android.intent.category.DEFAULT" /> <type android:value="vnd.android.cursor.item/vnd.google.note" /> </intent-filter> <intent-filter> <action android:value="android.intent.action.INSERT" /> <category android:value="android.intent.category.DEFAULT" /> <type android:value="vnd.android.cursor.dir/vnd.google.note" /> </intent-filter> </activity> 

In the first intent filter it allows you to see and edit a single note. In the second filter it allows you to insert a note in to a directory of notes.

Finally lets look at the title editor

 <activity android:label="@string/title_edit_title" android:theme="@android:style/Theme.Dialog"> <intent-filter android:label="@string/resolve_title"> <action android:value="com.android.notepad.action.EDIT_TITLE" /> <category android:value="android.intent.category.DEFAULT" /> <category android:value="android.intent.category.ALTERNATIVE" /> <category android:value="android.intent.category.SELECTED_ALTERNATIVE" /> <type android:value="vnd.android.cursor.item/vnd.google.note" /> </intent-filter> </activity> 

This activity allows you to show a set of menu items to edit a title of a note. Notice that the action is a specific type and not a generic action.

Given these definitions here is what you can do with intents outside of this application

{ action=android.app.action.MAIN }: matches all of the activities that can be used as top-level entry points into an application.

{ action=android.app.action.MAIN, category=android.app.category.LAUNCHER }: is the actual intent used by the Launcher to populate its top-level list.

{ action=android.app.action.VIEW data=content://com.google.provider.NotePad/notes }: displays a list of all the notes under “content://com.google.provider.NotePad/notes”, which the user can browse through and see the details on.

{ action=android.app.action.PICK data=content://com.google.provider.NotePad/notes }: provides a list of the notes under “content://com.google.provider.NotePad/notes”, from which the user can pick a note whose data URL is returned back to the caller.

{ action=android.app.action.GET_CONTENT type=vnd.android.cursor.item/vnd.google.note }: is similar to the pick action, but allows the caller to specify the kind of data they want back so that the system can find the appropriate activity to pick something of that data type.

{ action=android.app.action.VIEW data=content://com.google.provider.NotePad/notes/{ID} }: shows the user the content of note {ID}.

{ action=android.app.action.EDIT data=content://com.google.provider.NotePad/notes/{ID} }: allows the user to edit the content of note {ID}.

{ action=android.app.action.INSERT data=content://com.google.provider.NotePad/notes }: creates a new, empty note in the notes list at “content://com.google.provider.NotePad/notes” and allows the user to edit it. If they keep their changes, the URI of the newly created note is returned to the caller.

{ action=com.android.notepad.action.EDIT_TITLE data=content://com.google.provider.NotePad/notes/{ID} }: displays and allows the user to edit the title associated with note {ID}.

Exercising ACTION_PICK intent

So far we have exercised intents or actions that mainly invoke another activity and not expect any result back. Let us look at an activity that is a bit more involved and which returns a value as a result of that activity. ACTION_PICK is one such action. Here is what the documentation says about ACTION_PICK:

ACTION_PICK picks an item from the data, returning what was selected. The intent invoking ACTION_PICK should carry with it a URI containing a directory of data (vnd.android.cursor.dir/*) from which to pick an item. This should be set using the setData() on the intent. The output from the action will be a URI of the item that was picked.

For all actions and intents that return data like this we cannot use startActivity() because startActivity() does not return any result. The reason why startActivity can not return result is because it opens the new activity as a modal dialog in a separate thread and leaves the main thread for attending events in the main ui thread. In other words “startActivity” is an asynchronous call with any call back to indicate what happened in the invoked activity. There is a variation on this method called startActivityForResult() that comes with a call back.

Let us look at the signature of this method from the Activity class:

 public void startActivityForResult(Intent intent, int requestCode) 

This method launches an activity for which you would like a result when it finished. When this activity exits, your onActivityResult() method will be called with the given requestCode. Using a negative requestCode is the same as calling startActivity(Intent) (the activity is not launched as a sub-activity).

Note that this method should only be used with Intent protocols that are defined to return a result. In other protocols (such as ACTION_MAIN or ACTION_VIEW), you may not get the result when you expect. For example, if the activity you are launching uses the singleTask launch mode, it will not run in your task and thus you will immediately receive a cancel result.

The result will come back to the activity through an overriden method called onActivityResult. The signature of this method is

 protected void onActivityResult(int requestCode, int resultCode, Intent data) 

Called when an activity you launched exits, giving you the requestCode you started it with, the resultCode it returned, and any additional data from it. The resultCode will be RESULT_CANCELED if the activity explicitly returned that, didn’t return any result, or crashed during its operation. You will receive this call immediately before onResume() when your activity is re-starting.

When an activity exits, it can call setResult(int) to return data back to its parent. It must always supply a result code, which can be the standard results RESULT_CANCELED, RESULT_OK, or any custom values starting at RESULT_FIRST_USER. In addition, it can optionally return back an Intent containing any additional data it wants. All of this information appears back on the parent’s Activity.onActivityResult(), along with the integer identifier it originally supplied. If a child activity fails for any reason (such as crashing), the parent activity will receive a result with the code RESULT_CANCELED.

Let us look at some samplecode demonstrating this

 Intent pickIntent = new Intent(Intent.ACTION_PICK); pickIntent.setData(Uri.parse("content://contacts")); int requestCode = 1; activity.startActivityForResult(pickIntent,requestCode); protected void onActivityResult(int requestCode, int resultCode, Intent outputIntent) { if (requestCode == 1) { if (resultCode == RESULT_OK) { Uri outputUri = outputIntent.getData(); //Log it out Log.d("test",outputUri.toString()); //Do something with the uri including viewing it outputIntent.setAction(Intent.VIEW); startActivity(outputIntent); } } } 

The constants RESULT_OK, RESULT_CANCEL, RESULT_FIRST_USER are all defined in the activity class. The numerical values of these constants are

 RESULT_OK = -1; RESULT_CANCEL = 0; RESULT_FIRST_USER = 1; 

The constant RESULT_FIRST_USER is used as a starting number for user defined activity results.

To make this work the implementer should have code that explicitly addresses the needs of a PICK. Notice how this is done in the sample note pad application. When the item is selected in the list of items, the intent that invoked the activity is checked to see if it is a PICK intent. If it is the data uri is set in a new intent and returned through setResult().

 @Override protected void onListItemClick(ListView l, View v, int position, long id) { Uri uri = ContentUris.withAppendedId(getIntent().getData(), id); String action = getIntent().getAction(); if (Intent.ACTION_PICK.equals(action) || Intent.ACTION_GET_CONTENT.equals(action)) { // The caller is waiting for us to return a note selected by // the user. The have clicked on one, so return it now. setResult(RESULT_OK, new Intent().setData(uri)); } else { // Launch activity to view/edit the currently selected item startActivity(new Intent(Intent.ACTION_EDIT, uri)); } } 

Exercising GET_CONTENT action

ACTION_GET_CONTENT allows the user to select a particular kind of data and return it. This is different than ACTION_PICK in that here we just say what kind of data is desired, not a URI of existing data from which the user can pick. A ACTION_GET_CONTENT could allow the user to create the data as it runs (for example taking a picture or recording a sound), let them browser over the web and download the desired data, etc.

Notice how the activity that displays a list of notes in the notepad application declares itself in response to PICK and GET_CONTENT:

 <intent-filter> <action android:name="android.intent.action.VIEW" /> <action android:name="android.intent.action.EDIT" /> <action android:name="android.intent.action.PICK" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="vnd.android.cursor.dir/vnd.google.note" /> </intent-filter> <intent-filter> <action android:name="android.intent.action.GET_CONTENT" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="vnd.android.cursor.item/vnd.google.note" /> </intent-filter> 

For a PICK action you need to specify the uri which will yield a mime type of “directory of note” indicated by dir/note which will then resolve to this list activity.

The get_content action is defined in a separate filter identified by not a directory of notes but just an “item” of a note indicated by “item/note”. For a GET_CONTENT you will not specify the URI.

The sample code then will look like

 Intent intent = new Intent(Intent.ACTION_PICK); intent.setType("vnd.android.cursor.item/vnd.google.note"); int requestCode = 1; activity.startActivityForResult(pickIntent,requestCode); 

Knowing the mime type android will then launch the best application to select that kind of data for you.

GET_CONTENT action also allows another way of picking a data uri. For instance, you may be interested in any of a set of types of content that you can pick. For example, an e-mail application that wants to allow the user to add an attachment to an e-mail message can use this action to bring up a list of all of the types of content the user can attach.

In this case, you should wrap the GET_CONTENT intent with a chooser (through createChooser(Intent, CharSequence)), which will give the proper interface for the user to pick how to send your data and allow you to specify a prompt indicating what they are doing. You will usually specify a broad MIME type (such as image/* or */*), resulting in a broad range of content types the user can select from.

When using such a broad GET_CONTENT action, it is often desireable to only pick from data that can be represented as a stream. This is accomplished by requiring the CATEGORY_OPENABLE in the Intent.

To reiterate the input to an ACTION_GET_CONTENT is the desired MIME type to retrieve. No URI is supplied in the intent, as there are no constraints on where the returned data originally comes from. You may also include the CATEGORY_OPENABLE if you can only accept data that can be opened as a stream. The result of invoking this action is a URI of the item that was picked. This must be a content: URI so that any receiver can access it.

List of of useful actions defined in Intent

Here is a quick sample of actions that the Intent class defines

 ACTION_MAIN ACTION_VIEW ACTION_ATTACH_DATA ACTION_EDIT ACTION_PICK ACTION_CHOOSER ACTION_GET_CONTENT ACTION_DIAL ACTION_CALL ACTION_SEND ACTION_SENDTO ACTION_ANSWER ACTION_INSERT ACTION_DELETE ACTION_RUN ACTION_SYNC ACTION_PICK_ACTIVITY ACTION_SEARCH ACTION_WEB_SEARCH ACTION_FACTORY_TEST 

The details of each of these actions are

ACTION_ALL_APPS: List all available applications

ACTION_MAIN: Invoke the main screen of an application.

ACTION_VIEW : Show an activity that is capable of seeing a uri. Input is the uri of the data to be shown.

ACTION_ATTACH_DATA: Used to indicate that some piece of data should be attached to some other place. For example, image data could be attached to a contact. It is up to the recipient to decide where the data should be attached; the intent does not specify the ultimate destination. Input is the Uri of the data to be attached. It has no output.

ACTION_EDIT : A generic action for editing data at a given input uri. no output.

ACTION_PICK : Picks the uri of a data item from a directory of data items. Input is the data uri for the directory of items. the output is the data uri of a specific item.

ACTION_CHOOSER :Activity Action: Display an activity chooser, allowing the user to pick what they want to before proceeding. This can be used as an alternative to the standard activity picker that is displayed by the system when you try to start an activity with multiple possible matches, with these differences in behavior:

You can specify the title that will appear in the activity chooser. The user does not have the option to make one of the matching activities a preferred activity, and all possible activities will always be shown even if one of them is currently marked as the preferred activity.

This action should be used when the user will naturally expect to select an activity in order to proceed. An example if when not to use it is when the user clicks on a “mailto:” link. They would naturally expect to go directly to their mail app, so startActivity() should be called directly: it will either launch the current preferred app, or put up a dialog allowing the user to pick an app to use and optionally marking that as preferred.

In contrast, if the user is selecting a menu item to send a picture they are viewing to someone else, there are many different things they may want to do at this point: send it through e-mail, upload it to a web service, etc. In this case the CHOOSER action should be used, to always present to the user a list of the things they can do, with a nice title given by the caller such as “Send this photo with:”.

As a convenience, an Intent of this form can be created with the createChooser(Intent, CharSequence) function.

Input: No data should be specified. get*Extra must have a EXTRA_INTENT field containing the Intent being executed, and can optionally have a EXTRA_TITLE field containing the title text to display in the chooser.

ACTION_GET_CONTENT: Similar to PICK but uses the data type instead of the data uri.

ACTION_DIAL : Show the dialler allowing a user to dial a number. Can pass a phone uri to prepopulate the dialler. No output.

ACTION_CALL : Make a call based on a phone uri. You may need permissions to call a number like this. You should use DIAL where needed. Emergency numbers can be dialled only through DIAL.

ACTION_SEND:Deliver some data to someone else. Who the data is being delivered to is not specified; it is up to the receiver of this action to ask the user where the data should be sent. When launching a SEND intent, you should usually wrap it in a chooser (through createChooser(Intent, CharSequence)), which will give the proper interface for the user to pick how to send your data and allow you to specify a prompt indicating what they are doing.

The intent should specify the MIME type of the data being sent. get*Extra can have either a EXTRA_TEXT or EXTRA_STREAM field, containing the data to be sent. If using EXTRA_TEXT, the MIME type should be “text/plain”; otherwise it should be the MIME type of the data in EXTRA_STREAM. Use */* if the MIME type is unknown (this will only allow senders that can handle generic data streams).

Optional standard extras, which may be interpreted by some recipients as appropriate, are: EXTRA_EMAIL, EXTRA_CC, EXTRA_BCC, EXTRA_SUBJECT.

ACTION_SENDTO: Send a message to someone specified by the data.

ACTION_ANSWER: Handle an incoming phone call. No inputs and outputs.

ACTION_INSERT : Insert an empty item into a given container. Needs a data uri pointing to the directory of items. Output is the uri of the data that was inserted.

ACTION_INSERT_OR_EDIT: Pick an existing item, or insert a new item, and then edit it. Input is the desired MIME type of the item to create or edit. The extras can contain type specific data to pass through to the editing/creating activity. Output is the URI of the item that was picked.

ACTION_DELETE : Delete what is pointed to by a Uri. Input is the data uri that is to be deleted. No outputs.

ACTION_SEARCH: invoke search activity using extra string information

ACTION_WEB_SEARCH: Opens a web page to search

ACTION_BUG_REPORT: show activity to report a bug. no inputs or outputs.

ACTION_SET_WALLPAPER: Show settings for chosing a wall paper

ACTION_VOICE_COMMAND: Start voice command

Here are some broadcast actions

ACTION_BATTERY_CHANGED: Charge level of the battery changed

ACTION_BATTERY_LOW: Battery is low

ACTION_BOOT_COMPLETED: This is broadcast once, after the system has finished booting. It can be used to perform application-specific initialization, such as installing alarms. You must hold the RECEIVE_BOOT_COMPLETED permission in order to receive this broadcast.

ACTION_CALL_BUTTON: The user pressed the “call” button to go to the dialer or other appropriate UI for placing a call. no inputs and outputs.

ACTION_CAMERA_BUTTON: The “Camera Button” was pressed. Includes a single extra field, EXTRA_KEY_EVENT, containing the key event that caused the broadcast.

ACTION_DATE_CHANGED: The date has changed.

ACTION_MEDIA_BUTTON: Media button was pressed. Includes a single extra field, EXTRA_KEY_EVENT, containing the key event that caused the broadcast.

ACTION_MEDIA_EJECT: User has expressed the desire to remove the external storage media. Applications should close all files they have open within the mount point when they receive this intent. The path to the mount point for the media to be ejected is contained in the Intent.mData field.

ACTION_MEDIA_MOUNTED: External media is present and mounted at its mount point. The path to the mount point for the removed media is contained in the Intent.mData field. The Intent contains an extra with name “read-only” and Boolean value to indicate if the media was mounted read only.

ACTION_PACKAGE_ADDED: A new package has been installed on the device. Name of the package will be in the intent.

ACTION_PACKAGE_CHANGED: A named package has been changed either by enabling a component or disabling.

ACTION_PACKAGE_INSTALL: A trigger to download and eventual installation of a package. The data part of the intent contains the uri of the package to download.

ACTION_PACKAGE_REMOVED: A named package has been removed.

ACTION_PROVIDER_CHANGED: Some content providers have parts of their namespace where they publish new events or items that the user may be especially interested in. For these things, they may broadcast this action when the set of interesting items change. For example, GmailProvider sends this notification when the set of unread mail in the inbox changes.

The data of the intent identifies which part of which provider changed. When queried through the content resolver, the data URI will return the data set in question.

The intent will have the following extra values:

count – The number of items in the data set. This is the same as the number of items in the cursor returned by querying the data URI. This intent will be sent at boot (if the count is non-zero) and when the data set changes. It is possible for the data set to change without the count changing (for example, if a new unread message arrives in the same sync operation in which a message is archived). The phone should still ring/vibrate/etc as normal in this case.

ACTION_SCREEN_OFF: Screen turned off

ACTION_SCREEN_ON: Screen turned on

ACTION_TIMEZONE_CHANGED: Time zone has changed. The id of the new time zone will be the extra info.

ACTION_TIME_CHANGED: The time was set.

ACTION_TIME_TICK: Sent every minute.

ACTION_UID_REMOVED: User id removed from the system. The user ID number is stored in the extra data under EXTRA_UID.

ACTION_WALLPAPER_CHANGED: Wall paper has changed.

Intent Flags

Intents use a set of flags to control the behavior of how new activities are invoked. Here is a brief look at these flags

FLAG_ACTIVITY_BROUGHT_TO_FRONT: This flag is not normally set by application code, but set for you by the system as described in the launchMode documentation for the singleTask mode.

FLAG_ACTIVITY_CLEAR_TOP : If set, and the activity being launched is already running in the current task, then instead of launching a new instance of that activity, all of the other activities on top of it will be closed and this Intent will be delivered to the (now on top) old activity as a new Intent.

For example, consider a task consisting of the activities: A, B, C, D. If D calls startActivity() with an Intent that resolves to the component of activity B, then C and D will be finished and B receive the given Intent, resulting in the stack now being: A, B.

The currently running instance of task B in the above example will either receiving the new intent you are starting here in its onNewIntent() method, or be itself finished and restarting with the new intent. If it has declared its launch mode to be “multiple” (the default) it will be finished and re-created; for all other launch modes it will receive the Intent in the current instance.

This launch mode can also be used to good effect in conjunction with FLAG_ACTIVITY_NEW_TASK: if used to start the root activity of a task, it will bring any currently running instance of that task to the foreground, and then clear it to its root state. This is especially useful, for example, when launching an activity from the notification manager.

FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS: If set, the new activity is not kept in the list of recently launched activities.

FLAG_ACTIVITY_FORWARD_RESULT :If set and this intent is being used to launch a new activity from an existing one, then the reply target of the existing activity will be transfered to the new activity. This way the new activity can call setResult(int) and have that result sent back to the reply target of the original activity.

FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY: If set, this activity is being launched from history (longpress home key).

FLAG_ACTIVITY_MULTIPLE_TASK :Do not use this flag unless you are implementing your own top-level application launcher. Used in conjunction with FLAG_ACTIVITY_NEW_TASK to disable the behavior of bringing an existing task to the foreground. When set, a new task is always started to host the Activity for the Intent, regardless of whether there is already an existing task running the same thing. Because the default system does not include graphical task management, you should not use this flag unless you provide some way for a user to return back to the tasks you have launched.

This flag is ignored if FLAG_ACTIVITY_NEW_TASK is not set.

FLAG_ACTIVITY_NEW_TASK :If set, this activity will become the start of a new task on this history stack. A task (from the activity that started it to the next task activity) defines an atomic group of activities that the user can move to. Tasks can be moved to the foreground and background; all of the activities inside of a particular task always remain in the same order. See the Application Model documentation for more details on tasks.

This flag is generally used by activities that want to present a “launcher” style behavior: they give the user a list of separate things that can be done, which otherwise run completely independently of the activity launching them.

When using this flag, if a task is already running for the activity you are now starting, then a new activity will not be started; instead, the current task will simply be brought to the front of the screen with the state it was last in. See FLAG_ACTIVITY_MULTIPLE_TASK for a flag to disable this behavior.

This flag can not be used when the caller is requesting a result from the activity being launched.

FLAG_ACTIVITY_NO_HISTORY : If set, the new activity is not kept in the history stack.

FLAG_ACTIVITY_PREVIOUS_IS_TOP : If set and this intent is being used to launch a new activity from an existing one, the current activity will not be counted as the top activity for deciding whether the new intent should be delivered to the top instead of starting a new one. The previous activity will be used as the top, with the assumption being that the current activity will finish itself immediately.

FLAG_ACTIVITY_RESET_TASK_IF_NEEDED :If set, and this activity is either being started in a new task or bringing to the top an existing task, then it will be launched as the front door of the task. This will result in the application of any affinities needed to have that task in the proper state (either moving activities to or from it), or simply resetting that task to its initial state if needed.

FLAG_ACTIVITY_SINGLE_TOP : If set, the activity will not be launched if it is already running at the top of the history stack.

FLAG_DEBUG_LOG_RESOLUTION : A flag you can enable for debugging: when set, log messages will be printed during the resolution of this intent to show you what has been found to create the final resolved list.

FLAG_FROM_BACKGROUND : Can be set by the caller to indicate that this Intent is coming from a background operation, not from direct user interaction.

FLAG_GRANT_READ_URI_PERMISSION: If set, the recipient of this Intent will be granted permission to perform read operations on the Uri in the Intent’s data.

FLAG_GRANT_WRITE_URI_PERMISSION : If set, the recipient of this Intent will be granted permission to perform write operations on the Uri in the Intent’s data.

FLAG_RECEIVER_REGISTERED_ONLY : If set, when sending a broadcast only registered receivers will be called — no BroadcastReceiver components will be launched.

Definitions for EXTRA Info

EXTRA_TEMPLATE :The initial data to place in a newly created record. Use with ACTION_INSERT. The data here is a Map containing the same fields as would be given to the underlying ContentProvider.insert() call.

EXTRA_TEXT :A constant CharSequence that is associated with the Intent, used with ACTION_SEND to supply the literal data to be sent. Note that this may be a styled CharSequence, so you must use Bundle.getCharSequence() to retrieve it.

EXTRA_TITLE :A CharSequence dialog title to provide to the user when used with a ACTION_CHOOSER.

EXTRA_UID :Used as an int extra field in ACTION_UID_REMOVED intents to supply the uid the package had been assigned. Also an optional extra in ACTION_PACKAGE_REMOVED or ACTION_PACKAGE_CHANGED for the same purpose.

The string keys for these extras start with “android.intent.extra.*”

satya – Saturday, February 05, 2011 11:03:40 AM

Directly invoking an intent

 private void invokeTabNav() { Intent i = new Intent(this,ActionBarActivity.class); startActivity(i); }


Reference
http://www.satyakomatineni.com/akc/display?url=DisplayNoteBodyURL&ownerUserId=satya&reportId=2884

Converting UTM to Latitude and Longitude (Or Vice Versa)

Steven Dutch, Natural and Applied Sciences, University of Wisconsin – Green Bay
First-time Visitors: Please visit Site Map and Disclaimer. Use “Back” to return here


Information on the UTM system
New! Javascript-Convert Between Geographic and UTM Coordinates
Spreadsheet For UTM Conversion
Help! My Data Doesn’t Look Like A UTM Grid!

I get enough inquiries on this subject that I decided to create a page for it.

Caution! Unlike latitude and longitude, there is no physical frame of reference for UTM grids. Latitude is determined by the earth’s polar axis. Longitude is determined by the earth’s rotation. If you can see the stars and have a sextant and a good clock set to Greenwich time, you can find your latitude and longitude. But there is no way to determine your UTM coordinates except by calculation.

UTM grids, on the other hand, are created by laying a square grid on the earth. This means that different maps will have different grids depending on the datum used (model of the shape of the earth). I saw US military maps of Germany shift their UTM grids by about 300 meters when a more modern datum was used for the maps. Also, old World War II era maps of Europe apparently used a single grid for all of Europe and grids in some areas are wildly tilted with respect to latitude and longitude.

The two basic references for converting UTM and geographic coordinates are U.S. Geological Survey Professional Paper 1395 and U. S. Army Technical Manual TM 5-241-8 (complete citations below). Each has advantages and disadvantages.

For converting latitude and longitude to UTM, the Army publication is better. Its notation is more consistent and the formulas more clearly laid out, making code easier to debug. In defense of the USGS, their notation is constrained by space, and the need to be consistent with cartographic literature and descriptions of several dozen other map projections in the book.

For converting UTM to latitude and longitude, however, the Army publication has formulas that involve latitude (the quantity to be found) and which require reverse interpolation from tables. Here the USGS publication is the only game in town.

Some extremely tiny terms that will not seriously affect meter-scale accuracy have been omitted.

Converting Between Decimal Degrees, Degrees, Minutes and Seconds, and Radians

(dd + mm/60 +ss/3600) to Decimal degrees (dd.ff)

dd = whole degrees, mm = minutes, ss = seconds

dd.ff = dd + mm/60 + ss/3600

Example: 30 degrees 15 minutes 22 seconds = 30 + 15/60 + 22/3600 = 30.2561

Decimal degrees (dd.ff) to (dd + mm/60 +ss/3600)

For the reverse conversion, we want to convert dd.ff to dd mm ss. Here ff = the fractional part of a decimal degree.

mm = 60*ff

ss = 60*(fractional part of mm)

Use only the whole number part of mm in the final result.

30.2561 degrees = 30 degrees

.2561*60 = 15.366 minutes

.366 minutes = 22 seconds, so the final result is 30 degrees 15 minutes 22 seconds

Decimal degrees (dd.ff) to Radians

Radians = (dd.ff)*pi/180

Radians to Decimal degrees (dd.ff)

(dd.ff) = Radians*180/pi

Degrees, Minutes and Seconds to Distance

A degree of longitude at the equator is 111.2 kilometers. A minute is 1853 meters. A second is 30.9 meters. For other latitudes multiply by cos(lat). Distances for degrees, minutes and seconds in latitude are very similar and differ very slightly with latitude. (Before satellites, observing those differences was a principal method for determining the exact shape of the earth.)

Converting Latitude and Longitude to UTM

Okay, take a deep breath. This will get very complicated, but the math, although tedious, is only algebra and trigonometry. It would sure be nice if someone wrote a spreadsheet to do this. Or better yet, a Javascript page.

P = point under consideration
F = foot of perpendicular from P to the central meridian. The latitude of F is called the footprint latitude.
O = origin (on equator)
OZ = central meridian
LP = parallel of latitude of P
ZP = meridian of P
OL = k0S = meridional arc from equator
LF = ordinate of curvature
OF = N = grid northing
FP = E = grid distance from central meridian
GN = grid north
C = convergence of meridians = angle between true and grid north

Another thing you need to know is the datum being used:

Datum Equatorial Radius, meters (a) Polar Radius, meters (b) Flattening (a-b)/a Use
NAD83/WGS84 6,378,137 6,356,752.3142 1/298.257223563 Global
GRS 80 6,378,137 6,356,752.3141 1/298.257222101 US
WGS72 6,378,135 6,356,750.5 1/298.26 NASA, DOD
Australian 1965 6,378,160 6,356,774.7 1/298.25 Australia
Krasovsky 1940 6,378,245 6,356,863.0 1/298.3 Soviet Union
International (1924) -Hayford (1909) 6,378,388 6,356,911.9 1/297 Global except as listed
Clake 1880 6,378,249.1 6,356,514.9 1/293.46 France, Africa
Clarke 1866 6,378,206.4 6,356,583.8 1/294.98 North America
Airy 1830 6,377,563.4 6,356,256.9 1/299.32 Great Britain
Bessel 1841 6,377,397.2 6,356,079.0 1/299.15 Central Europe, Chile, Indonesia
Everest 1830 6,377,276.3 6,356,075.4 1/300.80 South Asia

Don’t interpret the chart to mean there is radical disagreement about the shape of the earth. The earth isn’t perfectly round, it isn’t even a perfect ellipsoid, and slightly different shapes work better for some regions than for the earth as a whole. The top three are based on worldwide data and are truly global. Also, you are very unlikely to find UTM grids based on any of the earlier projections.

The most modern datums (jars my Latinist sensibilities since the plural of datum in Latin is data, but that has a different meaning to us) are NAD83 and WGS84. These are based in turn on GRS80. Differences between the three systems derive mostly from redetermination of station locations rather than differences in the datum. Unless you are locating a first-order station to sub-millimeter accuracy (in which case you are way beyond the scope of this page) you can probably regard them as essentially identical.

I have no information on the NAD83 and WGS84 datums, nor can my spreadsheet calculate differences between those datums and WGS84.

Formulas For Converting Latitude and Longitude to UTM

These formulas are slightly modified from Army (1973). They are accurate to within less than a meter within a given grid zone. The original formulas include a now obsolete term that can be handled more simply – it merely converts radians to seconds of arc. That term is omitted here but discussed below.

Symbols

  • lat = latitude of point
  • long = longitude of point
  • long0 = central meridian of zone
  • k0  = scale along long0 = 0.9996. Even though it’s a constant, we retain it as a separate symbol to keep the numerical coefficients simpler, also to allow for systems that might use a different Mercator projection.
  • e = SQRT(1-b2/a2) = .08 approximately. This is the eccentricity of the earth’s elliptical cross-section.
  • e’2 = (ea/b)2 = e2/(1-e2) = .007 approximately. The quantity e’ only occurs in even powers so it need only be calculated as e’2.
  • n = (a-b)/(a+b)
  • rho = a(1-e2)/(1-e2sin2(lat))3/2. This is the radius of curvature of the earth in the meridian plane.
  • nu = a/(1-e2sin2(lat))1/2. This is the radius of curvature of the earth perpendicular to the meridian plane. It is also the distance from the point in question to the polar axis, measured perpendicular to the earth’s surface.
  • p = (long-long0) in radians (This differs from the treatment in the Army reference)

Calculate the Meridional Arc

S is the meridional arc through the point in question (the distance along the earth’s surface from the equator). All angles are in radians.

  • S = A’lat – B’sin(2lat) + C’sin(4lat) – D’sin(6lat) + E’sin(8lat), where lat is in radians and
  • A’ = a[1 – n + (5/4)(n2 – n3) + (81/64)(n4 – n5) …]
  • B’ = (3 tanS/2)[1 – n + (7/8)(n2 – n3) + (55/64)(n4 – n5) …]
  • C’ = (15 tan2S/16)[1 – n + (3/4)(n2 – n3)  …]
  • D’ = (35 tan3S/48)[1 – n + (11/16)(n2 – n3)  …]
  • E’ = (315 tan4S/512)[1 – n  …]

The USGS gives this form, which may be more appealing to some. (They use M where the Army uses S)

  • M = a[(1 – e2/4 – 3e4/64 – 5e6/256 ….)lat
    – (3e2/8 + 3e4/32 + 45e6/1024…)sin(2lat)
    + (15e4/256 + 45e6/1024 + ….)sin(4lat)
    – (35e6/3072 + ….) sin(6lat) + ….)] where lat is in radians

This is the hard part. Calculating the arc length of an ellipse involves functions called elliptic integrals, which don’t reduce to neat closed formulas. So they have to be represented as series.

Converting Latitude and Longitude to UTM

All angles are in radians.

y = northing = K1 + K2p2 + K3p4, where

  • K1 = Sk0,
  • K2 = k0 nu sin(lat)cos(lat)/2 = k0 nu sin(2 lat)/4
  • K3 = [k0 nu sin(lat)cos3(lat)/24][(5 – tan2(lat) + 9e’2cos2(lat) + 4e’4cos4(lat)]

x = easting = K4p + K5p3, where

  • K4 = k0 nu cos(lat)
  • K5 = (k0 nu cos3(lat)/6)[1 – tan2(lat) + e’2cos2(lat)]

Easting x is relative to the central meridian. For conventional UTM easting add 500,000 meters to x.

What the Formulas Mean

The hard part, allowing for the oblateness of the Earth, is taken care of in calculating S (or M). So K1 is simply the arc length along the central meridian of the zone corrected by the scale factor. Remember, the scale is a hair less than 1 in the middle of the zone, and a hair more on the outside.

All the higher K terms involve nu, the local radius of curvature (roughly equal to the radius of the earth or roughly 6,400,000 m), trig functions, and powers of e’2 ( = .007 ). So basically they are never much larger than nu. Actually the maximum value of K2 is about nu/4 (1,600,000), K3 is about nu/24 (267,000) and K5 is about nu/6 (1,070,000). Expanding the expressions will show that the tangent terms don’t affect anything.

If we were just to stop with the K2 term in the northing, we’d have a quadratic in p. In other words, we’d approximate the parallel of latitude as a parabola. The real curve is more complex. It will be more like a hyperbola equatorward of about 45 degrees and an ellipse poleward, at least within the narrow confines of a UTM zone. (At any given latitude we’re cutting the cone of latitude vectors with an inclined plane, so the resulting intersection will be a conic section. Since the projection cylinder has a curvature, the exact curve is not a conic but the difference across a six-degree UTM zone is pretty small.)  Hence the need for higher order terms. Now p will never be more than +/-3 degrees = .05 radians, so p2 is always less than .0025 (1/400) and p4 is always less than .00000625 (1/160000). Using a spreadsheet, it’s easy to see how the individual terms vary with latitude. K2p2 never exceeds 4400 and K3p4 is at most a bit over 3. That is, the curvature of a parallel of latitude across a UTM zone is at most a little less than 4.5 km and the maximum departure from a parabola is at most a few meters.

K4 is what we’d calculate for easting in a simple-minded way, just by calculating arc distance along the parallel of latutude. But, as we get farther from the central meridian, the meridians curve inward, so our actual easting will be less than K4. That’s what K5 does. Since p is never more than +/-3 degrees = .05 radians, p3 is always less than .000125 (1/8000). The maximum value of K5p3 is about 150 meters.

That Weird Sin 1″ Term in the Original Army Reference

The Army reference defines p in seconds of arc and includes a sin 1″ term in the K formulas. The Sin 1″ term is a holdover from the days when this all had to be done on mechanical desk calculators (pre-computer) and terms had to be kept in a range that would  retain sufficient precision at intermediate steps. For that small an angle the difference between sin 1″ and 1″ in radians is negligible. If p is in seconds of arc, then (psin 1″) merely converts it to radians.

The sin 1″ term actually included an extra factor of 10,000, which was then corrected by multiplying by large powers of ten afterward.

The logic is a bit baffling. If I were doing this on a desk calculator, I’d factor out as many terms as possible rather than recalculate them for each term. But perhaps in practice the algebraically obvious way created overflows or underflows, since calculators could only handle limited ranges.

In any case, the sin1″ term is not needed any more. Calculate p in radians and omit the sin1″ terms and the large power of ten multipliers.

Converting UTM to Latitude and Longitude

In response to innumerable e-mails, you cannot use UTM grid coordinates without knowing your zone. There are sixty points on the earth’s surface that have the same numerical UTM coordinates, 120 if you consider that northing is duplicated in both hemispheres.

y = northing, x = easting (relative to central meridian; subtract 500,000 from conventional UTM coordinate).

Calculate the Meridional Arc

This is easy: M = y/k0.

Calculate Footprint Latitude

  • mu = M/[a(1 – e2/4 – 3e4/64 – 5e6/256…)
  • e1 = [1 – (1 – e2)1/2]/[1 + (1 – e2)1/2]

footprint latitude fp = mu + J1sin(2mu) + J2sin(4mu) + J3sin(6mu) + J4sin(8mu), where:

  • J1 = (3e1/2 – 27e13/32 ..)
  • J2 = (21e12/16 – 55e14/32 ..)
  • J3 = (151e13/96 ..)
  • J4 = (1097e14/512 ..)

Calculate Latitude and Longitude

  • e’2 = (ea/b)2 = e2/(1-e2)
  • C1 = e’2cos2(fp)
  • T1 = tan2(fp)
  • R1 = a(1-e2)/(1-e2sin2(fp))3/2. This is the same as rho in the forward conversion formulas above, but calculated for fp instead of lat.
  • N1 = a/(1-e2sin2(fp))1/2. This is the same as nu in the forward conversion formulas above, but calculated for fp instead of lat.
  • D = x/(N1k0)

lat = fp – Q1(Q2 – Q3 + Q4), where:

  • Q1 = N1 tan(fp)/R1
  • Q2 = (D2/2)
  • Q3 = (5 + 3T1 + 10C1 – 4C12 -9e’2)D4/24
  • Q4 = (61 + 90T1 + 298C1 +45T12  – 3C12 -252e’2)D6/720

long = long0 + (Q5 – Q6 + Q7)/cos(fp), where:

  • Q5 = D
  • Q6 = (1 + 2T1 + C1)D3/6
  • Q7 = (5 – 2C1 + 28T1 – 3C12 + 8e’2 + 24T12)D5/120

What Do The Formulas Mean?

As the sketch above shows, because of the poleward curve of parallels, the footprint latitude is always greater than the true latitude. Q1 is just a scaling coefficient and is constant for any given fp. The tangent term basically means the closer to the pole you are, the faster the parallels curve. Q2 is a quadratic term in x. Again, as with converting from geographic coordinates to UTM, we approximate the parallel as a parabola and add higher order corrections.

To determine longitude, we make a simple minded approximation that longitude is proportional to easting, but then, since fp is too large, the true longitude is smaller, since it lies on a parallel closer to the the equator. The divisor cos(fp) corrects for the varying length of degrees of longitude as latitude varies.

A Spreadsheet Program

Before linking to the program, note (especially the last item):

  • It is an Excel spreadsheet. If you have Excel on your computer, it will (or should) open when you click the link. Most major spreadsheet programs can read spreadsheets in other formats.
  • A spreadsheet is not an applet or program. In particular, you can’t manually enter data into a cell and preserve any formulas that are there. That’s why some aspects of data entry are clunkier than they might otherwise be with, say, a Visual Basic program.
  • There are three computation pages, one for single conversions, the other two for batch conversions. Other pages contain information on datums and the specific conversion formulas. To use the batch conversions you need to be somewhat proficient in spreadsheets as you will have to copy data and cell formulas.
  • For our mutual peace of mind, run a virus check.
  • You may copy the program for your own non-commercial use and for non-commercial distribution to others, but not for commercial use. Please give appropriate credit when citing your calculations. You may also modify it as needed for your personal use. In Internet Explorer, right click on the link and select Save Target As… to save the spreadsheet to your own disk.
  • There is now a Javascript Page which I hope is free of some of the bugs in the spreadsheet. Since it’s a program, it should handle complex what-ifs a lot better than a spreadsheet can. All the permissions for the spreadsheet apply here, too.

Spreadsheet For UTM Conversion
JavaScript Page to Convert Between Geographic and UTM Coordinates

References

Snyder, J. P., 1987; Map Projections – A Working Manual. U.S. Geological Survey Professional Paper 1395, 383 p. If you are at all serious about maps you need this book.

Army, Department of, 1973; Universal Transverse Mercator Grid, U. S. Army Technical Manual TM 5-241-8, 64 p.

NIMA Technical Report 8350.2, “Department of Defense World Geodetic System 1984, Its Definition and Relationships with Local Geodetic Systems,” Second Edition, 1 September 1991 and its supplements. The report is available from the NIMA Combat Support Center and its stock number is DMATR83502WGS84. Non-DoD requesters may obtain the report as a public sale item from the U.S. Geological Survey, Box 25286, Denver Federal Center, Denver, Colorado 80225 or by phone at 1-800-USA-MAPS.

 

Reference

http://www.uwgb.edu/dutchs/usefuldata/utmformulas.htm

/*---------------------------------------------------------*/ /* parameters and functions for UTM<->Lat/Long conversions */ /* UTM conversion is based on WGS84 ellipsoid parameters */ /*---------------------------------------------------------*/

RADIUS = 6378137.0;
FLATTENING = 0.00335281068; /* GRS80 or WGS84 */
K_NOT = 0.9996;     /* UTM scale factor */
DEGREES_TO_RADIANS = 0.01745329252;
FALSE_EASTING = 500000.0;
FALSE_NORTHING = 10000000.0;

/*--------------------------------------------------------*/
/* These Java functions were converted from original      */
/* C fucntions provided by Dana Yoerger, Steve Gegg,      */
/* and Louis Whitcomb at WHOI                             */
/*--------------------------------------------------------*/

function geo_utm(lat, lon, zone)
{
   with(Math)
   {
      /* first compute the necessary geodetic parameters and constants */

      lambda_not = ((-180.0 + zone*6.0) -3.0)/RADIANS ;
      e_squared = 2.0 * FLATTENING - FLATTENING*FLATTENING;
      e_fourth = e_squared * e_squared;
      e_sixth = e_fourth * e_squared;
      e_prime_sq = e_squared/(1.0 - e_squared);
      sin_phi = sin(lat);
      tan_phi = tan(lat);
      cos_phi = cos(lat);
      N = RADIUS/sqrt(1.0 - e_squared*sin_phi*sin_phi);
      T = tan_phi*tan_phi;
      C = e_prime_sq*cos_phi*cos_phi;
      M = RADIUS*((1.0 - e_squared*0.25 -0.046875*e_fourth  -0.01953125*e_sixth)*lat-
	      (0.375*e_squared + 0.09375*e_fourth +
				 0.043945313*e_sixth)*sin(2.0*lat) +
	      (0.05859375*e_fourth + 0.043945313*e_sixth)*sin(4.0*lat) -
	      (0.011393229 * e_sixth)*sin(6.0*lat));
      A = (lon - lambda_not)*cos_phi;
      A_sq = A*A;
      A_fourth =  A_sq*A_sq;

      /* now go ahead and compute X and Y */

      x_utm = K_NOT*N*(A + (1.0 - T + C)*A_sq*A/6.0 +
		   (5.0 - 18.0*T + T*T + 72.0*C -
		    58.0*e_prime_sq)*A_fourth*A/120.0);

      /* note:  specific to UTM, vice general trasverse mercator.
         since the origin is at the equator, M0, the M at phi_0,
         always equals zero, and I won't compute it   */                                            

       y_utm = K_NOT*(M + N*tan_phi*(A_sq/2.0 +
			    (5.0 - T + 9.0*C + 4.0*C*C)*A_fourth/24.0 +
			    (61.0 - 58.0*T + T*T + 600.0*C -
			     330.0*e_prime_sq)*A_fourth*A_sq/720.0));

       /* now correct for false easting and northing */

       if( lat < 0)
       {
          y_utm +=10000000.0;
       }
       x_utm +=500000;
    }
    return true;
}

function utm_geo(x_utm, y_utm, zone)
{
   with(Math)
   {
      /* first, subtract the false easting */
      x_utm = x_utm - FALSE_EASTING;

      /* compute the necessary geodetic parameters and constants */

      e_squared = 2.0 * FLATTENING - FLATTENING*FLATTENING;
      e_fourth = e_squared * e_squared;
      e_sixth = e_fourth * e_squared;
      oneminuse = sqrt(1.0-e_squared);  

      /* compute the footpoint latitude */

      M = y_utm/K_NOT;
      mu =M/(RADIUS*(1.0 - 0.25*e_squared -
                  0.046875*e_fourth - 0.01953125*e_sixth));
      e1 = (1.0 - oneminuse)/(1.0 + oneminuse);
      e1sq =e1*e1;
      footpoint = mu + (1.5*e1 - 0.84375*e1sq*e1)*sin(2.0*mu) +
              (1.3125*e1sq - 1.71875*e1sq*e1sq)*sin(4.0*mu) +
              (1.57291666667*e1sq*e1)*sin(6.0*mu) +
              (2.142578125*e1sq*e1sq)*sin(8.0*mu);

      /* compute the other necessary terms */

      e_prime_sq =  e_squared/(1.0 -  e_squared);
      sin_phi = sin(footpoint);
      tan_phi = tan(footpoint);
      cos_phi = cos(footpoint);
      N = RADIUS/sqrt(1.0 - e_squared*sin_phi*sin_phi);
      T = tan_phi*tan_phi;
      Tsquared = T*T;
      C = e_prime_sq*cos_phi*cos_phi;
      Csquared = C*C;
      denom = sqrt(1.0-e_squared*sin_phi*sin_phi);
      R = RADIUS*oneminuse*oneminuse/(denom*denom*denom);
      D = x_utm/(N*K_NOT);
      Dsquared = D*D;
      Dfourth = Dsquared*Dsquared;

      lambda_not = ((-180.0 + zone*6.0) -3.0) * DEGREES_TO_RADIANS;

      /* now, use the footpoint to compute the real latitude and longitude */

      var lat = footpoint - (N*tan_phi/R)*(0.5*Dsquared - (5.0 + 3.0*T + 10.0*C -
                           4.0*Csquared - 9.0*e_prime_sq)*Dfourth/24.0 +
                           (61.0 + 90.0*T + 298.0*C + 45.0*Tsquared -
                            252.0*e_prime_sq -
                            3.0*Csquared)*Dfourth*Dsquared/720.0);
      var lon = lambda_not + (D - (1.0 + 2.0*T + C)*Dsquared*D/6.0 +
                         (5.0 - 2.0*C + 28.0*T - 3.0*Csquared + 8.0*e_prime_sq +
                          24.0*Tsquared)*Dfourth*D/120.0)/cos_phi;

   }
   return true;
}

Reference:
http://www.whoi.edu/marine/ndsf/utility/NDSFref.txt

Calculators and Convertors

Posted: September 3, 2011 in Java, Mapping

Degrees, Minutes, Seconds and Decimal Degrees Latitude/Longitude Conversions

http://transition.fcc.gov/mb/audio/bickel/DDDMMSS-decimal.html

Circle Intersection Solver

http://mysite.verizon.net/res148h4j/javascript/script_circle_intersections.html#the%20source%20code

Online Math Calculators and Solvers

http://www.analyzemath.com/Calculators.html

Calculate distance, bearing and more between two latitude/longitude points

http://www.anycalculator.com/longitude.htm

NDSF Coordinate Conversion Utility

http://www.whoi.edu/marine/ndsf/utility/NDSFutility.html

Convert Between Geographic and UTM Coordinates

http://www.uwgb.edu/dutchs/UsefulData/ConvertUTMNoOZ.HTM

802.11g

Posted: September 2, 2011 in WiFi

802.11g is one of the standards used for high speed wireless networks, commonly known as Wifi. This standard was created by the IEEE (Institute of Electrical and Electronics Engineers) in June of 2003 and uses a 2.4 to 2.5 gigahertz radio frequency to send and receive data from one device to another. There are several standards that are in use today for wireless communication, others include 802.11a, 802.11b and 802.11n. The standard 802.11g is becoming quite popular during the last several years for its speed, quality of transmission and competitive price.

More people than ever are building Wifi networks, either for their business, home use or for commercial enterprises such as to provide Internet access at a cafe. For many people, building a Wifi network usually involves the standard 802.11g.

In order to set up a home or business Wifi network on the 802.11g standard, you will need an 802.11g wireless router and an 802.11g compatible Wifi card. Usually a Wifi router is hooked up to either a broadband Internet connection or a computer server. In order for each part of the network to communicate with one another it is necessary that they all have a Wifi card able to send and receive 802.11g signals.

802.11g has become very popular as a Wifi standard in the last couple of years due to 5 major attributes. They include Speed, Range, Clarity of the Signal, Price and Compatibility

802 11g 802.11g

Speed

The max speed of 802.11g is 54 megabits per second; however expect around 11 megabits per second in normal day to day use.

Range

802.11g delivers a range of about 33 meters or about 100 feet. While this is less than its cousin 802.11b which delivers a range of about 150 feet, most people’s networks are well within this range’s limits. It is important to note that range can vary depending on many factors including whether a network is set up in an apartment, office environment, if a router is on another floor than computers tied into the network or if there is interference from signals operating close to 802.11g’s.

Clarity of the Signal

802.11g operates on the frequency 2.4 -2.5 GHZ, for the most part, the clarity of the signal is generally clear and interference free. In addition, this frequency works well penetrating walls or other types of building obstructions due to the fact it operates at low frequencies.

Price

The Price for 802.11g is relatively affordable for both corporations, home based businesses and private home networks. Expect price points around the $100 mark for both the router and Wifi cards.

Compatibility

A great reason to choose 802.11g is due to its downward compatibility with 802.11b. The “b” standard is widely used and “g” can work seamlessly with this standard.

Other 802.11 Standards

802.11b

Besides 802.11g, you should be aware of other types of standards most notably 802.11b. 802.11b is another common standard similar to “g” except that its speed is much slower at about 11 megabits per second max. However, the range of the 802.11b is slightly more than the “g” standard. Where “g” has a range of about 33 meters (100 feet), “b” standard has a range of 50 meters (150 feet). Regarding price, “b” is a little less expensive.

802.11a

This is another standard actually created at the same time as 802.11b. It operates at a higher frequency and thus sometimes has less interference. It should be noted that 802.11a has a shorter range than “b”. 802.11a is not as popular as “b” or “g”. Possibly the reason why this standard did not catch is because this standard is much more expensive than its cousin 802.11b making it less attractive to businesses and individuals.

Reference

http://www.tech-faq.com/80211g.html

using a Latitude and Longitude value (Point A), I am trying to calculate another Point B, X meters away bearing 0 radians from point A. Then display the point B Latitude and Longitude values.

Example (Pseudo code):

PointA_Lat = x.xxxx; PointA_Lng = x.xxxx; Distance = 3; //Meters bearing = 0; //radians new_PointB = PointA-Distance; 

I was able to calculate the distance between two Points but what I want to find is the second point knowing the distance and bearing.

Preferably in PHP or Javascript.

Thank you

 

4 down vote accepted

It seems you are measuring distance (R) in meters, and bearing (theta) counterclockwise from due east. And for your purposes (hundereds of meters), plane geometry should be accurate enough. In that case,

dx = R*cos(theta) ; theta measured counterclockwise from due east dy = R*sin(theta) ; dx, dy same units as R 

If theta is measured clockwise from due north (for example, compass bearings), the calculation for dx and dy is slightly different:

dx = R*sin(theta) ; theta measured clockwise from due north dy = R*cos(theta) ; dx, dy same units as R 

In either case, the change in degrees longitude and latitude is:

delta-longitude = dx/(111320*cos(latitude)) ; dx, dy in meters delta-latitude = dy/110540 ; result in degrees long/lat 

The difference between the constants 110540 and 111320 is due to the earth’s oblateness (polar and equatorial circumferences are different).

Here’s a worked example, using the parameters from a later question of yours:

Given a start location at longitude -87.62788 degrees, latitude 41.88592 degrees, find the coordinates of the point 500 meters northwest from the start location.

If we’re measuring angles counterclockwise from due east, “northwest” corresponds to theta=135 degrees. R is 500 meters.

dx = R*cos(theta) = 500 * cos(135 deg) = -353.55 meters dy = R*sin(theta) = 500 * sin(135 deg) = +353.55 meters delta_longitude = dx/(111320*cos(latitude)) = -353.55/(111320*cos(41.88592 deg)) = -.004266 deg (approx -15.36 arcsec) delta-latitude = dy/110540 = 353.55/110540 = .003198 deg (approx 11.51 arcsec) Final longitude = start_longitude + delta_longitude = -87.62788 - .004266 = -87.632146 Final latitude = start_latitude + delta_latitude = 41.88592 + .003198 = 41.889118 



Reference:

http://stackoverflow.com/questions/2187657/calculate-second-point-knowing-the-starting-point-and-distance

Positional Astronomy:
Spherical trigonometry

A great-circle arc, on the sphere, is the analogue of a straight line, on the plane.

Where two such arcs intersect, we can define the spherical angle
either as angle between the tangents to the two arcs, at the point of intersection,
or as the angle between the planes of the two great circles where they intersect at the centre of the sphere.
(Spherical angle is only defined where arcs of great circles meet.)

A spherical triangle is made up of three arcs of great circles, all less than 180°.
The sum of the angles is not fixed, but will always be greater than 180°.
If any side of the triangle is exactly 90°, the triangle is called quadrantal.

There are many formulae relating the sides and angles of a spherical triangle.
In this course we use only two: the sine rule and the cosine rule.

diagramConsider a triangle ABC on the surface of a sphere with radius = 1.

(See note)

We use the capital letters A, B, C to denote the angles at these corners;
we use the lower-case letters a, b, c to denote the opposite sides.
(Remember that, in spherical geometry, the side of a triangle is the arc of a great circle,
so it is also an angle.)


Turn the sphere so that A is at the “north pole”,
and let arc AB define the “prime meridian”.

Set up a system of rectangular axes OXYZ:
O is at the centre of the sphere;
OZ passes through A;
OX passes through arc AB (or the extension of it);
OY is perpendicular to both.
Find the coordinates of C in this system:
x = sin(b) cos(A)
y = sin(b) sin(A)
z = cos(b)

diagram

Now create a new set of axes,
keeping the y-axis fixed and moving the “pole” from A to B
(i.e. rotating the x,y-plane through angle c).
The new coordinates of C are
x’ = sin(a) cos(180-B) = – sin(a) cos(B)
y’ = sin(a) sin(180-B) =    sin(a) sin(B)
z’ = cos(a)

The relation between the old and new systems
is simply a rotation of the x,z-axes through angle c:
x’ = x cos(c) – z sin(c)
y’ = y
z’ = x sin(c) + z cos(c)

That is:
– sin(a) cos(B) = sin(b) cos(A) cos(c) – cos(b) sin(c)
sin(a) sin(B)  = sin(b) sin(A)
cos(a) = sin(b) cos(A) sin(c) + cos(b) cos(c)

These three equations give us the formulae for solving spherical triangles.

The first equation is the transposed cosine rule,
which is sometimes useful but need not be memorised.

The second equation gives the sine rule. Rearrange as:
   sin(a)/sin(A) = sin(b)/sin(B)
Similarly,
sin(b)/sin(B) = sin(c)/sin(C), etc.

So the sine rule is usually expressed as:
   sin(a)/sin(A) = sin(b)/sin(B) = sin(c)/sin(C)

The third equation gives the cosine rule:
cos(a) = cos(b) cos(c) + sin(b) sin(c) cos(A)
and similarly:
cos(b) = cos(c) cos(a) + sin(c) sin(a) cos(B)
cos(c) = cos(a) cos(b) + sin(a) sin(b) cos(C)


Here they are together:

sine rule:
   sin(a)/sin(A) = sin(b)/sin(B) = sin(c)/sin(C)

cosine rule:
cos(a) = cos(b) cos(c) + sin(b) sin(c) cos(A)
cos(b) = cos(c) cos(a) + sin(c) sin(a) cos(B)
cos(c) = cos(a) cos(b) + sin(a) sin(b) cos(C)

The cosine rule will solve almost any triangle if it is applied often enough.
The sine rule is simpler to remember but not always applicable.

Note that both formulae can suffer from ambiguity:
E.g. if the sine rule yields
sin(x) = 0.5,
then x may be 30° or 150°.
Or, if the cosine rule yields
cos(x) = 0.5,
then x may be 60° or 300° (-60°).
In this case, there is no ambiguity if x is a side of the triangle, as it must be less than 180°,
but there could still be uncertainty if an angle of the triangle was positive or negative.

So, when applying either formula, check to see if the answer is sensible.
If in doubt, recalculate using the other formula, as a check.

Exercise:

Alderney, in the Channel Islands, has longitude 2°W, latitude 50°N.
Winnipeg, in Canada, has longitude 97°W, latitude 50°N.
How far apart are they, in nautical miles, along a great-circle arc?

If you set off from Alderney on a great-circle route to Winnipeg,
in what direction (towards what azimuth) would you head?

Click here for the answer.

 

Reference

http://star-www.st-and.ac.uk/~fv/webnotes/chapter2.htm