When calling textfield on flutter in fireOS in the fire tv devices, to do a search for example the fireOS virtual keyboard pops on top of textfield and doesnt work like on other android devices where the keyboard is on the bottom and textfield is visible.
On android legacy for example i can use edittext widget and the same keyboard pops on top but whatever i type with the controller updates on the virtual keyboard itself, because the keyboard has its own textfield or edittext. So my problem is how could i update the edittext on firetv virtual keyboard with flutter.
Okay, so I didnt find an answer anywhere so I had to do some hacky stuff heres how i got it to work since flutter is a no go.
Solution Overview:
1.- So first check is you are running on Android, you can do this with if (Platform.isAndroid) on flutter.
2.- If you are actually running on android you can then open a platform channel to native android to check the actual manufacturer(I will post how to code below).
3.- Check manufacturer or device name for "Amazon" or "Kindle" or whatever an if(string.contains("")) will do the trick.
4.- Open again a platform channel to Native Android and open an Alert Dialog with an Edittext, capture the resulting string and return it to flutter.
And thats how i got firetv's keyboard to work under flutter.
if (Platform.isAndroid){
checkOs().then((String osName){
print("Device running on: $osName");
if(osName.contains("Amazon") || osName.contains("AFTN")){
fireTvKeyboardInput().then((String result){
buscarTitulo(result);
});
}else{
_showDialog(); // Keyboard for NON FIREOS devices on Android.
}
});
}else{
//IF Device is not Android Eg. IOS
_showDialog();
}
Now theres two functions i used "checkOs" and "fireTvKeyboardInput" heres the code:
Future<String> checkOs() async {
String myResult = "";
try {
myResult = await platform.invokeMethod("checkOS", <String, dynamic>{
'param1': "hello",
});
}catch (e){
print ("exception: $e");
}
return myResult;
}
Future<String> fireTvKeyboardInput() async {
String myResult = "";
try {
myResult = await platform.invokeMethod("fireKeyBoard", <String, dynamic>{
'param1': "hello",
});
}catch (e){
print ("exception: $e");
}
return myResult;
}
On Native Android heres the code:
if(call.method == "checkOS"){
val operatingSystem = android.os.Build.MANUFACTURER + "- " + android.os.Build.MODEL
result.success(operatingSystem)
}
if(call.method == "fireKeyBoard"){
val alert = AlertDialog.Builder(this)
alert.setMessage("Search")
// Set an EditText view to get user input
val input = EditText(this)
input.hint = "Enter Text"
input.inputType = InputType.TYPE_CLASS_TEXT
alert.setView(input)
input.setOnKeyListener { view, keyCode, keyEvent ->
if (keyCode == 66) {
val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
imm.hideSoftInputFromWindow(input.windowToken, 0)
}
false
}
alert.setPositiveButton("Ok") { dialog, whichButton ->
result.success(input.text.toString());
}
alert.setNegativeButton("Cancel") { dialog, whichButton ->
// Canceled.
}
alert.show()
}
Related
I have to develop app which Scans for available Wi-Fi networks, then connect to these network,
So For this which package if best?
I have Flutter version 3.0.4, wifi_iot: ^0.3.17,
I used above package but its deprecated, So please any Suggestion to which package should I use?
Below is My Code to scan networks but i can not get any networks.
getWifis() async {
isEnabled = await WiFiForIoTPlugin.isEnabled();
isConnected = await WiFiForIoTPlugin.isConnected();
htNetworkResult = await loadWifiList();
setState(() {});
if (isConnected) {
WiFiForIoTPlugin.getSSID().then((value) => setState(() {
ssid = value!;
}));
}
}
Future<List<WifiNetwork>> loadWifiList() async {
List<WifiNetwork> htResultNetwork;
try {
htResultNetwork = await WiFiForIoTPlugin.loadWifiList();
} on PlatformException {
htResultNetwork = <WifiNetwork>[];
}
return htResultNetwork;
}
The plugin is not the problem here. It's the changes that had came with the android versions. You cannot get list of available Wi-Fi networks on the Android devices that are running on Android 10 or above. You can get the floating Wi-Fi panel that shows all the available Wi-Fi networks.
It can easily be done through native channel.
On the native side, you can make changes like this:
private val CHANNEL = "flutter. Native/wifi"
private lateinit var channel: MethodChannel
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
var wifiManager = this.context.applicationContext.getSystemService(WIFI_SERVICE) as WifiManager
val mBluetoothAdapter: BluetoothAdapter = BluetoothAdapter.getDefaultAdapter()
channel = MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL)
channel.setMethodCallHandler { call, result ->
if (call.method == "wifi"){
println(!wifiManager.isWifiEnabled)
if(Build.VERSION.SDK_INT <= Build.VERSION_CODES.Q){
val wifiManager: WifiManager =
this.context.applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager
wifiManager.setWifiEnabled(!wifiManager.isWifiEnabled)
}
else{
val panelIntent = Intent(Settings.Panel.ACTION_INTERNET_CONNECTIVITY)
startActivityForResult(panelIntent, 0)
}
}
Make sure to make these changes in the MainActivity class.
Then on the flutter side, you can create a function and then call it on button press:
getWifi(){
static const Channel = MethodChannel('flutter. Native/uninstall');
await Channel.invokeMethod('wifi');
}
Hope it helps. :-)
I'm using Zxing barcode scanner and Rg Pop up pages in Xamarin forms. The whole idea is that when the camera catches a barcode it displays a pop up. The problem is that I want to wait for the user to close the pop up before it scans again. Now if I keep the camera towards a barcode it keeps showing multiple alerts.
public async void Scan(Result result)
{
//random linq to get product
if (product != null)
{
await PopupNavigation.PushAsync(new DisplayDialog(product));
}
}
Method for when user closes the window
private async void Button_OnClicked(object sender, EventArgs e)
{
await PopupNavigation.RemovePageAsync(this);
}
I tried using a flag to stop the scan and setting isScanning or isAnalyzing to false but it didnt work. Any ideas? Thank you!
use a bool to control the flow
bool popup = false;
public async void Scan(Result result)
{
if (popup) return;
//random linq to get product
if (product != null)
{
popup = true;
await PopupNavigation.PushAsync(new DisplayDialog(product));
}
}
then whenever your popup is dismissed, reset the popup flag to false
Unable to get Input using Custom Keyboards in an Unity App , both iOS and Android.
private var keyboard : TouchScreenKeyboard;
var text : String = "";
function Start() {
keyboard = TouchScreenKeyboard.Open(text, TouchScreenKeyboardType.Default);
}
function Update() {
if (keyboard != null && keyboard.done)
{
text = keyboard.text;
print ("User input is: " + text);
}
}
Did you try this?
Iam new to flutter,tried hello_services example provided by flutter.io .
in that example both flutter view and native view are in same screen.
My question is, how to navigate to two different screens like one written in flutter and another in native(android/ios) with params or extras.Please help !!!! thanks
The only solution I found, it is to send a message to your native view (https://flutter.io/platform-services/), catch the message in Java or Swift/ObjectiveC code then navigate to the other view.
Dart Code
Map params = <String, dynamic>{
"view": "MyView"
};
PlatformMessages.sendJson("navigateTo", params);
Java Code
flutterView.addOnMessageListener("navigateTo", new FlutterView.OnMessageListener() {
#Override
public String onMessage(FlutterView view, String message) {
try {
JSONObject object = new JSONObject(message);
if (object.getString("view") == "MyView") {
// navigate to MyView
}
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
});
I am displaying a dialog while launching the app, and user has to click on that dialog to move on for next screens, so dialog should not close if user press back/search buttons of the device.
dialog.setCancleble() is working for back button but not for search button.
So, what should I implement to achieve this?
You have to override the Key Event in your Activity. Here is a little snippet which catches few Key Events,
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_MENU) {
// PhysicalMenuClicked=true;
}
if(keyCode==KeyEvent.KEYCODE_BACK)
{
// CustomDialog.exitApp_Dialog(context);
}
if(keyCode==KeyEvent.KEYCODE_SEARCH && event.getRepeatCount() == 0)
{
return true; //true means that we are handling the event here.
}
return true;
}