-1

I need to make android app with map and some markers. When i'm come within 10 meters to the marker, it becomes clickable, and on click plays audiotrack, then changes marker icon and shows another marker. I tried to use geofences, but i can't change icon or call MediaPlayer from BroadcastReciever or from other activity or service.

marker - center of geofence.

The Question:

How can I change marker's icon and start audiotrack, when geofence triggers?

adding geofences in MapsActivity

private void createGeofences(){
        if (Build.VERSION.SDK_INT >= 29) {
            //We need background permission
            if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_BACKGROUND_LOCATION) == PackageManager.PERMISSION_GRANTED) {
                for (int i=0; i < ARRAY_SIZE; i++){
                    addGeofence(latLngArray[i], GEOFENCE_RADIUS, Integer.toString(i));
                }
            }
            } else {
                if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_BACKGROUND_LOCATION)) {
                    //We show a dialog and ask for permission
                    ActivityCompat.requestPermissions(this, new String[] {Manifest.permission.ACCESS_BACKGROUND_LOCATION}, BACKGROUND_LOCATION_ACCESS_REQUEST_CODE);
                } else {
                    ActivityCompat.requestPermissions(this, new String[] {Manifest.permission.ACCESS_BACKGROUND_LOCATION}, BACKGROUND_LOCATION_ACCESS_REQUEST_CODE);
                }
            }

    }

     private void addGeofence(LatLng latLng, float radius, String id){
        Geofence geofence = GeofenceHelper.getGeofence(id, latLng, radius, Geofence.GEOFENCE_TRANSITION_ENTER);
        GeofencingRequest geofencingRequest = geofenceHelper.getGeofencingRequest(geofence);
        PendingIntent pendingIntent = geofenceHelper.getPendingIntent();
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
            geofencingClient.addGeofences(geofencingRequest, pendingIntent)
                    .addOnSuccessListener(new OnSuccessListener<Void>() {
                        @Override
                        public void onSuccess(Void aVoid) {
                            Log.d(TAG, "onSuccess: Geofence Added...");
                        }
                    })
            .addOnFailureListener(new OnFailureListener() {
                @Override
                public void onFailure(@NonNull Exception e) {
                    String errorMessage = GeofenceHelper.getErrorString(e);
                    Log.d(TAG, "onFailure: " + errorMessage);
                }
            });
        }
    }

GeofenceHelper.class

public class GeofenceHelper extends ContextWrapper {

    private static final int loiteringDelay = 0;

    private static final String TAG = "GeofenceHelper";
    PendingIntent pendingIntent;


    public GeofenceHelper(Context base) {
        super(base);
    }

    public GeofencingRequest getGeofencingRequest(Geofence geofence){

        return new GeofencingRequest.Builder()
                .addGeofence(geofence)
                .setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER)
                .build();
    }

    public static Geofence getGeofence(String ID, LatLng latLng, float radius, int transitionTypes){
        return new Geofence.Builder()
                .setCircularRegion(latLng.latitude, latLng.longitude, radius)
                .setRequestId(ID)
                .setTransitionTypes(transitionTypes)
                .setLoiteringDelay(loiteringDelay)
                .setExpirationDuration(Geofence.NEVER_EXPIRE)
                .build();
    }

    public PendingIntent getPendingIntent(){
        if(pendingIntent != null){
            return pendingIntent;
        }
        Intent intent = new Intent(this, GeofenceBroadcastReceiver.class);
        pendingIntent = PendingIntent.getBroadcast(this, 956, intent, PendingIntent.FLAG_UPDATE_CURRENT);

        return pendingIntent;
    }

    public static String getErrorString(Exception e) {
        if (e instanceof ApiException) {
            ApiException apiException = (ApiException) e;
            switch (apiException.getStatusCode()) {
                case GeofenceStatusCodes
                        .GEOFENCE_NOT_AVAILABLE:
                    return "GEOFENCE_NOT_AVAILABLE";
                case GeofenceStatusCodes
                        .GEOFENCE_TOO_MANY_GEOFENCES:
                    return "GEOFENCE_TOO_MANY_GEOFENCES";
                case GeofenceStatusCodes
                        .GEOFENCE_TOO_MANY_PENDING_INTENTS:
                    return "GEOFENCE_TOO_MANY_PENDING_INTENTS";
            }
        }
        return e.getLocalizedMessage();
    }
}

GeofenceBroadcastReciever.class

public class GeofenceBroadcastReceiver extends BroadcastReceiver {
    private static final String TAG = "GeofenceBroadcastReceiv";

    //MediaPlayer mediaPlayer;

    @Override
    public void onReceive(Context context, Intent intent) {
        // an Intent broadcast.


        GeofencingEvent geofencingEvent = GeofencingEvent.fromIntent(intent);

        if (geofencingEvent.hasError()) {
            Log.d(TAG, "onReceive: Error receiving geofence event...");
            return;
        };


        List<Geofence> geofenceList = geofencingEvent.getTriggeringGeofences();
        String id = geofenceList.get(0).getRequestId();

        switch (id){
            case "0":
                Toast.makeText(context, "Geofence " + id + " triggered.", Toast.LENGTH_SHORT).show();
            case "1":
                Toast.makeText(context, "Geofence " + id + " triggered.", Toast.LENGTH_SHORT).show();
            case "2":
                Toast.makeText(context, "Geofence " + id + " triggered.", Toast.LENGTH_SHORT).show();
            case "3":
                Toast.makeText(context, "Geofence " + id + " triggered.", Toast.LENGTH_SHORT).show();
            case "4":
                Toast.makeText(context, "Geofence " + id + " triggered.", Toast.LENGTH_SHORT).show();
            case "5":
                Toast.makeText(context, "Geofence " + id + " triggered.", Toast.LENGTH_SHORT).show();
        }

    }
}
Kitty Ket
  • 3
  • 2
  • Please insert the code where you register your BroadcastReciever and use it. How did you try using geofences _exactly_? Why are you not able to call something from the receiver, do you get an exception? – Hawk Aug 15 '20 at 11:15
  • I edited question. I try to catch when user enters the geofence and start audiotrack, but MediaPlayer need context, but i can't make something like String id = geofenceList.get(0).getRequestId(); switch (id){ case "0": mediaplayer =MediaPlayer.create(MapsActivity, R.raw.track0) } – Kitty Ket Aug 15 '20 at 13:21

1 Answers1

0

MediaPlayer need context Well you can pass a context to the broadcast receiver. I assume (because you have not shown it) that you register your broadcast receiver in an Activity or App which are contexts. Multiple solutions:

  1. Your broadcast receiver can be an inner class of your activity or an anonymous class, in both cases the broadcast receiver would have a reference to the wrapping class (MapsActivity.this).
  2. Pass the Context as a constructor parameter to your broadcast receiver. Useful when you want it to be a top-class and reuse it on multiple places.
  3. Pass a callback (some FunctionalInterface, f.e. Consumer<Integer> onCheckpointReached) in the constructor of the broadcast receiver.

As per accessing the specific track dynamically, you should not use such a switch but get a resource dynamically, the exact solution (with sounds even!) is here: https://stackoverflow.com/a/7182576/9274948


Side note: your switch (apiException.getStatusCode()) { does not make much sense, just use apiException.getStatusCode().name() or apiException.getStatusCode().toString().

Hawk
  • 2,042
  • 8
  • 16