Mobile Programming Lecture 6
description
Transcript of Mobile Programming Lecture 6
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
Code Examples
• BroadcastReceiverExample
• SimpleFragmentUsingXml
• SimpleFragmentProgrammatically
• FragmentActivityReferenceExample
• FragmentTransitionExample
• LayoutInflaterExample
• PermissionsExample
• ComplexFragmentsExample
• DynamicUiExample
References
• The Busy Coder's Guide to Android Development - Mark Murphy
• Android Developers
• The Mobile Lab at Florida State University
• Code Examples