Статьи

Как распознать активность пользователя с помощью распознавания активности

Создание приложения с учетом контекста является одним из лучших способов предложить полезные услуги для ваших пользователей. Есть несколько способов сделать это, включая создание приложений, которые используют геозоны и другие службы определения местоположения . В этой статье основное внимание уделяется использованию API распознавания активности служб Google Play, чтобы определить, бегает ли пользователь, ходит ли он в автомобиле, ездит на велосипеде или остается неподвижным.

Знание того, какое действие выполняет пользователь, может помочь вам оценить работу приложения, например, спросив, начинает ли пользователь выполнять упражнения, чтобы вы могли отслеживать его с помощью Google Fit , или запретив отправку уведомлений, когда пользователь за рулем. , Исходные файлы для этого урока можно найти на GitHub .

Первое, что вам нужно сделать, это создать новое приложение для Android. Для этого примера приложения я установил минимальный SDK 14 и создал пустое действие по умолчанию. Как только Android Studio создаст базовое приложение, откройте файл build.gradle и импортируйте Play Services (последняя версия на момент написания этой статьи — 8.4) в узле dependencies .

1
compile ‘com.google.android.gms:play-services:8.4.0’

Затем создайте новый класс, назовите его ActivityRecognizedService и IntentService ему расширить IntentService . Когда Google Play Services возвращает активность пользователя, она будет отправлена ​​на этот IntentService . Это позволит вам выполнять логику вашего приложения в фоновом режиме, когда пользователь идет в свой день.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
public class ActivityRecognizedService extends IntentService {
 
    public ActivityRecognizedService() {
        super(«ActivityRecognizedService»);
    }
 
    public ActivityRecognizedService(String name) {
        super(name);
    }
 
    @Override
    protected void onHandleIntent(Intent intent) {
    }
}

Чтобы завершить настройку, откройте AndroidManifest.xml . Вам необходимо объявить ActivityRecognizedService и включить разрешение com.google.android.gms.permission.ACTIVITY_RECOGNITION для вашего приложения.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
<?xml version=»1.0″ encoding=»utf-8″?>
<manifest xmlns:android=»http://schemas.android.com/apk/res/android»
    package=»com.tutsplus.activityrecognition»>
 
    <uses-permission android:name=»com.google.android.gms.permission.ACTIVITY_RECOGNITION» />
 
    <application
        android:icon=»@mipmap/ic_launcher»
        android:label=»@string/app_name»
        android:theme=»@style/AppTheme»>
        <activity android:name=».MainActivity»>
            <intent-filter>
                <action android:name=»android.intent.action.MAIN» />
 
                <category android:name=»android.intent.category.LAUNCHER» />
            </intent-filter>
        </activity>
 
        <service android:name=».ActivityRecognizedService» />
    </application>
 
</manifest>

Теперь, когда у вас есть базовая структура вашего приложения, вы можете перейти к следующему шагу подключения к Сервисам Google Play и запроса данных об активности.

Чтобы использовать Сервисы Google Play, сначала необходимо подключиться к ним. Начните с открытия MainActivity.java и реализуйте интерфейсы ConnectionCallbacks и OnConnectionFailedListener . Вам также необходимо создать переменную-член типа GoogleApiClient чтобы сохранить ссылку на клиент API.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class MainActivity extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
 
    public GoogleApiClient mApiClient;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
 
    @Override
    public void onConnected(@Nullable Bundle bundle) {
         
    }
 
    @Override
    public void onConnectionSuspended(int i) {
 
    }
 
    @Override
    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
 
    }
}

После реализации необходимых интерфейсов для GoogleApiClient вы можете инициализировать клиент и подключиться к onCreate() Google Play в onCreate() , запросив ActivityRecognition.API и связав своих слушателей с экземпляром GoogleApiClient .

01
02
03
04
05
06
07
08
09
10
11
12
13
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
 
    mApiClient = new GoogleApiClient.Builder(this)
            .addApi(ActivityRecognition.API)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .build();
 
    mApiClient.connect();
}

После GoogleApiClient экземпляра GoogleApiClient вызывается onConnected() . Когда это происходит, вам нужно создать PendingIntent который идет к IntentService вы создали ранее, и передать его в ActivityRecognitionApi . Вам также необходимо установить интервал для того, как часто API должен проверять активность пользователя. Для этого примера приложения мы используем значение 3000 или три секунды, хотя в реальном приложении вы можете проверять реже для экономии энергии.

1
2
3
4
5
6
@Override
public void onConnected(@Nullable Bundle bundle) {
    Intent intent = new Intent( this, ActivityRecognizedService.class );
    PendingIntent pendingIntent = PendingIntent.getService( this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT );
    ActivityRecognition.ActivityRecognitionApi.requestActivityUpdates( mApiClient, 3000, pendingIntent );
}

На этом этапе ваше приложение должно пытаться распознавать активность пользователя каждые три секунды и отправлять эти данные в ActivityRecognizedService .

В onHandleIntent() ActivityRecognizedService первое, что вы делаете, проверяете, что полученный Intent содержит данные распознавания активности. Если это так, то вы можете извлечь ActivityRecognitionResult из Intent чтобы увидеть, какие действия может выполнять ваш пользователь. Вы можете получить список возможных действий, вызвав getProbableActivities() для объекта ActivityRecognitionResult .

1
2
3
4
5
6
7
@Override
protected void onHandleIntent(Intent intent) {
    if(ActivityRecognitionResult.hasResult(intent)) {
        ActivityRecognitionResult result = ActivityRecognitionResult.extractResult(intent);
        handleDetectedActivities( result.getProbableActivities() );
    }
}

Для этого примера приложения вы просто регистрируете каждое обнаруженное действие и показываете, насколько Google Play Services уверены в том, что пользователь выполняет это действие, вызывая getConfidence() для экземпляра DetectedActivity . Если достоверность 75 или выше, то можно с уверенностью предположить, что пользователь выполняет эту деятельность. Чтобы продемонстрировать это, вы также отображаете уведомление, когда ваше приложение обнаруживает, что пользователь идет с высокой достоверностью.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
private void handleDetectedActivities(List<DetectedActivity> probableActivities) {
    for( DetectedActivity activity : probableActivities ) {
        switch( activity.getType() ) {
            case DetectedActivity.IN_VEHICLE: {
                Log.e( «ActivityRecogition», «In Vehicle: » + activity.getConfidence() );
                break;
            }
            case DetectedActivity.ON_BICYCLE: {
                Log.e( «ActivityRecogition», «On Bicycle: » + activity.getConfidence() );
                break;
            }
            case DetectedActivity.ON_FOOT: {
                Log.e( «ActivityRecogition», «On Foot: » + activity.getConfidence() );
                break;
            }
            case DetectedActivity.RUNNING: {
                Log.e( «ActivityRecogition», «Running: » + activity.getConfidence() );
                break;
            }
            case DetectedActivity.STILL: {
                Log.e( «ActivityRecogition», «Still: » + activity.getConfidence() );
                break;
            }
            case DetectedActivity.TILTING: {
                Log.e( «ActivityRecogition», «Tilting: » + activity.getConfidence() );
                break;
            }
            case DetectedActivity.WALKING: {
                Log.e( «ActivityRecogition», «Walking: » + activity.getConfidence() );
                if( activity.getConfidence() >= 75 ) {
                    NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
                    builder.setContentText( «Are you walking?» );
                    builder.setSmallIcon( R.mipmap.ic_launcher );
                    builder.setContentTitle( getString( R.string.app_name ) );
                    NotificationManagerCompat.from(this).notify(0, builder.build());
                }
                break;
            }
            case DetectedActivity.UNKNOWN: {
                Log.e( «ActivityRecogition», «Unknown: » + activity.getConfidence() );
                break;
            }
        }
    }
}

Если вы запустите это приложение, сделаете пробную версию, а затем подключите свое устройство к компьютеру, вы должны увидеть журнал, похожий на следующий, в консоли разработки.

1
2
3
4
E/ActivityRecogition: On Foot: 92
E/ActivityRecogition: Running: 87
E/ActivityRecogition: On Bicycle: 8
E/ActivityRecogition: Walking: 5

Если вы отправляетесь на прогулку, вы должны получить уведомление с вопросом, ходите ли вы. Если у вас есть приложение для упражнений, это будет идеальной возможностью предоставить вашему пользователю действие, которое позволит ему начать отслеживать свои упражнения.

Уведомление, полученное при ходьбе, распознано

Сервисы Google Play позволяют легко определить текущую активность пользователя. Это может быть невероятно ценно для того, чтобы сделать ваши приложения контекстно-зависимыми и полезными для ваших пользователей, что отлично подходит для всех участников. С помощью всего лишь нескольких строк кода вы можете сделать свои приложения более умными.