Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Mobile and Embedded
  4. QJniObject.callObjectMethod "getString" on android.os.Bundle Returns "" Despite Bundle.toString() Showing Value
Forum Updated to NodeBB v4.3 + New Features

QJniObject.callObjectMethod "getString" on android.os.Bundle Returns "" Despite Bundle.toString() Showing Value

Scheduled Pinned Locked Moved Solved Mobile and Embedded
7 Posts 2 Posters 738 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • K Offline
    K Offline
    KenAppleby 0
    wrote on 28 Jan 2023, 17:27 last edited by
    #1

    I have an android.os.Bundle which is passed to C++ from Java via a native function call. The received object, when printed with .toString() appears to contain all the expected values.

    static ReceivedFileDetails fromBundle(QJniObject bundle)  {
      qDebug() << "ReceivedFileDetails::fromBundle" << bundle.toString();
    

    => ReceivedFileDetails::fromBundle "Bundle[{my.package.aat.Bundle.Flags=50331649, my.package.aat.Bundle.Action=android.intent.action.VIEW, my.package.aat.Bundle.Scheme=content, my.package.aat.Bundle.Subject=null, my.package.aat.Bundle.Uri=content://com.google.android.apps.nbu.files.provider/2/1000001836, my.package.aat.Bundle.Data=content://com.google.android.apps.nbu.files.provider/2/1000001836, my.package.aat.Bundle.Path=null, my.package.aat.Bundle.Text=null, my.package.aat.Bundle.Type=application/octet-stream}]"

    But I can't find a way to extract the individual values via QJniObject.callObjectMethod calls, for example:

    jstring actionKey = QJniObject::fromString("my.package.aat.Bundle.Action").object<jstring>();
    QString action = bundle.callObjectMethod("getString", "(Ljava/lang/String;)Ljava/lang/String;", actionKey).toString();
    qDebug() << "action" << action;
    

    => action ""

    The returned value is always "".
    Please can anyone tell me what I am doing wrong?

    Thanks.

    1 Reply Last reply
    0
    • J Offline
      J Offline
      JoeCFD
      wrote on 30 Jan 2023, 16:07 last edited by JoeCFD
      #2

      It may be your Java code is not made properly. Can you show your Java function?
      Use new to create the return String in your Java code.

      K 1 Reply Last reply 30 Jan 2023, 18:36
      0
      • J JoeCFD
        30 Jan 2023, 16:07

        It may be your Java code is not made properly. Can you show your Java function?
        Use new to create the return String in your Java code.

        K Offline
        K Offline
        KenAppleby 0
        wrote on 30 Jan 2023, 18:36 last edited by
        #3

        @JoeCFD
        This is the Java code, simplified:

        // ReceivedFileDetails is a Java class to hold parameters from the Intent
        public class ReceivedFileDetails {
            public static final String Action = "my.package.aat.Bundle.Action";
            public String mAction;
            public Bundle getBundle() {
                Bundle bundle = new Bundle();
                 if (mAction != null) { 
                    bundle.putString(Action, new String(mAction));
                }
                return bundle;
            }
            public static native void sendNativeBundle(Bundle bundle); // the native call to pass the Bundle to C++
        }
        
        // In Activity.onCreate():
            mDetails = new ReceivedFileDetails();
            mDetails.mAction = getIntent().getAction();
            Bundle bundle = mDetails.getBundle();
            ReceivedFileDetails.sendNativeBundle(bundle);
        

        When I first posted about this the code to insert the Action into the Bundle did not instantiate a new String. The new code, even with the new String(...) still gives "" for the return value from .Bundle.getString JNI call.

        Thanks.

        1 Reply Last reply
        0
        • J Offline
          J Offline
          JoeCFD
          wrote on 30 Jan 2023, 18:57 last edited by JoeCFD
          #4

          Not sure if what you did is right or not. How did you get bundle in in the following Qt code?
          QString action = bundle.callObjectMethod("getString", "(Ljava/lang/String;)Ljava/lang/String;", actionKey).toString();
          I guess you may not need to pass bundle to Qt code. Instead send back only a string.

          This is what I did and it works.

              auto info_obj = QAndroidJniObject::callStaticObjectMethod( "java class name with path",
                                                                         "static func name",
                                                                         "(Landroid/content/Context;)Ljava/lang/String;",
                                                                         QtAndroid::androidContext().object() );
          
              auto info_str = info_obj.toString();
          
          K 1 Reply Last reply 30 Jan 2023, 19:39
          0
          • J JoeCFD
            30 Jan 2023, 18:57

            Not sure if what you did is right or not. How did you get bundle in in the following Qt code?
            QString action = bundle.callObjectMethod("getString", "(Ljava/lang/String;)Ljava/lang/String;", actionKey).toString();
            I guess you may not need to pass bundle to Qt code. Instead send back only a string.

            This is what I did and it works.

                auto info_obj = QAndroidJniObject::callStaticObjectMethod( "java class name with path",
                                                                           "static func name",
                                                                           "(Landroid/content/Context;)Ljava/lang/String;",
                                                                           QtAndroid::androidContext().object() );
            
                auto info_str = info_obj.toString();
            
            K Offline
            K Offline
            KenAppleby 0
            wrote on 30 Jan 2023, 19:39 last edited by
            #5

            @JoeCFD
            The Bundle comes in effectively like this:

            static void receivedFileBundle(JNIEnv *env, jobject thiz, jobject jbundle)
            {
                QJniObject bundle(jbundle);
                qDebug() << "receivedFileBundle:" << bundle.toString();
                jstring actionKey = QJniObject::fromString("my.package.aat.Bundle.Action").object<jstring>();
                QString action = bundle.callObjectMethod("getString", "(Ljava/lang/String;)Ljava/lang/String;", actionKey).toString();
                qDebug() << "action" << action;
            }
            
            const JNINativeMethod methods[] {
                { "sendNativeBundle", "(Landroid/os/Bundle;)V",
                    reinterpret_cast<void *>(aat::ReceivedFileDetailsJavaClass::receivedFileBundle) },
                };
                
                sEnv.registerNativeMethods("my/package/aat/ReceivedFileDetails", methods, 1);
            
            // Java: In Activity.onCreate():
                mDetails = new ReceivedFileDetails();
                mDetails.mAction = getIntent().getAction();
                Bundle bundle = mDetails.getBundle();
                ReceivedFileDetails.sendNativeBundle(bundle);
            

            I have since moved past this passing a String (Json) instead of a Bundle, and it works fine, as you say. But it would be good to know why using a Bundle doesn't work.

            I note that "getString" is not a method of android.os.Bundle but of android.os.BaseBundle, but I doubt that that is the reason.

            J 1 Reply Last reply 30 Jan 2023, 19:43
            0
            • K KenAppleby 0
              30 Jan 2023, 19:39

              @JoeCFD
              The Bundle comes in effectively like this:

              static void receivedFileBundle(JNIEnv *env, jobject thiz, jobject jbundle)
              {
                  QJniObject bundle(jbundle);
                  qDebug() << "receivedFileBundle:" << bundle.toString();
                  jstring actionKey = QJniObject::fromString("my.package.aat.Bundle.Action").object<jstring>();
                  QString action = bundle.callObjectMethod("getString", "(Ljava/lang/String;)Ljava/lang/String;", actionKey).toString();
                  qDebug() << "action" << action;
              }
              
              const JNINativeMethod methods[] {
                  { "sendNativeBundle", "(Landroid/os/Bundle;)V",
                      reinterpret_cast<void *>(aat::ReceivedFileDetailsJavaClass::receivedFileBundle) },
                  };
                  
                  sEnv.registerNativeMethods("my/package/aat/ReceivedFileDetails", methods, 1);
              
              // Java: In Activity.onCreate():
                  mDetails = new ReceivedFileDetails();
                  mDetails.mAction = getIntent().getAction();
                  Bundle bundle = mDetails.getBundle();
                  ReceivedFileDetails.sendNativeBundle(bundle);
              

              I have since moved past this passing a String (Json) instead of a Bundle, and it works fine, as you say. But it would be good to know why using a Bundle doesn't work.

              I note that "getString" is not a method of android.os.Bundle but of android.os.BaseBundle, but I doubt that that is the reason.

              J Offline
              J Offline
              JoeCFD
              wrote on 30 Jan 2023, 19:43 last edited by JoeCFD
              #6

              @KenAppleby-0 QJniObject has limited types to handle. Bundle is not one of them. Check out what QJniObject can handle.
              Scroll all way down and look for JNI Types
              https://doc.qt.io/qt-6/qjniobject.html

              K 1 Reply Last reply 30 Jan 2023, 20:01
              0
              • J JoeCFD
                30 Jan 2023, 19:43

                @KenAppleby-0 QJniObject has limited types to handle. Bundle is not one of them. Check out what QJniObject can handle.
                Scroll all way down and look for JNI Types
                https://doc.qt.io/qt-6/qjniobject.html

                K Offline
                K Offline
                KenAppleby 0
                wrote on 30 Jan 2023, 20:01 last edited by
                #7

                @JoeCFD

                So C++ bundle.toString() calls a Java method on java.lang.Object, via jobject, which is a supported JNI type.

                That explains it.

                Thank you.

                1 Reply Last reply
                0

                1/7

                28 Jan 2023, 17:27

                • Login

                • Login or register to search.
                1 out of 7
                • First post
                  1/7
                  Last post
                0
                • Categories
                • Recent
                • Tags
                • Popular
                • Users
                • Groups
                • Search
                • Get Qt Extensions
                • Unsolved