ActivityRecognitionClient из библиотеки Google Play Services — «распознавание действий пользователя»

в 16:12, , рубрики: Разработка под android

Предисловие

В одно из обновлений библиотеки Google Play Services прокрался новый компонент, который может быть очень полезен при реализации некоторого типа приложений. Имя этому компоненту — ActivityRecognitionClient.

ActivityRecognitionClient позволяет приложению получать данные о действиях пользователя. Например, приложение может определять текущее действие пользователя, к примеру ходьбу, езду в автомобиле, чтение книги, и даже езду на велосипеде.
Многие уже успели догадаться, что механизм работает за счёт сенсоров устройства. Однако не смотря на использование множества датчиков, энергопотребление компонента очень низкое, что позволяет использовать его без ограничений.

Надеюсь понятно объяснил, но для наглядности предлагаю просмотреть 4-х минутный ролик представленный компанией Google:


Реализация

Давайте приступим к реализации и набросаем пример использования, но для начала не забудьте подключить к вашему проекту библиотеку Google Play Services.

Добавим в main.xml TextView для отображения текущего действия и его точность:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:paddingBottom="20dp"
                android:paddingLeft="20dp"
                android:paddingRight="20dp"
                android:paddingTop="20dp">

    <TextView
            android:id="@+id/tvActivity"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_alignParentRight="true"
            android:text=""/>

</RelativeLayout>

Приступаем к написанию кода нашей MyActivity.java, которая должна реализовать интерфейсы GooglePlayServicesClient.ConnectionCallbacks и GooglePlayServicesClient.OnConnectionFailedListener.

public class MyActivity extends Activity implements GooglePlayServicesClient.ConnectionCallbacks,GooglePlayServicesClient.OnConnectionFailedListener

Объявляем объекты:

    private ActivityRecognitionClient activityRecognitionClient;
    private PendingIntent pIntent;
    private BroadcastReceiver receiver;
    private TextView tvActivity;

В методе onCreate инициализируем объявленные ранее объекты и проверяем наличие Google Play Services на устройстве:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        tvActivity = (TextView) findViewById(R.id.tvActivity);

        int resp = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
        if(resp == ConnectionResult.SUCCESS){
            activityRecognitionClient = new ActivityRecognitionClient(this, this, this);
            activityRecognitionClient.connect();
        }
        else {
            Toast.makeText(this, "Please install Google Play Service.", Toast.LENGTH_SHORT).show();
        }

        receiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                String v =  "Activity :" + intent.getStringExtra("Activity") + " " + "Confidence : " + intent.getExtras().getInt("Confidence") + "n";
                v += tvActivity.getText();
                tvActivity.setText(v);
            }
        };

        IntentFilter filter = new IntentFilter();
        filter.addAction("com.alexche.recognitionservice.ACTIVITY_RECOGNITION_DATA");
        registerReceiver(receiver, filter);
    }

В методе onConnected связываем наш activityRecognitionClient с ActivityRecognitionService, код реализации которого будет представлен ниже:

    @Override
    public void onConnected(Bundle arg0) {
        Intent intent = new Intent(this, ActivityRecognitionService.class);
        pIntent = PendingIntent.getService(this, 0, intent,PendingIntent.FLAG_UPDATE_CURRENT);
        activityRecognitionClient.requestActivityUpdates(1000, pIntent);
    }

И наконец переходим к реализации ActivityRecognitionService.java, наследующего класс IntentService:

public class ActivityRecognitionService extends IntentService

Переопределяем метод onHandleIntent:

    @Override
    protected void onHandleIntent(Intent intent) {
        if(ActivityRecognitionResult.hasResult(intent)){
            ActivityRecognitionResult result = ActivityRecognitionResult.extractResult(intent);
            Log.i(TAG, getType(result.getMostProbableActivity().getType()) + "t" + result.getMostProbableActivity().getConfidence());
            Intent i = new Intent("com.alexche.recognitionservice.ACTIVITY_RECOGNITION_DATA");
            i.putExtra("Activity", getType(result.getMostProbableActivity().getType()) );
            i.putExtra("Confidence", result.getMostProbableActivity().getConfidence());
            sendBroadcast(i);
        }
    }

Дописываем метод getType, который возвращает нам текущее состояние:

private String getType(int type){
        if(type == DetectedActivity.UNKNOWN)
            return "Unknown";
        else if(type == DetectedActivity.IN_VEHICLE)
            return "In Vehicle";
        else if(type == DetectedActivity.ON_BICYCLE)
            return "On Bicycle";
        else if(type == DetectedActivity.ON_FOOT)
            return "On Foot";
        else if(type == DetectedActivity.STILL)
            return "Still";
        else if(type == DetectedActivity.TILTING)
            return "Tilting";
        else
            return "";
    }

Не забываем добавить разрешение в AndroidManifest.xml:

<uses-permission android:name="com.google.android.gms.permission.ACTIVITY_RECOGNITION"/>

Демонстрация

image

Скриншоты

image

image

image

Заключение

В принципе ActivityRecognitionClient мне показался очень забавной и полезной штукой, однако тестирование на нескольких устройствах показало, что «действие/состояние» не всегда определяется адекватно.

Надеюсь, ничего не забыл.

Если будут вопросы — спрашивайте.

Полные исходники смотрите на GitHub.

Автор: cdqpst

Источник


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js