繁体   English   中英

权限违规 - uid=10293 不允许 getConfiguredNetworks,原因=java.lang.SecurityException:UID 10293 没有位置权限

[英]Permission violation - getConfiguredNetworks not allowed for uid=10293, reason=java.lang.SecurityException: UID 10293 has no location permission

我正在开发一个应用程序,它可以在我通过扫描连接到它时共享文件,它不会在目标 sdk 版本 29 及更高版本上连接,但在目标 sdk 版本 28 上工作正常这只发生在 android 10 上。请帮助我。 它在所有 android 9 及更高版本上运行良好,但不适用于 android 10 版本。 我该怎么办请建议我,我正在遭受它。 请帮助我将非常感激。

 This is my manifest file
    <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.Anand.ShareMe">

    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE"
        tools:ignore="ProtectedPermissions" />
    <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
        tools:ignore="ScopedStorage" />
    <uses-permission android:name="android.permission.WRITE_SETTINGS"
        tools:ignore="ProtectedPermissions" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.VIBRATE" />

    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.NETWORK_SETTINGS"
        tools:ignore="ProtectedPermissions" />

    <application
        android:name="com.Anand.ShareMe.base.App"
        android:allowBackup="true"
        android:appComponentFactory="@string/app_name"
        android:fullBackupContent="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/Theme.TBShare"
        tools:ignore="GoogleAppIndexingWarning"
        tools:replace="android:appComponentFactory">

        <meta-data
            android:name="com.google.android.gms.version"
            android:value="@integer/google_play_services_version" />
        <meta-data
            android:name="com.google.android.gms.ads.APPLICATION_ID"
            android:value="@string/admob_app_id" />

        <activity
            android:name="com.Anand.ShareMe.activity.MainActivity"
            android:label="@string/app_name"
            android:launchMode="singleTask"
            android:theme="@style/Theme.TBShare.NoActionBar">

        </activity>
        <activity
            android:name="com.Anand.ShareMe.activity.ShareActivity"
            android:label="@string/app_name"
            android:theme="@style/Theme.TBShare.NoActionBar.StaticStatusBar">
            <intent-filter>
                <action android:name="genonbeta.intent.action.TBShare_SEND_TEXT" />
                <action android:name="android.intent.action.SEND" />
                <action android:name="android.intent.action.SEND_MULTIPLE" />
                <action android:name="genonbeta.intent.action.TBShare_SEND" />
                <action android:name="genonbeta.intent.action.TBShare_SEND_MULTIPLE" />

                <category android:name="android.intent.category.DEFAULT" />
                <data android:mimeType="*/*" />
            </intent-filter>


        </activity>

        <activity
            android:name="com.Anand.ShareMe.activity.AddDevicesToTransferActivity"
            android:label="@string/text_addDevicesToTransfer"
            android:theme="@style/Theme.TBShare.NoActionBar.StaticStatusBar" />

        <activity
            android:name="com.Anand.ShareMe.activity.FileExplorerActivity"
            android:label="@string/text_fileExplorer"
            android:theme="@style/Theme.TBShare.NoActionBar.StaticStatusBar" />

        <activity
            android:name="com.Anand.ShareMe.activity.ConnectionManagerActivity"
            android:label="@string/text_connectDevices"
            android:theme="@style/Theme.TBShare.NoActionBar.StaticStatusBar" />

        <activity
            android:name="com.Anand.ShareMe.activity.ContentSharingActivity"
            android:label="@string/text_send"
            android:launchMode="singleTask"
            android:theme="@style/Theme.TBShare.NoActionBar.StaticStatusBar" />

        <activity
            android:name="com.Anand.ShareMe.activity.FilePickerActivity"
            android:label="@string/text_fileExplorer" />

        <activity
            android:name="com.Anand.ShareMe.activity.ViewTransferActivity"
            android:label="@string/text_transactionViewer"
            android:theme="@style/Theme.TBShare.NoActionBar.StaticStatusBar">
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />

                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />

                <data android:scheme="file" />
                <data android:scheme="content" />
                <data android:mimeType="*/*" />

                <data android:host="*" />
                <data android:pathPattern=".*\\.tshare" />
                <data android:pathPattern=".*\\..*\\.tshare" />
            </intent-filter>
        </activity>

        <activity
            android:name="com.Anand.ShareMe.activity.ManageDevicesActivity"
            android:label="@string/text_manageDevices"
            android:theme="@style/Theme.TBShare.NoActionBar"/>

        <activity
            android:name="com.Anand.ShareMe.activity.SearchActivity"
            android:label="@string/butn_search" />

        <activity
            android:name="com.Anand.ShareMe.activity.TextEditorActivity"
            android:label="@string/text_textEditor" />

        <activity
            android:name="com.Anand.ShareMe.activity.ChangeStoragePathActivity"
            android:theme="@style/Base.Theme.AppCompat.Dialog">
            <intent-filter>
                <action android:name="com.genonbeta.intent.action.UPDATE_STORAGE_PATH" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>

        <activity
            android:name="com.Anand.ShareMe.activity.BarcodeScannerActivity"
            android:label="@string/text_scanQrCode"
            android:theme="@style/Theme.TBShare.BarcodeScannerActivity" />

        <activity
            android:name="com.Anand.ShareMe.activity.SplashActivity"
            android:label="@string/app_name"
            android:theme="@style/Theme.TBShare.NoActionBar" >

            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>

        </activity>
        <activity android:name="com.Anand.ShareMe.activity.WebShareActivity"
            android:label="Web Share"
            android:theme="@style/Theme.TBShare.NoActionBar"/>

        <provider
            android:name="androidx.core.content.FileProvider"
            android:authorities="${applicationId}.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/provider_paths" />
        </provider>

        <receiver
            android:name="com.Anand.ShareMe.receiver.NetworkStatusReceiver"
            android:process=":transfer">
            <intent-filter>
                <action android:name="android.net.wifi.WIFI_STATE_CHANGED" />
                <action android:name="android.net.wifi.WIFI_AP_STATE_CHANGED" />
                <action android:name="android.net.wifi.STATE_CHANGE" />
                <action android:name="android.net.wifi.p2p.CONNECTION_STATE_CHANGE" />
            </intent-filter>
        </receiver>
        <receiver
            android:name="com.Anand.ShareMe.receiver.DialogEventReceiver"
            android:process=":transfer" />

        <service
            android:name="com.Anand.ShareMe.service.CommunicationService"
            android:enabled="true"
            android:label="@string/text_communicationService"
            android:process=":transfer" />

        <service
            android:name="com.Anand.ShareMe.service.DeviceChooserService"
            android:label="@string/text_chooserTargetService"
            android:permission="android.permission.BIND_CHOOSER_TARGET_SERVICE">
            <intent-filter>
                <action android:name="android.service.chooser.ChooserTargetService" />
            </intent-filter>
        </service>
        <service android:name="com.Anand.ShareMe.service.DeviceScannerService">
            <intent-filter>
                <action android:name="genonbeta.intent.action.SCAN_DEVICES" />
                <action android:name="genonbeta.intent.action.ADD_IP" />

                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </service>

        <service
            android:name="com.Anand.ShareMe.service.WorkerService"
            android:label="@string/text_workerService" />

        <service
            android:name="com.Anand.ShareMe.service.CommunicationToggleTile"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/text_shareFiles"
            android:permission="android.permission.BIND_QUICK_SETTINGS_TILE"
            android:process=":transfer">
            <intent-filter>
                <action android:name="android.service.quicksettings.action.QS_TILE" />
            </intent-filter>
        </service>
    </application>


</manifest>

这是我的 ConnectionUtill 代码

package com.Anand.ShareMe.util;

import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.location.LocationManager;
import android.net.ConnectivityManager;
import android.net.DhcpInfo;
import android.net.NetworkInfo;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.util.Log;

import androidx.annotation.WorkerThread;
import androidx.core.content.ContextCompat;

import com.Anand.ShareMe.base.AppConfig;
import com.Anand.ShareMe.adapter.NetworkDeviceListAdapter;
import com.genonbeta.android.framework.util.Interrupter;

import java.util.List;

public class ConnectionUtils
{
    public static final String TAG = ConnectionUtils.class.getSimpleName();

    private Context mContext;
    private WifiManager mWifiManager;
    private HotspotUtils mHotspotUtils;
    private LocationManager mLocationManager;
    private ConnectivityManager mConnectivityManager;

    ConnectionUtils(Context context) {
        mContext = context;

        mWifiManager = (WifiManager) getContext().getApplicationContext().getSystemService(Context.WIFI_SERVICE);
        mLocationManager = (LocationManager) getContext().getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
        mHotspotUtils = HotspotUtils.getInstance(getContext());
        mConnectivityManager = (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
    }

    public static ConnectionUtils getInstance(Context context) {
        return new ConnectionUtils(context);
    }

    public static String getCleanNetworkName(String networkName) {
        if (networkName == null)
            return "";

        return networkName.replace("\"", "");
    }

    public boolean canAccessLocation() {
        return hasLocationPermission(getContext()) && isLocationServiceEnabled();
    }

    public boolean canReadScanResults() {
        return getWifiManager().isWifiEnabled() && (Build.VERSION.SDK_INT < 23 || canAccessLocation());
    }

    public boolean disableCurrentNetwork() {
        // TODO: Networks added by other applications will possibly reconnect even if we disconnect them
        // This is because we are only allowed to manipulate the connections that we added.
        // And if it is the case, then the return value of disableNetwork will be false.
        return isConnectedToAnyNetwork()
                && getWifiManager().disconnect()
                && getWifiManager().disableNetwork(getWifiManager().getConnectionInfo().getNetworkId());
    }

    @WorkerThread
    public String establishHotspotConnection(final Interrupter interrupter,
                                             final NetworkDeviceListAdapter.HotspotNetwork hotspotNetwork,
                                             final ConnectionCallback connectionCallback) {
        final int pingTimeout = 1000; // ms
        final long startTime = System.currentTimeMillis();

        String remoteAddress = null;
        boolean connectionToggled = false;
        boolean secondAttempt = false;
        boolean thirdAttempt = false;

        while (true) {
            int passedTime = (int) (System.currentTimeMillis() - startTime);

            // retry code will be here.
            if (passedTime >= 10000 && !secondAttempt) {
                secondAttempt = true;
                disableCurrentNetwork();
                connectionToggled = false;
            }

            if (passedTime >= 20000 && !thirdAttempt) {
                thirdAttempt = true;
                disableCurrentNetwork();
                connectionToggled = false;
            }

            if (!getWifiManager().isWifiEnabled()) {
                Log.d(TAG, "establishHotspotConnection(): Wifi is off. Making a request to turn it on");

                if (!getWifiManager().setWifiEnabled(true)) {
                    Log.d(TAG, "establishHotspotConnection(): Wifi was off. The request has failed. Exiting.");
                    break;
                }
            } else if (!isConnectedToNetwork(hotspotNetwork) && !connectionToggled) {
                Log.d(TAG, "establishHotspotConnection(): Requested network toggle");
                toggleConnection(hotspotNetwork);

                connectionToggled = true;
            } else {
                Log.d(TAG, "establishHotspotConnection(): Waiting to connect to the server");
                final DhcpInfo routeInfo = getWifiManager().getDhcpInfo();
                //Log.w(TAG, String.format("establishHotspotConnection(): DHCP: %s", routeInfo));

                if (routeInfo != null && routeInfo.gateway != 0) {
                    final String testedRemoteAddress = NetworkUtils.convertInet4Address(routeInfo.gateway);

                    Log.d(TAG, String.format("establishHotspotConnection(): DhcpInfo: gateway: %s dns1: %s dns2: %s ipAddr: %s serverAddr: %s netMask: %s",
                            testedRemoteAddress,
                            NetworkUtils.convertInet4Address(routeInfo.dns1),
                            NetworkUtils.convertInet4Address(routeInfo.dns2),
                            NetworkUtils.convertInet4Address(routeInfo.ipAddress),
                            NetworkUtils.convertInet4Address(routeInfo.serverAddress),
                            NetworkUtils.convertInet4Address(routeInfo.netmask)));

                    Log.d(TAG, "establishHotspotConnection(): There is DHCP info provided waiting to reach the address " + testedRemoteAddress);

                    /*if (NetworkUtils.ping(testedRemoteAddress, pingTimeout)) {
                        Log.d(TAG, "establishHotspotConnection(): AP has been reached. Returning OK state.");
                        remoteAddress = testedRemoteAddress;
                        break;
                    } else
                        Log.d(TAG, "establishHotspotConnection(): Connection check ping failed");*/

                    if (UIConnectionUtils.isOSAbove(Build.VERSION_CODES.P)
                            ? NetworkUtils.ping(testedRemoteAddress, pingTimeout)
                            : NetworkUtils.ping(testedRemoteAddress)) {
                        Log.d(TAG, "establishHotspotConnection(): AP has been reached. Returning OK state.");
                        remoteAddress = testedRemoteAddress;
                        break;
                    } else
                        Log.d(TAG, "establishHotspotConnection(): Connection check ping failed");

                } else
                    Log.d(TAG, "establishHotspotConnection(): No DHCP provided. Looping...");
            }

            if (connectionCallback.onTimePassed(1000, passedTime) || interrupter.interrupted()) {
                Log.d(TAG, "establishHotspotConnection(): Timed out or onTimePassed returned true. Exiting...");
                break;
            }

            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
                break;
            }
        }

        return remoteAddress;
    }

    public boolean hasLocationPermission(Context context) {
        return ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED;
    }

    public Context getContext() {
        return mContext;
    }

    public ConnectivityManager getConnectivityManager() {
        return mConnectivityManager;
    }

    public HotspotUtils getHotspotUtils() {
        return mHotspotUtils;
    }

    public LocationManager getLocationManager() {
        return mLocationManager;
    }

    public WifiManager getWifiManager() {
        return mWifiManager;
    }

    public boolean isConnectionSelfNetwork() {
        WifiInfo wifiInfo = getWifiManager().getConnectionInfo();

        return wifiInfo != null
                && getCleanNetworkName(wifiInfo.getSSID()).startsWith(AppConfig.PREFIX_ACCESS_POINT);
    }

    public boolean isConnectedToAnyNetwork() {
        NetworkInfo info = getConnectivityManager().getActiveNetworkInfo();

        return info != null
                && info.getType() == ConnectivityManager.TYPE_WIFI
                && info.isConnected();
    }

    public boolean isConnectedToNetwork(NetworkDeviceListAdapter.HotspotNetwork hotspotNetwork) {
        if (!isConnectedToAnyNetwork())
            return false;

        if (hotspotNetwork.BSSID != null)
            return hotspotNetwork.BSSID.equals(getWifiManager().getConnectionInfo().getBSSID());

        return hotspotNetwork.SSID.equals(getCleanNetworkName(getWifiManager().getConnectionInfo().getSSID()));
    }

    public boolean isLocationServiceEnabled() {
        return mLocationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
    }

    public boolean isMobileDataActive() {
        return mConnectivityManager.getActiveNetworkInfo() != null
                && mConnectivityManager.getActiveNetworkInfo().getType() == ConnectivityManager.TYPE_MOBILE;
    }

    public boolean toggleConnection(NetworkDeviceListAdapter.HotspotNetwork hotspotNetwork) {
        if (!isConnectedToNetwork(hotspotNetwork)) {
            if (isConnectedToAnyNetwork())
                disableCurrentNetwork();

            /*WifiConfiguration config = new WifiConfiguration();
            config.allowedAuthAlgorithms.clear();
            config.allowedGroupCiphers.clear();
            config.allowedKeyManagement.clear();
            config.allowedPairwiseCiphers.clear();
            config.allowedProtocols.clear();*/

            WifiConfiguration config = new WifiConfiguration();

            config.SSID = String.format("\"%s\"", hotspotNetwork.SSID);

            switch (hotspotNetwork.keyManagement) {
                case 0: // OPEN
                    config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
                    break;
                case 1: // WEP64
                    config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
                    config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
                    config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED);
                    config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);

                    if (hotspotNetwork.password != null
                            && hotspotNetwork.password.matches("[0-9A-Fa-f]*")) {
                        config.wepKeys[0] = hotspotNetwork.password;
                    } else {
                        //fail("Please type hex pair for the password");
                    }
                    break;
                case 2: // WEP128
                    config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
                    config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
                    config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED);
                    config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);

                    if (hotspotNetwork.password != null
                            && hotspotNetwork.password.matches("[0-9A-Fa-f]*")) {
                        config.wepKeys[0] = hotspotNetwork.password;
                    } else {
                        //fail("Please type hex pair for the password");
                    }
                    break;
                case 3: // WPA_TKIP
                    config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
                    config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
                    config.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
                    config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
                    config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);

                    if (hotspotNetwork.password != null
                            && hotspotNetwork.password.matches("[0-9A-Fa-f]{64}")) {
                        config.preSharedKey = hotspotNetwork.password;
                    } else {
                        config.preSharedKey = '"' + hotspotNetwork.password + '"';
                    }
                    break;
                case 4: // WPA2_AES
                    config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
                    config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
                    config.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
                    config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
                    config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
                    config.allowedProtocols.set(WifiConfiguration.Protocol.RSN);

                    if (hotspotNetwork.password != null
                            && hotspotNetwork.password.matches("[0-9A-Fa-f]{64}")) {
                        config.preSharedKey = hotspotNetwork.password;
                    } else {
                        config.preSharedKey = '"' + hotspotNetwork.password + '"';
                    }
                    break;
            }

            /*
            old wifi connectivity code works for below M
            int netId = getWifiManager().addNetwork(config);
            getWifiManager().disconnect();
            getWifiManager().enableNetwork(netId, true);
            return getWifiManager().reconnect();*/

            try {
                int netId = getWifiManager().addNetwork(config);

                if (/*Build.VERSION.SDK_INT >= */UIConnectionUtils.isOSAbove(Build.VERSION_CODES.M)) {
                    List<WifiConfiguration> list = getWifiManager().getConfiguredNetworks();
                    for (WifiConfiguration hotspotWifi : list) {
                        if (hotspotWifi.SSID != null && hotspotWifi.SSID.equalsIgnoreCase(config.SSID)) {
                            getWifiManager().disconnect();
                            getWifiManager().enableNetwork(hotspotWifi.networkId, true);
                            return getWifiManager().reconnect();
                        }
                    }
                } else {
                    getWifiManager().disconnect();
                    getWifiManager().enableNetwork(netId, true);
                    return getWifiManager().reconnect();
                }
            } catch (Exception exp) {
                disableCurrentNetwork();
                return false;
            }
        }

        disableCurrentNetwork();

        return false;
    }

    public interface ConnectionCallback {
        boolean onTimePassed(int delimiter, long timePassed);
    }
}

这是我的堆栈跟踪

在清单中指定位置权限是不够的,您还需要实际请求它(就像您对WRITE_EXTERNAL_STORAGEREAD_PHONE_STATE的那样)。 这就是您在日志中看到SecurityException: UID 10293 has no location permission的原因。

您偶然发现的确实是 Android 10 中的新内容 请注意,这只是一个记录在此处的错误。 您的应用不应崩溃,它只会从getConfiguredNetworks接收到一个空列表(并打印这些日志)。

但是,一旦您成功请求权限,您可能最终会被下一次检查捕获(除非您的应用程序是运营商应用程序)。 因此,您可能需要重新考虑是否要以 API 29 为目标(从长远来看不现实)或考虑其他解决方案来实现您的功能。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM