【问题标题】:Android clipboard code that works on all API levels适用于所有 API 级别的 Android 剪贴板代码
【发布时间】:2012-02-20 02:35:16
【问题描述】:

适用于 API 级别 = 11 的设备上崩溃。

适用于 API 级别 >= 11 的剪贴板代码在 API 级别

我无法为这两个版本编译代码,因为它们有冲突的导入要求。

一个需求: 导入android.text.ClipboardManager;

而其他需要: 导入 android.content.ClipboardManager;

当然有一种方法可以编写一些适用于 API 级别 11 双方的代码。我就是想不通。

***已编辑(因为我无法回答自己的问题)*******

我发现了问题。异常消息说:“无法在未调用 Looper.prepare() 的线程内创建处理程序。”

显然,由于我是从异步任务执行此代码,因此我必须跳过更多的障碍。

【问题讨论】:

  • 您应该只从主应用程序线程运行此代码,例如您的AsyncTaskonPostExecute()

标签: android api clipboard


【解决方案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());
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2011-11-02
      • 1970-01-01
      • 2014-10-29
      • 1970-01-01
      • 2016-11-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多