企业🤖AI Agent构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
我们来看一个示例,代码如下所示: **Sample** ~~~ final void performPaste() { //获取ClipboardManager对象 ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); //获取ContentResolver对象 ContentResolver cr = getContentResolver(); //从剪贴板中取出ClipData ClipDataclip = clipboard.getPrimaryClip(); if (clip!= null) { String text=null; String title=null; //取剪切板ClipData中的第一项Item ClipData.Item item = clip.getItemAt(0); /* 下面这行代码取出Item中所包含的Uri。看起来顺理成章,其实不然。 应思考这样一个问题,为什么这里一定是取Uri呢?原因是在本例中, copy方和paste方都事先了解ClipData中的数据类型。 如果paste方不了解ClipData中的数据类型,该如何处理? 一种简单的方法就是采用if/else的判断语句。另外还有别的方法, 下文将做分析。 */ Uriuri = item.getUri(); Cursor orig = cr.query(uri,PROJECTION, null, null,null); ......//查询数据库并获取信息 orig.close(); } } if(text == null) { //如果paste方不了解ClipData中的数据类型,可调用coerceToText //函数,强制得到文本类型的数据 text = item.coerceToText(this).toString();//强制为文本 } ...... } ~~~ 下面来分析getPrimaryClip函数。 **ClipboardManager.java** ~~~ public ClipData getPrimaryClip() { try { //调用CBS的getPrimaryClip,并传递自己的package名 return getService().getPrimaryClip(mContext.getPackageName()); }...... } ~~~ **ClipboardManagerService.java** ~~~ public ClipData getPrimaryClip(String pkg) { synchronized (this) { //赋予该pkg相应的权限,后文再作分析 addActiveOwnerLocked(Binder.getCallingUid(), pkg); return mPrimaryClip;//返回ClipData给客户端 } } ~~~ 在上边的代码注释中,曾提到coerceToText函数。该函数在paste方不了解ClipData中数据类型的情况下,可以强制得到文本类型的数据。对于URI和Intent,这个功能又是如何实现的呢?来看下面的代码: **ClipData.java** ~~~ public CharSequence coerceToText(Context context){ //如果该Item已经有mText,则直接返回文本 if (mText!= null) { return mText; } //如果该Item中的数据是URI类型 if (mUri!= null) { FileInputStream stream = null; try{ /* ContentProvider需要实现openTypedAssetFileDescriptor函数, 以返回指定MIME(这里是text/*)类型的数据源(AssetFileDescriptor) */ AssetFileDescriptor descr = context.getContentResolver() .openTypedAssetFileDescriptor(mUri, "text/*", null); //创建一个输入流 stream = descr.createInputStream(); //创建一个InputStreamReader,读出来的数据将转换成UTF-8的文本 InputStreamReader reader = new InputStreamReader(stream, "UTF-8"); StringBuilder builder = new StringBuilder(128); char[] buffer = new char[8192]; int len; //从ContentProvider那读取数据,然后转换成UTF-8的字符串 while ((len=reader.read(buffer)) > 0) { builder.append(buffer, 0, len); } //返回String return builder.toString(); } ...... } //如果是Intent,则调用toUri返回一个字符串 if (mIntent != null) { returnmIntent.toUri(Intent.URI_INTENT_SCHEME); } return""; } } ~~~ 分析上边代码可知,针对URI类型的数据,coerceToText函数还是做了不少工作的。当然,还需要提供该URI的ContentProvider实现相应的函数。