Android Developer API Guides
1. System Permissions:
(1)To enforce your own permissions, you must first declare them in your AndroidManifest.xml
using one or more
tags.<permission>
For example, an application that wants to control who can start one of its activities could declare a permission for this operation as follows:
<manifestxmlns:android="http://schemas.android.com/apk/res/android" package="com.me.app.myapp"> <permissionandroid:name="com.me.app.myapp.permission.DEADLY_ACTIVITY" android:label="@string/permlab_deadlyActivity" android:description="@string/permdesc_deadlyActivity" android:permissionGroup="android.permission-group.COST_MONEY" android:protectionLevel="dangerous"/> ... </manifest>
The <protectionLevel>
attribute is required, telling the system how the user is to be informed of applications requiring the permission, or who is allowed to hold that permission, as described in the linked documentation.
The <permissionGroup>
attribute is optional, and only used to help the system display permissions to the user. You will usually want to set this to either a standard system group (listed inandroid.Manifest.permission_group
) or in more rare cases to one defined by yourself. It is preferred to use an existing group, as this simplifies the permission UI shown to the user.
Note that both a label and description should be supplied for the permission. These are string resources that can be displayed to the user when they are viewing a list of permissions (
) or details on a single permission ( android:label
). The label should be short, a few words describing the key piece of functionality the permission is protecting. The description should be a couple sentences describing what the permission allows a holder to do. Our convention for the description is two sentences, the first describing the permission, the second warning the user of what bad things can happen if an application is granted the permission.android:description
(2)
ContentProvider
permissions (applied to the <provider>
tag) restrict who can access the data in aContentProvider
. (Content providers have an important additional security facility available to them called URI permissions which is described later.) Unlike the other components, there are two separate permission attributes you can set: android:readPermission
restricts who can read from the provider, andandroid:writePermission
restricts who can write to it. Note that if a provider is protected with both a read and write permission, holding only the write permission does not mean you can read from a provider. The permissions are checked when you first retrieve a provider (if you don't have either permission, a SecurityException will be thrown), and as you perform operations on the provider. UsingContentResolver.query()
requires holding the read permission; using ContentResolver.insert()
,ContentResolver.update()
, ContentResolver.delete()
requires the write permission. In all of these cases, not holding the required permission results in a SecurityException
being thrown from the call.
2.Intents and Intent Filters
(1)To set only the data URI, call setData()
. To set only the MIME type, call setType()
. If necessary, you can set both explicitly with setDataAndType()
.
Caution: If you want to set both the URI and MIME type, do not call setData()
and setType()
because they each nullify the value of the other. Always use setDataAndType()
to set both URI and MIME type.
(2)Extras
The Intent
class specifies many EXTRA_*
constants for standardized data types. If you need to declare your own extra keys (for intents that your app receives), be sure to include your app's package name as a prefix. For example:
static final String EXTRA_GIGAWATTS ="com.example.EXTRA_GIGAWATTS";
(3)Example implicit intent
Caution: It's possible that a user won't have any apps that handle the implicit intent you send tostartActivity()
. If that happens, the call will fail and your app will crash. To verify that an activity will receive the intent, call resolveActivity()
on your Intent
object. If the result is non-null, then there is at least one app that can handle the intent and it's safe to call startActivity()
. If the result is null, you should not use the intent and, if possible, you should disable the feature that issues the intent.
// Create the text message with a string Intent sendIntent =newIntent(); sendIntent.setAction(Intent.ACTION_SEND); sendIntent.putExtra(Intent.EXTRA_TEXT, textMessage); sendIntent.setType(HTTP.PLAIN_TEXT_TYPE);// "text/plain" MIME type // Verify that the intent will resolve to an activity if(sendIntent.resolveActivity(getPackageManager())!=null){ startActivity(sendIntent); }
(4)Category
Note: In order to receive implicit intents, you must include the CATEGORY_DEFAULT
category in the intent filter. The methods startActivity()
and startActivityForResult()
treat all intents as if they declared the CATEGORY_DEFAULT
category. If you do not declare this category in your intent filter, no implicit intents will resolve to your activity.
(5)Service
Caution: To avoid inadvertently running a different app'sService
, always use an explicit intent to start your own service and do not declare intent filters for your service.
(6)Fragment
The inflate()
method takes three arguments:
- The resource ID of the layout you want to inflate.
- The
ViewGroup
to be the parent of the inflated layout. Passing thecontainer
is important in order for the system to apply layout parameters to the root view of the inflated layout, specified by the parent view in which it's going. - A boolean indicating whether the inflated layout should be attached to the
ViewGroup
(the second parameter) during inflation. (In this case, this is false because the system is already inserting the inflated layout into thecontainer
—passing true would create a redundant view group in the final layout.)
Now you've seen how to create a fragment that provides a layout. Next, you need to add the fragment to your activity.
Each transaction is a set of changes that you want to perform at the same time. You can set up all the changes you want to perform for a given transaction using methods such as add()
, remove()
, and replace()
. Then, to apply the transaction to the activity, you must call commit()
.
Before you call commit()
, however, you might want to call addToBackStack()
, in order to add the transaction to a back stack of fragment transactions. This back stack is managed by the activity and allows the user to return to the previous fragment state, by pressing the Back button.
If you do not call addToBackStack()
when you perform a transaction that removes a fragment, then that fragment is destroyed when the transaction is committed and the user cannot navigate back to it. Whereas, if you do call addToBackStack()
when removing a fragment, then the fragment is stopped and will be resumed if the user navigates back.
The most significant difference in lifecycle between an activity and a fragment is how one is stored in its respective back stack. An activity is placed into a back stack of activities that's managed by the system when it's stopped, by default (so that the user can navigate back to it with the Back button, as discussed in Tasks and Back Stack). However, a fragment is placed into a back stack managed by the host activity only when you explicitly request that the instance be saved by calling addToBackStack()
during a transaction that removes the fragment.
(7)Tasks and Back Stack
When the user presses the Backbutton, the current activity is popped from the top of the stack (the activity is destroyed) and the previous activity resumes (the previous state of its UI is restored).
If the user continues to press Back, then each activity in the stack is popped off to reveal the previous one, until the user returns to the Home screen (or to whichever activity was running when the task began). When all activities are removed from the stack, the task no longer exists.
As discussed above, the system's default behavior preserves the state of an activity when it is stopped. This way, when users navigate back to a previous activity, its user interface appears the way they left it. However, you can—and should—proactively retain the state of your activities using callback methods, in case the activity is destroyed and must be recreated.(Saving activity state)
Regardless of whether an activity starts in a new task or in the same task as the activity that started it, the Backbutton always takes the user to the previous activity. However, if you start an activity that specifies thesingleTask
launch mode, then if an instance of that activity exists in a background task, that whole task is brought to the foreground. At this point, the back stack now includes all activities from the task brought forward, at the top of the stack. Figure 4 illustrates this type of scenario.
Note: Although the activity starts in a new task, the Back button still returns the user to the previous activity.
FLAG_ACTIVITY_NEW_TASK
Start the activity in a new task. If a task is already running for the activity you are now starting, that task is brought to the foreground with its last state restored and the activity receives the new intent inonNewIntent()
.
This produces the same behavior as the "singleTask"(?)
launchMode
value, discussed in the previous section.
When the intent that launches an activity contains the FLAG_ACTIVITY_NEW_TASK
flag.
A new activity is, by default, launched into the task of the activity that called startActivity()
. It's pushed onto the same back stack as the caller. However, if the intent passed to startActivity()
contains theFLAG_ACTIVITY_NEW_TASK
flag, the system looks for a different task to house the new activity. Often, it's a new task. However, it doesn't have to be. If there's already an existing task with the same affinity as the new activity, the activity is launched into that task(with its last state restored). If not, it begins a new task.
This second ability is important: Users must be able to leave a task and then come back to it later using this activity launcher. For this reason, the two launch modes that mark activities as always initiating a task,"singleTask"
and ""singleInstance"
, should be used only when the activity has an ACTION_MAIN
and aCATEGORY_LAUNCHER
filter. Imagine, for example, what could happen if the filter is missing: An intent launches a"singleTask"
activity, initiating a new task, and the user spends some time working in that task. The user then presses the Home button. The task is now sent to the background and is not visible. Now the user has no way to return to the task, because it is not represented in the application launcher.
(8)View.OnTouchListener
Public Methods
public abstract boolean onTouch (View v, MotionEvent event)
Called when a touch event is dispatched to a view. This allows listeners to get a chance to respond before the target view.
Parameters
v | The view the touch event has been dispatched to. |
---|---|
event | The MotionEvent object containing full information about the event. |
Returns
- True if the listener has consumed the event, false otherwise.