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 826 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.
  • KenAppleby 0K Offline
    KenAppleby 0K Offline
    KenAppleby 0
    wrote on 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
    • JoeCFDJ Offline
      JoeCFDJ Offline
      JoeCFD
      wrote on 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.

      KenAppleby 0K 1 Reply Last reply
      0
      • JoeCFDJ JoeCFD

        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.

        KenAppleby 0K Offline
        KenAppleby 0K Offline
        KenAppleby 0
        wrote on 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
        • JoeCFDJ Offline
          JoeCFDJ Offline
          JoeCFD
          wrote on 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();
          
          KenAppleby 0K 1 Reply Last reply
          0
          • JoeCFDJ JoeCFD

            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();
            
            KenAppleby 0K Offline
            KenAppleby 0K Offline
            KenAppleby 0
            wrote on 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.

            JoeCFDJ 1 Reply Last reply
            0
            • KenAppleby 0K KenAppleby 0

              @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.

              JoeCFDJ Offline
              JoeCFDJ Offline
              JoeCFD
              wrote on 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

              KenAppleby 0K 1 Reply Last reply
              0
              • JoeCFDJ JoeCFD

                @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

                KenAppleby 0K Offline
                KenAppleby 0K Offline
                KenAppleby 0
                wrote on 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

                • Login

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