Android clipboard code that works on all API levels

后端 未结 4 960
[愿得一人]
[愿得一人] 2020-12-09 07:05

The clipboard code that works for API levels < 11 crashes on devices with API levels >= 11.

The clipboard code that work for API level >= 11 crashes on devices wi

相关标签:
4条回答
  • 2020-12-09 07:34

    To avoid the exception

    [FATAL EXCEPTION: GLThread 6132  java.lang.RuntimeException: 
    Can't create handler inside thread that has not called Looper.prepare() ], 
    

    -> just create the ClipboardManager once at startup, for example in your onCreate() method and use it anytime in a separate function.

    tested working on 2.3.3 and 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);
      }
    }
    
    0 讨论(0)
  • 2020-12-09 07:37

    The clipboard code that works for API levels < 11 crashes on devices with API levels >= 11.

    This sample project works quite nicely on API levels before and after 11. I just retested it on Android 2.3 (Nexus One) and Android 4.0 (Nexus S).

    The clipboard code that work for API level >= 11 crashes on devices with API levels < 11.

    That is not surprising. If you are referring to classes or methods that do not exist in older versions of Android, you will get a VerifyError or similar crashes.

    I can not compile code for both versions because they have conflicting import requirements.

    Not really.

    One needs: import android.text.ClipboardManager;

    That works on all API levels.

    while the other needs: import android.content.ClipboardManager;

    That was added to API Level 11. If your app will only run on API Level 11 or higher, use this class (method signatures are all the same IIRC).

    0 讨论(0)
  • 2020-12-09 07:37

    Write yourself your own Clipboard compat class, for example:

    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());
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-09 07:43

    I recently faced a similar problem. Here's how I handled it.

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

    I'm not entirely sure if the first if block is necessary. But I'd rather not take a chance :)

    0 讨论(0)
提交回复
热议问题