适用于所有API级别的Android剪贴板代码

时间:2012-01-27 00:47:43

标签: android api clipboard

适用于API级别的剪贴板代码<在API级别> = 11的设备上发生11次崩溃。

适用于API级> = 11的剪贴板代码在API级别<的设备上崩溃了11。

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

一个需要: import android.text.ClipboardManager;

而另一方需要: import android.content.ClipboardManager;

当然有一种方法可以编写一些可以在API级别11的两端工作的代码。我只是想不出来。

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

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

显然,由于我从Async任务执行此代码,因此我必须跳过更多的箍。

4 个答案:

答案 0 :(得分:21)

我最近遇到了类似的问题。 这就是我处理它的方式。

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块。但我宁愿不冒险:)

答案 1 :(得分:6)

避免例外

[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);
  }
}

答案 2 :(得分:1)

  

适用于API级别的剪贴板代码<在API级别> = 11的设备上发生11次崩溃。

This sample project在11级之前和之后的API级别上运行得非常好。我只是在Android 2.3(Nexus One)和Android 4.0(Nexus S)上重新测试它。

  

适用于API级> = 11的剪贴板代码在API级别<的设备上崩溃了11。

这并不奇怪。如果您指的是旧版Android中不存在的类或方法,则会出现VerifyError或类似的崩溃。

  

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

不是。

  

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

适用于所有API级别。

  

而另一个需要:import android.content.ClipboardManager;

已添加到API级别11.如果您的应用仅在API级别11或更高级别上运行,请使用此类(方法签名与IIRC相同)。

答案 3 :(得分:1)

自己编写剪贴板compat类,例如:

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());
        }
    }
}