协议查询

快径通过ContentProvider向第三方应用提供协议查询的能力,目前支持以下能力

准备工作及基本内容

权限

首先你需要在AndroidManifest.xml内添加如下权限:

<!-- 快径的第三方读取权限 -->
<uses-permission android:name="com.liuzh.quickly.read" />

Authority

快径QuicklyProvider的Authority为:com.liuzh.quickly.pub.provider

支持的查询字段

支持查询的字段如下

查询所有协议列表

构建Uri

快径QuicklyProvider的查询Uri说明如下

构建uri代码示例如下

Uri queryUri = new Uri.Builder()
               .scheme("content")
               .authority("com.liuzh.quickly.pub.provider")
               .appendPath("quickly")
               .appendPath("schemes")
               .appendQueryParameter("do", "queryAll")
               .build();

或者

Uri queryUri = Uri.parse("content://com.liuzh.quickly.pub.provider/quickly/schemes?do=queryAll");

查询内容

通过contentResolver进行查询,示例代码如下

private static final String COLUMN_NAME = "name";
private static final String COLUMN_SCHEME = "scheme";
private static final String COLUMN_ICON = "icon";
private static final String COLUMN_ID = "_id";

private void queryOnWorker() {
    Uri queryUri = new Uri.Builder()
            .scheme("content")
            .authority("com.liuzh.quickly.pub.provider")
            .appendPath("quickly")
            .appendPath("schemes")
            .appendQueryParameter("do", "queryAll")
            .build();

    // 可根据需要的信息进行查询
    String[] projection = new String[]{
            COLUMN_NAME,
            COLUMN_SCHEME,
            COLUMN_ICON,
            COLUMN_ID
    };

    Cursor query = null;
    try {
        query = getContentResolver().query(queryUri, projection, null, null, null);
        if (query != null) {
            if (query.moveToFirst()) {
                do {
                    // 协议id
                    long id = query.getLong(query.getColumnIndex(COLUMN_ID));
                    // 协议名称
                    String name = query.getString(query.getColumnIndex(COLUMN_NAME));
                    // 协议内容
                    String scheme = query.getString(query.getColumnIndex(COLUMN_SCHEME));
                    // icon bytes
                    byte[] iconBytes = query.getBlob(query.getColumnIndex(COLUMN_ICON));
                    // icon bitmap
                    Bitmap icon = BitmapFactory.decodeByteArray(iconBytes, 0, iconBytes.length);
                } while (query.moveToNext());
            }
        } else {
            // failed
        }
    } catch (Exception e) {
        // failed
        Log.i("LiuZh", "queryOnWorker: ", e);
    } finally {
        if (query != null) {
            try {
                query.close();
            } catch (Throwable ignore) {                
            }
        }
    }
}

特殊情况

由于国产手机对应用关联启动的限制,若快径不被允许”关联启动”,或者说快径没有”关联启动”的权限,那么在通过ContentProvider查询时会无法查询到结果,即上述示例代码中会query == null成立

在查询得到空cursor时,通过快径支持的一个alive协议quickly://alive将快径无感知唤醒,之后再重新查询

示例代码如下

private void queryOnWorker() {
    ...
    try {
        query = getContentResolver().query(queryUri, projection, null, null, null);
        if (query != null) {
            ....
        } else {
            wakeQuickly();
        }
    } catch (Exception e) {
        ...
    } finally {
        ...
    }
}

/**
 * 无感知唤醒快径,快径会在收到该请求后立刻finish自己,达到application被创建,但对用户无感知的效果
 */
private void wakeQuickly() {
    Intent intent = new Intent();
    intent.setData(Uri.parse("quickly://alive"));
    startActivityForResult(intent, 123);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == 123 && resultCode == RESULT_OK) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                queryOnWorker();
            }
        }).start();
    }
}

执行协议

基本内容

scheme

快径的scheme为quickly://

支持的内容

通过协议内容执行

quickly://do?scheme=协议内容

请注意协议内容必须经过encode,否则无法被正确获取

示例代码如下

Intent intent = new Intent();
String scheme = "com.liuzh.quickly.DP:word#https://www.baidu.com/s?";
try {
    // 协议内容必须经过encode否则可能无法被正确获取
    scheme = URLEncoder.encode(scheme, "utf-8");
} catch (UnsupportedEncodingException ignore) {
}
intent.setData(Uri.parse("quickly://do?scheme=" + scheme);
try {
    startActivity(intent);
} catch (ActivityNotFoundException e) {
    // 未安装快径
}

通过协议id执行

quickly://do?id=协议ID

协议ID为通过查询得到的_id字段

请注意通过id执行可能在用户删除协议后,导致id空缺而无法执行协议

示例代码如下

Intent intent = new Intent();
intent.setData(Uri.parse("quickly://do?id=123"));
try {
    startActivity(intent);
} catch (ActivityNotFoundException e) {
    // 未安装快径
}