Android 开发之 App Components

Android的应用程序框架允许您创建丰富和创新应用使用一组可重用的组件。本篇解释如何构建的组件定义应用程序的构建块,并使用意图如何连接在一起。

  • Intents and Intent Filters
  • Activities
  • Services
  • Content Providers
  • App Widgets
  • Processes and Threads

Intent Type可分为显式意图(Explicit intents)和隐式意图(Implicit intents),下图所示。描述一个隐含的意图是通过系统启动另一个活动:[1]活动创建一个意图的行动描述并将其传递给startActivity()。[2]的Android系统搜索所有应用程序意图过滤器匹配的意图。当找到匹配,[3]系统开始匹配的活动(活动B)通过调用itsonCreate()方法并传递它的意图。警告:确保你的应用程序是安全的,开始时总是使用一个显式意图服务,不为你的服务声明意图过滤器。使用隐式意图启动一个服务是一个安全隐患,因为你无法确定服务响应的目的,和用户不能看到哪些服务开始。


在某些时候比如调用系统相册传入action,就可以调出系统相册,当然也可以自定义Action,例如

static final String ACTION_TIMETRAVEL = "com.example.action.TIMETRAVEL";

activity的启动通过startActivityForResult时,需要声明Action:CATEGORY_DEFAULT,用于意图过滤。

<activity android:name="TestActivity">
    <intent-filter>
        <action android:name="android.intent.action.SEND"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <data android:mimeType="text/plain"/>
    </intent-filter>
</activity>

一个应用有多少个Context对象?这个问题其实很简单。Application、Activity和Service从继承关系来看,最终父类是Context,我们可以这样认为:每个Activity都是一个Context,每一个Service都是一个Context,而Application也是一个Context。每个应用自启动都会创建一个Application,如果应用内有自定义Application那么在清单文件manifest里面需要声明,Activity和Service同样需要。

在开发中调用系统服务,通过Action过滤,例如调用系统的闹钟,只需要传入ACTION_SET_ALARM即可,实例代码如下:

public void createAlarm(String message, int hour, int minutes) {
    Intent intent = new Intent(AlarmClock.ACTION_SET_ALARM)
            .putExtra(AlarmClock.EXTRA_MESSAGE, message)
            .putExtra(AlarmClock.EXTRA_HOUR, hour)
            .putExtra(AlarmClock.EXTRA_MINUTES, minutes);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

调用系统服务需要更具功能请求相应的权限,以设置闹钟为例,权限如下:

<uses-permission android:name="com.android.alarm.permission.SET_ALARM" />

下面是一些列的系统功能调用代码块,先来看倒计时,在(Android 4.4)

public void startTimer(String message, int seconds) {
    Intent intent = new Intent(AlarmClock.ACTION_SET_TIMER)
            .putExtra(AlarmClock.EXTRA_MESSAGE, message)
            .putExtra(AlarmClock.EXTRA_LENGTH, seconds)
            .putExtra(AlarmClock.EXTRA_SKIP_UI, true);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

在日历上添加事件,实例和意图过滤如下:

public void addEvent(String title, String location, Calendar begin, Calendar end) {
    Intent intent = new Intent(Intent.ACTION_INSERT)
            .setData(Events.CONTENT_URI)
            .putExtra(Events.TITLE, title)
            .putExtra(Events.EVENT_LOCATION, location)
            .putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, begin)
            .putExtra(CalendarContract.EXTRA_EVENT_END_TIME, end);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}
<activity ...>
    <intent-filter>
        <action android:name="android.intent.action.INSERT" />
        <data android:mimeType="vnd.android.cursor.dir/event" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

调用系统Camera

static final int REQUEST_IMAGE_CAPTURE = 1;
static final Uri mLocationForPhotos;

public void capturePhoto(String targetFilename) {
    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    intent.putExtra(MediaStore.EXTRA_OUTPUT,
            Uri.withAppendedPath(mLocationForPhotos, targetFilename);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivityForResult(intent, REQUEST_IMAGE_CAPTURE);
    }
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
        Bitmap thumbnail = data.getParcelable("data");
        // Do other work with full size photo saved in mLocationForPhotos
        ...
    }
}

读取联系人(READ_CONTACTS)

static final int REQUEST_SELECT_CONTACT = 1;

public void selectContact() {
    Intent intent = new Intent(Intent.ACTION_PICK);
    intent.setType(ContactsContract.Contacts.CONTENT_TYPE);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivityForResult(intent, REQUEST_SELECT_CONTACT);
    }
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_SELECT_CONTACT && resultCode == RESULT_OK) {
        Uri contactUri = data.getData();
        // Do something with the selected contact at contactUri
        ...
    }
}

查询联系人信息

static final int REQUEST_SELECT_PHONE_NUMBER = 1;

public void selectContact() {
    // Start an activity for the user to pick a phone number from contacts
    Intent intent = new Intent(Intent.ACTION_PICK);
    intent.setType(CommonDataKinds.Phone.CONTENT_TYPE);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivityForResult(intent, REQUEST_SELECT_PHONE_NUMBER);
    }
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_SELECT_PHONE_NUMBER && resultCode == RESULT_OK) {
        // Get the URI and query the content provider for the phone number
        Uri contactUri = data.getData();
        String[] projection = new String[]{CommonDataKinds.Phone.NUMBER};
        Cursor cursor = getContentResolver().query(contactUri, projection,
                null, null, null);
        // If the cursor returned is valid, get the phone number
        if (cursor != null && cursor.moveToFirst()) {
            int numberIndex = cursor.getColumnIndex(CommonDataKinds.Phone.NUMBER);
            String number = cursor.getString(numberIndex);
            // Do something with the phone number
            ...
        }
    }
}

诸如此类方法块太多就不一一列举。Android系统设置的功能模块的打开方法,除了通过manager实现,也可以通过intent传递意图打开,代码如下:

public void openWifiSettings() {
    Intent intent = new Intent(Intent.ACTION_WIFI_SETTINGS);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

ACTION:ACTION_SETTINGS
       ACTION_WIRELESS_SETTINGS
       ACTION_AIRPLANE_MODE_SETTINGS
       ACTION_WIFI_SETTINGS
       ACTION_APN_SETTINGS
       ACTION_BLUETOOTH_SETTINGS
       ACTION_DATE_SETTINGS
       ACTION_LOCALE_SETTINGS
       ACTION_INPUT_METHOD_SETTINGS
       ACTION_DISPLAY_SETTINGS
       ACTION_SECURITY_SETTINGS
       ACTION_LOCATION_SOURCE_SETTINGS
       ACTION_INTERNAL_STORAGE_SETTINGS
       ACTION_MEMORY_CARD_SETTINGS

你可能感兴趣的:(android,Components)