I'm using Onesignal to push notification in my app ionic, but the custom sound does not ring.
Here my app.component:
setupNotification() {
this.oneSignal.startInit('xxxxxxxxxx-xxxx-xxxxxxxxxxx-xxxxxxxx', 'xxxxxxxxxxxx');
this.oneSignal.inFocusDisplaying(this.oneSignal.OSInFocusDisplayOption.InAppAlert);
this.oneSignal.handleNotificationReceived().subscribe(data => {
data.payload.sound = 'coins.mp3'
});
this.oneSignal.handleNotificationOpened().subscribe(() => {
// do something when a notification is opened
});
this.oneSignal.endInit();
}
here my config.xml:
<platform name="android">
<resource-file src="res/raw/coins.mp3" target="res/raw/coins.mp3" />
</platform>
Where am I going wrong?
I've just managed to get this working on my Ionic3 app with OneSignal, and testing on Android 8.0. So maybe this can help someone.
I also updated to Cordova 9, and updated onesignal-cordova-plugin to 2.4.7
I also assume here you already have notifications working, its just the custom sound file that's not working.
My sound file is alert.wav, and placed it under 'src/assets/audio` (I created the audio folder)
In config.xml, I had to add the following to copy this file to the correct location:
<resource-file src="www/assets/audio/alert.wav" target="app/src/main/res/raw/alert.wav" />
(the audio dir will get copied to the www dir on build)
Android 8 requires you to create a notification channel/category. You can create a Group and Category in OneSignal settings.
In the Category settings - Sound section, set to 'Custom' and add the name of the file (without the file extension) - in my case alert. Everything else can be left as default.
I also found that if you edit it, it seems to be ignored. so I had to create a new Category when testing a different sound file. I recommend for testing, delete the Category and create a new one to be sure - don't bother editing it. Once a notification is sent using this Channel, the channel is created on the users device and cant be removed/edited - user has to uninstall/reinstall the app.
I triggered the notifications through my backend server, this is PHP:
$request = json_encode([
'app_id' => 'xxxxxxxxxxxxxxxxxxxxxx',
'headings' => [
'en' => $title,
],
'contents' => [
'en' => $message,
],
'include_player_ids' => $playerIds,
'android_channel_id' => 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee',
// 'android_sound' => 'alert',
]);
Make sure to copy the new Channel ID from OneSignal into this request payload.
Ultimately didn't need the 'android_sound' value, as it triggers the channel default settings (which has the audio file name), and changing the android_sound value has no effect.
unfortunately you need to create one Category per sound file you want to play which may not suit some use cases - the user will see these channels in their app notification settings.
Some other things I recommend when testing this is to uninstall the App before each build to test specific changes, and running cordova clean I found helps too.
Hope this helps!
use this code :
<resource-file src="www/assets/audio/alert.wav"target="app/src/main/res/raw/alert.wav" />
to move the sound file to location that use by onesignal plugin
add this to send code :
'android_sound' => 'alert'
it worked
Related
I'm updating an old Ionic app:
Angular: 8.2.9 => 11.2.12
Angular CLI: 8.3.8 => 11.2.11
Ionic: 4.10.0 => 5.6.6
Ionic CLI: 5.4.16 => 6.14.0
The app starts when i run it locally (using ionic serve), but the SVG-icons does not show.
If I look at one particular icon, I find two versions of the icon in the source files:
\src\assets\custom-ion-icons\md-br-home.svg
\src\assets\custom-ion-icons\ios-br-home.svg
The place where the icon is used looks lite this:
<ion-icon name="br-home"></ion-icon>
When running the old version of the app, the icon gets fetched and shown with this url:
http://localhost:8100/svg/md-br-home.svg
However, running after the update, the app requests this url:
http://localhost:8100/svg/br-home.svg
I'm not sure how the "md-" part is added in the old version of the app, but somehow this have disappeared.
If I change the filename of md-br-home.svg to br-home.svg, it works. Maybe that's the solution? But will this mess something up when I build and distribute this app? I'd like to get a better understanding of how this i supposed to work.
Just found the answer to my question.
Updating Ionic from 4 to 5 changes how icons (ionicons) are handled. Platform specific variants are no longer used, thus "md-" and "ios-" in filenames are no longer used.
https://github.com/ionic-team/ionicons/releases/tag/5.0.0
I just changed the names of the SVG-files beginning with "md-" (e.g. md-br-home.svg to br-home.svg), and then deleted the ones beginning with "ios-".
I also used some standard ionicons icons that had been removed or renamed, so I had to fix that too. A list of all changes is available on the page linked above.
I'm using the following plugin
https://pub.dev/packages/receive_sharing_intent
It is working with android.
But the instruction for IOS are unclear - I follow the IOS instruction and I'm able to share files with my app, when I do so, my app opens but the flutter code is not executed, the only thing I see in the log is:
6.26.0 - [Firebase/Analytics][I-ACS023000] Deep Link Web URL query is empty
Which doesn't mean any thing to me.
I tried to look for this error and couldn't find anything that is related to sharing intent.
Can someone clarify this?
Is there a tutorial on how to set sharing intent for IOS?
In the instruction it says:
ios/Runner/Runner.entitlements
....
<!--TODO: Add this tag, if you want support opening urls into your app-->
<key>com.apple.developer.associated-domains</key>
<array>
<string>applinks:example.com</string>
</array>
But I don't have such file in my directory structure, any idea how to set it correctly?
....
EDIT:
I created and added the file ios/Runner/Runner.entitlements manually
I noticed I missed the last step (after publishing the question), so I did it:
Add Runner and Share Extension in the same group
Go to the Capabilities tab and switch on the App Groups switch for both targets. Add a new group and name it group.YOUR_HOST_APP_BUNDLE_IDENTIFIER in my case group.com.kasem.sharing
This step is not very clear:
the name of the tab is Signing & Capabilities
in order to switch on the App Group you should click on `+ Capability' in the top left of the tab
I checked the checkbox next to App Group
Add a new group and name it group.YOUR_HOST_APP_BUNDLE_IDENTIFIER in my case group.com.kasem.sharing
After this I was able to receive the file intent in the App but couldn't open the file:
print("$path, exist ${await io.File(path).exists()}");
I was able to print the path but the exists method return false
NOTE:
works with no issues in android
works with no issues in IOS when sharing an image
only fails with files (PDF)
I am using ionic 3 for these and i need to give a force update feature for android users.
can i able to do it with-->
like first compare current play store version and user version and then set
a page for those users who don't have the updated version and force user's
for update the app, can i use file transfer plugin for update the app.
what approch is right?
You can use following plugins to verify that updates is available in playstore.
cordova-plugin-app-update
You should first host an XML file on your server with the following data in it:
<update>
<version>302048</version>
<name>APK Name</name>
<url>https://your-remote-api.com/YourApp.apk</url>
</update>
And then check with
constructor(private appUpdate: AppUpdate) {
const updateUrl = 'https://your-remote-api.com/update.xml';
this.appUpdate.checkAppUpdate(updateUrl).then(() => { console.log('Update
available') });
}
More details available here
Did you try this with release build package ?
I am working on an app in which I have to restrict the user to share the apk personally. One can download it but should not be allowed to share the App (apk) personally via bluetooth etc.
I searched and read alot about the same issue but didn't find a complete answer. I have tried the below.
How to get the file *.apk location in Android device
Download, Installing and Delete .apk file on android device programmatically from a website other than marketplace
What I have understood from above is that the easy way to do this is to delete the apk file from the User's device after the app is installed. (I also know that user may generate this apk again via root access but that is fine as at-least I will be able to restrict not all but many).
Now what I have tried, I am registering a Broadcast receiver and in my onReceive() method I have the below,
PackageManager pm = getPackageManager();
for (ApplicationInfo app : pm.getInstalledApplications(0)) {
if (myPackage.equalsIgnoreCase(app.packageName)) {
apkPath = app.sourceDir;
break;
}
}
Log.d("Package", myPackage + " - APK - " + apkPath);
if (intent.getAction().equals("android.intent.action.PACKAGE_ADDED")) {
File sdcard = Environment.getExternalStorageDirectory();
File file = new File(sdcard, apkPath);
file.delete();
}
But this does nothing as I am not aware of the IntentFilter I should use to register this.
Can any one guide me on what is the next step? and in case I am completely on a wrong land then help me achieve the above?
Any help will be appreciated. :)
On later versions of Android, some (all?) broadcasts aren't sent to an app until it has been manually opened at least once. This is a security feature that can't be circumvented.
As far as I know, It is not possible to listen the installation complete broadcast event. Android Api having Broadcast Action: "ACTION_PACKAGE_ADDED" But newly installed package does not receive this broadcast. Source : Here
My suggestion is check in your first launcher activity and delete the apk.
You can use the Android App Licensing Service here.
Refer http://developer.android.com/google/play/licensing/index.html and the implmentation here http://developer.android.com/google/play/licensing/adding-licensing.html.
This will ensure that the apk cannot be shared(making it protected) using any of the apps available on market.
Sorry for bad english.
Here my solution not actual code:
1) set your broadcastreciver when any new application is install in your device.
2) When your broadcastreciver is call, that time you write code in onRecive() method
check the your app package if install or not
private boolean isPackageInstalled(String packagename, Context context) {
PackageManager pm = context.getPackageManager();
try {
pm.getPackageInfo(packagename, PackageManager.GET_ACTIVITIES);
return true;
} catch (NameNotFoundException e) {
return false;
}
}
using this method or any
if you get true means your application is install
3) if you get true from isPackageInstalled("com.download.app", context) method
that time delete apk file from your SD card or any loaction in device
if you more clarification i will be explain.
i used the idea of creating a folder when the app runs for the first time .if it doesnot exist , delete the apk. if the folder exists , then the apk has already been deleted.
This folder will be deleted on its own if the app is unstalled.
public static String link = Environment.getExternalStorageDirectory()
.getPath() + "/Android/data/YourAppPackageName/";
//check if its running for the first time
File f = new File(link);
if (f.exists()) {
File f1 = new File("/data/app/YourAppPackageName.apk")
if(f1.exists()){f1.delete();}
}
else {
f.mkdirs();
}
You can also use the HockeyApp product and distribute using the Android App that they provide, as well as enable the "restriction" features. I'm pretty sure that will do what you need without having to write extra code.
Background
I am developing a Cordova app that must run as a service, i.e. continue in the background and restart when the device does. As far as I can tell, on iOS it is just a case of setting the UIBackgroundModes correctly but on Android requires a little more effort and the service needs to be explicitly started.
I have developed a plugin for Android based on Mark Taylor's example here.
At present I have some JS called on deviceready to start the Android code but don't need to do anything for iOS.
Question
How should I package my plugin so that it will work on all platforms with zero config. It seems clunky to write if (Device.type == 'android') statements in my main JS but I don't really want to write native null implementations.
Is there a suggested approach for this?
Figured it out using the <js-module> tag described here.
Added this to my plugin.xml:
<platform name='android'>
...
<js-module src="androidSpecificStuff.js" name="SomeModule">
<clobbers target="SomeModule" />
</js-module>
...
</platform>
Then in androidSpecificStuff.js had code like:
document.addEventListener('deviceready', function () {
// do android-specific initialisation here
})