Titanium JIRA Archive
Titanium SDK/CLI (TIMOB)

[TIMOB-25782] Cannot Access Google Fit Read Result

GitHub Issuen/a
TypeBug
Priorityn/a
StatusReopened
ResolutionUnresolved
Affected Version/sn/a
Fix Version/sn/a
ComponentsHyperloop
Labelsn/a
ReporterYanko Valera
AssigneeUnknown
Created2018-02-06T17:18:19.000+0000
Updated2018-04-05T09:36:07.000+0000

Description

While trying to access Google Fit History data, the onSuccess is called, but the DataReadResponse methods can't be successfully called to retrieve data. Test code:
Fitness.getHistoryClient(windowActivity, GoogleSignIn.getLastSignedInAccount(windowActivity))
        .readData(new DataReadRequest.Builder()
            // The data request can specify multiple data types to return, effectively
            // combining multiple data queries into one call.
            // In this example, it's very unlikely that the request is for several hundred
            // datapoints each consisting of a few steps and a timestamp.  The more likely
            // scenario is wanting to see how many steps were walked per day, for 7 days.
            .aggregate(DataType.TYPE_STEP_COUNT_DELTA, DataType.AGGREGATE_STEP_COUNT_DELTA)
            // Analogous to a "Group By" in SQL, defines how data should be aggregated.
            // bucketByTime allows for a time span, whereas bucketBySession would allow
            // bucketing by "sessions", which would need to be defined in code.
            .bucketByTime(1, TimeUnit.DAYS)
            .setTimeRange(startTime, endTime, TimeUnit.MILLISECONDS)
            .build())
        .addOnSuccessListener(new OnSuccessListener({
            onSuccess: function(e) {
                var dataResponse = new DataReadResponse(e);

                console.log("onSuccess()" + e.toString() + "/" + dataResponse.toString());
                console.log("buckets size: " + dataResponse.getDataSets().size());
            }
        }))
        .addOnFailureListener(new OnFailureListener({
            onFailure: function(e) {
                console.log("onFailure()");
            }
        }));
This error is happening [INFO] onSuccess()com.google.android.gms.fitness.result.DataReadResponse@645f427/com.google.android.gms.fitness.result.DataReadResponse@95706d4 [WARN] W/System.err: java.lang.NullPointerException: Attempt to invoke virtual method 'java.util.List com.google.android.gms.fitness.result.DataReadResult.getDataSets()' on a null object reference [WARN] W/System.err: at com.google.android.gms.fitness.result.DataReadResponse.getDataSets(Unknown Source:6) [WARN] W/System.err: at java.lang.reflect.Method.invoke(Native Method) [WARN] W/System.err: at hyperloop.BaseProxy.invokeMethod(BaseProxy.java:157) [WARN] W/System.err: at hyperloop.InstanceProxy.invokeMethod(InstanceProxy.java:184) [WARN] W/System.err: at hyperloop.BaseProxy.callNativeFunction(BaseProxy.java:129) [WARN] W/System.err: at org.appcelerator.kroll.runtime.v8.V8Function.nativeInvoke(Native Method) [WARN] W/System.err: at org.appcelerator.kroll.runtime.v8.V8Function.callSync(V8Function.java:57) [WARN] W/System.err: at org.appcelerator.kroll.runtime.v8.V8Function.call(V8Function.java:43) [WARN] W/System.err: at hyperloop.HyperloopInvocationHandler.invoke(HyperloopInvocationHandler.java:58) [WARN] W/System.err: at java.lang.reflect.Proxy.invoke(Proxy.java:913) [WARN] W/System.err: at $Proxy0.onSuccess(Unknown Source) [WARN] W/System.err: at com.google.android.gms.tasks.zzj.run(Unknown Source:27) [WARN] W/System.err: at android.os.Handler.handleCallback(Handler.java:790) [WARN] W/System.err: at android.os.Handler.dispatchMessage(Handler.java:99) [WARN] W/System.err: at android.os.Looper.loop(Looper.java:164) [WARN] W/System.err: at android.app.ActivityThread.main(ActivityThread.java:6494) [WARN] W/System.err: at java.lang.reflect.Method.invoke(Native Method) [WARN] W/System.err: at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438) [WARN] W/System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)

Attachments

FileDateSize
googlefittest.zip2018-02-07T08:58:19.000+00005183082

Comments

  1. Hans Knöchel 2018-02-06

    Your environment is completely missing, we cannot help until thats available, sorry.
  2. Yanko Valera 2018-02-06

    I'm using SDK7.0.1, Hyperloop 3.0.1/3.0.2. Google Play Fitness API 11.8.0. Testing in Google Nexus 5X running Android 8.1.0 let me know if you need more details
  3. Hans Knöchel 2018-02-07

    [~jvennemann] The java.util.List related method should be fixed in 3.0.2, do you see whats wrong here?
  4. Yanko Valera 2018-02-07

    I've attached the full source code to help to reproduce issue
  5. Mostafizur Rahman 2018-02-12

    [~yankovalera@gmail.com], Thanks for sharing the source code.Tested the sample code on an android device and unable to reproduce the error. Can you please provide the exact test steps to reproduce this on our end? Best
  6. Yanko Valera 2018-02-12

  7. Yanko Valera 2018-03-08

    Hi, were you able to reproduce this issue? Regards
  8. Hans Knöchel 2018-04-03

    Okay, so I spent some time validating this, since there are no known Android Hyperloop issues where classes are not recognized. I focussed on your following code:
       onSuccess: function(e) {
         var dataResponse = new DataReadResponse(e);
        
         console.log("onSuccess()" + e.toString() + "/" + dataResponse.toString());
         console.log("buckets size: " + dataResponse.getDataSets().size());
        }
       
    You are trying to create a new DataReadResponse instance from e, which is weird because the onSuccess callback already returns DataReadResponse dataReadResult, so it's a valid DataReadResponse instance. The concrete error is that dataResponse is null, which may be very possible due to instantiating a custom version of it (cloning it). Looking at [this snippet](https://github.com/googlesamples/android-fit/blob/master/BasicHistoryApi/app/src/main/java/com/google/android/gms/fit/samples/basichistoryapi/MainActivity.java#L151-L155), they pass the callback property to an [own method](https://github.com/googlesamples/android-fit/blob/master/BasicHistoryApi/app/src/main/java/com/google/android/gms/fit/samples/basichistoryapi/MainActivity.java#L247-L267) and extract the response there. So to see if you have a valid instance, you can try the following inside the onSuccess
       onSuccess: function(dataResponse) {
         console.log("Size of Buckets: " + dataResponse.getBuckets().size());
         console.log("Size of Data Sets: " + dataResponse.getDataSets().size());
       }
       
    Based on which one if it is non-empty, you can loop them with a typical JS-for-loop and dump the native Bucket or DataSet for it's contents.
  9. Yanko Valera 2018-04-03

    Hi Hans, I've tried your code and now I get
       [ERROR] TiExceptionHandler: (main) [485,961] ----- Titanium Javascript Runtime Error -----
       [ERROR] TiExceptionHandler: (main) [0,962] - Message: Uncaught TypeError: dataResponse.getBuckets is not a function
       [ERROR] TiExceptionHandler: (main) [0,962] - Source: console.log('Size of Buckets: '+dataResponse.getBuckets().size()),
       dataResponse.getBuckets is not a function
       
  10. Hans Knöchel 2018-04-03

    And you renamed e to dataResponse? What does dataResponse consist of when you log it?
  11. Yanko Valera 2018-04-03

    My current code is
        onSuccess: function(dataResponse) {
                        console.log(typeof(dataResponse));
                        console.log("Size of Buckets: " + dataResponse.getBuckets().size());
                        console.log("Size of Data Sets: " + dataResponse.getDataSets().size());
                    }
        
    The log says typeof(dataResponse) is [INFO] object
  12. Gary Mathews 2018-04-04

    [~yankovalera@gmail.com] let's see what dataResponse contains:
        onSuccess: function(dataResponse) {
            console.log(JSON.stringify(Object.keys(dataResponse), null, 1));
        }
        
  13. Yanko Valera 2018-04-05

    This the output [INFO] [ [INFO] "$native", [INFO] "_hasPointer", [INFO] "_private" [INFO] ]

JSON Source