Tuesday, October 12, 2010

Progress bar implementation using Level list drawable.

In this post i am gonna cover how to implement battery level changes by changing the images using Level list drawable resource.

First create a set of images you want to show for sequence of progress bar.
In this example, these were the images taken to show percentages of battert level from 10 to 100.


level-list is a XML definition of a drawable resource which manages alternate drawables for different max & minimum levels. This can be applied to a View, or widget ,ImageView,Button etc. Once this is applied, the levels can be changed using api,
setLevel() and setImageLevel()

1 - Consider the below xml file [ images.xml ]. It defines the maxLevel values and its corresponding drawable ( in this example, it picks up the different battery images] .


images.xml:
-----------


<?xml version="1.0" encoding="utf-8"?>
<level-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:maxLevel="0" android:drawable="@drawable/batt_10" />
<item android:maxLevel="1" android:drawable="@drawable/batt_20" />
<item android:maxLevel="2" android:drawable="@drawable/batt_30" />
<item android:maxLevel="3" android:drawable="@drawable/batt_40" />
<item android:maxLevel="4" android:drawable="@drawable/batt_50" />
<item android:maxLevel="5" android:drawable="@drawable/batt_60" />
<item android:maxLevel="6" android:drawable="@drawable/batt_70" />
<item android:maxLevel="7" android:drawable="@drawable/batt_80" />
<item android:maxLevel="8" android:drawable="@drawable/batt_90" />
<item android:maxLevel="9" android:drawable="@drawable/batt_100" />
</level-list>




2 - Create a imageView in main.xml which forms the activities content. And note here, set the images.xml as a src to imageView property.

android:src="@drawable/images"

Layout:

main.xml



<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="battery-progress"
/>
<ImageView
android:id="@+id/battery"
android:layout_width="fill_parent"
android:layout_height="40px"
android:src="@drawable/images"
/>
</LinearLayout>



3 - Inside the activity we are gonna access the imageView and set a setImagelevel() api with different values from 0 to 10 and repeat this for indefinite number of times.




package com.android.imageselector;

import java.util.Timer;
import java.util.TimerTask;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.widget.ImageView;

public class imageselector extends Activity {
/** Called when the activity is first created. */
int i=0;
ImageView v;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

v = (ImageView)findViewById(R.id.battery);
int delay = 1000; // delay for 1 sec.
int period = 1000; // repeat every 10 sec.
Timer timer = new Timer();

final Handler messageHandler = new Handler() {

public void handleMessage(Message msg) {
super.handleMessage(msg);
if(msg.what == 0)
{
if(i<10)
{
i++;
v.setImageLevel(i);
}
else
{
i=0;
v.setImageLevel(i);
}
}

}
};

timer.scheduleAtFixedRate(new TimerTask()
{
public void run()
{

messageHandler.sendEmptyMessage(0);

}
}, delay, period);

}
}



4 - A timer object is created and scheduleAtFixedRate() api is used to invoke the thread for every 1 sec and call Handler object to set the imagelevel value from 0 to 10.

5 - Now the total outcome looks like, the battery images are set for values from 0 to 10 from the images.xml file. And looks like a battery is charged.Similarly the images can be changed as per your requirement to show the circular progress bar images, or horizontal progress bar images based on the progress levels.

Saturday, October 9, 2010

How to identify when lock screen is unlocked.?

My requirement was to listen for the intent when the screen is unlocked successfully.
Unfortunately, there is no such intent defined by Android framework, when the screen is unlocked successfully.

So i went into the framework code which takes care of showing lock screen, unlock screen and handling the events on that. It is present
/frameworks/policies/base/phone/com/android/internal/policy/impl

If in case you are working in framework level code and looking for the exact place in the code, here it is.

KeyguardViewMediator.java

Line no 801:
Here i have written code, to notify the Notification service, when the screen is unlocked. It works fine.



public void keyguardDone(boolean authenticated, boolean wakeup) {
synchronized (this) {
EventLog.writeEvent(70000, 2);
if (DEBUG) Log.d(TAG, "keyguardDone(" + authenticated + ")");
System.out.println("Keygaurd screen unlocked ");
mManager.notify("SCREEN_UNLOCKED"); // The code i added.
Message msg = mHandler.obtainMessage(KEYGUARD_DONE);
msg.arg1 = wakeup ? 1 : 0;
mHandler.sendMessage(msg);

if (authenticated) {
mUpdateMonitor.clearFailedAttempts();
}

if (mExitSecureCallback != null) {
mExitSecureCallback.onKeyguardExitResult(authenticated);
mExitSecureCallback = null;

if (authenticated) {
// after succesfully exiting securely, no need to reshow
// the keyguard when they've released the lock
mExternallyEnabled = true;
mNeedToReshowWhenReenabled = false;
}
}
}
}



There are intents for when the screen is ON & OFF, but you can use that for screen unlocking.

- ACTION_SCREEN_ON
- ACTION_SCREEN_OFF.

I found in one of the forums which suggesting in round other way.

- Wait for ACTION_SCREEN_ON.
- (After screen is on,) Wait for ACTION_MAIN with category CATEGORY_HOME (Which launches the home screen) - This is probably what is sent after the phone gets unlocked.

Not sure this works. !! Check it out.

Friday, October 8, 2010

how to flip between two images and change images based on states of a widget

Lets us discuss about how do we do image switching with the help of ViewFlipper class. And also some tips about using item-selector for selecting images based on various states ( of a widget like button, imageview )

What we are gonna achieve now is, we have two images, which needs to flipped or toggled between them.

We have two images stop & refresh.
we need to toggle the stop / refresh button based on a button click.

1 - In the layout --> main.xml

I am going to add the two imageviews ( stop & refresh imageviews ) under a tag .



<ViewFlipper android:id="@+id/imageflipper"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >

<ImageView
android:layout_width="50dip"
android:layout_height="50dip"
android:src="@drawable/stop"/>

<ImageView
android:layout_width="50dip"
android:layout_height="50dip"
android:src="@drawable/refresh"/>

</ViewFlipper>



2 - Two most attributes for ViewFlipper class is setting In & Out animations when a view is switched from one to another and next one is the time taken to do switch the views. This is will come into picture if you had set the setAutoStart(true)



flipper=(ViewFlipper)findViewById(R.id.details);
flipper.setInAnimation(getApplicationContext(), R.anim.slide_right_in);
flipper.setOutAnimation(getApplicationContext(), R.anim.slide_left_out);
btn=(Button)findViewById(R.id.flip_me);

btn.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
flipper.showNext();
}
});


flipper.showNext() -> shows the next view in that ViewFlipper content. For us the initially when the screen is launched, Stop will be showed. When the button is clicked, it shows the refresh.
It circulates the two images for each button click.

Suppose, you had three imageviews in the <ViewFlipper> tag, each one will be showed next to next ( 1 to 2 to 3 ) again ( 3 to 1 to 2 to 3 ... ) on each button press.




In this example, i had set the imageview src. Which means you cannot change the image backgrounds, when clicked.

To achieve that I am gonna write a xml which handles the different states of images.( pressed, focused ) Basically this xml is a <selector>

More info http://developer.android.com/guide/topics/resources/available-resources.html

Note : Clicking the image wont flip the images in ViewFlipper.

Lets write a refresh_state.xml and put it in /drawable folder. [ keep the images refresh_pressed, refresh_default in drawable folder ]



<?xml version="1.0" encoding="utf-8"?>

<selector xmlns:android="http://schemas.android.com/apk/res/android">

<item android:state_pressed="true"
android:drawable="@drawable/refresh_pressed">
</item>

<item android:state_focused="true"
android:drawable="@drawable/refresh_default">
</item>

<item
android:drawable="@drawable/refresh_default">
</item>

</selector>



1 - android:state_pressed="true"
android:state_enabled="true"
This state implies that the widget is set Enabled (true ) and also pressed, it picks this image.

2 - android:state_pressed="true"
android:state_enabled="false"

This state implies that the widget is set Enabled (false ) ex. button is disabled like it is dimmed meaning no action for that,and if imageView is pressed, it picks this image.

3 - android:state_enabled="false"

This state implies that the widget is set Enabled (false ) ex. button is disabled like it is dimmed meaning no action for that, then it displays this image.

How to make the widget ( button, imageView etc ) to be disable or enabled in code.

this api sets the state ' state_enabled' to 'true' or 'false'

Imageview v = (ImageView) findViewById(R.id.refresh);
v.setEnabled(true);
v.setEnabled(false);

make changes in layout.xml file as below.

Remove the src settings and set the 'background' property to point the refresh_state.xml file created in above step.
- android:clickable="true" --> this has to be set otherwise, click events will not allowed for imageview



<ViewFlipper android:id="@+id/imageflipper"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >

<ImageView
android:layout_width="50dip"
android:layout_height="50dip"
android:background="@drawable/stop_state"
android:clickable="true"/>

<ImageView
android:layout_width="50dip"
android:layout_height="50dip"
android:background="@drawable/refresh_state"
android:clickable="true"/>

</ViewFlipper>

Monday, October 4, 2010

How to set height,width for activity or how to make the activity window look in desired size..

This post talks about

- how to display a activity of fixed width & height ?

- why the activity screen is of full screen ? how to reduce the size of activity size?


These were the questions which were running through my mind, when i first started implementing activities in android.

This applies not only to activities it is even for dialogs.How to position the dialog in the desired place in the screen.Sometime we want alert to be displayed on the top right, rather at the center of the screen as user might be reading something.

Lets work on it more to find the answers...!!


1 step - To make the activity to have a desired size rather than full screen, set the theme for your activity as Dialog like below.

android:theme="@android:style/Theme.Dialog"

In AndroidManifest.xml



<activity android:name="urldisplay"
android:label="@string/app_name"
android:windowSoftInputMode="stateAlwaysVisible|adjustPan"
android:theme="@android:style/Theme.Dialog">
</activity>


2 step - We need to get the window from dialog and set the layout attributes, then the window will be positioned accordingly in the screen. This can be done as below.



WindowManager.LayoutParams params = getWindow().getAttributes();
params.x = -100;
params.height = 70;
params.width = 1000;
params.y = -50;

this.getWindow().setAttributes(params);


here is the complete example.




layout.xml (main.xml)



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

<EditText android:id="@+id/textbox1"
android:hint="eg. pubs,restuarants "
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="1"/>

<Button android:id="@+id/press"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello"/>


</LinearLayout>


urldisplay.java



package com.android.urldisplay;

import android.widget.Button;
import android.widget.EditText;
import android.app.Activity;
import android.os.Bundle;
import android.view.WindowManager;
import android.app.Notification;
import android.app.NotificationManager;
import android.content.Intent;
import android.view.View;
import android.content.Context;
import android.net.Uri;
import android.app.PendingIntent;
import android.os.Handler;
import android.view.inputmethod.InputMethodManager;

public class urldisplay extends Activity
{
EditText nameText;
private static final int APP_ID = 0;
private NotificationManager mManager;
private Handler mHandler = new Handler();

private Runnable mShowInputMethodTask = new Runnable() {
public void run() {
showInputMethodForQuery();
}
};
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

WindowManager.LayoutParams params = getWindow().getAttributes();
params.x = -100;
params.height = 70;
params.width = 1000;
params.y = -50;

this.getWindow().setAttributes(params);
nameText = (EditText) findViewById(R.id.textbox1);

Context context;
context = getApplicationContext();
mManager = (NotificationManager) getSystemService(context.NOTIFICATION_SERVICE);

Button press = (Button)findViewById(R.id.press);

press.setOnClickListener(new Button.OnClickListener(){

public void onClick(View v) {

String url = nameText.getText().toString();
if (!url.startsWith("http://") && !url.startsWith("https://"))
url = "http://" + url;

Intent browserIntent = new Intent("android.intent.action.VIEW", Uri.parse(url));
browserIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mManager.notify(url);
startActivity(browserIntent);
finish();

}
});
}

@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus) {
// Launch the IME after a bit
mHandler.postDelayed(mShowInputMethodTask, 0);
}
}
protected void showInputMethodForQuery() {
InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
if (imm != null) {
imm.showSoftInput(nameText, 0);
}
}
}

Saturday, October 2, 2010

Dynamic layout changes with visibility property


When i started working on the layouts, i was in a situation where i need to hide a textbox based on checkbox selection. If checkbox selected hide the textbox and checkbox deselected show the textbox. That was my need.

there is a propery called VISIBILITY. It can be set a element on the layoutxml as below ( element can be a LinearLayout(viewgroup) or widgets like TextView,ImageView, etc )

" android:visible = "gone" or "visible" or "invisible"

- gone - Means the element will not be shown and its doesnt occupy space in the entire viewgroup.

- visible - THe element is shown. Visible to user.

- invisible - the element will not be shown, but it occupies empty space in for its width & height in the entire layout.

- in the code this propery can be set as

void setVisibility (int visibility)

- View.VISIBLE or View.INVISIBLE or View.GONE.

Let see an example.

layout.xml:
--------------------------


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/MainLayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="3dip"
android:orientation="vertical">
<RelativeLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingTop="10dip">

<ImageView android:id="@+id/favorite"
android:layout_width="30dip"
android:layout_height="30dip"
android:layout_alignParentLeft="true"
android:src="@drawable/favorite"/>

<TextView android:id="@+id/title1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="Local Guide"
android:textSize="25sp" />

<ImageView android:id="@+id/info"
android:layout_width="30dip"
android:layout_height="30dip"
android:layout_alignParentRight="true"
android:src="@drawable/info"/>

</RelativeLayout>

<TextView android:id="@+id/text"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="25sp"
android:paddingTop="30dip"
android:text="Enter category :" />

<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="6dip"
android:orientation="horizontal">

<EditText android:id="@+id/categotytextbox"
android:hint="eg. pubs,restuarants "
android:layout_width="250dip"
android:layout_height="wrap_content"
android:singleLine="true"
android:visibility="gone"
android:ellipsize="marquee"
android:maxLines="1"/>

<ImageView android:id="@+id/search"
android:layout_marginLeft="20dip"
android:layout_width="40dip"
android:layout_height="40dip"
android:src="@drawable/find"/>
</LinearLayout>

<Button android:id="@+id/categories"
android:layout_width="150dip"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:text="Choose categories"/>

<TextView android:id="@+id/text1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="25sp"
android:text="Enter Location :" />

<EditText android:id="@+id/locationtextbox"
android:hint="eg. Liverpool,uk "
android:layout_width="250dip"
android:layout_height="wrap_content"
android:maxLines="1"/>

<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingTop="20dip"
android:id="@+id/locationLayout">

<CheckBox android:id="@+id/checkbox"
android:layout_width="40dp"
android:layout_height="40dp"
android:checked="true"/>

<TextView android:id="@+id/checkboxtext"
android:layout_width="fill_parent"
android:layout_height="40dp"
android:paddingLeft="20dp"
android:layout_gravity="center_horizontal"
android:layout_centerHorizontal="true"
android:textSize="25sp"
android:text="Current Location" />

</LinearLayout>


</LinearLayout>





Main activity ( java file )
-------------------------------

On selection of checkbox, i dynamically show or hide the elements on above that.!!



locationCheckbox.setOnClickListener(new CheckBox.OnClickListener(){
public void onClick(View v) {
if(((CheckBox)v).isChecked())
{
TextView text1 = (TextView)findViewById(R.id.text1);
text1.setVisibility(View.GONE);
EditText locationbox = (EditText)findViewById(R.id.locationtextbox);
locationbox.setVisibility(View.GONE);
}
else
{ TextView text1 = (TextView)findViewById(R.id.text1);
text1.setVisibility(View.VISIBLE);
EditText locationbox = (EditText)findViewById(R.id.locationtextbox);
locationbox.setVisibility(View.VISIBLE);

}
}
});







import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;


public class WelcomeScreen extends Activity {

public final int CATEGORY_ID =0;
EditText categoryTextbox;
EditText locationTextbox;
Dialog dialog;
String category;
String location;
public final static int ACTIVITY_INVOKE = 0;

public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.welcome);

categoryTextbox = (EditText)findViewById(R.id.categotytextbox);
locationTextbox = (EditText)findViewById(R.id.locationtextbox);
ImageView search = (ImageView)findViewById(R.id.search);
ImageView info = (ImageView) findViewById(R.id.info);
CheckBox locationCheckbox =(CheckBox)findViewById(R.id.checkbox);

search.setOnClickListener(new Button.OnClickListener(){
public void onClick(View v) {
Intent intent = new Intent();
intent.putExtra("categoryString", category);
location = locationTextbox.getText().toString();
intent.putExtra("locationString", location);
Bundle bun = new Bundle();
bun.putString("categoryString", category);
bun.putString("locationString", location);
intent.putExtras(bun);
intent.setClass(v.getContext(), results.class);
startActivity(intent);
}
});

info.setOnClickListener(new Button.OnClickListener(){
public void onClick(View v) {
Intent intent = new Intent();
intent.setClass(v.getContext(), information.class);
startActivity(intent);
}
});

locationCheckbox.setOnClickListener(new CheckBox.OnClickListener(){
public void onClick(View v) {
if(((CheckBox)v).isChecked())
{
TextView text1 = (TextView)findViewById(R.id.text1);
text1.setVisibility(View.GONE);
EditText locationbox = (EditText)findViewById(R.id.locationtextbox);
locationbox.setVisibility(View.GONE);
}
else
{ TextView text1 = (TextView)findViewById(R.id.text1);
text1.setVisibility(View.VISIBLE);
EditText locationbox = (EditText)findViewById(R.id.locationtextbox);
locationbox.setVisibility(View.VISIBLE);

}
}
});
}
}

Monday, September 27, 2010

PhonewindowManager - Some details.

Some details and information i would like to share about some framework related on window managers, phone window managers. It might be a insight to dig more by first come learners .. !!

The three important managers interlinked for an application to be displayed are

– Window manager

(frameworks/base/services/java/com/android/server/WindowManagerService.java)
(frameworks/base/core/java/android/view/WindowManager.java)

– Surface manager / Surface flinger

(frameworks/base/libs/surfacelinger)

–Activity manager

(frameworks/base/services/java/com/android/server/am/ActivityManagerService.java)


All the three are started as thread by main proc “SystemServer”, when the system starts.

Window manager

– Asks the surface manager to create layout surfaces on behalf of client application.

– Dispatches input events to client.

– Transitions animations

[ The window manager creates surfaces for the application, and applications draw directly into those surfaces without going through the window manager.]

Surface manager

– Allocates surfaces ( means creation of memory,front end, back end buffers for application to draw its layout ).

– Interacts with OpenGL.

Activity Manager

– Manages life cycles of activities, stacking of activities.

– Takes care of intent dispatching.

There are two window manager implemented one for phone (phoneWindow manager) and another for mid (midWindow manager which is obselete now).

Window - Is a abstract base class for a top-level window look and behavior policy. An instance of this class should be used as the top-level view added to the window manager. It provides standard UI policies such as a background, title area, default key processing, etc.

The only existing implementation of this abstract class is android.policy.PhoneWindow, which you should instantiate when needing a Window.So it is designed like when an application is started, the activity manager(ActivityThread main loop ) gets the handle and requests creation of a PhoneWindow for the application on which the application's layouts will be drawn with the surface manager as said earlier.



The instantiation of PhoneWindow is provided in /frameworks/policies/base/phone/com/android/internal/policy.java file.

public PhoneWindow makeNewWindow(Context context) {
return new PhoneWindow(context);
}

public PhoneLayoutInflater makeNewLayoutInflater(Context context) {
return new PhoneLayoutInflater(context);
}

public PhoneWindowManager makeNewWindowManager() {
return new PhoneWindowManager();
}



When the window manager is started by SystemServer, it instantiates the deamon kind of thread named 'PhoneWindowManager ' which manages each 'phoneWindow'.What are the activities it manages and for phoneWindow ?

– Starts the power manager intially when the window manager instantiates this class.

– Intercepts / Handles the keys like Home,Back,Menu,Search, Keyguard, Media Key up and down. All these keys will be given to each PhoneWindow. So all the interactions on these keys will be handled here.

– Long press of Home button shows Recent apps dialog.

– Behavior of the power button,long press on KeyGaurd shows this dialog.

– Behavior of how to handle END_BUTTON_BEHAVIOR(Call button),INCALL_POWER_BUTTON_BEHAVIOR,ACCELEROMETER_ROTATION,SCREEN_OFF_TIMEOUT,DEFAULT_INPUT_METHOD . Basically it registers for the above contentRegister URIs.

– Adds the startingWindow ( a phoneWindow ) for an application. Basically to this window object,views are added to display the content.



public View addStartingWindow(IBinder appToken, String packageName, int theme, CharSequence nonLocalizedLabel,
int labelRes, int icon) {
Window win = PolicyManager.makeNewWindow(context); --> lin 867
----------------------
win.getDecorView(); --> Asks the 'PhoneWindow' to get the view
}


When an application is started, activity manager and window manager handles creation of 'PhoneWindow'. I havenot figured out why two windows are created.


1- Created by WindowManager (PhoneWindowManager ) :
------------------------------------------------------


I/ActivityManager( 60): Starting activity: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.android.HelloWorld/.HelloWorld }
V/PhoneWindowManager( 60): addStartingWindow com.android.HelloWorld: nonLocalizedLabel=null theme=0
D/dalvikvm( 60): GC_FOR_MALLOC freed 10917 objects / 494680 bytes in 133ms
I/PhonePolicy( 60): Making new Phone Window
I/PhonePolicy( 60): java.lang.RuntimeException
I/PhonePolicy( 60): at com.android.internal.policy.impl.Policy.makeNewWindow(Policy.java:59)
I/PhonePolicy( 60): at com.android.internal.policy.impl.Policy.makeNewWindow(Policy.java:33)
I/PhonePolicy( 60): at com.android.internal.policy.PolicyManager.makeNewWindow(PolicyManager.java:58)
I/PhonePolicy( 60): at com.android.internal.policy.impl.PhoneWindowManager.addStartingWindow(PhoneWindowManager.java:867)
I/PhonePolicy( 60): at com.android.server.WindowManagerService$H.handleMessage(WindowManagerService.java:9007)
I/PhonePolicy( 60): at android.os.Handler.dispatchMessage(Handler.java:99)
I/PhonePolicy( 60): at android.os.Looper.loop(Looper.java:123)
I/PhonePolicy( 60): at com.android.server.WindowManagerService$WMThread.run(WindowManagerService.java:570)


2 – Activity manager asks for a new PhoneWindow.
---------------------------------------------------


I/PhonePolicy( 279): Making new Phone Window
I/PhonePolicy( 279): java.lang.RuntimeException
I/PhonePolicy( 279): at com.android.internal.policy.impl.Policy.makeNewWindow(Policy.java:59)
I/PhonePolicy( 279): at com.android.internal.policy.impl.Policy.makeNewWindow(Policy.java:33)
I/PhonePolicy( 279): at com.android.internal.policy.PolicyManager.makeNewWindow(PolicyManager.java:58)
I/PhonePolicy( 279): at android.app.Activity.attach(Activity.java:3746)
I/PhonePolicy( 279): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2610)
I/PhonePolicy( 279): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
I/PhonePolicy( 279): at android.app.ActivityThread.access$2300(ActivityThread.java:125)
I/PhonePolicy( 279): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
I/PhonePolicy( 279): at android.os.Handler.dispatchMessage(Handler.java:99)
I/PhonePolicy( 279): at android.os.Looper.loop(Looper.java:123)
I/PhonePolicy( 279): at android.app.ActivityThread.main(ActivityThread.java:4627)
I/PhonePolicy( 279): at java.lang.reflect.Method.invokeNative(Native Method)
I/PhonePolicy( 279): at java.lang.reflect.Method.invoke(Method.java:521)
I/PhonePolicy( 279): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
I/PhonePolicy( 279): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
I/PhonePolicy( 279): at dalvik.system.NativeStart.main(Native Method)


setContentView()

– Whenever an setContentView() is called in application's main activity, it will be given to PhoneWindow instance to create the view and display it.At this point, window manager talk to surface manager to draw the layouts on to the Window. This fundamental is common for all applications in Android.



public class HelloWorld extends Activity
{
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}





V/PhoneWindow( 279): Phonewindow generateLayout
V/PhoneWindow( 279): java.lang.RuntimeException
V/PhoneWindow( 279): at com.android.internal.policy.impl.PhoneWindow.generateLayout(PhoneWindow.java:2058)
V/PhoneWindow( 279): at com.android.internal.policy.impl.PhoneWindow.installDecor(PhoneWindow.java:2234)
V/PhoneWindow( 279): at com.android.internal.policy.impl. PhoneWindow.setContentView(PhoneWindow.java:200)
V/PhoneWindow( 279): at android.app.Activity.setContentView(Activity.java:1647)
V/PhoneWindow( 279): at com.android.HelloWorld.HelloWorld.onCreate(HelloWorld.java:13)
V/PhoneWindow( 279): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
V/PhoneWindow( 279): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)
V/PhoneWindow( 279): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
V/PhoneWindow( 279): at android.app.ActivityThread.access$2300(ActivityThread.java:125)
V/PhoneWindow( 279): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
V/PhoneWindow( 279): at android.os.Handler.dispatchMessage(Handler.java:99)
V/PhoneWindow( 279): at android.os.Looper.loop(Looper.java:123)
V/PhoneWindow( 279): at android.app.ActivityThread.main(ActivityThread.java:4627)
V/PhoneWindow( 279): at java.lang.reflect.Method.invokeNative(Native Method)
V/PhoneWindow( 279): at java.lang.reflect.Method.invoke(Method.java:521)
V/PhoneWindow( 279): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
V/PhoneWindow( 279): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
V/PhoneWindow( 279): at dalvik.system.NativeStart.main(Native Method)



PhoneWindowManager and PhoneWindow – Plays a major role in framework to display the content of view, talk to surface manager and handles common utilities which a window ( in otherwords an application) can get. Like, menu,back, call, media keys handling.

There many ways we can set a View to an activity. One way is to create a LinearLayout?FrameLayout add it to a ViewGroup then add the ViewGroup to Window to display it. This is followed in showing Lock screen.

The hierarchy between them is as follows,

onCreate()
Activty --------------------------> Window
|
setContentView(View v, LayoutParams p) - Set a view to a Window.

View --> ViewGroup --> LinearLayout/FrameLayout.
|
|
|
addview(View , LayoutParams ) ( This is inherited to all subclasses )



Example to explain:
------------------------------


public class HelloWorld extends Activity
{
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
View v = new MyLinearLayoutView(this);
setContentView(v);
}

}

public class MyLinearLayoutView extends LinearLayout
{
public MyLinearLayoutView(Context context)
{
super(context);
this.setOrientation(LinearLayout.VERTICAL);

\ TextView welcome = new TextView(context);
welcome.setTypeface(Typeface.SANS_SERIF, Typeface.BOLD);
welcome.setText("Welcome screen");

TextView content = new TextView(context);
content.setTypeface(Typeface.SANS_SERIF, Typeface.BOLD);
content.setText("This is a LinearLayout");

LayoutParams params = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
this.addView(welcome,params);
this.addView(content,params);
}
}


If you dont specify the LayoutParams the default will be set as
new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT);

This is the same methodology which will be followed in the flow of creating LockScreen,UnlockScreen. In this way, to the 'PhoneWindow' instance addView( is used to set the content for the window ).