I’m creating an augmented reality app that relies on the DeviceMotion API in DangerZone. This works perfectly in IOS but when attempting to use in Android I receive an “Expected to run on UI thread!” error. I did not see in the docs that DeviceMotion was only meant for IOS, but that appears to be the case?
Is there another way to get these events for Android? (I realize I can calculate pitch and roll from the Accelerometer events, but azimuth is another matter). I’d prefer not to detach to ExpoKit if I can help it. Any help would be appreciated!
Hi @estesjl - DeviceMotion should work on both iOS and Android. Could you provide more details about the error you’re seeing (e.g. stacktrace), and maybe share the code that’s producing it?
Code itself is pretty simple. Your basic call to DeviceMotion, and it works perfectly on IOS. However Android ignores these lines. If I put a console log inside the listener, it is never triggered. I only receive an error when I trigger a back action on unmount. I’m using version 25 of the SDK, everything is updated. My hunch is that it is somehow trying to run tasks in the background when it shouldn’t (such as the similar issue here: https://github.com/facebook/react-native/issues/15915), though I don’t know why this would be.
Here’s a picture of the error, and the code is below it. Let me know if there’s anything else that could be helpful.
Hey @estesjl - thanks for the code. I’ve reproduced the issue you described about not seeing the listener triggered, and also your crash by calling DeviceMotion.removeAllListeners(). @sjchmiela - can you help?
Update: I ended up resolving this by using the Expo code in DeviceMotionModule.java inside my own React Native module. I edited MainApplication.java to look like the following:
package host.exp.exponent;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage;
import java.util.Arrays;
import java.util.List;
// Needed for `react-native link`
import com.facebook.react.ReactApplication;
import com.facebook.react.shell.MainReactPackage;
import com.sensormanager.SensorManagerPackage;
public class MainApplication extends ExpoApplication implements ReactApplication {
@Override
public boolean isDebug() {
return BuildConfig.DEBUG;
}
// Needed for `react-native link`
public List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
// Add your own packages here!
// TODO: add native modules!
// Needed for `react-native link`
// new MainReactPackage(),
new SensorManagerPackage(),
);
}
@Override
public String gcmSenderId() {
return getString(R.string.gcm_defaultSenderId);
}
@Override
public boolean shouldUseInternetKernel() {
return BuildVariantConstants.USE_INTERNET_KERNEL;
}
@Override
public ReactNativeHost getReactNativeHost() {
return mReactNativeHost;
}
private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
@Override
public boolean getUseDeveloperSupport() {
return BuildConfig.DEBUG;
}
@Override
protected List<ReactPackage> getPackages() {
return MainApplication.this.getPackages();
}
};
}
On top of this, I had to revert back to gradle version 2.2.3 from 3.0.1. I did this so I could run a buildToolsversion at 23.0.1, which is the most recent version that appears to work with module linking in my code.