适用于所有 API 级别的 Android 剪贴板代码
Posted
技术标签:
【中文标题】适用于所有 API 级别的 Android 剪贴板代码【英文标题】:Android clipboard code that works on all API levels 【发布时间】:2012-02-20 02:35:16 【问题描述】:适用于 API 级别 = 11 的设备上崩溃。
适用于 API 级别 >= 11 的剪贴板代码在 API 级别
我无法为这两个版本编译代码,因为它们有冲突的导入要求。
一个需求: 导入android.text.ClipboardManager;
而其他需要: 导入 android.content.ClipboardManager;
当然有一种方法可以编写一些适用于 API 级别 11 双方的代码。我就是想不通。
***已编辑(因为我无法回答自己的问题)*******
我发现了问题。异常消息说:“无法在未调用 Looper.prepare() 的线程内创建处理程序。”
显然,由于我是从异步任务执行此代码,因此我必须跳过更多的障碍。
【问题讨论】:
您应该只从主应用程序线程运行此代码,例如您的AsyncTask
的onPostExecute()
。
【参考方案1】:
我最近遇到了类似的问题。 以下是我的处理方式。
int currentapiVersion = android.os.Build.VERSION.SDK_INT;
if (currentapiVersion >= android.os.Build.VERSION_CODES.HONEYCOMB)
android.content.ClipboardManager clipboard = (android.content.ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
ClipData clip = ClipData.newPlainText("label", "Text to Copy");
clipboard.setPrimaryClip(clip);
else
android.text.ClipboardManager clipboard = (android.text.ClipboardManager)getSystemService(CLIPBOARD_SERVICE);
clipboard.setText("Text to Copy");
Toast.makeText(getApplicationContext(), "Text copied to clipboard", Toast.LENGTH_SHORT).show();
我不完全确定第一个 if 块是否必要。但我宁愿不要冒险:)
【讨论】:
这里的label
是什么?
@SrujanBarai - label
是剪辑数据的用户可见标签。这个label
字段主要由剪贴板管理器应用程序用作复制的剪辑数据的标题。更多信息请参考:developer.android.com/reference/android/content/…, java.lang.CharSequence)【参考方案2】:
避免异常
[FATAL EXCEPTION: GLThread 6132 java.lang.RuntimeException:
Can't create handler inside thread that has not called Looper.prepare() ],
-> 只需在启动时创建一次ClipboardManager
,例如在您的onCreate()
方法中,然后随时在单独的函数中使用它。
在 2.3.3 和 4.0.3 上测试过:
import android.text.ClipboardManager;
import android.content.ClipData;
..
public class myActivity extends Activity
private static ClipboardManager m_ClipboardManager;
@Override
protected void onCreate(..)
...
m_ClipboardManager = (ClipboardManager) m_sInstance.getSystemService(Context.CLIPBOARD_SERVICE);
public static void myCopyToClipBoard(String sTxt)
m_ClipboardManager.setText(sTxt);
【讨论】:
【参考方案3】:适用于 API 级别 = 11 的设备上崩溃。
This sample project 在 11 前后的 API 级别上运行良好。我刚刚在 Android 2.3 (Nexus One) 和 Android 4.0 (Nexus S) 上重新测试了它。
适用于 API 级别 >= 11 的剪贴板代码在 API 级别
这并不奇怪。如果您指的是旧版本 Android 中不存在的类或方法,您将收到 VerifyError
或类似的崩溃。
我无法为这两个版本编译代码,因为它们有冲突的导入要求。
不是真的。
一个需求:导入android.text.ClipboardManager;
这适用于所有 API 级别。
而其他需要:import android.content.ClipboardManager;
这已添加到 API 级别 11。如果您的应用只能在 API 级别 11 或更高级别上运行,请使用此类(方法签名都是相同的 IIRC)。
【讨论】:
我在 4.0 模拟器上运行了几乎相同的代码。当我执行“ClipboardManager cm=(ClipboardManager)getSystemService(CLIPBOARD_SERVICE);”我得到:01-26 16:27:10.886: W/AsyncTask(725): java.lang.InterruptedException 好的,您的代码正在运行,但仍然显示不推荐使用的方法警告。以后会不会有问题???我的意思是该方法将来会被永远删除吗???【参考方案4】:自己编写自己的剪贴板兼容类,例如:
import android.annotation.SuppressLint;
import android.content.ClipData;
import android.content.Context;
import android.net.Uri;
public class ClipboardCompat
private android.content.ClipboardManager currentCM=null;
private android.text.ClipboardManager legacyCM=null;
public ClipboardCompat()
if(android.os.Build.VERSION.SDK_INT >= 11 && currentCM == null)
currentCM = (android.content.ClipboardManager)
[getsomecontext].getSystemService(Context.CLIPBOARD_SERVICE);
else if(legacyCM == null)
legacyCM = (android.content.ClipboardManager)
[getsomecontext].getSystemService(Context.CLIPBOARD_SERVICE);
@SuppressLint("NewApi")
public String getText()
if(currentCM!=null)
try
return currentCM.getPrimaryClip().getItemAt(0).getText().toString();
catch (NullPointerException e)
return null;
else
try
return legacyCM.getText().toString();
catch (NullPointerException e)
return null;
@SuppressLint("NewApi")
public Uri getUri()
if(currentCM!=null)
try
return currentCM.getPrimaryClip().getItemAt(0).getUri();
catch (NullPointerException e)
return null;
else
return null;
@SuppressLint("NewApi")
public void set(String name, String s)
if(currentCM!=null)
ClipData clip = ClipData.newPlainText(name, s);
currentCM.setPrimaryClip(clip);
else
legacyCM.setText(s);
@SuppressLint("NewApi")
public void set(String name, Uri u)
if(currentCM!=null)
ClipData clip = ClipData.newRawUri(name, u);
currentCM.setPrimaryClip(clip);
else
legacyCM.setText(u.toString());
【讨论】:
以上是关于适用于所有 API 级别的 Android 剪贴板代码的主要内容,如果未能解决你的问题,请参考以下文章
如果我在 API 级别 21 (5.0) 上制作应用程序,它是不是适用于较新版本的 android?
@TargetApi 注释是不是仅适用于一个 Api 级别或更高级别?