2016-10-11 3 views
1

Ich arbeite an Step-Count-Implementierung und dafür verwende ich die Google fit API von Android.Unfähig, die Schrittzählung mit google fit Android

Unten ist mein Code.

public class GoogleFitDemoActivity extends AppCompatActivity { 
    public static final String TAG = "BasicSensorsApi"; 
    private GoogleApiClient mClient = null; 
    private static final int REQUEST_PERMISSIONS_REQUEST_CODE = 34; 
    private OnDataPointListener mListener; 
    private TextView stepsCountTextView; 
    ProgressDialog progressDialog; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     setContentView(R.layout.google_fit_main); 
     progressDialog = new ProgressDialog(this); 

     if (!checkPermissions()) { 
      requestPermissions(); 
      Debug.displayToast(this, "Requesting for permisstion "); 
     } 

     stepsCountTextView = (TextView) findViewById(R.id.sample_logview); 
    } 

    /** 
    * Return the current state of the permissions needed. 
    */ 
    private boolean checkPermissions() { 
     int permissionState = ActivityCompat.checkSelfPermission(this, 
       Manifest.permission.ACCESS_FINE_LOCATION); 
     return permissionState == PackageManager.PERMISSION_GRANTED; 
    } 

    /** 
    * Unregister the listener with the Sensors API. 
    */ 
    private void unregisterFitnessDataListener() { 
     if (mListener == null) { 
      return; 
     } 
     Fitness.SensorsApi.remove(
       mClient, 
       mListener) 
       .setResultCallback(new ResultCallback<Status>() { 
        @Override 
        public void onResult(Status status) { 
         if (status.isSuccess()) { 
          Debug.print(TAG, "Listener was removed!"); 
         } else { 
          Debug.print(TAG, "Listener was not removed."); 
         } 
        } 
       }); 
    } 

    private void buildFitnessClient() { 
     if (progressDialog == null) { 
      return; 
     } 

     progressDialog.setMessage("Wait....."); 
     progressDialog.show(); 
     if (mClient == null && checkPermissions()) { 
      mClient = new GoogleApiClient.Builder(this) 
        .addApi(Fitness.SENSORS_API) 
        .addScope(new Scope(Scopes.FITNESS_ACTIVITY_READ_WRITE)) 
        .addConnectionCallbacks(
          new GoogleApiClient.ConnectionCallbacks() { 
           @Override 
           public void onConnected(Bundle bundle) { 
            runOnUiThread(new Runnable() { 
             @Override 
             public void run() { 
              progressDialog.setMessage("Client Connected waiting for fit register"); 

             } 
            }); 
            Debug.print(TAG, "Connected!!!"); 
            findFitnessDataSources(); 
           } 

           @Override 
           public void onConnectionSuspended(int i) { 
            // If your connection to the sensor gets lost at some point, 
            // you'll be able to determine the reason and react to it here. 
            if (i == GoogleApiClient.ConnectionCallbacks.CAUSE_NETWORK_LOST) { 
             Debug.print(TAG, "Connection lost. Cause: Network Lost."); 
            } else if (i 
              == GoogleApiClient.ConnectionCallbacks.CAUSE_SERVICE_DISCONNECTED) { 
             Debug.print(TAG, 
               "Connection lost. Reason: Service Disconnected"); 
            } 
           } 
          } 
        ) 
        .enableAutoManage(this, 0, new GoogleApiClient.OnConnectionFailedListener() { 
         @Override 
         public void onConnectionFailed(ConnectionResult result) { 
          Debug.print(TAG, "Google Play services connection failed. Cause: " + 
            result.toString()); 
          Snackbar.make(
            GoogleFitDemoActivity.this.findViewById(R.id.main_activity_view), 
            "Exception while connecting to Google Play services: " + 
              result.getErrorMessage(), 
            Snackbar.LENGTH_INDEFINITE).show(); 
         } 
        }) 
        .build(); 
     } 
    } 

    private void findFitnessDataSources() { 
     Fitness.SensorsApi.findDataSources(mClient, new DataSourcesRequest.Builder() 
       .setDataTypes(DataType.TYPE_STEP_COUNT_CUMULATIVE) 
       .setDataSourceTypes(DataSource.TYPE_DERIVED) 
       .build()) 
       .setResultCallback(new ResultCallback<DataSourcesResult>() { 
        @Override 
        public void onResult(DataSourcesResult dataSourcesResult) { 
         progressDialog.dismiss(); 
         Debug.print(TAG, "Result: " + dataSourcesResult.getStatus().toString()); 
         for (DataSource dataSource : dataSourcesResult.getDataSources()) { 
          Debug.print(TAG, "Data source found: " + dataSource.toString()); 
          Debug.print(TAG, DataType.TYPE_STEP_COUNT_CUMULATIVE + " Data Source type: " + dataSource.getDataType().getName()); 

          //Let's register a listener to receive Activity data! 
          if (dataSource.getDataType().equals(DataType.TYPE_STEP_COUNT_CUMULATIVE) 
            && mListener == null) { 
           Debug.print(TAG, "Data source for LOCATION_SAMPLE found! Registering."); 
           registerFitnessDataListener(dataSource, 
             DataType.TYPE_STEP_COUNT_CUMULATIVE); 
          } 
         } 
        } 
       }); 
    } 

    @Override 
    protected void onDestroy() { 
     super.onDestroy(); 
    } 

    @Override 
    protected void onResume() { 
     super.onResume(); 
     buildFitnessClient(); 
    } 

    private void registerFitnessDataListener(DataSource dataSource, DataType dataType) { 
     mListener = new OnDataPointListener() { 
      @Override 
      public void onDataPoint(DataPoint dataPoint) { 
       for (Field field : dataPoint.getDataType().getFields()) { 
        final Value val = dataPoint.getValue(field); 

        runOnUiThread(new Runnable() { 
         @Override 
         public void run() { 
          stepsCountTextView.setText("Steps count is " + val); 
         } 
        }); 

        Debug.print(TAG, "Detected DataPoint field: " + field.getName()); 
        Debug.print(TAG, "Detected DataPoint value: " + val); 
       } 
      } 
     }; 

     Fitness.SensorsApi.add(
       mClient, 
       new SensorRequest.Builder() 
         .setDataSource(dataSource) // Optional but recommended for custom data sets. 
         .setDataType(dataType) // Can't be omitted. 
         .setSamplingRate(1, TimeUnit.SECONDS) 
         .build(), 
       mListener) 
       .setResultCallback(new ResultCallback<Status>() { 
        @Override 
        public void onResult(Status status) { 
         if (status.isSuccess()) { 
          Debug.print(TAG, "Listener registered!"); 
         } else { 
          Debug.print(TAG, "Listener not registered."); 
         } 
        } 
       }); 
    } 


    private void requestPermissions() { 
     boolean shouldProvideRationale = 
       ActivityCompat.shouldShowRequestPermissionRationale(this, 
         Manifest.permission.ACCESS_FINE_LOCATION); 

     if (shouldProvideRationale) { 
      Debug.print(TAG, "Displaying permission rationale to provide additional context."); 
      Snackbar.make(
        findViewById(R.id.main_activity_view), 
        R.string.permission_rationale, 
        Snackbar.LENGTH_INDEFINITE) 
        .setAction(R.string.ok, new View.OnClickListener() { 
         @Override 
         public void onClick(View view) { 
          // Request permission 
          ActivityCompat.requestPermissions(GoogleFitDemoActivity.this, 
            new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 
            REQUEST_PERMISSIONS_REQUEST_CODE); 
         } 
        }) 
        .show(); 
     } else { 
      Debug.print(TAG, "Requesting permission"); 
      ActivityCompat.requestPermissions(GoogleFitDemoActivity.this, 
        new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 
        REQUEST_PERMISSIONS_REQUEST_CODE); 
     } 
    } 

    @Override 
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, 
              @NonNull int[] grantResults) { 
     Debug.print(TAG, "onRequestPermissionResult"); 
     if (requestCode == REQUEST_PERMISSIONS_REQUEST_CODE) { 
      if (grantResults.length <= 0) { 
       Debug.print(TAG, "User interaction was cancelled."); 
      } else if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { 
       buildFitnessClient(); 
      } else { 
       Snackbar.make(
         findViewById(R.id.main_activity_view), 
         R.string.permission_denied_explanation, 
         Snackbar.LENGTH_INDEFINITE) 
         .setAction(R.string.settings, new View.OnClickListener() { 
          @Override 
          public void onClick(View view) { 
           // Build intent that displays the App settings screen. 
           Intent intent = new Intent(); 
           intent.setAction(
             Settings.ACTION_APPLICATION_DETAILS_SETTINGS); 
           Uri uri = Uri.fromParts("package", 
             BuildConfig.APPLICATION_ID, null); 
           intent.setData(uri); 
           intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
           startActivity(intent); 
          } 
         }) 
         .show(); 
      } 
     } 
    } 
} 

Unten sind Fragen in diesem Code, denen ich gegenüberstehen.

(Angenommen, ich habe begonnen zu laufen und Schritte zählen ist 10 und ich töte meine alle und wieder App starten, sobald meine onConnected() aufgerufen wird Ich registrieren für Datenpunkt erhalten und ich bekomme den DataPoint Wert 10, während es 0 geben sollte von der ersten

1 der Schrittwert zurückgesetzt wird fortgesetzt.

zu erhöhen, nicht

2 Every-Zeit auf 0 und starten betreibe ich den Code der Schritte Wert nicht zurückgesetzt auf 0, so in einigen es nimmt frühere Werte

3 Die Anzahl der Schritte wird nicht aktualisiert, da es oft Zeit braucht, um aktualisiert zu werden (wenn ich 5 Minuten gehe, dann i t gibt ersten Schritt count)

4 Auch nach dem Töten app und erneut relaunching App erhalten die vorherigen Schritte zählen, Schritte zählen nicht starten Formular 0 Start von alt. (Wie ich keine Werte in Präferenz oder Datenbank speichern. Wie ich den vorherigen Schritt Zahl wie 10) bekommen

Bitte beachten Sie die Ergebnisprotokoll

Erkannt Datapoint-Wert: 1 >>>>>>>>>> bei dieser sollte es von 0

starten werden

Detected Datapoint Feld: Schritte Detected Datenpunktwert: 1

Detected Datapoint Feld: Schritte Detected Datenpunktwert: 6

Detected Datapoint Feld: Schritte Detected Datenpunktwert: 6

Detected Datapoint Feld: Schritte Detected Datenpunktwert: 7

Detected Datapoint Feld: Schritte Detected Datenpunktwert: 7

Detected Datapoint Feld: Schritte Detected Datenpunktwert: 2

Bitte helfen Sie, wo ich den Fehler mache.

+0

Es ist nett, dass Sie Ihre Probleme aufgezählt haben - könnten Sie die Einzelteile spezifischer die Teile des Codes verbinden? –

+0

können Sie bitte meinen Code sehen, wo ich Fehler mache? –

+0

hi .. überprüfen Sie, ob Sie beim Erstellen von 'new DataSourcesRequest.Builder' den Standardwert auf" 0 "setzen können – user1182217

Antwort

0

Es gibt 2 Möglichkeiten Schrittwert von Google Fit durch ihre API zu bekommen, denke ich:

1) Geschichte API: wir nur mit GG Fit anmelden müssen, welche Art von Wert wollen wir erhalten und GG-Fit Speichern Sie Informationen von selbst (irgendwie kann es Ihren Schritt erkennen, indem Sie Sensor, maschinelles Lernen, ... verwenden (nicht per GPS - Sie können es leicht auf Google herausfinden)). Wenn wir den Wert, den GG Fit gespeichert hat, erhalten möchten, heben Sie die Verlaufs-API einfach mit einem Zeitbereich auf.

2) Sensor-API: Wir werden Sensor-API mit einem fantastischen Algorithmus zur Kommunikation mit unserem eigenen Sensor im Gerät verwenden, um direkt den Schrittwert zu erhalten (nicht durch GG Fit auf ihrem Server speichern und später abrufen).Bei dieser Methode wird jedoch temporärer Speicher des Sensors in Ihrem Gerät verwendet, um den Schrittwert zu speichern. und dieser Wert steigt weiter an, nur wenn Ihr Gerät neu gestartet wird, dann wird es zurückgesetzt :(=> Sie können also einen kleinen Trick machen, um den tatsächlichen Wert zu erhalten. (Zum Beispiel den ersten Wert speichern und dann für den späteren Wert subtrahieren. Angenommen, wir haben zuerst 1990, dann gespeichert, dann 1995, dann subtrahiere es 1995 - 1190 = 5 Schritte. Ich weiß jedoch nicht, was passiert, wenn der im Speicher des Sensors gespeicherte Wert zu groß wird und überläuft :(

** Meine Erfahrung: sollte nicht Typ DELTA verwenden.Es könnte aufgrund des Zeitbereichs einen falschen Wert hervorbringen, zum Beispiel von 17:30:00 bis 17:31:00 hat es Wert Schritt 15, aber Wenn wir den Zeitbereich von 17:30:00 bis 17:30:10 aufheben, hat er keinen Wert und keinen Zeitbereich von 17:30:10 bis 17:31:00, er hat den Wert von Schritt 10. Und irgendwann fehlt der Wert, wenn Wenn Ihr Bildschirmgerät schläft, ruft GG Fit den API-Underground auf, aber nicht die Aufnahmezeit. irgendwann bekam ich negative Werte @@. Gott weiß, was sie tun!

Schließlich glaube ich GG Fit App irgendwie einen Trick zu verwenden, um den Schrittwert in Echtzeit anzuzeigen (vielleicht Sensor API, und die meiste Zeit verwende ich Sensor API mit Schritt ansammeln (nicht Delta), die das beste Ergebnis ähnlich gibt zur GG Fit App). Dann, wenn ich reaktive App, wach Gerät Bildschirm (wenn Sie in Android entwickeln, bedeutet es, dass Ihre Aktivität onResume() -Methode aufruft), widerrufe ich History API mit Zeitbereich von Anfang bis zur aktuellen Zeit rewake ich meine App und bekomme die neueste Wert.

https://developers.google.com/fit/android -> diesen Link, um Ihnen zu zeigen, welche Art von API GG Fit Unterstützung für Android.

https://developer.android.com/reference/android/hardware/Sensor.html#TYPE_STEP_COUNTER -> Dieser Link ist die Beschreibung für TYPE_STEP vom Sensor, es wird gesagt, dass es bis zum Neustart des Geräts weiter zunehmen wird.

Verwandte Themen