簡體   English   中英

Flutter 連接 Package:Android 權限

[英]Flutter Connectivity Package: Android Permissions

我在 Flutter 應用程序中使用來自https://pub.dev/packages/connectivity#-example-tab-的示例代碼,並且在 Android 應用程序上運行應用程序時,請參閱調試程序網絡。 但是,當我在我的 Pixel 4XL 上運行該應用程序時,我會得到 null 以獲取 Wi-Fi 名稱和 BSSID。

我假設我必須啟用訪問 Wi-Fi 設置的權限才能使用此 package,但我在任何地方都找不到任何參考資料來描述 ZC047B10EEE761CC264C078 上此 package 所需的內容

我使用 Wi-Fi package 示例中的 Wi-Fi 權限更新了 Android 應用程序 appmanifest 文件,但我的應用程序沒有任何變化。

我創建了一個示例應用程序來演示解決方案,但顯然 Stack Overflow 的人們希望我更加努力地與您分享這些信息。 他們刪除了我原來的答案(盡管它為每個有問題的人解決了問題)。 並希望我提取部分答案並將其張貼在這里。 我做了很多工作來解決這個問題並將它作為一個完整的應用程序示例發布,但顯然這還不夠。 我討厭這個。 我正在嘗試幫助人們,但他們不喜歡對解決方案的外部引用。

我創建了一個完整的解決方案來演示如何在https://github.com/johnwargo/flutter-android-connectivity-permissions中解決這個問題。

Flutter 似乎沒有辦法查詢應用程序用戶的權限,所以有人創建了 Flutter permissions_handler package。 將它添加到我的應用程序以及原始問題中顯示的代碼變體解決了我的問題。

我很快意識到 Flutter repo 上的答案是不完整的,任何嘗試實施此解決方案的人都需要一些幫助。 為了讓這些開發人員更容易,我在這個 repo 中創建了一個完整的示例應用程序。

這就是我所做的

從項目的pubspec.yaml文件開始,我添加了連接和權限處理程序包:

dependencies:
  flutter:
    sdk: flutter

  cupertino_icons: ^0.1.3
  connectivity: ^0.4.8+6  
  permission_handler: ^5.0.1

接下來,我將導入添加到項目的main.dart文件中:

import 'package:connectivity/connectivity.dart';
import 'package:permission_handler/permission_handler.dart';

然后我在initConnectivity function 中添加了一些代碼:

Future<void> initConnectivity() async {
  ConnectivityResult result;
  // Platform messages may fail, so we use a try/catch PlatformException.
  try {
    result = await _connectivity.checkConnectivity();
  } on PlatformException catch (e) {
    print(e.toString());
  }

  // If the widget was removed from the tree while the asynchronous platform
  // message was in flight, we want to discard the reply rather than calling
  // setState to update our non-existent appearance.
  if (!mounted) {
    return Future.value(null);
  }

  // Check to see if Android Location permissions are enabled
  // Described in https://github.com/flutter/flutter/issues/51529
  if (Platform.isAndroid) {
    print('Checking Android permissions');
    var status = await Permission.location.status;
    // Blocked?
    if (status.isUndetermined || status.isDenied || status.isRestricted) {
      // Ask the user to unblock
      if (await Permission.location.request().isGranted) {
        // Either the permission was already granted before or the user just granted it.
        print('Location permission granted');
      } else {
        print('Location permission not granted');
      }
    } else {
      print('Permission already granted (previous execution?)');
    }
  }

  return _updateConnectionStatus(result);
}

我添加的代碼是:

// Check to see if Android Location permissions are enabled
// Described in https://github.com/flutter/flutter/issues/51529
if (Platform.isAndroid) {
  print('Checking Android permissions');
  var status = await Permission.location.status;
  // Blocked?
  if (status.isUndetermined || status.isDenied || status.isRestricted) {
    // Ask the user to unblock
    if (await Permission.location.request().isGranted) {
      // Either the permission was already granted before or the user just granted it.
      print('Location permission granted');
    } else {
      print('Location permission not granted');
    }
  } else {
    print('Permission already granted (previous execution?)');
  }
}

此代碼在啟動時執行一次,並在從設備檢索連接狀態之前檢查權限。

如果此時運行代碼,似乎一切正常,但 Wi-Fi 名稱、BSSID 和 IP 地址的值都會報告null 當您查看控制台時,您會看到:

I/flutter ( 6506): Checking Android permissions
I/flutter ( 6506): Result: ConnectivityResult.wifi
D/permissions_handler( 6506): No permissions found in manifest for: 3
I/flutter ( 6506): Wi-Fi Name: null
D/permissions_handler( 6506): No permissions found in manifest for: 3
I/flutter ( 6506): Location permission not granted
I/flutter ( 6506): Result: ConnectivityResult.wifi
I/flutter ( 6506): BSSID: 02:00:00:00:00:00
I/flutter ( 6506): Wi-Fi Name: null
I/flutter ( 6506): BSSID: 02:00:00:00:00:00

這是因為如果沒有在應用程序中定義正確的權限, status值為null並且不會發生其他權限檢查。 甚至從未像預期的那樣要求用戶許可。

要解決這個問題,請打開項目的android/app/src/main/AndroidManifest.xml文件並將位置權限添加到應用程序的配置中:

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

我使用了課程設置,我認為您也可以使用罰款。

很多時候,作者會告訴您要進行哪些權限更改,但沒有告訴您應該在文件中的哪個位置進行更改。 我沒有做很多原生 Android 開發,所以我不知道該設置在哪里,所以這里是完整的文件列表,所以你可以看到它的正確位置:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.johnwargo.connectivitypermissions">
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <application
        android:name="io.flutter.app.FlutterApplication"
        android:label="connectivitypermissions"
        android:icon="@mipmap/ic_launcher">
        <activity
            android:name=".MainActivity"
            android:launchMode="singleTop"
            android:theme="@style/LaunchTheme"
            android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
            android:hardwareAccelerated="true"
            android:windowSoftInputMode="adjustResize">
            <!-- Specifies an Android theme to apply to this Activity as soon as
                 the Android process has started. This theme is visible to the user
                 while the Flutter UI initializes. After that, this theme continues
                 to determine the Window background behind the Flutter UI. -->
            <meta-data
              android:name="io.flutter.embedding.android.NormalTheme"
              android:resource="@style/NormalTheme"
              />
            <!-- Displays an Android View that continues showing the launch screen
                 Drawable until Flutter paints its first frame, then this splash
                 screen fades out. A splash screen is useful to avoid any visual
                 gap between the end of Android's launch screen and the painting of
                 Flutter's first frame. -->
            <meta-data
              android:name="io.flutter.embedding.android.SplashScreenDrawable"
              android:resource="@drawable/launch_background"
              />
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
        <!-- Don't delete the meta-data below.
             This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
        <meta-data
            android:name="flutterEmbedding"
            android:value="2" />
    </application>
</manifest>

當您在 Android API 29 上啟動應用程序時,它看起來像這樣:

對於我的特定應用程序,我不關心在應用程序未運行時從設備獲取設置,因此我選擇了“僅在使用應用程序時允許”。 如果您查看控制台,您將看到以下內容:

I/flutter ( 7670): Checking Android permissions
I/flutter ( 7670): Result: ConnectivityResult.wifi
I/flutter ( 7670): Wi-Fi Name: null
I/flutter ( 7670): BSSID: 02:00:00:00:00:00
I/flutter ( 7670): Location permission granted
I/flutter ( 7670): Result: ConnectivityResult.wifi
I/flutter ( 7670): Wi-Fi Name: AndroidWifi
I/flutter ( 7670): BSSID: 02:15:b2:00:01:00

請注意,該應用程序會在等待用戶授予權限時繼續檢查 Wi-Fi 設置; 那是因為代碼的編寫方式,您可以輕松地對其進行調整,以便在嘗試之前等待許可,但它會運行兩次 init,因此您將第二次獲得正確的數據(不,我不知道為什么它運行兩次)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM