mobile programming lecture 6

Post on 07-Jan-2016

45 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

DESCRIPTION

Mobile Programming Lecture 6. Fragments, Permissions, BroadcastReceivers. Agenda. Dynamic UI LayoutInflater Fragments Permissions BroadcastReceiver. Building the UI Dynamically. So far we've been creating UIs that are defined before runtime - PowerPoint PPT Presentation

TRANSCRIPT

Mobile ProgrammingLecture 6

Fragments, Permissions, BroadcastReceivers

Agenda

• Dynamic UI

• LayoutInflater

• Fragments

• Permissions

• BroadcastReceiver

Building the UI Dynamically

So far we've been creating UIs that are defined before runtime

There are some cases where you will need to build the UI dynamically

Consider this XML layout file

Building the UI Dynamically<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="match_parent"

android:layout_height="match_parent" >

<TableRow

android:layout_width="wrap_content"

android:layout_height="wrap_content" >

<TextView

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="Medium Text"

android:textAppearance="?android:attr/textAppearanceMedium" />

</TableRow>

<TableRow

android:layout_width="wrap_content"

android:layout_height="wrap_content" >

</TableRow>

</TableLayout>

Building the UI Dynamically

Now let's look at Java code that can build a similar UI at runtime

Building the UI Dynamically

<TableLayout android:layout_width="match_parent"

android:layout_height="match_parent" >

<TableRow

android:layout_width="wrap_content"

android:layout_height="wrap_content" >

<TextView

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="Medium Text"/>

</TableRow>

<TableRow

android:layout_width="wrap_content"

android:layout_height="wrap_content" >

</TableRow>

</TableLayout>

public void onCreate(Bundle state) {

super.onCreate(savedInstanceState);

TableLayout layout = new TableLayout(this);

TableRow row = new TableRow(this);

TextView tv = new TextView(this);

tv.setText("Medium Text");

row.addView(tv);

layout.addView(row);

row = new TableRow(this);

layout.addView(row);

setContentView(layout);

}

Building the UI Dynamically

<TableLayout android:layout_width="match_parent"

android:layout_height="match_parent" >

<TableRow

android:layout_width="wrap_content"

android:layout_height="wrap_content" >

<TextView

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="Medium Text"/>

</TableRow>

<TableRow

android:layout_width="wrap_content"

android:layout_height="wrap_content" >

</TableRow>

</TableLayout>

public void onCreate(Bundle state) {

super.onCreate(savedInstanceState);

TableLayout layout = new TableLayout(this);

TableRow row = new TableRow(this);

TextView tv = new TextView(this);

tv.setText("Medium Text");

row.addView(tv);

layout.addView(row);

row = new TableRow(this);

layout.addView(row);

setContentView(layout);

}

This argument asks for a Context, e.g.this or getApplicationContext()

Building the UI Dynamically

<TableLayout android:layout_width="match_parent"

android:layout_height="match_parent" >

<TableRow

android:layout_width="wrap_content"

android:layout_height="wrap_content" >

<TextView

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="Medium Text"/>

</TableRow>

<TableRow

android:layout_width="wrap_content"

android:layout_height="wrap_content" >

</TableRow>

</TableLayout>

public void onCreate(Bundle state) {

super.onCreate(savedInstanceState);

TableLayout layout = new TableLayout(this);

TableRow row = new TableRow(this);

TextView tv = new TextView(this);

tv.setText("Medium Text");

row.addView(tv);

layout.addView(row);

row = new TableRow(this);

layout.addView(row);

setContentView(layout);

}

"this" refers to the instance of whichever class the code is currently in!

Building the UI Dynamically

<TableLayout android:layout_width="match_parent"

android:layout_height="match_parent" >

<TableRow

android:layout_width="wrap_content"

android:layout_height="wrap_content" >

<TextView

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="Medium Text"/>

</TableRow>

<TableRow

android:layout_width="wrap_content"

android:layout_height="wrap_content" >

</TableRow>

</TableLayout>

public void onCreate(Bundle state) {

super.onCreate(savedInstanceState);

TableLayout layout = new TableLayout(this);

TableRow row = new TableRow(this);

TextView tv = new TextView(this);

tv.setText("Medium Text");

row.addView(tv);

layout.addView(row);

row = new TableRow(this);

layout.addView(row);

setContentView(layout);

}

In this case, it would refer to your Activity (since you know that onCreate() is a method of an Activity)

Building the UI Dynamically

You can't add the same child element twice!

This is an easy way to get a Force Close

LayoutInflater

• instantiates a layout XML file into its corresponding View objects

• use getLayoutInflater()

LayoutInflater

@Override

public void onCreate(Bundle state) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

}

@Override

public void onCreate(Bundle state) {

super.onCreate(savedInstanceState);

LayoutInflater inflater =

getLayoutInflater();

setContentView(

inflater.inflate(R.layout.main, null));

}

LayoutInflater

@Override

public void onCreate(Bundle state) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

}

@Override

public void onCreate(Bundle state) {

super.onCreate(savedInstanceState);

LayoutInflater inflater =

getLayoutInflater();

setContentView(

inflater.inflate(R.layout.main, null));

}

Gives you the same result

LayoutInflater

@Override

public void onCreate(Bundle state) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

}

@Override

public void onCreate(Bundle state) {

super.onCreate(savedInstanceState);

LayoutInflater inflater =

getLayoutInflater();

setContentView(

inflater.inflate(R.layout.main, null));

}

Second argument is of type ViewGroup

LayoutInflater

@Override

public void onCreate(Bundle state) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

}

@Override

public void onCreate(Bundle state) {

super.onCreate(savedInstanceState);

LayoutInflater inflater =

getLayoutInflater();

setContentView(

inflater.inflate(R.layout.main, null));

}

Use it if you want to embed the first argument into the second argument

Fragments

Fragments

• A Fragment represents a behavior or a portion of user interface in an Activity.

• Add multiple fragments to a screen to avoid switching activities

• Fragments have their own lifecycle, state, and back stack

• Fragments require API Level 11 or greater

Fragments - Lifecycle

A fragment must always be embedded in an activity and the fragment's lifecycle is directly affected by the host activity's lifecycle.

• http://developer.android.com/guide/components/fragments.html

onCreateView() is the one we'll be focusing on for now ...

Fragments - Steps for Creating One

1. You must create a subclass of Fragment1. Fragment, ListFragment, etc

2. You must implement onCreateView()1. onCreateView() must return a View

i.e. @Override public View onCreateView( /* required args */)

Fragments - onCreateView()

There are two ways to return a view in your implementation of onCreateView()

Fragments - onCreateView()

1. Use the LayoutInflater argument to instantiate a predefined layout XML file

e.g.

public class MyFragment extends Fragment {

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle state)

{return inflater.inflate(R.layout.example_fragment, container, false);

}}

Fragments - onCreateView()

1. Use the LayoutInflater argument to instantiate a predefined layout XML file

e.g.

public class MyFragment extends Fragment {

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle state)

{return inflater.inflate(R.layout.example_fragment, container, false);

}}

extend Fragment, not Activity

Fragments - onCreateView()

1. Use the LayoutInflater argument to instantiate a predefined layout XML file

e.g.

public class MyFragment extends Fragment {

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle state)

{return inflater.inflate(R.layout.example_fragment, container, false);

}}

The XML layout file to instantiate

Fragments - onCreateView()

1. Use the LayoutInflater argument to instantiate a predefined layout XML file

e.g.

public class MyFragment extends Fragment {

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle state)

{return inflater.inflate(R.layout.example_fragment, container, false);

}}

The ViewGroup to insert it into

Fragments - onCreateView()

1. Use the LayoutInflater argument to instantiate a predefined layout XML file

e.g.

public class MyFragment extends Fragment {

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle state)

{return inflater.inflate(R.layout.example_fragment, container, false);

}}

Passing true would create a redundant ViewGroup, so pass false for now

Fragments - onCreateView()

2. Build a UI dynamically and return the root View

public class MyFragment extends Fragment {

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle state)

{ScrollView scroller = new ScrollView(getActivity());TextView text = new TextView(getActivity());scroller.addView(text);text.setText("Sample Text");

return scroller;

}}

Fragments - onCreateView()

2. Build a UI dynamically and return the root View

public class MyFragment extends Fragment {

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle state)

{ScrollView scroller = new ScrollView(getActivity());TextView text = new TextView(getActivity());scroller.addView(text);text.setText("Sample Text");

return scroller;

}}

You've seen most of this before!

Fragments - onCreateView()

2. Build a UI dynamically and return the root View

public class MyFragment extends Fragment {

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle state)

{ScrollView scroller = new ScrollView(getActivity());TextView text = new TextView(getActivity());scroller.addView(text);text.setText("Sample Text");

return scroller;

}}

Last time we used the keyword this to get the Context

Fragments - onCreateView()

2. Build a UI dynamically and return the root View

public class MyFragment extends Fragment {

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle state)

{ScrollView scroller = new ScrollView(getActivity());TextView text = new TextView(getActivity());scroller.addView(text);text.setText("Sample Text");

return scroller;

}}

Since we're in a Fragment here, and not an Activity ...

Fragments - onCreateView()

2. Build a UI dynamically and return the root View

public class MyFragment extends Fragment {

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle state)

{ScrollView scroller = new ScrollView(getActivity());TextView text = new TextView(getActivity());scroller.addView(text);text.setText("Sample Text");

return scroller;

}}

We can get the controlling Activity from within the Fragment using getActivity()

Fragments - onCreateView()

2. Build a UI dynamically and return the root View

public class MyFragment extends Fragment {

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle state)

{ScrollView scroller = new ScrollView(getActivity());TextView text = new TextView(getActivity());scroller.addView(text);text.setText("Sample Text");

return scroller;

}}

This is how we get the Context. Alternatively, we can say getActivity().getApplicationContext()

Fragments - Adding a Fragment

There are 2 ways to add a Fragment

Fragments - Adding a Fragment

1. Declare the Fragment inside of the Activity's layout file<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="match_parent"> <fragment android:name="edu.fsu.cs.mobile.example.MyFragment" android:id="@+id/list" android:tag="list_fragment" android:layout_weight="1" android:layout_width="match_parent" android:layout_height="match_parent" /> <fragment android:name="edu.fsu.cs.mobile.example.MyOtherFragment" android:id="@+id/viewer" android:tag="viewer_fragment" android:layout_weight="2" android:layout_width="match_parent" android:layout_height="match_parent" /></LinearLayout>

Fragments - Adding a Fragment

1. Declare the Fragment inside of the Activity's layout file

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="match_parent"> <fragment android:name="edu.fsu.cs.mobile.example.MyFragment" android:id="@+id/list" android:tag="list_fragment" android:layout_weight="1" android:layout_width="match_parent" android:layout_height="match_parent" /> <fragment android:name="edu.fsu.cs.mobile.example.MyOtherFragment" android:id="@+id/viewer" android:tag="viewer_fragment" android:layout_weight="2" android:layout_width="match_parent" android:layout_height="match_parent" /></LinearLayout>

<fragment>

Fragments - Adding a Fragment

1. Declare the Fragment inside of the Activity's layout file

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="match_parent"> <fragment android:name="edu.fsu.cs.mobile.example.MyFragment" android:id="@+id/list" android:tag="list_fragment" android:layout_weight="1" android:layout_width="match_parent" android:layout_height="match_parent" /> <fragment android:name="edu.fsu.cs.mobile.example.MyOtherFragment" android:id="@+id/viewer" android:tag="viewer_fragment" android:layout_weight="2" android:layout_width="match_parent" android:layout_height="match_parent" /></LinearLayout>

absolute reference to your Fragment class, which includes the package name

Fragments - Adding a Fragment

1. Declare the Fragment inside of the Activity's layout file

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="match_parent"> <fragment android:name="edu.fsu.cs.mobile.example.MyFragment" android:id="@+id/list" android:tag="list_fragment" android:layout_weight="1" android:layout_width="match_parent" android:layout_height="match_parent" /> <fragment android:name="edu.fsu.cs.mobile.example.MyOtherFragment" android:id="@+id/viewer" android:tag="viewer_fragment" android:layout_weight="2" android:layout_width="match_parent" android:layout_height="match_parent" /></LinearLayout>

Fragment id

Fragments - Adding a Fragment

1. Declare the Fragment inside of the Activity's layout file

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="match_parent"> <fragment android:name="edu.fsu.cs.mobile.example.MyFragment" android:id="@+id/list" android:tag="list_fragment" android:layout_weight="1" android:layout_width="match_parent" android:layout_height="match_parent" /> <fragment android:name="edu.fsu.cs.mobile.example.MyOtherFragment" android:id="@+id/viewer" android:tag="viewer_fragment" android:layout_weight="2" android:layout_width="match_parent" android:layout_height="match_parent" /></LinearLayout>

Fragment TAG

Fragments - Adding a Fragment

1. Declare the Fragment inside of the Activity's layout file

This works because you return a View object in your onCreateView() method for the specified Fragment

The View then gets embedded into the UI

Fragments - Adding a Fragment

2. Programmatically add the Fragment to an existing ViewGroup

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

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:orientation="vertical" >

<TextView

android:layout_width="fill_parent"

android:layout_height="wrap_content" />

<FrameLayout

android:id="@+id/fragment_container"

android:layout_width="match_parent"

android:layout_height="match_parent" >

</FrameLayout>

</LinearLayout>

Use a FrameLayout as a container for your Fragment

Fragments - Adding a Fragment

2. Programmatically add the Fragment to an existing ViewGroup

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

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:orientation="vertical" >

<TextView

android:layout_width="fill_parent"

android:layout_height="wrap_content" />

<FrameLayout

android:id="@+id/fragment_container"

android:layout_width="match_parent"

android:layout_height="match_parent" >

</FrameLayout>

</LinearLayout>

Remember the id of the container ...

Fragments - Adding a Fragment

2. Programmatically add the Fragment to an existing ViewGroup

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

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:orientation="vertical" >

<TextView

android:layout_width="fill_parent"

android:layout_height="wrap_content" />

<FrameLayout

android:id="@+id/fragment_container"

android:layout_width="match_parent"

android:layout_height="match_parent" >

</FrameLayout>

</LinearLayout>

This is main.xml layout file

Fragments - Adding a Fragment

2. Programmatically add the Fragment to an existing ViewGroup

public class MyActivity extends Activity {

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

FragmentManager manager = getFragmentManager();

FragmentTransaction trans = manager.beginTransaction();

MyFragment fragment = new MyFragment();

trans.add(R.id.fragment_container, fragment, "my_fragment");

trans.commit();

}

}

Fragments - Adding a Fragment

2. Programmatically add the Fragment to an existing ViewGroup

public class MyActivity extends Activity {

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

FragmentManager manager = getFragmentManager();

FragmentTransaction trans = manager.beginTransaction();

MyFragment fragment = new MyFragment();

trans.add(R.id.fragment_container, fragment, "my_fragment");

trans.commit();

}

}

This XML layout file contains the FrameLayout container

Fragments - Adding a Fragment

2. Programmatically add the Fragment to an existing ViewGroup

public class MyActivity extends Activity {

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

FragmentManager manager = getFragmentManager();

FragmentTransaction trans = manager.beginTransaction();

MyFragment fragment = new MyFragment();

trans.add(R.id.fragment_container, fragment, "my_fragment");

trans.commit();

}

}

FragmentManager allows you to interact with Fragments that are in an Activity

Fragments - Adding a Fragment

2. Programmatically add the Fragment to an existing ViewGroup

public class MyActivity extends Activity {

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

FragmentManager manager = getFragmentManager();

FragmentTransaction trans = manager.beginTransaction();

MyFragment fragment = new MyFragment();

trans.add(R.id.fragment_container, fragment, "my_fragment");

trans.commit();

}

}

FragmentTransaction allows you to perform operations on Fragments (add, remove, replace)

Fragments - Adding a Fragment

2. Programmatically add the Fragment to an existing ViewGroup

public class MyActivity extends Activity {

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

FragmentManager manager = getFragmentManager();

FragmentTransaction trans = manager.beginTransaction();

MyFragment fragment = new MyFragment();

trans.add(R.id.fragment_container, fragment, "my_fragment");

trans.commit();

}

}

Our Fragment doesn't exist at this point (was not specified in XML), let's create an instance of it

Fragments - Adding a Fragment

2. Programmatically add the Fragment to an existing ViewGroup

public class MyActivity extends Activity {

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

FragmentManager manager = getFragmentManager();

FragmentTransaction trans = manager.beginTransaction();

MyFragment fragment = new MyFragment();

trans.add(R.id.fragment_container, fragment, "my_fragment");

trans.commit();

}

}

Add our Fragment to the FrameLayout container

Fragments - Adding a Fragment

2. Programmatically add the Fragment to an existing ViewGroup

public class MyActivity extends Activity {

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

FragmentManager manager = getFragmentManager();

FragmentTransaction trans = manager.beginTransaction();

MyFragment fragment = new MyFragment();

trans.add(R.id.fragment_container, fragment, "my_fragment");

trans.commit();

}

}

The unique TAG for your Fragment, so that you can reference it later

Fragments - Adding a Fragment

2. Programmatically add the Fragment to an existing ViewGroup

public class MyActivity extends Activity {

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

FragmentManager manager = getFragmentManager();

FragmentTransaction trans = manager.beginTransaction();

MyFragment fragment = new MyFragment();

trans.add(R.id.fragment_container, fragment, "my_fragment");

trans.commit();

}

}

Update the UI

Fragments - Passing data to

You will often want to pass data from your Activity to your Fragment. You can do this several ways. From within the Activity ...

public class MyActivity extends Activity {

@Override

public void onCreate(Bundle savedInstance) {

super.onCreate(savedInstance);

setContentView(R.layout.main);

MyFragment fragment = new MyFragment();

fragment.my_custom_field = value;

fragment.setMyCustomField(value);

FragmentManager manager = getFragmentManager();

FragmentTransaction trans = manager.beginTransaction();

trans.add(R.id.fragment_container, fragment, "my_fragment");

trans.commit();

}

}

Fragments - Passing data to

You will often want to pass data from your Activity to your Fragment. You can do this several ways. From within the Activity ...

Fragments - Passing data to

You will often want to pass data from your Activity to your Fragment. You can do this several ways. From within the Activity ...

public class MyActivity extends Activity {

@Override

public void onCreate(Bundle savedInstance) {

super.onCreate(savedInstance);

setContentView(R.layout.main);

MyFragment fragment = new MyFragment();

fragment.my_custom_field = value;

fragment.setMyCustomField(value);

FragmentManager manager = getFragmentManager();

FragmentTransaction trans = manager.beginTransaction();

trans.add(R.id.fragment_container, fragment, "my_fragment");

trans.commit();

}

}

You will need to have my_custom_field as a public field in your Fragment, and setMyCustomField() as a public method

Fragments - Passing data to

Alternatively, you can use Fragments setArguments(Bundle) and getArguments() methods.

Fragments - Passing data to

Alternatively, you can use Fragments setArguments(Bundle) and getArguments() methods.

public class MyActivity extends Activity {

@Override

public void onCreate(Bundle savedInstance) {

super.onCreate(savedInstance);

setContentView(R.layout.main);

MyFragment fragment = new MyFragment();

Bundle extras = new Bundle();

extras.putInt("selected",15);

fragment.setArguments(extras);

FragmentManager manager = getFragmentManager();

FragmentTransaction trans = manager.beginTransaction();

trans.add(R.id.fragment_container, fragment, "my_fragment");

trans.commit();

}

}

Fragments - Passing data to

Alternatively, you can use Fragments setArguments(Bundle) and getArguments() methods.

public class MyActivity extends Activity {

@Override

public void onCreate(Bundle savedInstance) {

super.onCreate(savedInstance);

setContentView(R.layout.main);

MyFragment fragment = new MyFragment();

Bundle extras = new Bundle();

extras.putInt("selected",15);

fragment.setArguments(extras);

FragmentManager manager = getFragmentManager();

FragmentTransaction trans = manager.beginTransaction();

trans.add(R.id.fragment_container, fragment, "my_fragment");

trans.commit();

}

}

You've seen Bundle before!

Fragments - Passing data to

Alternatively, you can use Fragments setArguments(Bundle) and getArguments() methods.

public class MyActivity extends Activity {

@Override

public void onCreate(Bundle savedInstance) {

super.onCreate(savedInstance);

setContentView(R.layout.main);

MyFragment fragment = new MyFragment();

Bundle extras = new Bundle();

extras.putInt("selected",15);

fragment.setArguments(extras);

FragmentManager manager = getFragmentManager();

FragmentTransaction trans = manager.beginTransaction();

trans.add(R.id.fragment_container, fragment, "my_fragment");

trans.commit();

}

}

setArguments() takes a Bundle as an argument. This is a standard Fragment method

Fragments - Passing data to

Then, in your Fragment, you can get the arguments using getArguments()

Fragments - Passing data to

Then, in your Fragment, you can get the arguments using getArguments()

public class MyFragment extends Fragment{

@Override

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle state) {

Bundle args = getArguments();

...

return new TextView(getActivity());

}

@Override

public void onActivityCreated(Bundle state) {

super.onActivityCreated(state);

Bundle args = getArguments();

}

}

Fragments - Passing data to

Then, in your Fragment, you can get the arguments using getArguments()

public class MyFragment extends Fragment{

@Override

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle state) {

Bundle args = getArguments();

...

return new TextView(getActivity());

}

@Override

public void onActivityCreated(Bundle state) {

super.onActivityCreated(state);

Bundle args = getArguments();

}

}

Bundle args and Bundle state are two separate Bundles. Ignore Bundle state for now

Fragments - Passing data to

Then, in your Fragment, you can get the arguments using getArguments()

public class MyFragment extends Fragment{

@Override

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle state) {

Bundle args = getArguments();

...

return new TextView(getActivity());

}

@Override

public void onActivityCreated(Bundle state) {

super.onActivityCreated(state);

Bundle args = getArguments();

}

}

get the arguments that were passed by the Activity

Fragments - Passing data to

Then, in your Fragment, you can get the arguments using getArguments()

public class MyFragment extends Fragment{

@Override

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle state) {

Bundle args = getArguments();

...

return new TextView(getActivity());

}

@Override

public void onActivityCreated(Bundle state) {

super.onActivityCreated(state);

Bundle args = getArguments();

}

}

onCreateView must return a View

Fragments - Passing data to

Then, in your Fragment, you can get the arguments using getArguments()

public class MyFragment extends Fragment{

@Override

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle state) {

Bundle args = getArguments();

...

return new TextView(getActivity());

}

@Override

public void onActivityCreated(Bundle state) {

super.onActivityCreated(state);

Bundle args = getArguments();

}

}

You may need to get the arguments at this point in the Lifecycle instead

Fragments - Passing data to

Then, in your Fragment, you can get the arguments using getArguments()

public class MyFragment extends Fragment{

@Override

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle state) {

Bundle args = getArguments();

...

return new TextView(getActivity());

}

@Override

public void onActivityCreated(Bundle state) {

super.onActivityCreated(state);

Bundle args = getArguments();

}

}

This is usually if you extended ListFragment instead

Fragments - How to Reference

• A Fragment is not a View!

• You can't call findViewById() in order to reference a Fragment within an Activity

• use getFragmentManager().findFragmentById() or getFragmentManager().findFragmentByTag() instead

• of course, an instance of your Fragment Manager needs to already be a part of your Activity

FragmentManager manager = getFragmentManager();

MyFragment fragment = (MyFragment) manager.findFragmentById(R.id.fragment_id);

MyFragment fragment = (MyFragment) manager.findFragmentByTag("my_fragment");

Fragments - Removing a Fragment

You can also remove Fragments from the UI

Fragments - Removing a Fragment

You can also replace one Fragment with another

public class MyActivity extends Activity {

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

FragmentManager manager = getFragmentManager();

FragmentTransaction trans = manager.beginTransaction();

MyFragment fragment = manager.findFragmentById(R.id.my_fragment);

trans.remove(fragment);

trans.commit();

}

}

Fragments - Removing a Fragment

You can also replace one Fragment with another

public class MyActivity extends Activity {

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

FragmentManager manager = getFragmentManager();

FragmentTransaction trans = manager.beginTransaction();

MyFragment fragment = manager.findFragmentById(R.id.my_fragment);

trans.remove(fragment);

trans.commit();

}

}

You can only remove it if it was added somehow. This gets a reference to a Fragment that was already added.

Fragments - Removing a Fragment

You can also replace one Fragment with another

public class MyActivity extends Activity {

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

FragmentManager manager = getFragmentManager();

FragmentTransaction trans = manager.beginTransaction();

MyFragment fragment = manager.findFragmentById(R.id.my_fragment);

trans.remove(fragment);

trans.commit();

}

}

Remove the Fragment from this Activity

Fragments - Replacing a Fragment

You can replace a Fragment by removing an existing Fragment and adding an new one. But an easier way to do this is to call replace() instead

Fragments - Replacing a Fragment

You can also replace Fragments

public class MyActivity extends Activity {

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

FragmentManager manager = getFragmentManager();

FragmentTransaction trans = manager.beginTransaction();

MyFragment fragment = new MyFragment();

trans.replace(R.id.fragment_container, fragment);

trans.commit();

}

}

Fragments - Replacing a Fragment

You can also replace Fragments

public class MyActivity extends Activity {

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

FragmentManager manager = getFragmentManager();

FragmentTransaction trans = manager.beginTransaction();

MyFragment fragment = new MyFragment();

trans.replace(R.id.fragment_container, fragment);

trans.commit();

}

}

Reference the Fragment (if you don't already have a reference to it)

Fragments - Replacing a Fragment

You can also replace Fragments

public class MyActivity extends Activity {

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

FragmentManager manager = getFragmentManager();

FragmentTransaction trans = manager.beginTransaction();

MyFragment fragment = new MyFragment();

trans.replace(R.id.fragment_container, fragment);

trans.commit();

}

}

Remove Fragment from the Activity

Fragments - Reference the Activity

• You can reference the controlling Activity from within the Fragment

e.g, in the onCreateView() method of the Fragment class:

View listView = getActivity().findViewById(R.id.list);

Permissions

• no application, by default, has permission to perform any operations that would adversely impact

o other applicationso the operating systemo the user

• How does the system know that this app uses these permissions?

Using Permissions

Permissions requested by your application must be specified in the Android Manifest file.

For example, here we request permission to access the Internet

<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.app.myapp" > <uses-permission android:name="android.permission.INTERNET" /> ...</manifest>

How to Request Permissions

Your app doesn't request to use any permissions by default

To request to use a permission

1. Open AndroidManifest.xml

2. Click the Permissions tab at the bottom of the Editor

3. Click Add ...

4. Select Uses Permission

5. Select the permission you want to request from the drop-down list

6. Save AndroidManifest.xml

Permissions - WebView Example

A WebView is a View that allows you to load and display web page content to the user

Permissions - WebView Example

@Override

public void onCreate(Bundle savedInstanceState) {

WebView webview = (WebView) findViewById(R.id.webView1);

webview.setWebViewClient(new WebViewClient() {

@Overridepublic boolean shouldOverrideUrlLoading(WebView view, String url) {

return false;

}

});

webview.loadUrl("http://www.google.com");

}

Of course, this is in our XML layout file somewhere

Permissions - WebView Example

@Override

public void onCreate(Bundle savedInstanceState) {

WebView webview = (WebView) findViewById(R.id.webView1);

webview.setWebViewClient(new WebViewClient() {

@Overridepublic boolean shouldOverrideUrlLoading(WebView view, String url) {

return false;

}

});

webview.loadUrl("http://www.google.com");

}

This block of code prevents the system from opening the URL in the default browser

Permissions - WebView Example

@Override

public void onCreate(Bundle savedInstanceState) {

WebView webview = (WebView) findViewById(R.id.webView1);

webview.setWebViewClient(new WebViewClient() {

@Overridepublic boolean shouldOverrideUrlLoading(WebView view, String url) {

return false;

}

});

webview.loadUrl("http://www.google.com");

}

It has to return false, in order to load the URL in our webview instead of the default browser

Permissions - WebView Example

@Override

public void onCreate(Bundle savedInstanceState) {

WebView webview = (WebView) findViewById(R.id.webView1);

webview.setWebViewClient(new WebViewClient() {

@Override

public boolean shouldOverrideUrlLoading(WebView view, String url) {

return false;

}

});

webview.loadUrl("http://www.google.com");

}

The WebView will not load the URL if you don't have INTERNET permissions!, i.e.

android.permissions.INTERNET

Permissions

There are many more permissions that can be used

You can find a list of them here

Android Application Components

1. Activity

2. Broadcast Receiver

3. Content Provider

4. Service

Broadcast Receiver

• �a component that responds to system wide broadcast announcementso �Incoming SMS, MMS, Email, phone callo Battery low, Screen has turned off, or a picture was

captured.

• �think of a Broadcast receiver as a “gateway” to the other components.

• intended to very little worko Depending on the incoming event to the receiver, it

could start a Service or Activity.

Broadcast Receiver

To add a new Broadcast Receiver• open the AndroidManifest.xml file

• click on the Application tab at the bottom of the window

• under the Application Nodes section, click Add ...

• select Receiver

• in the Attributes for Receiver section, click on the Name* link

• Enter the name of your Broadcast Receivero e.g. "MyBroadcastReceiver"

• Finish

Broadcast Receiver - Manifest File

If you view AndroidManifest.xml in the XML editor, you should see something like this

<receiver android:name="MyBroadcastReceiver"></receiver>

Broadcast Receiver

Your new Broadcast Receiver file should look something like this

public class MyBroadcastReceiver extends BroadcastReceiver {

@Overridepublic void onReceive(Context context, Intent intent) {

}}

Broadcast Receiver

public class MyBroadcastReceiver extends BroadcastReceiver {

@Overridepublic void onReceive(Context context, Intent intent) {

}}

Event listener for when a broadcast has been received.

Broadcast Receiver

public class MyBroadcastReceiver extends BroadcastReceiver {

@Overridepublic void onReceive(Context context, Intent intent) {

}}

How do you know which broadcasts to listen for?

Registering BroadcastReceiver

There are two ways to register a BroadcastReceiver to listen for a broadcast

1 . Adding an <intent-filter> to the Manifest file

2. Programmatically

Registering BroadcastReceiver

1. To add an <intent-filter> to the Manifest and listen for a Broadcast ...

1. Open AndroidManifest.xml and click on the Application Tab at the bottom of the Window

2. Select your BroadcastReceiver

3. Click Add ...

4. Make sure "Create new element in the selected element ... " is selected, then choose Intent Filter

5. Click Add ...

6. Choose Action

7. Select the appropriate permission in the Name drop-down list

a. e.g. android.intent.action.TIME_SET

8. Save AndroidManifest.xml

Registering BroadcastReceiver

Alternatively, if you view AndroidManifest.xml in the XML editor, you should see something like this

<receiver android:name="MyBroadcastReceiver">

</receiver>

Registering BroadcastReceiver

We need to tell the system which broadcast(s) we want to listen for. First we need to add an <intent-filter> tag

<receiver android:name="MyBroadcastReceiver">

</receiver>

Registering BroadcastReceiver

We need to tell the system which broadcast(s) we want to listen for. First we need to add an <intent-filter> tag

<receiver android:name="MyBroadcastReceiver">

</receiver>

Place the cursor here and press Ctrl + Space

Registering BroadcastReceiver

We need to tell the system which broadcast(s) we want to listen for. First we need to add an <intent-filter> tag

<receiver android:name="MyBroadcastReceiver">

</receiver>

Select <intent-filter>

Registering BroadcastReceiver

We need to tell the system which broadcast(s) we want to listen for. First we need to add an <intent-filter> tag

<receiver android:name="MyBroadcastReceiver">

<intent-filter>

</intent-filter>

</receiver>

Registering BroadcastReceiver

We need to tell the system which broadcast(s) we want to listen for. First we need to add an <intent-filter> tag

<receiver android:name="MyBroadcastReceiver">

<intent-filter>

</intent-filter>

</receiver>

an <intent-filter> describes what this receiver should listen for

Registering BroadcastReceiver

We need to tell the system which broadcast(s) we want to listen for. First we need to add an <intent-filter> tag

<receiver android:name="MyBroadcastReceiver">

<intent-filter>

</intent-filter>

</receiver>

Place the cursor here and press Ctrl + Space

Registering BroadcastReceiver

We need to tell the system which broadcast(s) we want to listen for. First we need to add an <intent-filter> tag

<receiver android:name="MyBroadcastReceiver">

<intent-filter>

</intent-filter>

</receiver>

Select <action/>

Registering BroadcastReceiver

We need to tell the system which broadcast(s) we want to listen for. First we need to add an <intent-filter> tag

<receiver android:name="MyBroadcastReceiver">

<intent-filter><action />

</intent-filter>

</receiver>

Press Ctrl + Space again

Registering BroadcastReceiver

We need to tell the system which broadcast(s) we want to listen for. First we need to add an <intent-filter> tag

<receiver android:name="MyBroadcastReceiver">

<intent-filter>

<action />

</intent-filter>

</receiver>

Select android:name

Registering BroadcastReceiver

We need to tell the system which broadcast(s) we want to listen for. First we need to add an <intent-filter> tag

<receiver android:name="MyBroadcastReceiver">

<intent-filter>

<action android:name=" "/>

</intent-filter>

</receiver>

Let's try receiving a broadcast for when the screen has been turned on

Registering BroadcastReceiver

We need to tell the system which broadcast(s) we want to listen for. First we need to add an <intent-filter> tag

<receiver android:name="MyBroadcastReceiver">

<intent-filter>

<action android:name=" "/>

</intent-filter>

</receiver>

Press Ctrl + Space again

Registering BroadcastReceiver

We need to tell the system which broadcast(s) we want to listen for. First we need to add an <intent-filter> tag

<receiver android:name="MyBroadcastReceiver">

<intent-filter>

<action android:name=" "/>

</intent-filter>

</receiver>

Select android.intent.action.TIME_SET

Registering BroadcastReceiver

We need to tell the system which broadcast(s) we want to listen for. First we need to add an <intent-filter> tag

<receiver android:name="MyBroadcastReceiver">

<intent-filter>

<action android:name="android.intent.action.TIME_SET"/>

</intent-filter>

</receiver>

Registering BroadcastReceiver

We need to tell the system which broadcast(s) we want to listen for. First we need to add an <intent-filter> tag

<receiver android:name="MyBroadcastReceiver">

<intent-filter>

<action android:name="android.intent.action.TIME_SET"/>

</intent-filter>

</receiver>

Registering BroadcastReceiver

2. To register a BroadcastReceiver programmatically ...

Registering BroadcastReceiver

public class MainActivity extends Activity {

MyBroadcastReceiver receiver;

@Override public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

receiver = new MyBroadcastReceiver();

IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);

registerReceiver(receiver, filter);

}

}

Registering BroadcastReceiver

public class MainActivity extends Activity {

MyBroadcastReceiver receiver;

@Override public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

receiver = new MyBroadcastReceiver();

IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);

registerReceiver(receiver, filter);

}

}

Create a new instance of your receiver

Registering BroadcastReceiver

public class MainActivity extends Activity {

MyBroadcastReceiver receiver;

@Override public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

receiver = new MyBroadcastReceiver();

IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);

registerReceiver(receiver, filter);

}

}

Create an intent filter

Registering BroadcastReceiver

public class MainActivity extends Activity {

MyBroadcastReceiver receiver;

@Override public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

receiver = new MyBroadcastReceiver();

IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);

registerReceiver(receiver, filter);

}

}

The receiver is now registered

BroadcastReceiver - onReceive()

public class MyBroadcastReceiver extends BroadcastReceiver {

@Override

public void onReceive(Context context, Intent intent) {

Intent myIntent = new Intent(context, ActivityToBeLaunched.class);

Toast.makeText(

context,

"Broadcast Received!",

Toast.LENGTH_LONG).show();

myIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

context.startActivity(myIntent);

}

}

Now let's look at our BroadcastReceiver

BroadcastReceiver - onReceive()

public class MyBroadcastReceiver extends BroadcastReceiver {

@Override

public void onReceive(Context context, Intent intent) {

Intent myIntent = new Intent(context, ActivityToBeLaunched.class);

Toast.makeText(

context,

"Broadcast Received!",

Toast.LENGTH_LONG).show();

myIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

context.startActivity(myIntent);

}

}

At this point, the broadcast has been received

BroadcastReceiver - onReceive()

public class MyBroadcastReceiver extends BroadcastReceiver {

@Override

public void onReceive(Context context, Intent intent) {

Intent myIntent = new Intent(context, ActivityToBeLaunched.class);

Toast.makeText(

context,

"Broadcast Received!",

Toast.LENGTH_LONG).show();

myIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

context.startActivity(myIntent);

}

}

Let's say we want to launch a new Activity when we receive the broadcast

BroadcastReceiver - onReceive()

public class MyBroadcastReceiver extends BroadcastReceiver {

@Override

public void onReceive(Context context, Intent intent) {

Intent myIntent = new Intent(context, ActivityToBeLaunched.class);

Toast.makeText(

context,

"Broadcast Received!",

Toast.LENGTH_LONG).show();

myIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

context.startActivity(myIntent);

}

}

And we want to show a Toast

BroadcastReceiver - onReceive()

public class MyBroadcastReceiver extends BroadcastReceiver {

@Override

public void onReceive(Context context, Intent intent) {

Intent myIntent = new Intent(context, ActivityToBeLaunched.class);

Toast.makeText(

context,

"Broadcast Received!",

Toast.LENGTH_LONG).show();

myIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

context.startActivity(myIntent);

}

}

You need to add flags to your intent this time

BroadcastReceiver - onReceive()

public class MyBroadcastReceiver extends BroadcastReceiver {

@Override

public void onReceive(Context context, Intent intent) {

Intent myIntent = new Intent(context, ActivityToBeLaunched.class);

Toast.makeText(

context,

"Broadcast Received!",

Toast.LENGTH_LONG).show();

myIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

context.startActivity(myIntent);

}

}

Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag

Unregistering BroadcastReceiver

Sometimes after you start listening for a Broadcast, you may want to STOP listening for it at some point

To UNregister a BroadcastReceiver programmatically ...

Unregistering BroadcastReceiver

public class MainActivity extends Activity {

@Override

public void onPause() {

unregisterReceiver(receiver);

super.onPause();

}

}

Unregistering BroadcastReceiver

public class MainActivity extends Activity {

@Override

public void onPause() {

unregisterReceiver(receiver);

super.onPause();

}

}

You will want to unregister before calling a super.onSomething() method, otherwise you may get Force Close

Unregistering BroadcastReceiver

If you register a BroadcastReceiver programmatically, you should unregister it before your Activity is destroyed!

• otherwise you will have a "leaked" receiver

• Please call unregisterReceiver in o onPause()o onStop()o or onDestroy()

This is important

References

• The Busy Coder's Guide to Android Development - Mark Murphy

• Android Developers

• The Mobile Lab at Florida State University

• Code Examples

top related