AndroidAndroid知识Android开发

通用Intent

2016-12-20  本文已影响347人  sunnygarden

(1)闹钟

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);    //确认存在对应Activity组件再开启
         }
}

注:为了调用ACTION_SET_ALARM,应用必须在清单文件中注册SET_ALARM权限:
<uses-permission android:name="com.android.alarm.permission.SET_ALARM" />
示例 Intent 过滤器:

<activity ...>
    <intent-filter>
        <action android:name="android.intent.action.SET_ALARM" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>
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);  //一个布尔型值,用于指定响应定时器的应用在设置定时器时是否应跳过其 UI。 
                  //若为 true,则应用应跳过任何确认 UI,直接启动指定的定时器。
    if (intent.resolveActivity(getPackageManager()) != null)
    {
        startActivity(intent);  //确认存在对应Activity组件再开启
    }
}

注:为了调用ACTION_SET_TIMER,应用必须在清单文件中注册SET_ALARM权限:
<uses-permission android:name="com.android.alarm.permission.SET_ALARM" />
示例 Intent 过滤器:

<activity ...>
    <intent-filter>
        <action android:name="android.intent.action.SET_TIMER" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>
<activity ...>
    <intent-filter>
        <action android:name="android.intent.action.SHOW_ALARMS" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

(2)日历

public void addEvent(String title, String location, Calendar begin, Calendar end)
 {
    Intent intent = new Intent(Intent.ACTION_INSERT)
            .setData(Events.CONTENT_URI)  //指定内容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 过滤器:

<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>

(3)相机

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 位置
                    Uri.withAppendedPath(mLocationForPhotos, targetFilename));
    if (intent.resolveActivity(getPackageManager()) != null) //确认存在对应Activity组件再开启
            {
                  //通过startActivityForResult获得Intent中返回缩小尺寸的照片副本(缩略图)
                  startActivityForResult(intent, REQUEST_IMAGE_CAPTURE);
             }
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
 {
    if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK)
             {
                    //拍照获得的副本(缩略图)以Bitmap形式保存在名为 "data"的 extra 字段中
                    Bitmap thumbnail = data.getParcelable("data");//获得副本Bitmap
                    //此外,还可以通过URI访问原始尺寸的照片或视频,该URI为上面通过EXTRA_OUTPUT设置的URI
                    // Do other work with full size photo saved in mLocationForPhotos
                    ...
              }
}

示例 Intent 过滤器:

<activity ...>
    <intent-filter>
        <action android:name="android.media.action.IMAGE_CAPTURE" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

处理此 Intent 的Activity 应检查传入Intent中有无EXTRA_OUTPUT extra,然后将拍摄的图像或视频保存在该 extra 指定的位置,并调用带Intent的setResult(),该 Intent 将经过压缩的缩略图包括在名为 "data"的 extra中,注意相关权限的注册。

public void capturePhoto()
 {
    Intent intent = new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA);
    //Intent intent = new Intent(MediaStore.INTENT_ACTION_VIDEO_CAMERA);
    if (intent.resolveActivity(getPackageManager()) != null)
    {
        startActivityForResult(intent);   //确认存在对应Activity组件再开启
    }
}

示例 Intent 过滤器:

<activity ...>
    <intent-filter>
          <!--若为视频模式此处应为"android.media.action.VIDEO_CAMERA"-->
        <action android:name="android.media.action.STILL_IMAGE_CAMERA" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

(4)联系人

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)
    {
         //回调的结果Intent包含指向所选联系人的 content:URI,
        //响应会利用Contacts Provide API 为我们的应用授予该联系人的临时读取权限,
        //即使我们的应用不具READ_CONTACTS权限也没有关系。
        startActivityForResult(intent, REQUEST_SELECT_CONTACT);   //确认存在对应Activity组件再开启
 
    }
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
 {
    if (requestCode == REQUEST_SELECT_CONTACT && resultCode == RESULT_OK)
 {
        Uri contactUri = data.getData(); //取出包含指向所选联系人的 content:URI,读取该联系人的详情并不需要READ_CONTACTS权限
        // Do something with the selected contact at contactUri
        ...
    }
}
  1. CommonDataKinds.Phone.CONTENT_TYPE——从有电话号码的联系人中选取
  2. CommonDataKinds.Email.CONTENT_TYPE——从有电子邮件地址的联系人中选取
  3. CommonDataKinds.StructuredPostal.CONTENT_TYPE——从有邮政地址的联系人中选取
  4. ContactsContract下众多其他 CONTENT_TYPE值中的一个
      如果只需要检索一种类型的联系人数据,则此方法要比上一部分中使用的MIME 类型Contacts.CONTENT_TYPE更高效,因为结果可让我们直接访问所需数据,无需对联系人提供程序执行更复杂的查询。
    示例 Intent:
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);   //确认存在对应Activity组件再开启
    }
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
 { 
   if (requestCode == REQUEST_SELECT_PHONE_NUMBER && resultCode == RESULT_OK) 
{
        Uri contactUri = data.getData(); //得到指向所选联系人数据的 content:URI
        String[] projection = new String[]{CommonDataKinds.Phone.NUMBER};
        Cursor cursor = getContentResolver().query(contactUri, projection,
                null, null, null);  //从联系人提供程序中查询电话号码
        if (cursor != null && cursor.moveToFirst()) {  //若cursor的返回值有效,取出查询到的电话号码
            int numberIndex = cursor.getColumnIndex(CommonDataKinds.Phone.NUMBER);
            String number = cursor.getString(numberIndex);
            //对取出的电话号码进行一些操作
            ... 
       } 
   }
}

由于查询出来的cursor的初始位置是指向第一条记录的前一个位置的,故使用cursor.moveToFirst()函数来指向查询结果的第一个位置。一般通过判断cursor.moveToFirst()的值为true或false来确定查询结果是否为空。

  1. 使用ACTION_PICK返回的联系人 URI,如上述所示(此方法不需要任何应用权限)
  2. 直接访问所有联系人的列表(此方法需要 READ_CONTACTS权限)
    示例 Intent:
public void viewContact(Uri contactUri)
 {
    Intent intent = new Intent(Intent.ACTION_VIEW, contactUri);//无需指定MIME类型,该类型可以从联系人URI中推断得出
    if (intent.resolveActivity(getPackageManager()) != null)
    {
        startActivity(intent);
    }
}
public void editContact(Uri contactUri, String email)
 {
    Intent intent = new Intent(Intent.ACTION_EDIT);
    intent.setData(contactUri);
    //可使用ContactsContract.Intents.Insert中定义的一个或多个extra,来填充联系人详情字段
    intent.putExtra(Intents.Insert.EMAIL, email); 
    if (intent.resolveActivity(getPackageManager()) != null)
    {
        startActivity(intent);   //确认存在对应Activity组件再开启
    }
}
public void insertContact(String name, String email)
 {
    Intent intent = new Intent(Intent.ACTION_INSERT);
    intent.setType(Contacts.CONTENT_TYPE);
    //可使用ContactsContract.Intents.Insert中定义的一个或多个extra
    intent.putExtra(Intents.Insert.NAME, name);
    intent.putExtra(Intents.Insert.EMAIL, email); 
    if (intent.resolveActivity(getPackageManager()) != null)
    {
        startActivity(intent);   //确认存在对应Activity组件再开启
    }
}

(5)电子邮件

  1. ACTION_SENDTO(适用于不带附件)
  2. ACTION_SEND(适用于带一个附件)
  3. ACTION_SEND_MULTIPLE(适用于带多个附件)
    并使用下列 extra 键加入收件人和主题等电子邮件详情:
  4. Intent.EXTRA_EMAIL
    包含所有“主送”收件人电子邮件地址的字符串数组。
  5. Intent.EXTRA_CC
    包含所有“抄送”收件人电子邮件地址的字符串数组。
  6. Intent.EXTRA_BCC
    包含所有“密件抄送”收件人电子邮件地址的字符串数组。
  7. Intent.EXTRA_SUBJECT
    包含电子邮件主题的字符串。
  8. Intent.EXTRA_TEXT
    包含电子邮件正文的字符串。
  9. Intent.EXTRA_STREAM
    指向附件的 Uri。如果使用的是 ACTION_SEND_MULTIPLE 操作,应将其改为包含多个 Uri对象的 ArrayList。
    示例 Intent:
public void composeEmail(String[] addresses, String subject, Uri attachment)
 {
    Intent intent = new Intent(Intent.ACTION_SEND);
    intent.setType("*/*");
    intent.putExtra(Intent.EXTRA_EMAIL, addresses);
    intent.putExtra(Intent.EXTRA_SUBJECT, subject);
    intent.putExtra(Intent.EXTRA_STREAM, attachment);
    if (intent.resolveActivity(getPackageManager()) != null)
    { 
       startActivity(intent);   //确认存在对应Activity组件再开启
    }
}

如果您想确保 Intent 只由电子邮件应用(而非其他短信或社交应用)进行处理,则需使用 ACTION_SENDTO操作并加入 "mailto:"数据架构。例如:

public void composeEmail(String[] addresses, String subject)
 {
    Intent intent = new Intent(Intent.ACTION_SENDTO);
    intent.setData(Uri.parse("mailto:")); // 只有电子邮件应用才能处理
    intent.putExtra(Intent.EXTRA_EMAIL, addresses);
    intent.putExtra(Intent.EXTRA_SUBJECT, subject);
    if (intent.resolveActivity(getPackageManager()) != null)
    { 
       startActivity(intent);   //确认存在对应Activity组件再开启
    }
}

示例 Intent 过滤器:

<activity ...>
    <intent-filter>
        <action android:name="android.intent.action.SEND" />
        <data android:type="*/*" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
    <intent-filter>
        <action android:name="android.intent.action.SENDTO" />
        <data android:scheme="mailto" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

(6)文件存储

static final int REQUEST_IMAGE_GET = 1;public void selectImage()
 {
    Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
    intent.setType("image/*");
    if (intent.resolveActivity(getPackageManager()) != null)
    {
        startActivityForResult(intent, REQUEST_IMAGE_GET);   //确认存在对应Activity组件再开启
    }
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
 {
    if (requestCode == REQUEST_IMAGE_GET && resultCode == RESULT_OK)
     { 
       Bitmap thumbnail = data.getParcelable("data");
        Uri fullPhotoUri = data.getData();
        // Do work with photo saved at fullPhotoUri
        ...
    }
}

用于返回照片的示例 Intent 过滤器

<activity ...>
    <intent-filter>
        <action android:name="android.intent.action.GET_CONTENT" />
        <data android:type="image/*" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.OPENABLE" />
    </intent-filter>
</activity>
static final int REQUEST_IMAGE_OPEN = 1;
public void selectImage()
 { 
   Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
    intent.setType("image/*");
    intent.addCategory(Intent.CATEGORY_OPENABLE);
    //只有系统能接收到ACTION_OPEN_DOCUMENT, 所以此处不需要判断Activity是否存在
    startActivityForResult(intent, REQUEST_IMAGE_OPEN);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
 {
    if (requestCode == REQUEST_IMAGE_OPEN && resultCode == RESULT_OK)
    {
        Uri fullPhotoUri = data.getData();
        // Do work with full size photo saved at fullPhotoUri
        ...
    }
}

第三方应用实际上无法通过ACTION_OPEN_DOCUMENT操作响应 Intent,而是由系统接收此 Intent,然后在统一用户界面中显示各类应用提供的所有文件。
  如需在该用户界面中提供我们的应用的文件,并允许其他应用打开它们,则必须实现一个DocumentsProvider,并加入一个PROVIDER_INTERFACE Intent 过滤器("android.content.action.DOCUMENTS_PROVIDER")。例如:

<provider ...
    android:grantUriPermissions="true"
    android:exported="true"
    android:permission="android.permission.MANAGE_DOCUMENTS">
    <intent-filter>
        <action android:name="android.content.action.DOCUMENTS_PROVIDER" />
    </intent-filter>
</provider>

(7)本地操作

public void callCar()
 {
    Intent intent = new Intent(ReserveIntents.ACTION_RESERVE_TAXI_RESERVATION);
    if (intent.resolveActivity(getPackageManager()) != null)
    {
        startActivity(intent);  //确认存在对应Activity组件再开启
    }
}

示例 Intent 过滤器:

<activity ...>
    <intent-filter>
        <action android:name="com.google.android.gms.actions.RESERVE_TAXI_RESERVATION" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>
public void showMap(Uri geoLocation)
 {
    Intent intent = new Intent(Intent.ACTION_VIEW);
    intent.setData(geoLocation);
    if (intent.resolveActivity(getPackageManager()) != null)
    {
        startActivity(intent); //确认存在对应Activity组件再开启
    }
}

示例 Intent 过滤器:

<activity ...>
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <data android:scheme="geo" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>
public void playMedia(Uri file)
 {
    Intent intent = new Intent(Intent.ACTION_VIEW);
    intent.setData(file);
    if (intent.resolveActivity(getPackageManager()) != null)
    {
        startActivity(intent); //确认存在对应Activity组件再开启
    }
}

示例 Intent 过滤器:

<activity ...>
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <data android:type="audio/*" />
        <data android:type="application/ogg" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>
public void dialPhoneNumber(String phoneNumber)
 {
    Intent intent = new Intent(Intent.ACTION_DIAL);
    intent.setData(Uri.parse("tel:" + phoneNumber));
    if (intent.resolveActivity(getPackageManager()) != null)
  {
        startActivity(intent); //确认存在对应Activity组件再开启
    }
}
public void composeMmsMessage(String message, Uri attachment)
 { 
    Intent intent = new Intent(Intent.ACTION_SENDTO);
    intent.setType(HTTP.PLAIN_TEXT_TYPE);
    intent.putExtra("sms_body", message); //表示消息正文的字符串
    intent.putExtra(Intent.EXTRA_STREAM, attachment); //指向附件的图像或视频的Uri
    if (intent.resolveActivity(getPackageManager()) != null)
    {
        startActivity(intent); //确认存在对应Activity组件再开启
    }
}

如果想确保 Intent 只由短信应用(而非其他电子邮件或社交应用)进行处理,则需使用ACTION_SENDTO操作并设置data "smsto:"。例如:

public void composeMmsMessage(String message, Uri attachment)
 {
    Intent intent = new Intent(Intent.ACTION_SEND);
    intent.setData(Uri.parse("smsto:"));  //确保只有短信应用进行处理
    intent.putExtra("sms_body", message); //表示消息正文的字符串
    intent.putExtra(Intent.EXTRA_STREAM, attachment); //指向附件的图像或视频的Uri
    if (intent.resolveActivity(getPackageManager()) != null)
    {
        startActivity(intent); //确认存在对应Activity组件再开启
    }
}

示例 Intent 过滤器:

<activity ...>
    <intent-filter>
        <action android:name="android.intent.action.SEND" />
        <data android:type="text/plain" />
        <data android:type="image/*" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>
  1. ACTION_SETTINGS
  2. ACTION_WIRELESS_SETTINGS
  3. ACTION_AIRPLANE_MODE_SETTINGS
  4. ACTION_WIFI_SETTINGS
  5. ACTION_APN_SETTINGS
  6. ACTION_BLUETOOTH_SETTINGS
  7. ACTION_DATE_SETTINGS
  8. ACTION_LOCALE_SETTINGS
  9. ACTION_INPUT_METHOD_SETTINGS
  10. ACTION_DISPLAY_SETTINGS
  11. ACTION_SECURITY_SETTINGS
  12. ACTION_LOCATION_SOURCE_SETTINGS
  13. ACTION_INTERNAL_STORAGE_SETTINGS
  14. ACTION_MEMORY_CARD_SETTINGS
    示例 Intent:
public void openWifiSettings()
 {
    Intent intent = new Intent(Intent.ACTION_WIFI_SETTINGS); //打开Wifi设置界面
    if (intent.resolveActivity(getPackageManager()) != null)
    {
        startActivity(intent);
    }
}
public void searchWeb(String query)
 {
    Intent intent = new Intent(Intent.ACTION_WEB_SEARCH);
    intent.putExtra(SearchManager.QUERY, query);//在SearchManager.QUERY extra 中指定搜索字符串
    if (intent.resolveActivity(getPackageManager()) != null)
    {
        startActivity(intent);
    }
}
上一篇下一篇

猜你喜欢

热点阅读