Не могу понять, почему мой пример ActivityTransition не работает с BroadcastReceiver - PullRequest
0 голосов
/ 13 февраля 2020

Я посмотрел несколько примеров и реализаций, у меня больше нет идей для проверки. Я надеюсь на внешнюю перспективу, чтобы видеть, пропустил ли я что-то. Вот полный проект на github для полного источника

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

Манифест:

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


<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    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>


    <receiver
        android:exported="true"
        android:enabled="true"
        android:name="com.example.myapplication.ActivityTransitionBroadcastReceiver"
        android:permission="com.google.android.gms.permission.ACTIVITY_RECOGNITION">
        <intent-filter>
            <action android:name="com.example.myapplication.ACTION_PROCESS_ACTIVITY_TRANSITIONS"/>
        </intent-filter>
    </receiver>

</application>

Основная активность:

    List<ActivityTransition> transitions = new ArrayList<>();

    transitions.add(
            new ActivityTransition.Builder()
                    .setActivityType(DetectedActivity.STILL)
                    .setActivityTransition(ActivityTransition.ACTIVITY_TRANSITION_ENTER)
                    .build());
    transitions.add(
            new ActivityTransition.Builder()
                    .setActivityType(DetectedActivity.STILL)
                    .setActivityTransition(ActivityTransition.ACTIVITY_TRANSITION_EXIT)
                    .build());
    transitions.add(
            new ActivityTransition.Builder()
                    .setActivityType(DetectedActivity.IN_VEHICLE)
                    .setActivityTransition(ActivityTransition.ACTIVITY_TRANSITION_ENTER)
                    .build());
    transitions.add(
            new ActivityTransition.Builder()
                    .setActivityType(DetectedActivity.IN_VEHICLE)
                    .setActivityTransition(ActivityTransition.ACTIVITY_TRANSITION_EXIT)
                    .build());


    ActivityTransitionRequest request = new ActivityTransitionRequest(transitions);

    Intent intent = new Intent(this.getApplicationContext(), ActivityTransitionBroadcastReceiver.class);
    intent.setAction(ActivityTransitionBroadcastReceiver.INTENT_ACTION);


    PendingIntent pendingIntent = PendingIntent.getBroadcast(this.getApplicationContext(), 0, intent,
            PendingIntent.FLAG_CANCEL_CURRENT);

    Task<Void> task = ActivityRecognition.getClient(this.getApplicationContext())
            .requestActivityTransitionUpdates(request, pendingIntent);
    task.addOnSuccessListener(aVoid -> Log.i(TAG, "\n\nTransitions API was successfully registered.\n\n"))
            .addOnFailureListener(e -> Log.e(TAG, "Transitions API could not be registered: " + e));

Ответы [ 3 ]

0 голосов
/ 17 февраля 2020

Вы пытались зарегистрировать BroadcastReceiver в методе действия onCreate или `onStart '

class CustomBroadcast extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        //do some stuff here
        Log.d("Broadcast", "Success");
    }
}

CustomBroadcast broadcast = new CustomBroadcast();

LocalBroadcastManager.getInstance(this).registerReceiver(broadcast,
                    new IntentFilter("com.example.myapplication.ACTION_PROCESS_ACTIVITY_TRANSITIONS"));

Затем в onStop отписаться:

LocalBroadcastManager.getInstance(this).unregisterReceiver(broadcast);

Я делаю это так поскольку после 26 * весьма проблематично c использовать декларируемые декларации.

Надеюсь, это поможет.

0 голосов
/ 17 февраля 2020

Прежде всего, если вы используете compileSdkVersion 29, вам нужно запросить разрешение "Manifest.permission.ACTIVITY_RECOGNITION", поэтому ваша MainActivity будет выглядеть следующим образом:

package com.example.myapplication;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import android.Manifest;
import android.app.PendingIntent;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;

import com.google.android.gms.location.ActivityRecognition;
import com.google.android.gms.location.ActivityTransition;
import com.google.android.gms.location.ActivityTransitionRequest;
import com.google.android.gms.location.DetectedActivity;
import com.google.android.gms.tasks.Task;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    private static final String TAG = "TransitionTest";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    @Override
    public void onResume(){
        super.onResume();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            checkIfAlreadyHavePermission();
        }else{
            requestForUpdates();
        }
    }

    private void checkIfAlreadyHavePermission() {
        int result = ContextCompat.checkSelfPermission(this, Manifest.permission.ACTIVITY_RECOGNITION);
        if (result == PackageManager.PERMISSION_GRANTED) {
            requestForUpdates();
        } else {
            requestPermissions();
        }
    }

    private void requestPermissions(){
        ActivityCompat.requestPermissions(MainActivity.this,
                new String[]{Manifest.permission.ACTIVITY_RECOGNITION},
                1);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode,
                                           @NonNull String[] permissions, @NonNull int[] grantResults) {
        if (requestCode == 1) {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                requestForUpdates();
            } else {
                Toast.makeText(MainActivity.this, "Recognition permission denied", Toast.LENGTH_SHORT).show();
            }
        }
    }

    private void requestForUpdates(){
        List<ActivityTransition> transitions = new ArrayList<>();

        transitions.add(
                new ActivityTransition.Builder()
                        .setActivityType(DetectedActivity.STILL)
                        .setActivityTransition(ActivityTransition.ACTIVITY_TRANSITION_ENTER)
                        .build());
        transitions.add(
                new ActivityTransition.Builder()
                        .setActivityType(DetectedActivity.STILL)
                        .setActivityTransition(ActivityTransition.ACTIVITY_TRANSITION_EXIT)
                        .build());
        transitions.add(
                new ActivityTransition.Builder()
                        .setActivityType(DetectedActivity.IN_VEHICLE)
                        .setActivityTransition(ActivityTransition.ACTIVITY_TRANSITION_ENTER)
                        .build());
        transitions.add(
                new ActivityTransition.Builder()
                        .setActivityType(DetectedActivity.IN_VEHICLE)
                        .setActivityTransition(ActivityTransition.ACTIVITY_TRANSITION_EXIT)
                        .build());
        transitions.add(
                new ActivityTransition.Builder()
                        .setActivityType(DetectedActivity.WALKING)
                        .setActivityTransition(ActivityTransition.ACTIVITY_TRANSITION_ENTER)
                        .build());
        transitions.add(
                new ActivityTransition.Builder()
                        .setActivityType(DetectedActivity.ON_FOOT)
                        .setActivityTransition(ActivityTransition.ACTIVITY_TRANSITION_EXIT)
                        .build());

        ActivityTransitionRequest request = new ActivityTransitionRequest(transitions);

        Intent intent = new Intent(getApplicationContext(), ActivityTransitionBroadcastReceiver.class);
        intent.setAction(ActivityTransitionBroadcastReceiver.INTENT_ACTION);


        PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, intent,
                PendingIntent.FLAG_CANCEL_CURRENT);

        Task<Void> task = ActivityRecognition.getClient(getApplicationContext())
                .requestActivityTransitionUpdates(request, pendingIntent);
        task.addOnSuccessListener(aVoid -> Log.i(TAG, "\n\nTransitions API was successfully registered.\n\n"))
                .addOnFailureListener(e -> Log.e(TAG, "Transitions API could not be registered: " + e));
    }

}

в манифесте также попытайтесь добавить

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

И для удобства создайте класс NotificationHelper:

class NotificationHelper {

    static void sendNotification(Context context, String textContent) {

        Intent notificationIntent;
        PendingIntent pendingIntent;

        notificationIntent = new Intent(context, MainActivity.class);
        notificationIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NO_HISTORY);
        pendingIntent = PendingIntent.getActivity(context, new Random().nextInt(100) + 1,
                notificationIntent, PendingIntent.FLAG_CANCEL_CURRENT);

        NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context,"notif_ch_myapplication")
                .setContentTitle(context.getResources().getString(R.string.app_name))
                .setContentText(textContent)
                .setChannelId("notif_ch_myapplication")
                .setSmallIcon(R.mipmap.ic_launcher)
                .setPriority(NotificationCompat.PRIORITY_DEFAULT)
                .setDefaults(Notification.DEFAULT_SOUND | Notification.DEFAULT_VIBRATE)
                .setContentIntent(pendingIntent);

        if (Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
            mBuilder.setSmallIcon(R.mipmap.ic_launcher);
            mBuilder.setLargeIcon(BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_launcher_background));
        } else {
            mBuilder.setLargeIcon(BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_launcher_background));
            mBuilder.setSmallIcon(R.mipmap.ic_launcher);
        }

        android.app.NotificationManager notificationManager = (android.app.NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {

            NotificationChannel channel = new NotificationChannel("notif_ch_myapplication",
                    context.getResources().getString(R.string.app_name),
                    android.app.NotificationManager.IMPORTANCE_DEFAULT);
            if (notificationManager != null) {
                notificationManager.createNotificationChannel(channel);
            }
        }
        if (notificationManager != null) {
            notificationManager.notify(new Random().nextInt(100) + 1, mBuilder.build());
        }
    }
}

и используйте его в ActivityTransitionBroadcastReceiver:

    public  class ActivityTransitionBroadcastReceiver extends BroadcastReceiver {

    public static final String INTENT_ACTION = "com.example.myapplication.ACTION_PROCESS_ACTIVITY_TRANSITIONS";

    @Override
    public  void onReceive(Context context, Intent intent) {
        if (ActivityTransitionResult.hasResult(intent)) {
            ActivityTransitionResult result = ActivityTransitionResult.extractResult(intent);
            for (ActivityTransitionEvent event : Objects.requireNonNull(result).getTransitionEvents()) {
                NotificationHelper.sendNotification(context, "Activity type:" + event.getActivityType()
                        + " Transition type: " + event.getTransitionType());
            }
        }
    }
}

Таким образом, вы сможете зарегистрироваться без android studio.

И еще одна важная вещь: когда вы будете устанавливать приложение - go снаружи не менее 10 минут. В моем случае я получил новое событие перехода активности только через ~ 5-7 минут.

0 голосов
/ 13 февраля 2020

1) Это может быть вызвано тем, что «приложения, ориентированные на уровень API 26 или выше, больше не могут регистрировать широковещательные приемники для неявных широковещательных передач в своем манифесте». Попробуйте использовать IntentService, но не BroadcastReceiver.

В манифесте:

<service
            android:name=".DetectedActivitiesIntentService"
            android:exported="false" />

Класс обслуживания:

public class DetectedActivityIntentService extends IntentService {

    protected static final String LOG_TAG = DetectedActivityIntentService.class.getSimpleName();

    public DetectedActivityIntentService() {
        super(LOG_TAG);
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        if (ActivityTransitionResult.hasResult(intent)) {
            ActivityTransitionResult result = ActivityTransitionResult.extractResult(intent);
        }
    }
}

Ожидаемое намерение:

 private PendingIntent getActivityDetectionPendingIntent() {
        Intent intent = new Intent(App.getInstance().getApplicationContext(), DetectedActivityIntentService.class);
        return PendingIntent.getService(App.getInstance().getApplicationContext(), 1, intent, PendingIntent.FLAG_UPDATE_CURRENT);
    }

И запуск метода прослушивания:

 public void startListenMoveUpdates(List<ActivityTransition> transitions) {

        ActivityTransitionRequest request = new ActivityTransitionRequest(transitions);
        Task<Void> task = mActivityRecognitionClient.requestActivityTransitionUpdates(request, getActivityDetectionPendingIntent());

        task.addOnSuccessListener(
                result -> LogManager.saveMsg("Start listen move actions")
        );
        task.addOnFailureListener(
                e -> {
                    e.printStackTrace();
                    LogManager.saveMsg("Start listen move actions error");
                }
        );
    }

2) Я бы также рекомендовал избегать тестирования в зданиях с низким уровнем сигнала GPS.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...