1

In my app I have bundled a custom unique sound for push notifications with FirebaseMessagingService.

I have also built in the ability for the user to choose their own custom sound.

With the below code if the use IS IN THE APP: the user chosen sound will play if they chose one. BUT if out of the application, my custom unique sound will play.

I would like for the users selected custom notification sound (if they chose one) to play if they are not using the app instead of my unique sound.

I have stored the Ringtone sound URI in a preferences file: content://media/internal/audio/media/57

public class MyAppFirebaseMessagingService extends FirebaseMessagingService {

    private static final String TAG = "FCMService";

    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {

        // Check if message contains a notification payload.
        if (remoteMessage.getNotification() != null) {
            sendNotification(remoteMessage.getNotification().getBody());
        }

    }

    private void sendNotification(final String messageBody) {
        Intent intent = new Intent(this, HomeActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent, PendingIntent.FLAG_ONE_SHOT);

        Uri defaultSoundUri = null;

        if (AppPref.getUserWantsCustomSound()){ 
            //ANDROID SOUND CHOSEN BY USER
            defaultSoundUri = Uri.parse(AppPref.getUserCustomSound()); // Returns content://media/internal/audio/media/57

        } else {
            //PRE PACKAGED SOUND included in app
            defaultSoundUri = Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.pushnotify);
        }

       Log.d(TAG, "defaultSoundUri: " + defaultSoundUri);

       NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
                .setSmallIcon(R.mipmap.ic_launcher)
                .setContentTitle("My App")
                .setContentText(messageBody)
                .setAutoCancel(true)
                .setSound(defaultSoundUri)
                .setContentIntent(pendingIntent);

        NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

        notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());

        //IF IN APP SHOW A TOAST MESSAGE
        Handler handler = new Handler(Looper.getMainLooper());
        handler.post(new Runnable() {
            public void run() {
                Toast.makeText(getApplicationContext(),messageBody,Toast.LENGTH_SHORT).show();
            }
        });

    }

}
AL.
  • 36,815
  • 10
  • 142
  • 281
user-44651
  • 3,924
  • 6
  • 41
  • 87
  • What format is your sound file ? – jpact Mar 20 '17 at 20:23
  • My sound file is an MP3. I don't think thats the problem. It plays just fine in and out of the app. I want the user to select a ringtone from within the app and play that. And it does in app only. I need it to play out of the app too. – user-44651 Mar 20 '17 at 20:24
  • Ok, so if I've understood correctly, you need to implement a logic for detecting whether user is "in app" or not. In another words, whether app is either in foreground or background – jpact Mar 20 '17 at 20:32
  • Any pointers on where to begin? – user-44651 Mar 20 '17 at 20:36
  • Implement ActivityLifecycleCallbacks in your Application class, and set a flag once app is going to background (its onStop() callback method). – jpact Mar 20 '17 at 20:43

1 Answers1

0

If you need to differ on client side whether app is either in foreground or background, try to implement an interface ActivityLifecycleCallbacks by your Application class and set a flag once you app is going to background.

public class App extends Application implements Application.ActivityLifecycleCallbacks {

    private static boolean isBackground = false;

    @Override
    public void onActivityStarted(Activity activity) {
        isBackground = false;
    }

    @Override
    public void onActivityStopped(Activity activity) {
        isBackground = true;
    }

    public static boolean isInBackground(){
        return this.isBackground;
    }
}

Also, don't forget to define this custom application class in your AndroidManifest.xml file.

<application
    android:name=".App">
</application>

Lastly, in your push notification code:

if (AppPref.getUserWantsCustomSound() && !App.isInBackground()){ 
    //ANDROID SOUND CHOSEN BY USER
    defaultSoundUri = Uri.parse(AppPref.getUserCustomSound()); // Returns content://media/internal/audio/media/57

} else {
    //PRE PACKAGED SOUND included in app
    defaultSoundUri = Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.pushnotify);
}
jpact
  • 1,042
  • 10
  • 23
  • I already have android.support.multidex.MultiDexApplication in my name.. – user-44651 Mar 20 '17 at 21:02
  • Thats not a problem at all as `MultiDexApplication` extends `Application` class. Just implement that interface, and keep some flag of app (background | foreground) state as I sent you above :) – jpact Mar 20 '17 at 21:14