3

Google Api Php ClientGoogle Fitで問題が発生しました。

1 日の歩数の合計を取得したい。

応答が見つかりましたが、機能しません(要点を見てください)。

私のphpコード:

// Retrive oauth data
$clientData = json_decode(file_get_contents("../Devbook-87e2bafd84e6.json")); 
$client_email = $clientData->client_email;
$private_key = $clientData->private_key;
$scopes = array(Google_Service_Fitness::FITNESS_ACTIVITY_READ);
$credentials = new Google_Auth_AssertionCredentials(
     $client_email,
     $scopes,
     $private_key
);

$client = new Google_Client();
$client->setState('offline');
$client->setRedirectUri('urn:ietf:wg:oauth:2.0:oob');  // Used in hybrid flows
$client->setAssertionCredentials($credentials);
if ($client->getAuth()->isAccessTokenExpired()) {
     $client->getAuth()->refreshTokenWithAssertion();
}

$fitness_service = new Google_Service_Fitness($client);

$dataSources = $fitness_service->users_dataSources;
$dataSets = $fitness_service->users_dataSources_datasets;

$listDataSources = $dataSources->listUsersDataSources("me");

$timezone = "GMT+0100";
$today = date("Y-m-d");
$endTime = strtotime($today.' 00:00:00 '.$timezone);
$startTime = strtotime('-1 day', $endTime);

while($listDataSources->valid()) {
     $dataSourceItem = $listDataSources->next();
     if ($dataSourceItem['dataType']['name'] == "com.google.step_count.delta") {
            $dataStreamId = $dataSourceItem['dataStreamId'];
            $listDatasets = $dataSets->get("me", $dataStreamId, $startTime.'000000000'.'-'.$endTime.'000000000');

            $step_count = 0;
            while($listDatasets->valid()) {
                $dataSet = $listDatasets->next();
                $dataSetValues = $dataSet['value'];

                if ($dataSetValues && is_array($dataSetValues)) {
                   foreach($dataSetValues as $dataSetValue) {
                       $step_count += $dataSetValue['intVal'];
                   }
                }
            }
            print("STEP: ".$step_count."<br />");
     };
 }

$listDataSources->valid() ここでの問題は、最初の while loop : returns alwaysに入らなかったことfalseです。

私の質問: false を返すのはなぜですか? どうすればステップを取得できますか?

Oauth Playground ( https://www.googleapis.com/fitness/v1/users/me/dataSources/derived:com.google.step_count.delta:com.google.android.gms:estimated_steps) でデータを取得しようとしましたが、データを取得できませんでした。

私はこれを得た :

{
    "dataType": {
         "field": [{
               "name": "steps", 
               "format": "integer"
         }], 
         "name": "com.google.step_count.delta"
    }, 
    "application": {
         "packageName": "com.google.android.gms", 
         "version": ""
    }, 
    "dataStreamId": "derived:com.google.step_count.delta:com.google.android.gms:estimated_steps", 
    "type": "derived", 
    "dataStreamName": "estimated_steps"
}
4

2 に答える 2

6

まず最初に、使用しているデバイスにデータはありますか? 私は間違いを犯しました。Google Fit データがまったくないアカウントからデータを取得しようとしました。私の過ちを繰り返さないでください。

私はあなたと同じ例を使用しましたが、うまくいきました。唯一の違いは、次のようにクライアント API をハードコーディングしたことです。

$APIKey = '1231231231231231231231231231123123';
$client_id = '12312312312-dkoasodiajsdaosdjh12h1kjakdahs.apps.googleusercontent.com';
$client_secret = '123123123-1231231-123123123';
$redirect_uri = 'http://localhost/fit/code.php';

資格情報に問題がある可能性があります。セッションを開始しましたか?session_start()上記のコードの後に​​ a を追加します。

以下のコードは私のために働いています。それを適応させてください。

<?php
/*
 * This code is an adaptation of Google API URL Shortener example from Google PHP API github.
 * This was modified to work with Google Fit.
 * This example will count steps from a logged in user.
 */

// I created an Autoloader to load Google API classes
require_once(__DIR__ . '/Autoloader.php');

$APIKey = '1231231231231231231231231231123123';
$client_id = '12312312312-dkoasodiajsdaosdjh12h1kjakdahs.apps.googleusercontent.com';
$client_secret = '123123123-1231231-123123123';
$redirect_uri = 'http://localhost/fit/code.php';

//This template is nothing but some HTML. You can find it on github Google API example. 
include_once "templates/base.php";

//Start your session.
session_start();

$client = new Google_Client();
$client->setApplicationName('google-fit');
$client->setAccessType('online');
$client->setApprovalPrompt("auto");
$client->setClientId($client_id);
$client->setClientSecret($client_secret);
$client->setRedirectUri($redirect_uri);

$client->addScope(Google_Service_Fitness::FITNESS_ACTIVITY_READ);
$service = new Google_Service_Fitness($client);

/************************************************
If we're logging out we just need to clear our
local access token in this case
 ************************************************/
if (isset($_REQUEST['logout'])) {
    unset($_SESSION['access_token']);
}
/************************************************
If we have a code back from the OAuth 2.0 flow,
we need to exchange that with the authenticate()
function. We store the resultant access token
bundle in the session, and redirect to ourself.
 ************************************************/
if (isset($_GET['code'])) {
    $client->authenticate($_GET['code']);
    $_SESSION['access_token'] = $client->getAccessToken();
    $redirect = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];
    header('Location: ' . filter_var($redirect, FILTER_SANITIZE_URL));
    echo "EXCHANGE";
}
/************************************************
If we have an access token, we can make
requests, else we generate an authentication URL.
 ************************************************/
if (isset($_SESSION['access_token']) && $_SESSION['access_token']) {
    $client->setAccessToken($_SESSION['access_token']);
    echo "GOT IT";
    echo "<pre>";

    // Same code as yours
    $dataSources = $service->users_dataSources;
    $dataSets = $service->users_dataSources_datasets;

    $listDataSources = $dataSources->listUsersDataSources("me");

    $timezone = "GMT+0100";
    $today = date("Y-m-d");
    $endTime = strtotime($today.' 00:00:00 '.$timezone);
    $startTime = strtotime('-1 day', $endTime);

    while($listDataSources->valid()) {
        $dataSourceItem = $listDataSources->next();
        if ($dataSourceItem['dataType']['name'] == "com.google.step_count.delta") {
            $dataStreamId = $dataSourceItem['dataStreamId'];
            $listDatasets = $dataSets->get("me", $dataStreamId, $startTime.'000000000'.'-'.$endTime.'000000000');

            $step_count = 0;
            while($listDatasets->valid()) {
                $dataSet = $listDatasets->next();
                $dataSetValues = $dataSet['value'];

                if ($dataSetValues && is_array($dataSetValues)) {
                    foreach($dataSetValues as $dataSetValue) {
                        $step_count += $dataSetValue['intVal'];
                    }
                }
            }
            print("STEP: ".$step_count."<br />");
        };
    }
    echo "</pre>";
} else {
    $authUrl = $client->createAuthUrl();
}

/************************************************
If we're signed in and have a request to shorten
a URL, then we create a new URL object, set the
unshortened URL, and call the 'insert' method on
the 'url' resource. Note that we re-store the
access_token bundle, just in case anything
changed during the request - the main thing that
might happen here is the access token itself is
refreshed if the application has offline access.
 ************************************************/
if ($client->getAccessToken() && isset($_GET['url'])) {
    $_SESSION['access_token'] = $client->getAccessToken();
}

//Dumb example. You don't have to use the code below.
echo pageHeader("User Query - URL Shortener");
if (strpos($client_id, "googleusercontent") == false) {
    echo missingClientSecretsWarning();
    exit;
}
?>
<div class="box">
    <div class="request">
        <?php
        if (isset($authUrl)) {
            echo "<a class='login' href='" . $authUrl . "'>Connect Me!</a>";
        } else {
            echo <<<END
    <form id="url" method="GET" action="{$_SERVER['PHP_SELF']}">
      <input name="url" class="url" type="text">
      <input type="submit" value="Shorten">
    </form>
    <a class='logout' href='?logout'>Logout</a>
END;
        }
        ?>
    </div>

    <div class="shortened">
        <?php
        if (isset($short)) {
            var_dump($short);
        }
        ?>
    </div>
</div>
于 2015-05-22T13:17:01.413 に答える
0

コードをありがとう、しかしバグがありました:

  • いくつかの場所で、ループ内の最初の項目をスキップする next() メソッドへの呼び出しがあります

  • アイテムがオブジェクトかどうかを確認するために必要な 1 つの場所

以下は私の機能です。いくつかの重要なポイント:

  • 現在と前日の歩数を取得し、セッションに保存します。他にもいくつかのセッション設定があります。

-$GooglefitCode グローバルは、'code' 引数を使用して、OAuth からのリダイレクトで設定されます。ここのコードは pull.php というスクリプト内にあり、コールバック URL は pull_googlefit.php です。これは、コードを $Googlefit グローバルに格納し、PHP に pull.php をインクルードするだけです。

  • 前のコードのように OAuth コードが渡された場合、header() リダイレクトは行いません。表示される URL からコード/状態引数を削除するためにこれを行ったと思います。他の場所で Javascript を使用して URL を消去するだけです。

  • コード内の歩数の取得に関するコメントを参照してください。Google の奇妙さ、アプリに合わせたい場合は「estimated_steps」を使用してください。「merge_step_deltas」は実際の歩数を取得します。

    session_start();
    require 'vendor/autoload.php';
    
    /***************************************************************
    Google Fit Setup
    ****************************************************************/
    $GooglefitClientId = '...';
    $GooglefitClientSecret = '...';
    $GooglefitCallbackURL = '...';
    
    /***************************************************************
    Google Fit Initialization
    ****************************************************************/
    
    if (!isset($_SESSION['googlefit']['pull_retrieved'])) $_SESSION['googlefit']['pull_retrieved'] = 0;
    if (!isset($_SESSION['googlefit']['pull_errors'])) $_SESSION['googlefit']['pull_errors'] = array();
    if (!isset($_SESSION['googlefit']['pull_data'])) $_SESSION['googlefit']['pull_data'] = array();
    if (!$_SESSION['googlefit']['pull_retrieved'] && !$_SESSION['googlefit']['pull_errors'])
    {
      GooglefitGet();
    }
    
    function GoogleFitGet()
    {
      global $GooglefitClientId, $GooglefitClientSecret, $GooglefitCallbackURL, $GooglefitCode;
      // $GooglefitCode is set in pull_googlefit.php, which is the redirect and just includes this file.
      $_SESSION['googlefit']['pull_retrieved'] = 0;
      $_SESSION['googlefit']['pull_errors'] = array();
      $_SESSION['googlefit']['pull_data'] = array();
    
      $client = new Google_Client();
      $client->setApplicationName('google-fit');
      $client->setAccessType('online');
      $client->setApprovalPrompt("auto");
      $client->setClientId($GooglefitClientId);
      $client->setClientSecret($GooglefitClientSecret);
      $client->setRedirectUri($GooglefitCallbackURL);
    
      $client->addScope(Google_Service_Fitness::FITNESS_ACTIVITY_READ);
      $service = new Google_Service_Fitness($client);
      if (isset($GooglefitCode) && ($GooglefitCode != "")) // from pull_googlefit.php
      {
          $client->authenticate($GooglefitCode);
          $_SESSION['googlefit']['access_token'] = $client->getAccessToken();
      }
      // If we have an access token, we can make requests, else we generate an authentication URL.
      if (isset($_SESSION['googlefit']['access_token']) && $_SESSION['googlefit']['access_token']) 
      {
        // There should be a try/catch in here for errors!
        $client->setAccessToken($_SESSION['googlefit']['access_token']);
        $data_sources = $service->users_dataSources;
        $data_sets = $service->users_dataSources_datasets;
        $list_data_sources = $data_sources->listUsersDataSources("me");
        $_SESSION['googlefit']['pull_retrieved'] = 1;
        $_SESSION['googlefit']['pull_errors'] = array();
        date_default_timezone_set('America/New_York');
        $timezone = "";
    
        $ymd = date("Y-m-d");
        $day = "$ymd 00:00:00 $timezone";
        $today_st = strtotime($day);
        $day = "$ymd 23:59:59 $timezone";
        $today_et = strtotime($day);
        $yesterday_st = strtotime("-1 day", $today_st);
        $yesterday_et = strtotime("-1 day", $today_et);
        $ranges = array();
        $ranges[1] = $today_st.'000000000'.'-'.$today_et.'000000000';
        $ranges[0] = $yesterday_st.'000000000'.'-'.$yesterday_et.'000000000';
        $any_list_data_sources = 0;
        while($list_data_sources->valid()) 
        {
          if (!$any_list_data_sources)
          {
            $any_list_data_sources = 1;
            $data_source_item = $list_data_sources->current();
          }
          else
          {
            $data_source_item = $list_data_sources->next();
          }
          if (!is_object($data_source_item)) continue;
          /* Google strangeness:
              This returns actual steps taken:
                if ($data_source_item['dataStreamName'] != 'merge_step_deltas') continue;
              It is the total from See Source Data on Google Fit app which shows each data point.
              I know because I have added up some tests, including 223 data point day.
              Instead, the Fit app does some additional processing on top of the steps. 
              It estimates steps based on the activity when none are recorded.
              This is the number that it shows you on the app.
          */
          if ($data_source_item['dataStreamName'] != 'estimated_steps') continue; 
          if ($data_source_item['dataType']['name'] == "com.google.step_count.delta") 
          {
            $data_stream_id = $data_source_item['dataStreamId'];
            for ($days=0;$days<2;$days++) 
            {
              $list_data_sets = $data_sets->get("me", $data_stream_id, $ranges[$days]);
              $step_count = 0;
              $any_list_data_sets = 0;
              while($list_data_sets->valid()) 
              {
                if (!$any_list_data_sets) 
                {
                   $data_set = $list_data_sets->current();
                   $any_list_data_sets = 1;
                }
                else
                {                             
                  $data_set = $list_data_sets->next();
                }
                if (!is_object($data_set) || !$data_set) continue;
                $data_set_values = $data_set['value'];
                if ($data_set_values && is_array($data_set_values)) 
                {
                  foreach($data_set_values as $data_set_value) 
                  {
                    $step_count += $data_set_value['intVal'];
                  }
                }
              }
              $str = ($days==0)?"steps_yesterday":"steps_today";
              $_SESSION['googlefit']['pull_data']['steps'][$days]['value'] = $step_count;
            }
          }
        }
      } 
      else 
      {
        $authUrl = $client->createAuthUrl();
        header("Location: $authUrl");
        exit;
      }
    }

于 2021-10-01T04:38:45.387 に答える