vedi0boy
vedi0boy

Reputation: 1040

Android cannot find class java.awt.datatransfer.StringSelection? Trying to put string on clipboard

I am trying to copy a stack trace to my clipboard in android so that when the app crashes people can report the bug to me if they want to. I am using this method:

StringWriter sw = new StringWriter();
exception.printStackTrace(new PrintWriter(sw));
String exceptionAsString = sw.toString();
StringSelection selection = new StringSelection(exceptionAsString);
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
clipboard.setContents(selection, null);

It works wonderfully when I run the program on my desktop (I am using LibGDX to deploy the game on desktop and android) but when I try to run it in android I get a java.lang.NoClassDefFoundError: java.awt.datatransfer.StringSelection error.

Does android not support the StringSelection class? Are their alternative ways to doing this that work on both android and desktop? Thank you!

Upvotes: 1

Views: 1306

Answers (2)

bpgergo
bpgergo

Reputation: 16037

If I understand correctly, the problem is you are try to use java.awt.datatransfer.Clipboard here:

Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();

I suggest you try to use LibGDX com.badlogic.gdx.utils.Clipboard

See example here: http://badlogicgames.com/forum/viewtopic.php?t=11503&p=51773

Upvotes: 0

bpgergo
bpgergo

Reputation: 16037

EDIT Updated the answer for a multiplatform solution. Here's an idea, what I would try to do:

  1. detect platform, I'm not sure what will work here, you'll need to try, maybe Build.VERSION.SDK
  2. as you mentioned, the awt class does not load on the Android device, so when we're running on android, we'll not try to load it at all.
  3. when we'll running on desktop, we'll try to load awt classes dynamically.

For the android part, you do not need StringSelection class.

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

StringWriter sw = new StringWriter();
exception.printStackTrace(new PrintWriter(sw));
String exceptionAsString = sw.toString();

if (isAndroidPlatform()){
  ClipboardManager myClipboard;
  myClipboard = (ClipboardManager)getSystemService(CLIPBOARD_SERVICE);
  ClipData myClip;
  myClip = ClipData.newPlainText("text", exceptionAsString);
  myClipboard.setPrimaryClip(myClip);
} else {
    ClassLoader classLoader = YourMainClass.class.getClassLoader();
    Class stringSelectionClass = classLoader.loadClass("java.awt.datatransfer.StringSelection");
    Constructor constructor = stringSelectionClass.getConstructor(String.class);
    Object stringSelection =  constructor.newInstance(exceptionAsString);

    //you can try to access dynamically the awt clipboard along these lines, using java.lang.reflection
    Class toolkitSelectionClass = classLoader.loadClass("java.awt.Toolkit");
    Method toolkitConstructor = toolkitSelectionClass.getMethod("getDefaultToolkit");
    Object toolkit = toolkitConstructor.invoke(null);
    Method clipboardConstructor = toolkitSelectionClass.getMethod("getSystemClipboard");
    Object clipBoard = clipboardConstructor.invoke(toolkit);
    Class transferableClass = classLoader.loadClass("java.awt.datatransfer.Transferable");
    Class clipboardOwnerClass = classLoader.loadClass("java.awt.datatransfer.ClipboardOwner");
    Method copyMethod = clipBoard.getClass().getMethod("setContents", transferableClass, clipboardOwnerClass);
    copyMethod.invoke(clipBoard, stringSelection, null);

}

Android Docs: http://developer.android.com/guide/topics/text/copy-paste.html

Upvotes: 1

Related Questions