Closed Wilmer-SHF closed 10 months ago
My Example
Code in app.component.ts
async createChannelGeneral(){ let dataChannel:any = { description: "", id: "general", name: "General", importance: 4, lightColor: "#FFFFFF", lights: true, visibility:0, vibration: true, sound:'beep.mp3' }; await PushNotifications.createChannel(dataChannel).then((data:any) =>{}).catch((err) => {}); }
File copy_files_android.js
`#!/usr/bin/env node var fs = require('fs'); var path = require('path');
try { var dirpath = './android/app/src/main/res/raw/'; fs.mkdirSync(dirpath, { recursive: true }); } catch (error) {
} var filestocopy = [{ "../resources/beep.mp3": "../android/app/src/main/res/raw/beep.mp3" }];
var path = require('path'); var rootdir = path.resolve(__dirname);
filestocopy.forEach(function(obj) { Object.keys(obj).forEach(function(key) { var val = obj[key]; var srcfile = path.join(rootdir, key); var destfile = path.join(rootdir, val); console.log("copying " + srcfile + " to " + destfile); var destdir = path.dirname(destfile); if (fs.existsSync(srcfile) && fs.existsSync(destdir)) { fs.createReadStream(srcfile).pipe( fs.createWriteStream(destfile)); } }); });`
Put file beep.mp3 in folder resources in root
Modify package.json in scripts, add this line
"capacitor:sync:after": "node scripts/copy_files_android.js"
File package.json
File app.component.js
File copy_files_android.js
This issue may need more information before it can be addressed. In particular, it will need a reliable Code Reproduction that demonstrates the issue.
Please see the Contributing Guide for how to create a Code Reproduction.
Thanks! Ionitron 💙
The problem is not copying the files dynamically into the res/raw
folder. The file I want to add is only one, and I can manually copy it into the respective folder. The problem, in this case audio.mp3
, is that the file no longer exists in the release bundle.
I show how the folder structure is inside the apk in a bundle made with debug. Notice how the audio.mp3
file exists.
.
└── apk
├── assets
│ └── ...
...
...
│ └── ...
└── res
├── color
├── color-night-v8
├── color-v21
├── color-v23
└── color-v31
└── raw
├── audio.mp3
Now I show how is the folder structure inside the apk in a bundle made with release. See how the raw folder does not exist
.
└── apk
├── assets
│ └── ...
...
...
│ └── ...
└── res
├── color
├── color-night-v8
├── color-v21
├── color-v23
└── color-v31
This means that the push notification will not sound with the custom audio.
This can be easily replicated, without the need to use the push notification
plugin (but the problem affects this plugin, so it needs to be fixed).
To replicate:
ionic start
ionic integrations enable capacitor
ionic capacitor add android
audio.mp3
in /android/app/src/main/res/raw/
ionic build --release && npx cap copy && npx cap sync && npx cap open android
audio.mp3
file has been added to the apk or no (If not added, push notification will not sound): find . -iname '*audio.mp3*'
Here I present a repository with a simple project of an ionic app that reproduces the mentioned error.
https://github.com/WilmerRS/ionic-push-notification-raw-files
Build, create apk as release and review the generated apk.
I thought if you can conditionally change where the audio file is taken from, it could be passed to ionic app assets. However it doesn't work for me.
File: NotificationChannelManager.java
file inside the plugin.
...
public void createChannel(JSObject channel) {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
...
String sound = channel.getString(CHANNEL_SOUND, null);
if (sound != null && !sound.isEmpty()) {
AudioAttributes audioAttributes = new AudioAttributes.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
.setUsage(AudioAttributes.USAGE_NOTIFICATION)
.build();
Uri soundUri = Uri.parse("file:///android_asset/public/assets/" + sound);
notificationChannel.setSound(soundUri, audioAttributes);
}
notificationManager.createNotificationChannel(notificationChannel);
}
}
...
I have tried creating several channels and each one assigning a different sound, even assigning a sound to the default channel and everything is correct, without modifying the android code
Any idea why in my release build there is no res/raw
folder left? Again I tell you that in the debug build it works correctly and the sound does sound.
Again I share this simple test project in which this is evidenced. Am I missing some configuration? https://github.com/WilmerRS/ionic-push-notification-raw-files
If I don't get the audio.mp3
file to exist within res/raw
, the custom notification sound will never play.
I can reproduce, but I can also reproduce on a native Android app without Capacitor involved, so looks like it's a bug on Android Studio or the intended behavior. Something on the signed apk creation is renaming the .mp3 file, if you inspect the generated apk you'll see the .mp3 file is there, but with a different name.
I've tried a few configurations such as the keep.xml file that the provided sample app already included and some proguard rules but none of them worked.
The only thing that worked was to create a signed AAB (Android App Bundle) instead of an APK and that keeps the mp3 name. But not sure if later on Google Play will present the same problem once the AAB gets signed there as I think they convert it to .apk.
You should report the issue to Google.
Thanks for the issue! This issue is being locked to prevent comments that are not relevant to the original issue. If this is still an issue with the latest version of the plugin, please create a new issue and ensure the template is fully filled out.
Bug Report
Plugin(s)
Push Notification
Capacitor Version
Capacitor 4.7.3
Platform(s)
The android release bundle is affected
Current Behavior
An
audio.mp3
file has been successfully added to the /res/raw folder. In thedebug
bundle everything works correctly, the apk stores this file in the path/res/raw/audio.mp3
and the notification sound works correctly. But when doing therelease
bundle, and analyzing theapk
, the file is not found in/res/raw/audio.mp3
, in fact, theraw
folder no longer exists. Therefore, the app does not play the notification sound.Expected Behavior
Is there a way to ensure that the
audio.mp3
file exists in the folder that is needed? or optionally you can select an audio file from the application'sassets
folder.Code Reproduction
Service inside code app.
Additional Context
This is the configuration tried so that the audio.mp3 file is not removed from the bundle in release. It has not achieved any effect.
Keep file,
android/app/src/main/res/raw/keep.xml
Proguard rules
android/app/proguard-rules.pro