rmtmckenzie / flutter_native_device_orientation

Native device orientation plugin for flutter.
MIT License
75 stars 63 forks source link

Does not work if using SystemChrome.setPreferredOrientations #17

Open timolehto opened 4 years ago

timolehto commented 4 years ago

We're limit the preferred orientations to just landscapes. However, we'd like to show a camera preview and order to be able to rotate it properly we'd need to know if the device is in landscape right or left mode. This plugin would solve the problem, but it doesn't work if we enforce landscape modes using

SystemChrome.setPreferredOrientations([
  DeviceOrientation.landscapeRight,
  DeviceOrientation.landscapeLeft,
])

This is happening at least with:

flutter --version                                                                                                                                                                   Flutter 1.12.13+hotfix.8 • channel stable • https://github.com/flutter/flutter.git
Framework • revision 0b8abb4724 (6 weeks ago) • 2020-02-11 11:44:36 -0800
Engine • revision e1e6ced81d
Tools • Dart 2.7.0

Here's a minima repro with freshly created flutter project https://github.com/timolehto/flutter_native_orientation_with_preferred_orientations

rmtmckenzie commented 4 years ago

Have you tried with useSensor:true?

timolehto commented 4 years ago

I haven't, but suppose that should work as then it doesn't rely on the OS level processes, but I would have expected things to work without having to rely on the sensors as well. I would have rather wanted to just rely on the OS level configuration change that when the landscape layout rotates from right side up to left side up I could also rotate my camera preview. Using in built sensors logic means the layout and the preview would use entirely different logic to detect when to rotate and thus there's greater change for these to be out of sync.

timolehto commented 4 years ago

Wow, I see. It seems to be simply impossible to detect configuration changes from landscape to reverse landscape on Android. The broadcast is not emitted, onConfigurationChanged isn't fired, nada.. I've never really done much orientation locked apps so I hadn't ran into this issue before. I suppose there's no other way then. Highly unlikely that AOSP will fix this any time soon since I suppose it's been like this basically forever.

Maybe the readme could be revised a bit to make this more clear and how the sensory thing fixes this?

Also, at least to me it is quite unexpected that even though my orientation is locked to landscape, plugin still reports all orientations and also has to do it's own calculations which may or may not be in sync with what the OS thinks the orientation is. I would rather see this method being applied: https://nickcarter9.github.io/en/2019/11/21/2019_11_21-reverselandscape-event/ Here we only listen to the onOrienationChanged event to get woken up by changes in orientation and the we ask the WindowManager to give us the current rotation. If it's different from the previous rotation then, we have a change in rotation. The rotation is also in sync with the OS and does not give "illegal" rotations. Ofc this would be a breaking change and I suppose others might have come up with valid uses for the "illegal" orientation information as well.. maybe they have some sort of static frame, but within it they have something that they want to rotate with the device.. so I guess introducing it would require fair bit of thinking and perhaps both ways would need to be supported. What do you think?

rmtmckenzie commented 4 years ago

Yeah unfortunately a lot of android things just check landscape vs portrait and so aren't that useful.

Essentially the reason I made the app the way I did is that I wanted people to be able to detect whether the app window rotates to landscape right vs left - the main reason was to be able to rotate a camera preview back to the right orientation which only needs to be done when the 'window' actually rotates. I've actually never tried this out with an app that doesn't allow portrait though, so that's interesting. I would expect the plugin to still report a change so this does actually sound like a bug.

The reason for the "sensor" would be to make an app like Youtube for example - even when have your app locked to portrait, when you play a video it fullscreens/switches to the right orientation.

I'd have to do some testing of the method you've proposed, because as you said it'll have different behaviour. I'd need to check that it doesn't report orientations that aren't allowed (i.e. if you set the preferred orientations to LandscapeLeft and LandscapeRight, I don't want to be reporting back PortaitUp). And there's the added fun of what happens on a phone with autorotate enabled vs not enabled. But if it doesn't report incorrect orientations, that would actually be a good change to the plugin and I'd be happy to accept a PR (or I'll take a look at some point, but don't count on it being in the next couple days).

If it does report disallowed orientations anyways, I still wouldn't be opposed to a PR, but I'd want to either put it behind a flag like useSensor so as not to change the current behaviour, or maybe use this method in conjunction with ConfigurationChanged so as to only report changes from one landscape to the other.

timolehto commented 4 years ago

@rmtmckenzie here's something I cooked up: https://github.com/timolehto/flutter_native_device_orientation

Maybe you'd like to do something like this?

w3ggy commented 3 years ago

The reason for the "sensor" would be to make an app like Youtube for example - even when have your app locked to portrait, when you play a video it fullscreens/switches to the right orientation.

What about the "Lock orientation" button? I could not find any solution for that. Sensors continue working if this button is enabled on both platforms. There is no API for getting its value. I manually set orientations via .onOrientationChanged(useSensor: true) and it works fine but I don't know how to stop switching orientations if the "Lock orientation" is enabled.