10 隐式intent

添加嫌疑人信息至模型层

为Crime添加成员变量

Crime.java

public class Crime {
    //...
    private String mSuspect;
    private String mPhone;
    //...
}

添加数据库字段

CrimeDbSchema.java

public class CrimeDbSchema {
    //数据表
    public static final class CrimeTable {
        //表名
        public static final String NAME = "crimes";
        //表的字段
        public static final class Cols {
            //...
            public static final String SUSPECT = "suspect";
            public static final String PHONE = "phone";
        }
    }
}

CrimeBaseHelper.java

@Override
public void onCreate(SQLiteDatabase db) {
    //执行创建数据表的SQL语句
    db.execSQL("create table " + CrimeTable.NAME +
            "(" +
            " _id integer primary key autoincrement, " +
            CrimeTable.Cols.UUID + ", " +
            CrimeTable.Cols.TITLE + ", " +
            CrimeTable.Cols.DATE + ", " +
            CrimeTable.Cols.SOLVED + ", " +
            CrimeTable.Cols.SUSPECT + ", " +
            CrimeTable.Cols.PHONE +
            ")"
    );
}

CrimeLab.java

//根据crime创建ContentValues并返回
private static ContentValues getContentValues(Crime crime) {
    ContentValues values = new ContentValues();
    //...
    values.put(CrimeTable.Cols.SUSPECT, crime.getSuspect());
    values.put(CrimeTable.Cols.PHONE, crime.getPhone());

    return values;
}

添加读取信息语句

CrimeCursorWrapper.java

public Crime getCrime() {
    //...
    String suspect = getString(getColumnIndex(CrimeTable.Cols.SUSPECT));
    String phone = getString(getColumnIndex(CrimeTable.Cols.PHONE));

    Crime crime = new Crime(UUID.fromString(uuidString));
    //...
    crime.setSuspect(suspect);
    crime.setPhone(phone);

    return crime;
}

使用格式化字符串

添加字符串资源

strings.xml

<resources>
    ...
    <string name="crime_report">
        [%1$s] 创建于 %2$s (%3$s),%4$s。
    </string>
    <string name="crime_report_solved">已经被解决了</string>
    <string name="crime_report_unsolved">还没有被解决</string>
    <string name="crime_report_no_suspect">没有嫌疑人</string>
    <string name="crime_report_suspect">嫌疑人是「%s」</string>
    <string name="crime_report_subject">陋习记录报告</string>
    <string name="send_report">发送报告到:</string>
</resources>

新增getCrimeReport()方法

CrimeFragment.java

private String getCrimeReport() {
    
    String solvedString = null;
    if (mCrime.isSolved()) solvedString = getString(R.string.crime_report_solved);
    else solvedString = getString(R.string.crime_report_unsolved);

    String dateFormat = "MM月dd日 EEE kk:mm";
    String dateString = DateFormat.format(dateFormat, mCrime.getDate()).toString();

    String suspect = mCrime.getSuspect();
    if (suspect == null) suspect = getString(R.string.crime_report_no_suspect);
    else suspect = getString(R.string.crime_report_suspect, suspect);

    String report = getString(R.string.crime_report, mCrime.getTitle(), dateString, solvedString, suspect);

    Log.d(TAG, "陋习报告:" + report);

    return report;
}

使用隐式intent

  • 使用显式intent,我们需要指定要操作系统启动哪个activity。
  • 使用隐式intent,只需告诉操作系统我们想要做什么,操作系统就会去启动能够胜任工作任务的activity。如果找到多个符合的activity,用户会看到一个可选应用列表。

隐式intent的组成

  1. 要执行的操作

    • 访问某个URL,使用Intent.ACTION_VIEW
    • 发送邮件,使用Intent.ACTION_SEND
  2. 要访问数据的位置

    • 某个网页的URL
    • 指向某个文件的URI
    • 指向ContentProvider中某条记录的某个content URI
  3. 操作涉及的数据类型

    • text/html
    • audio/mpeg3
  4. 可选类别(何时、何地或者如何使用某个activity)

发送消息

CrimeFragment.onCreateView(LayoutInflater, ViewGroup, Bundle)

mReportButton.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Log.d(TAG, "发送陋习报告...");

        //隐式intent要执行的操作[发送邮件]
        Intent intent = new Intent(Intent.ACTION_SEND);

        //隐式intent操作的数据类型[不指向任何数据、不包含任何类别]
        intent.setType("text/plain");

        //附加消息内容
        intent.putExtra(Intent.EXTRA_TEXT, getCrimeReport());

        //附加消息主题
        intent.putExtra(Intent.EXTRA_SUBJECT, getString(R.string.crime_report_subject));

        //创建每次都显示activity选择器
        intent = Intent.createChooser(intent, getString(R.string.send_report));

        startActivity(intent);
    }
});

获取联系人信息

发送隐式intent

CrimeFragment.onCreateView(LayoutInflater, ViewGroup, Bundle)

//隐式intent要执行的操作为[显示联系人],要访问的数据位置为[ContactsContract.Contacts.CONTENT_URI]
final Intent pickContact = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);

mSuspectButton.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Log.d(TAG, "选择嫌疑人...");

        startActivityForResult(pickContact, REQUEST_CONTACT);
    }
});
获取联系人姓名

CrimeFragment.onActivityResult(int, int, Intent)

if (requestCode == REQUEST_CONTACT) {
    //数据定位符,指向用户所选联系人
    Uri contactUri = data.getData();

    //要查询的字段
    String[] queryFields = new String[] { ContactsContract.Contacts.DISPLAY_NAME, ContactsContract.Contacts._ID };

    //返回查询结果(只有一条)
    Cursor cursor = getActivity().getContentResolver().query(contactUri, queryFields, null, null, null);

    String suspectId = null;
    try {
        if (cursor.getCount() == 0) return;

        cursor.moveToFirst();
        String suspect = cursor.getString(0);
        suspectId = cursor.getString(1);
        mCrime.setSuspect(suspect);
        mSuspectButton.setText("已选择嫌疑人「" + suspect + "」");
        Log.d(TAG, "已选择嫌疑人「" + suspect + "」");
    }
    finally {
        cursor.close();
    }
}

检查可响应任务的activity

如果设备没有联系人应用,就禁用选择嫌疑人按钮:

//检查是否存在联系人应用,没有就禁用按钮
//PackageManager.MATCH_DEFAULT_ONLY表示只搜索带CATEGORY_DEFAULT标志的activity
Intent pickContact = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);
PackageManager packageManager = getActivity().getPackageManager();
if (packageManager.resolveActivity(pickContact, PackageManager.MATCH_DEFAULT_ONLY) == null) mSuspectButton.setEnabled(false);

为测试上述代码,添加类别给intent,使任何联系人应用都不和此intent匹配:

pickContact.addCategory(Intent.CATEGORY_HOME);

实现拨打联系人电话

添加权限使用声明

AndroidManifest.xml

<manifest
    xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.criminalintent">

    <uses-permission android:name="android.permission.READ_CONTACTS" />
    <uses-permission android:name="android.permission.CALL_PHONE" />

    <application
        ...
    </application>
</manifest>

申请权限

CrimeFragment.onCreateView(LayoutInflater, ViewGroup, Bundle)

private static final int REQUEST_PERMISSION_CONTACT = 3;
if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
    ActivityCompat.requestPermissions(getActivity(), new String[] { Manifest.permission.READ_CONTACTS }, REQUEST_PERMISSION_CONTACT);
}
可在托管activity中重写授权回调方法

CrimePagerActivity.java

private static final int REQUEST_PERMISSION_CONTACT = 3;
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    switch (requestCode) {
        case REQUEST_PERMISSION_CONTACT:
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED)
                Toast.makeText(this, "已获取读取联系人权限。", Toast.LENGTH_SHORT).show();
            else
                Toast.makeText(this, "获取权限失败。", Toast.LENGTH_SHORT).show();
            return;

        default:
    }
}

获取联系人电话

为获取联系人电话,首先查询联系人的ContactsContract.Contacts._ID,在根据此ID查询ContactsContract.CommonDataKinds.Phone表,得到指定ID联系人的电话ContactsContract.CommonDataKinds.Phone.NUMBER。

CrimeFragment.onActivityResult(int, int, Intent)

if (requestCode == REQUEST_CONTACT) {
    //数据定位符,指向用户所选联系人
    Uri contactUri = data.getData();

    //要查询的字段
    String[] queryFields = new String[] { ContactsContract.Contacts.DISPLAY_NAME, ContactsContract.Contacts._ID };

    //返回查询结果(只有一条)
    Cursor cursor = getActivity().getContentResolver().query(contactUri, queryFields, null, null, null);

    String suspectId = null;
    try {
        if (cursor.getCount() == 0) return;

        cursor.moveToFirst();
        String suspect = cursor.getString(0);
        suspectId = cursor.getString(1);
        mCrime.setSuspect(suspect);
        mSuspectButton.setText("已选择嫌疑人「" + suspect + "」");
        Log.d(TAG, "已选择嫌疑人「" + suspect + "」");
    }
    finally {
        cursor.close();
    }

    queryFields = new String[] { ContactsContract.CommonDataKinds.Phone.NUMBER };
    String whereClause = ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?";
    String[] whereArgs = new String[] { suspectId };
    cursor = getActivity().getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, queryFields, whereClause, whereArgs, null);
    try {
        if (cursor.getCount() == 0) return;

        cursor.moveToFirst();
        String phone = cursor.getString(0);
        mCrime.setPhone(phone);
        mDialSuspectButton.setText("拨打嫌疑人电话「" + phone + "」");
        mDialSuspectButton.setEnabled(true);
        Log.d(TAG, "嫌疑人电话「" + phone + "」");
    }
    finally {
        cursor.close();
    }
}

拨打电话

创建隐式intent,实现拨打电话操作:

CrimeFragment.onCreateView(LayoutInflater, ViewGroup, Bundle)

mDialSuspectButton.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Log.d(TAG, "拨打嫌疑人电话「" + mCrime.getPhone() + "」...");

        Intent intent = new Intent(Intent.ACTION_DIAL);
        Uri number = Uri.parse("tel:" + mCrime.getPhone());
        intent.setData(number);

        startActivity(intent);
    }
});
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值