Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android:寻找复制/粘贴复杂对象的有效策略_Android_Copy Paste_Clipboardmanager - Fatal编程技术网

Android:寻找复制/粘贴复杂对象的有效策略

Android:寻找复制/粘贴复杂对象的有效策略,android,copy-paste,clipboardmanager,Android,Copy Paste,Clipboardmanager,我正在设计一个Android应用程序,它可以处理复杂对象列表。对象包括文本或图形数据,并附带一组属性(例如,重要性级别和上次查看时间)。我想通过复制和粘贴功能帮助我的应用程序,这将遵循3条规则: 当用户复制一个对象并将其粘贴到我的应用程序时,将添加具有相同属性的对象的完整副本 当用户复制一个对象,然后将其粘贴到使用新复制/粘贴API(android.content.ClipboardManager)的其他应用程序时,该应用程序将接收文本或图像,具体取决于该对象所代表的文本或图形数据。如果是图像

我正在设计一个Android应用程序,它可以处理复杂对象列表。对象包括文本或图形数据,并附带一组属性(例如,重要性级别和上次查看时间)。我想通过复制和粘贴功能帮助我的应用程序,这将遵循3条规则:

  • 当用户复制一个对象并将其粘贴到我的应用程序时,将添加具有相同属性的对象的完整副本
  • 当用户复制一个对象,然后将其粘贴到使用新复制/粘贴API(android.content.ClipboardManager)的其他应用程序时,该应用程序将接收文本或图像,具体取决于该对象所代表的文本或图形数据。如果是图像,该应用程序将以文件路径或媒体库内容URI的形式接收图像
  • 当用户复制一个对象,然后将其粘贴到使用老式不推荐的API(android.text.ClipboardManager)的其他应用程序时,该应用程序将只接收由该对象表示的文本。如果对象表示图像,该应用程序将接收文本表示的URI,甚至是空文本
到目前为止,我已经研究过谷歌文档,浏览过各种编程论坛,但没有找到任何关于如何做到这一点的答案,也没有找到不可行的解释。目前我有两个缺点可供选择:
1) 创建一个使用对象的内容提供程序,并将内容URI复制到剪贴板。不幸的是,这意味着为了检索文本或图像,第三方应用程序必须了解我的内容提供商的内部组织,我当然不能假设这一点。
2) 仅将文本数据(使用clipddescription.MIMETYPE\u TEXT\u PLAIN类型)复制到剪贴板,或仅将URI复制到图像(使用clipddescription.MIMETYPE\u TEXT\u URILIST类型)。在这种情况下,粘贴到自己的应用程序时,我无法保留对象的属性


有什么想法吗?

使用
内容提供者是正确的做法。其他应用不需要了解内容的结构或组织:内容URI可以用作不透明标识符,并且(在API 11和更高版本中)一个URI可以有多种类型

粘贴为文本 如果您实现,您的提供商可以向请求映像的客户端提供映像,并向请求特定于供应商的MIME类型的客户端提供您的内部数据格式。这是
ClipData.Item.胁迫文本
用于从任意内容URI获取文本的机制:它请求类型
text/*
,并将返回的流读入字符串。(不要尝试复制无限的文本流!)只有在调用失败时,它才会放入URI本身的文本。传统的
getText
API也使用这个
impresseText
函数。这将整理您的遗留客户端和纯文本客户端

粘贴为图像 只需要图像的客户端应使用与上述相同的机制,这意味着您的
内容提供者。openTypedAssetFile
将用作文本,但请求的类型为
image/*
。但我不认为您可以依赖于每个客户机都这样做,所以我建议您实现并返回该URI的映像类型(而不是特定于供应商的类型)

实现
query
以返回一个游标,该游标的列名为
MediaStore.Images.ImageColumns.DATA
。如果要将元数据提供给那些客户端,还可以包括来自
MediaStore.Images.ImageColumns
的其他列

然后,您只需实现
openFile
即可返回图像的文件描述符。确保选中
模式
参数,以避免让其他应用程序能够写入您的文件。您可以调用创建需要从已有路径返回的
ParcelFileDescriptor

粘贴为特定于供应商的对象 这就是为您服务的所有第三方客户。现在粘贴到你自己的应用程序中怎么样?在这里你可以做两件事。如前一节所述,您可以使用请求特定于供应商的类型,并实现
ContentProvider.openTypedAssetFile
以返回该类型的流。如果特定于应用程序的数据是一种特殊类型的文件,其中包含序列化数据或类似数据,则此选项适用。如果特定于应用程序的内容是数据库行,则可以使用
query
:它可以将您喜欢的任何特定于应用程序的数据以及上面讨论的
MediaStore
列放入返回的光标中

这两种方法都提供了一种方便的方法,可以使用
ContentProvider
从存储机制中提取前端。我在一个应用程序中实现共享时做到了这一点,这是一个非常积极的变化,强加了一个明确的边界,迫使我清理所有对数据库的偷偷摸摸、违反封装的访问,从而使代码库更易于维护。它还使使用
Loader
s、
Adapter
s和
ContentObserver
s中的内置支持更容易,以减少前端代码的大小

但是,对于您的应用程序来说,这个强制封装边界可能位于错误的位置,或者您的粘贴目标需要访问相同的Java对象,而不仅仅是游标或序列化数据。在这种情况下,粘贴目标中的代码很容易解析粘贴的URI并从中读取标识符。然后,它可以直接与后端代码对话(使用现有的任何机制)以获取对相关数据对象的引用:它根本不需要使用
ContentResolver

结论
所有这一切可能看起来像是一大罐要打开的虫子,从某种程度上说确实如此。但是
ContentProvider
如果你只想做一件事,其实很容易实现,一旦你开始使用它,你可能会发现它可以帮助你解决其他问题。

你有复制图像的例子吗@丹胡姆