Reputation: 146
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"
}
}
Upvotes: 4
Views: 7943
Reputation: 61
<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.
Upvotes: 3
Reputation: 63
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.
Upvotes: 2
Reputation: 66
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);
}
}
Upvotes: 2