Even listener stops working when app is running in the background - react-native

I am making a React Native app which talks to Spotify via this module: https://github.com/cjam/react-native-spotify-remote
The module has an event listener which allows us to listen to Spotify player state changes, for example:
import { remote as SpotifyRemote } from "react-native-spotify-remote";
// and in a React component:
SpotifyRemote.addListener("playerStateChanged", (state) => {
console.log(state);
});
The above works as long as our RN app is in focus. However, when the app is in the background (i.e. we are on a different app or the phone is locked), the event listner no longer gets triggered.
I am expecting the event listener to get triggered even when the app is running in the background but it isn't doing that.
Is there anyway to make this work even the app is not in focus? Thank you!

Related

How to bring a react native(expo) app to the foreground when user recieves a notification

I have set up expo notification wherein my app listens to incoming notifications and can execute tasks in the background but my question is how do I bring the app to the foreground upon receiving a notification without the user pressing on the notification first?
Something like this:
import * as Notifications from "expo-notifications";
import * as TaskManager from "expo-task-manager";
const BACKGROUND_NOTIFICATION_TASK = "BACKGROUND-NOTIFICATION-TASK";
TaskManager.defineTask(
BACKGROUND_NOTIFICATION_TASK,
({ data, error, executionInfo }) => {
console.log("Received a notification in the background!");
// Bring the app to the foreground
}
);
Notifications.registerTaskAsync(BACKGROUND_NOTIFICATION_TASK);
The closest thing that you can do, is to create a local notification and encourage the user to press the notification to put the app to the foreground. But the exact thing you are asking is not possible with Android or either with iOS.

React Native doesn't re-render when re-opening app

I have a functional component in my react native app that has an event listener watching the app state in order to clear out a cache when the app is closed. This works as expected, and I have logic written in a useEffect block to add/remove this event listener when the app is closed.
The functionality works perfectly when the user either navigates elsewhere in the app or closes the app, but when the app is re-opened after closing (not fully shutting down the app, just moving to a different app) the page is not re-rendered and so the event listener is not re-added.
I've attached the code in my useEffect below.
useEffect(() => {
if (!listenerRef.current) {
toggleEventListener(true);
}
return () => {
toggleEventListener(false);
};
}, []);
You can use appState from react-native to see foreground and background events
https://reactnative.dev/docs/appstate

Electron notifications don't bring app up to front again on click on the notification

I have an electron app that will just wrap a remote page while adding some extra features. With the following code the page loads and works. When the remote page fires some notifications using the notification API those notifications show up when the electron app is minimized. My problem is that when clicking on those notifications the app does not get put to front like it does when opening the remote page on any other browser directly. I could test this only for Ubuntu 19.10 Linux (Gnome 3).
Any idea if I need to configure something for that or if this is a bug with Electron/Ubuntu/Gnome?
const {app, shell, BrowserWindow} = require('electron');
let mainWindow;
function createWindow () {
// Create the browser window.
mainWindow = new BrowserWindow({
width: 1024,
height: 786,
});
mainWindow.setMenu(null);
mainWindow.setTitle('My app – Connecting…');
mainWindow.loadURL('https://some.url.somwhere');
// Emitted when the window is closed.
mainWindow.on('closed', () => {
mainWindow = null
})
}
app.on('ready', createWindow);
First of it is NOT a good idea to wrap a remote page unless you really know what you are doing as if you were redirected to a malicious page the page would have access to run code in the operating system. I would suggest giving this a read to make sure you're being safe.
Secondly the notification HTML5 API (runs in renderer) and notification module (runs in main) both do not have default behaviour to bring the page to the front when the notification is clicked you must add this behaviour yourself.
Because your loading a remote page you're probably using the notification module therefore it would be accomplished like follows:
notification = new Notification({title: "Message from: "+result[i].messageFrom,body: messagebody,icon: path.join(__dirname, 'assets','images','icon.png')})
notification.show()
notification.on('click', (event, arg)=>{
mainWindow.moveTop()
mainWindow.focus()
})

Expo.js: Capture event when my app goes into the background?

If I'm using my app and then switch out of it using the home button, app switcher, etc, Is there a way to reliably run some code when this event is detected? I want to do some tasks such as cancelling timers, scheduling notifications, and so on.
You can track app's state using AppState provided by 'react-native'
By using AppState.currentState you will know whether the app is in foreground, background, active or inactive. If you want to perform some tasks whenever the state changes you can use event listeners provided by AppState.
You can add the following logic in your Component to get it done -
componentDidMount() {
AppState.addEventListener('change', this.handleStateChange);
}
componentWillUnmount() {
AppState.removeEventListener('change', this.handleStateChange);
}
handleStateChange will be called every time the app moves from foreground to background or vice-versa with the app's current state passed as an argument.
For further reference see the docs
Hope it helped.

Vue 2.0.1 and Electron - Visual Flash

I'm creating an app visually similar to Alfred to manage and search for my bookmarks. Its working well, but when I do a search and open a bookmark, I immediately hide the app and when I invoke it again, it return to the default mode doing a visual flash. The reset to default is triggered right before hiding the app.
I hide the application like this : remote.app.hide() and I added a listener on win.hide in my components to reset the vue.
It works, but the reset is processed after the application show up again.
I don't know how to do it when the application is hide or to show up it right after the vue is reloaded.
If you have any clue, it would be great.
I created a sample project on Github you can clone and test this issue.
Github Project
I'm working on macOS at the moment.
Thank you.
I found an easy way, you cannot rely on the window.on('hide') event.
So in your shortcut registration, I made your app emit a custom event that your Vue.js will listen to reset your input before hiding the app:
main.js
const retShow = globalShortcut.register('CmdOrCtrl+Alt+V', () => {
if (!win.isVisible()) {
win.show()
} else {
app.emit('hide-window'); // Let the window hide the app
}
})
In your Vue.js app, in the created hook:
app.js
app.on('hide-window', function () {
vm.reset();
setTimeout(app.hide, 10);
});
Here my pull request: https://github.com/Cronos87/electron-vue-flash-issue/pull/1/files