Android Question [SOLVED] Clipboard Questions: What is wrong with this code?

hatzisn

Expert
Licensed User
Longtime User
Hi everyone,

Question 1:

When I try to run this code:
B4X:
Public Sub GetText As String
   Dim jo As JavaObject
   jo.InitializeContext
   Dim sOk As String
   sOk = jo.RunMethod("GetTextFromClipboard", Null)
   Return sOk
End Sub


Public Sub SetText(txt As String) As Boolean
   Dim jo As JavaObject
   jo.InitializeContext
   Dim bOk As Boolean
   bOk = jo.RunMethod("SetTextToClipboard", Array As String(txt))
   Return bOk
End Sub



#IF JAVA

import android.content.ClipboardManager;
import android.content.ClipData;
import android.content.ClipDescription;

public Boolean SetTextToClipboard(String txt) {
   try{
       ClipboardManager myClipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
       ClipData myClip;
       myClip = ClipData.newPlainText("text", txt);
       myClipboard.setPrimaryClip(myClip);
       return true;
   }   
   catch(Exception ex){
       return false;
   }
};

public String GetTextFromClipboard() {
   ClipboardManager myClipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
   ClipData myClip = myClipboard.getPrimaryClip();
   ClipData.Item item = myClip.getItemAt(0);
   String txt = item.getText().toString();
   return txt;
};


public Boolean HasTextCopied() {
ClipboardManager myClipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
if (!(myClipboard.hasPrimaryClip())) {
   return false;
} else if (!(myClipboard.getPrimaryClipDescription().hasMimeType(MIMETYPE_TEXT_PLAIN))) {
   return false;
} else {
   return true;
}
};

#End If

I get this error:
B4X:
B4A Version: 7.80
Parsing code.    (0.00s)
Compiling code.    (0.04s)
Compiling layouts code.    (0.00s)
Organizing libraries.    (0.00s)
Generating R file.    (0.05s)
Compiling generated Java code.    Error
javac 1.8.0_172
src\dhqi\ctrlc\application\main.java:464: error: cannot find symbol
} else if (!(myClipboard.getPrimaryClipDescription().hasMimeType(MIMETYPE_TEXT_PLAIN))) {
                                                                 ^
  symbol:   variable MIMETYPE_TEXT_PLAIN
  location: class main
Note: src\dhqi\ctrlc\application\starter.java uses or overrides a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
1 error

What is wrong with this code? Does the translated starter.java has something that troubles it?

Question 2:

If I remove the last function in java (HasTextCopied) everything runs fine but if I move this code (without the HasTextCopied function) in a class it does not work...

I could use some help...

Thanks in advance...
 

DonManfred

Expert
Licensed User
Longtime User
Where are these constants defined? I do not see them in your code (but it´s definition must be there)

Try using the constantvalues (String)
CLIPBOARD_SERVICE
The constant value is "clipboard"
MIMETYPE_TEXT_PLAIN
The constant value is "text/uri-list"
 
Last edited:
Upvote 0

hatzisn

Expert
Licensed User
Longtime User
Where are these constants defined? I do not see them in your code (but it´s definition must be there)

Hi DonManfred,

boy you log in your computer very early. We are one hour in front of you and yet you are logged in. I suppose you start working early...
Thanks for responding. The definition of these two variables in analyzed in the following link:

https://developer.android.com/reference/android/content/Context

Even if I insert the following line:

B4X:
import android.content.Context;

The same error occurs. As I believe the error happens only when I insert the MIMETYPE_TEXT_PLAIN string because if I remove the entire sub (HasTextCopied) it works ok. The string CLIPBOARD_SERVICE is understood. When I initialize the javaobject as InitializeContext doesn't it run in the current context and get all these values from the current context? Let's answer one question at a time... Your answer was involving the 1st question or the 2nd?

Thanks in advance...

P.S. Forgive me if what I say is way out of the answer but as I already mentioned my java knowledge is limited.
 
Upvote 0

DonManfred

Expert
Licensed User
Longtime User
boy you log in your computer very early. We are one hour in front of you and yet you are logged in. I suppose you start working early...
I start working on 8AM but i wake up at 6AM to have enough time for the forum, some cups of coffee :D
I just want to start in the day relaxed :)
 
Upvote 0

hatzisn

Expert
Licensed User
Longtime User
Thanks DonManfred, now it compiles but it gives wrong answers the HasTextCopied function. Here is my code:

B4X:
Public Sub GetText As String
    Dim jo As JavaObject
    jo.InitializeContext
    Dim sOk As String
    sOk = jo.RunMethod("GetTextFromClipboard", Null)
    Return sOk
End Sub


Public Sub SetText(txt As String) As Boolean
    Dim jo As JavaObject
    jo.InitializeContext
    Dim bOk As Boolean
    bOk = jo.RunMethod("SetTextToClipboard", Array As String(txt))
    Return bOk
End Sub


Public Sub ClipboardHasText As Boolean
    Dim jo As JavaObject
    jo.InitializeContext
    Dim bOk As Boolean
    bOk = jo.RunMethod("HasTextCopied", Null)
    Return bOk   
End Sub


#IF JAVA

import android.content.ClipboardManager;
import android.content.ClipData;
import android.content.ClipDescription;
import android.content.Context;

public Boolean SetTextToClipboard(String txt) {
    try{
        ClipboardManager myClipboard = (ClipboardManager) getSystemService("clipboard");
        ClipData myClip;
        myClip = ClipData.newPlainText("text", txt);
        myClipboard.setPrimaryClip(myClip);
        return true;
    }  
    catch(Exception ex){
        return false;
    }
};

public String GetTextFromClipboard() {
    ClipboardManager myClipboard = (ClipboardManager) getSystemService("clipboard");
    ClipData myClip = myClipboard.getPrimaryClip();
    ClipData.Item item = myClip.getItemAt(0);
    String txt = item.getText().toString();
    return txt;
};


public Boolean HasTextCopied() {
ClipboardManager myClipboard = (ClipboardManager) getSystemService("clipboard");
if (!(myClipboard.hasPrimaryClip())) {
    return false;
} else if (!(myClipboard.getPrimaryClipDescription().hasMimeType("text/uri-list"))) {
    return false;
} else {
    return true;
}
};

#End If

Even if it has plain text it returns false. Am I doing something wrong or the mime-type is wrong?
I call it with this sub like this:

B4X:
Sub cmdV_Click
   If ClipboardHasText Then
      
   Else
       ToastMessageShow("No text", True)
   End If
   txtTry.Text = GetText
  
End Sub

It toasts "No text" but it pastes the text. I moved there this code of line to check if it can paste from the clipboard even though it Toasts "No text"...

Edit - I got it!!! The MIME type is text/plain.
 
Upvote 0

hatzisn

Expert
Licensed User
Longtime User
I changed the code to text plain and it works in main activity.
Now I moved the following subs to a class:

Class code:
B4X:
Sub Class_Globals
    
End Sub

'Initializes the object. You can add parameters to this method if needed.
Public Sub Initialize

End Sub

Public Sub GetText As String
    Dim jo As JavaObject
    jo.InitializeContext
    Dim sOk As String
    sOk = jo.RunMethod("GetTextFromClipboard", Null)
    Return sOk
End Sub


Public Sub SetText(txt As String) As Boolean
    Dim jo As JavaObject
    jo.InitializeContext
    Dim bOk As Boolean
    bOk = jo.RunMethod("SetTextToClipboard", Array As String(txt))
    Return bOk
End Sub


Public Sub ClipboardHasText As Boolean
    Dim jo As JavaObject
    jo.InitializeContext
    Dim bOk As Boolean
    bOk = jo.RunMethod("HasTextCopied", Null)
    Return bOk
    
End Sub


#IF JAVA

import android.content.ClipboardManager;
import android.content.ClipData;
import android.content.ClipDescription;
import android.content.Context;

public Boolean SetTextToClipboard(String txt) {
    try{
        ClipboardManager myClipboard = (ClipboardManager) getSystemService("clipboard");
        ClipData myClip;
        myClip = ClipData.newPlainText("text", txt);
        myClipboard.setPrimaryClip(myClip);
        return true;
    }   
    catch(Exception ex){
        return false;
    }
};

public String GetTextFromClipboard() {
    ClipboardManager myClipboard = (ClipboardManager) getSystemService("clipboard");
    ClipData myClip = myClipboard.getPrimaryClip();
    ClipData.Item item = myClip.getItemAt(0);
    String txt = item.getText().toString();
    return txt;
};


public Boolean HasTextCopied() {
ClipboardManager myClipboard = (ClipboardManager) getSystemService("clipboard");
if (!(myClipboard.hasPrimaryClip())) {
    return false;
} else if (!(myClipboard.getPrimaryClipDescription().hasMimeType("text/plain"))) {
    return false;
} else {
    return true;
}
};

#End If

Now when I try to compile I get the following error:
B4X:
B4A Version: 7.80
Parsing code.    (0.00s)
Compiling code.    (0.03s)
Compiling layouts code.    (0.00s)
Organizing libraries.    (0.00s)
Generating R file.    (0.06s)
Compiling generated Java code.    Error
B4A line: 25
End Sub
javac 1.8.0_172
src\dhqi\ctrlc\application\clpb.java:103: error: cannot find symbol
        ClipboardManager myClipboard = (ClipboardManager) getSystemService("clipboard");
                                                          ^
  symbol:   method getSystemService(String)
  location: class clpb

I suppose that is has to do with the context. Right? It is a different context... If this is the problem what is the answer?
 
Upvote 0

hatzisn

Expert
Licensed User
Longtime User
Hi everyone,

I tried a lot, searched the Internet bigtime but no results. I 've spent a lot of energy for the answer but I am completely dissapointed. No result - no result.
Can somebody help me because it is not obvious to me what is wrong. Maybe @Erel? Any insights on this?

Thanks in advance
 
Upvote 0

hatzisn

Expert
Licensed User
Longtime User
I made some progress. I turned the code into the following and now it compiles:

B4X:
Private Sub Class_Globals
    
End Sub

'Initializes the object. You can add parameters to this method if needed.
Public Sub Initialize

End Sub

Public Sub GetText As String
    Dim r As Reflector
    Dim jo As JavaObject
    jo.InitializeContext
    Dim sOk As String
    sOk = jo.RunMethod("GetTextFromClipboard", Array As Object(r.GetContext))
    Return sOk
End Sub


Public Sub SetText(txt As String) As Boolean
    Dim r As Reflector
    Dim jo As JavaObject
    jo.InitializeContext
    Dim bOk As Boolean
    bOk = jo.RunMethod("SetTextToClipboard", Array As Object(txt, r.GetContext))
    Return bOk
End Sub


Public Sub ClipboardHasText As Boolean
    Dim jo As JavaObject
    Dim r As Reflector
    jo.InitializeContext
    Dim bOk As Boolean
    bOk = jo.RunMethod("HasTextCopied", Array As Object(r.GetContext))
    Return bOk
    
End Sub


#IF JAVA

import android.content.ClipboardManager;
import android.content.ClipData;
import android.content.ClipDescription;
import android.content.Context;

public Boolean SetTextToClipboard(Object objtxt, Object mObjContext) {
    try{
        String txt = (String) objtxt;
        Context mContext = (Context) mObjContext;
        ClipboardManager myClipboard = (ClipboardManager) mContext.getSystemService("clipboard");
        ClipData myClip;
        myClip = ClipData.newPlainText("text", txt);
        myClipboard.setPrimaryClip(myClip);
        return true;
    }   
    catch(Exception ex){
        return false;
    }
};

public String GetTextFromClipboard(Object mObjContext) {
    Context mContext = (Context) mObjContext;
    ClipboardManager myClipboard = (ClipboardManager) mContext.getSystemService("clipboard");
    ClipData myClip = myClipboard.getPrimaryClip();
    ClipData.Item item = myClip.getItemAt(0);
    String txt = item.getText().toString();
    return txt;
};


public Boolean HasTextCopied(Object mObjContext) {
Context mContext = (Context) mObjContext;
ClipboardManager myClipboard = (ClipboardManager) mContext.getSystemService("clipboard");
if (!(myClipboard.hasPrimaryClip())) {
    return false;
} else if (!(myClipboard.getPrimaryClipDescription().hasMimeType("text/plain"))) {
    return false;
} else {
    return true;
}
};

#End If


I define in main activity the class but when I call the SetText sub I get the following error:

*** Service (starter) Create ***
** Service (starter) Start **
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
** Activity (main) Resume **

Error occurred on line: 25 (CLPB)
java.lang.RuntimeException: Method: SetTextToClipboard not found in: b4a.example.main
at anywheresoftware.b4j.object.JavaObject$MethodCache.getMethod(JavaObject.java:366)
at anywheresoftware.b4j.object.JavaObject.RunMethod(JavaObject.java:119)
at b4a.example.clpb._settext(clpb.java:76)
at b4a.example.main._cmdc_click(main.java:413)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:710)
at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:339)
at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:249)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:139)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:170)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:166)
at anywheresoftware.b4a.objects.ViewWrapper$1.onClick(ViewWrapper.java:80)
at android.view.View.performClick(View.java:6261)
at android.widget.TextView.performClick(TextView.java:11159)
at android.view.View$PerformClick.run(View.java:23752)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6776)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1496)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1386)

Here is the code in main activity:

B4X:
Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.

End Sub

Sub Globals
    'These global variables will be redeclared each time the activity is created.
    'These variables can only be accessed from this module.

    Private cmdC As Button
    Private cmdV As Button
    Private txtTry As EditText
    Dim clpb As CLPB
End Sub

Sub Activity_Create(FirstTime As Boolean)
    'Do not forget to load the layout file created with the visual designer. For example:
    'Activity.LoadLayout("Layout1")
    Activity.LoadLayout("1")
    clpb.Initialize
End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub

Sub cmdV_Click
    If clpb.ClipboardHasText Then
        txtTry.Text = clpb.GetText
    Else
        ToastMessageShow("No text", True)
    End If   
End Sub

Sub cmdC_Click
    ToastMessageShow(clpb.SetText("Trial text in clipboard"), True)
End Sub


Any ideas anyone? Thanks in advance...
 
Upvote 0

hatzisn

Expert
Licensed User
Longtime User
Solved. Here is the end code of the class:

B4X:
Private Sub Class_Globals
   
End Sub

'Initializes the object. You can add parameters to this method if needed.
Public Sub Initialize

End Sub

Public Sub GetText As String
    Dim r As Reflector
    Dim jo As JavaObject
    jo = Me
    Dim sOk As String
    sOk = jo.RunMethod("GetTextFromClipboard", Array As Object(r.GetContext))
    Return sOk
End Sub


Public Sub SetText(txt As String) As Boolean
    Dim r As Reflector
    Dim jo As JavaObject
    jo = Me
    Dim bOk As Boolean
    bOk = jo.RunMethod("SetTextToClipboard", Array As Object(txt, r.GetContext))
    Return bOk
End Sub


Public Sub ClipboardHasText As Boolean
    Dim jo As JavaObject
    Dim r As Reflector
    jo = Me
    Dim bOk As Boolean
    bOk = jo.RunMethod("HasTextCopied", Array As Object(r.GetContext))
    Return bOk
End Sub


#IF JAVA

import android.content.ClipboardManager;
import android.content.ClipData;
import android.content.ClipDescription;
import android.content.Context;

public Boolean SetTextToClipboard(Object objtxt, Object mObjContext) {
    try{
        String txt = (String) objtxt;
        Context mContext = (Context) mObjContext;
        ClipboardManager myClipboard = (ClipboardManager) mContext.getSystemService("clipboard");
        ClipData myClip;
        myClip = ClipData.newPlainText("text", txt);
        myClipboard.setPrimaryClip(myClip);
        return true;
    }  
    catch(Exception ex){
        return false;
    }
};

public String GetTextFromClipboard(Object mObjContext) {
    Context mContext = (Context) mObjContext;
    ClipboardManager myClipboard = (ClipboardManager) mContext.getSystemService("clipboard");
    ClipData myClip = myClipboard.getPrimaryClip();
    ClipData.Item item = myClip.getItemAt(0);
    String txt = item.getText().toString();
    return txt;
};


public Boolean HasTextCopied(Object mObjContext) {
Context mContext = (Context) mObjContext;
ClipboardManager myClipboard = (ClipboardManager) mContext.getSystemService("clipboard");
if (!(myClipboard.hasPrimaryClip())) {
    return false;
} else if (!(myClipboard.getPrimaryClipDescription().hasMimeType("text/plain"))) {
    return false;
} else {
    return true;
}
};

#End If
 
Upvote 0
Top