flutter FCM notification sound not working in release

5,156

Solution 1

try this in your MainActivity.java

    import io.flutter.embedding.android.FlutterActivity;   
    import android.app.NotificationChannel;  
    import android.app.NotificationManager;  
    import android.media.AudioAttributes;  
    import android.net.Uri;  
    import android.os.Build;   
    import android.os.Bundle;   
    public class MainActivity extends FlutterActivity {  
@Override  
 protected void onCreate(Bundle savedInstanceState) {  
    super.onCreate(savedInstanceState);   
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {  
  Uri soundUri=Uri.parse("android.resource://"+getApplicationContext()   
.getPackageName() + "/" +  R.raw.[soundName without extension]);  
AudioAttributes audioAttributes = new AudioAttributes.Builder()   
                .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)    
                .setUsage(AudioAttributes.USAGE_ALARM)   
                .build();   

        // Creating Channel   
        NotificationChannel channel = new NotificationChannel([ChannelId],[ChannelName], NotificationManager.IMPORTANCE_HIGH);
        channel.setSound(soundUri, audioAttributes);

        NotificationManager notificationManager = getSystemService(NotificationManager.class);
        notificationManager.createNotificationChannel(channel);
    }
   // GeneratedPluginRegistrant.registerWith(this);
}

}

Solution 2

Ok, I think I found one solution that will (hopefully) work for you, too:

Like for you, everything worked in flutter run --release or flutter run, but not when actually building and installing a apk-release on my phone (A5 2017).

So I thought*: Only difference is shrinking, right? Flutter shrinks down the apk automatically (see: flutter.dev), so I used the --no-shrink flag and now everything works fine, even with the build app.

*By thinking I mean pulling my hair for 3hours, not remotely thinking about this specific difference.

Solution 3

enter image description here

<resources xmlns:tools="http://schemas.android.com/tools" tools:keep="@raw/{filename}"/>

add this in the keep.xml which is inside the raw folder of the android resource directory. while creating the release build it actually shrinks the file and changes the name so this is what i got for the solutions.

Share:
5,156
user2836291
Author by

user2836291

Updated on December 27, 2022

Comments

  • user2836291
    user2836291 over 1 year

    I'm struggling last few days with this. I have flutter app that should receive notification from firebase (using FCM) and play custom sound. This works fine if I run app using flutter run or using flutter run --release, but if I build app using flutter build apk --release and install it manually on my phone I still get notification but sound is missing, it won't even play default notification sound.

    I checked if my sound is on, and if notification channels in app settings are correct.

    main.dart

    void main() async {
      // needed if you intend to initialize in the `main` function
      WidgetsFlutterBinding.ensureInitialized();
    
      fcm.getToken().then((value) {
        print("TOKEN:" + value);
      });
    
      fcm.configure(
        onResume: (Map<String, dynamic> message) async {},
        onLaunch: (Map<String, dynamic> message) async {},
        onMessage: (Map<String, dynamic> message) async {
           AudioCache _audioCache = AudioCache(
              prefix: "sounds/",
              fixedPlayer: AudioPlayer()..setReleaseMode(ReleaseMode.STOP));
    
          _audioCache.play('merchant_notify.mp3');
        },
      );
    
      runApp(MyApp());
    }
    
    

    android/build.gradle

    buildscript {
        ext.kotlin_version = '1.3.50'
        repositories {
            google()
            jcenter()
        }
    
        dependencies {
            classpath 'com.android.tools.build:gradle:3.5.0'
            classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
            classpath 'com.google.gms:google-services:4.3.2'
        }
    }
    
    allprojects {
        repositories {
            google()
            jcenter()
        }
    }
    
    rootProject.buildDir = '../build'
    subprojects {
        project.buildDir = "${rootProject.buildDir}/${project.name}"
    }
    subprojects {
        project.evaluationDependsOn(':app')
       
    }
    
    task clean(type: Delete) {
        delete rootProject.buildDir
    }
    
    

    android/app/build.gradle

    apply plugin: 'com.android.application'
    apply plugin: 'kotlin-android'
    apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
    apply plugin: 'com.google.gms.google-services'
    
    android {
        compileSdkVersion 28
    
        sourceSets {
            main.java.srcDirs += 'src/main/kotlin'
        }
    
        lintOptions {
            disable 'InvalidPackage'
        }
    
        defaultConfig {
            applicationId "" 
            minSdkVersion 21
            targetSdkVersion 28
            versionCode flutterVersionCode.toInteger()
            versionName flutterVersionName
        }
    
        buildTypes {
            release {
                // TODO: Add your own signing config for the release build.
                // Signing with the debug keys for now, so `flutter run --release` works.
                signingConfig signingConfigs.debug
            }
        }
    }
    
    flutter {
        source '../..'
    }
    
    dependencies {
        implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"    
       
    }
    

    androidmanifest.xml

    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
        package="">
    
        <uses-permission android:name="android.permission.INTERNET"/>
        <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
        <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
        <uses-permission android:name="android.permission.VIBRATE"/>
        <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
        <application
            android:name="io.flutter.app.FlutterApplication"
            android:label=""
            android:icon="@mipmap/launcher_icon">
            <activity
               android:name=".MainActivity"
                android:launchMode="singleTop"
                android:theme="@style/LaunchTheme"
                android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
                android:hardwareAccelerated="true"
                android:windowSoftInputMode="adjustResize"
                android:showWhenLocked="true"
                android:turnScreenOn="true">
    
                <meta-data
                  android:name="io.flutter.embedding.android.NormalTheme"
                  android:resource="@style/NormalTheme"
                  />
    
                <meta-data
                  android:name="io.flutter.embedding.android.SplashScreenDrawable"
                  android:resource="@drawable/launch_background"
                  />
                <intent-filter>
                    <action android:name="android.intent.action.MAIN"/>
                    <category android:name="android.intent.category.LAUNCHER"/>
                </intent-filter>
    
                <intent-filter>
                    <action android:name="FLUTTER_NOTIFICATION_CLICK"/>
                    <category android:name="android.intent.category.DEFAULT"/>
                </intent-filter> 
            </activity>
           
            <receiver android:name="com.dexterous.flutterlocalnotifications.ScheduledNotificationBootReceiver">
                <intent-filter>
                    <action android:name="android.intent.action.BOOT_COMPLETED"/>
                    <action android:name="android.intent.action.MY_PACKAGE_REPLACED"/>
                    <action android:name="android.intent.action.QUICKBOOT_POWERON" />
                    <action android:name="com.htc.intent.action.QUICKBOOT_POWERON"/>
                </intent-filter>
            </receiver>
    
           
            <!-- Don't delete the meta-data below.
                 This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
           <meta-data
                android:name="flutterEmbedding"
                android:value="2" /> 
        </application>
    </manifest>
    

    MainActivity.kt

    package com.example.merchant_delivery
    
    import io.flutter.embedding.android.FlutterActivity
    
    
    
    class MainActivity: FlutterActivity()  { 
    }
    

    Also there is sound file in res\raw\sound.mp3

    Here is json that I send to firebase FCM:

    {
        "registration_ids": [
           
        ],
          "notification": {
            "title": "Test notification",
            "body": "Body test",
            "android_channel_id": "channel_name",
            "channel_id": "channel_name",
            "sound": "sound",
            "priority":"high"
        }
    }
    
    
  • user2836291
    user2836291 about 3 years
    Is there any specific reason that would couse this issue? I have fixed it but don't know how, here is my MainActivitiy.kt class Application : FlutterApplication(), PluginRegistrantCallback { override fun onCreate() { super.onCreate() FlutterFirebaseMessagingService.setPluginRegistrant(this); } override fun registerWith(registry: PluginRegistry?) { io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin‌​.registerWith(regist‌​ry?.registrarFor("io‌​.flutter.plugins.fir‌​ebasemessaging.Fireb‌​aseMessagingPlugin")‌​); } } I think that helped!
  • Pro Co
    Pro Co almost 3 years
    So Can you give me a Good Conclusion. Like, what should be the order, ex: will it be, flutter -- no-shrink or flutter run --no-shrink
  • user2836291
    user2836291 over 2 years
    Your solution should work, will check it out, thanks!