Android 开发中问题收集(一)

问题一:文件上传是进度出现负数?

问题描述:公共上传插件中,反馈上传大文件插件时候,上传进度在56%之后会出现出现进度为负数的情况如-57%。

进度计算方式:上传进度=累计上传大小*100/文件总大小

问题分析:通过检查代码和log输入,并没有发现有相关的负数的赋值,上传小一点的文件就不会有相关的问题,初步定位和文件大小有关系,并检查存储累计上传文件大小的数值范围和变量类型,发现变量类型为 int 而int 类型的最大值为 2^31-1 ,当文件比较大的时候,累计上传大小就会超过这个int类型的最大值所以就出现了负数。

解决方法: 将存储变量类型改为比int更大的整形数据类型,于是修改成long类型就行了。具体还要不要更大根据项目需要 更大还有BigInteger

忽略知识点: Java的基本类型和基本类型的取值范围

问题二:显示内容被底部导航栏遮挡?

问题描述:使用相册公共插件(uexImage)时候,显示的图片的部分内容被带有虚拟按键遮挡住无法操作了。

问题分析:显示内容试图view没有考虑底部导航栏的情况

解决方法 计算view大小要把底部导航栏考虑进去

知识点:怎么计算底部导航的高度
计算方式借鉴于网上 https://blog.csdn.net/xu20082100226/article/details/80098958

	/** 
	1 .获取底部导航栏
	**/
	private int getNavigationBarHeight() {
	    Resources resources = mActivity.getResources();
	    int resourceId = resources.getIdentifier("navigation_bar_height","dimen", "android");
	    int height = resources.getDimensionPixelSize(resourceId);
	    Log.v("dbw", "Navi height:" + height);
	    return height;
	}
		/** 
            2. 获取是否存在NavigationBar
	     **/
	
    public static boolean checkDeviceHasNavigationBar(Context context) {
        boolean hasNavigationBar = false;
        Resources rs = context.getResources();
        int id = rs.getIdentifier("config_showNavigationBar", "bool", "android");
        if (id > 0) {
            hasNavigationBar = rs.getBoolean(id);
        }
        try {
            Class systemPropertiesClass = Class.forName("android.os.SystemProperties");
            Method m = systemPropertiesClass.getMethod("get", String.class);
            String navBarOverride = (String) m.invoke(systemPropertiesClass, "qemu.hw.mainkeys");
            if ("1".equals(navBarOverride)) {
                hasNavigationBar = false;
            } else if ("0".equals(navBarOverride)) {
                hasNavigationBar = true;
            }
        } catch (Exception e) {
 
        }
        return hasNavigationBar;
 
    }
	    	/** 
		3.获取状态栏高度
		**/
	private int getStatusBarHeight() {
	    Resources resources = mActivity.getResources();
	    int resourceId = resources.getIdentifier("status_bar_height", "dimen","android");
	    int height = resources.getDimensionPixelSize(resourceId);
	    Log.v("dbw", "Status height:" + height);
	    return height;

问题三:关闭wifi的时候请求网络总是提示开启wifi提示框?

问题描述:在使用EMM插件进行启动上报和登陆的时候,在没有开启WiFi和2g/3g/4g/5g的时候总是弹出开启WiFi的提示框,应开发者要求取消该提示

问题分析:根据问题描述、项目负责人员沟通、项目打log发现,最近新加功能后出现的问题,回想最新新加功能也就是在启动上报和登陆接口新增加了ip地址和手机型号参数,怎么会导致这样的问题?最后怀疑是新增获取IP地址出现这个问题,最终插件代码发现是在没有WiFi和移动网络的情况下,主动去调用系统的开启wifi提示 。

解决方法 去掉主动开启WiF提示

........
 //wifiManager.setWifiEnabled(true);
 .......

知识点:获取手机IP地址
代码参考网上

import android.content.Context;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.telephony.TelephonyManager;

import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.util.Enumeration;

/**
 * Created by zhang on 2018/9/15.
 */

public class IpAdressUtils {
    /**
     * gps获取ip
     *
     * @return
     */
    public static String getLocalIpAddress() {
        try {
            for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements(); ) {
                NetworkInterface intf = en.nextElement();
                for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements(); ) {
                    InetAddress inetAddress = enumIpAddr.nextElement();
                    if (!inetAddress.isLoopbackAddress()) {
                        return inetAddress.getHostAddress().toString();
                    }
                }
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return null;
    }

    /**
     * wifi获取ip
     *
     * @param context
     * @return
     */
    public static String getIp(Context context) {
        try {
            //获取wifi服务
            WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
            //判断wifi是否开启
            if (!wifiManager.isWifiEnabled()) {
//                wifiManager.setWifiEnabled(true);
                return null;
            }
            WifiInfo wifiInfo = wifiManager.getConnectionInfo();
            int ipAddress = wifiInfo.getIpAddress();
            String ip = intToIp(ipAddress);
            return ip;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 格式化ip地址(192.168.11.1)
     *
     * @param i
     * @return
     */
    private static String intToIp(int i) {

        return (i & 0xFF) + "." +
                ((i >> 8) & 0xFF) + "." +
                ((i >> 16) & 0xFF) + "." +
                (i >> 24 & 0xFF);
    }

    /**
     * 3G/4g网络IP
     */
    public static String getIpAddress() {
        try {
            for (Enumeration<NetworkInterface> en = NetworkInterface
                    .getNetworkInterfaces(); en.hasMoreElements(); ) {
                NetworkInterface intf = en.nextElement();
                for (Enumeration<InetAddress> enumIpAddr = intf
                        .getInetAddresses(); enumIpAddr.hasMoreElements(); ) {
                    InetAddress inetAddress = enumIpAddr.nextElement();
                    if (!inetAddress.isLoopbackAddress()
                            && inetAddress instanceof Inet4Address) {
                        // if (!inetAddress.isLoopbackAddress() && inetAddress
                        // instanceof Inet6Address) {
                        return inetAddress.getHostAddress().toString();
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 获取本机的ip地址(3中方法都包括)
     *
     * @param context
     * @return
     */
    public static String getIpAdress(Context context) {
        String ip = null;
        try {
            ip = getIp(context);
            if (ip == null) {
                ip = getIpAddress();
                if (ip == null) {
                    ip = getLocalIpAddress();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ip;
    }



    public static String getDeviceId(Context context){
        TelephonyManager telephonyManager = (TelephonyManager) context
                .getSystemService(Context.TELEPHONY_SERVICE);
        return telephonyManager.getDeviceId();
    }
}

问题四:在不同窗口分别打开高德地图,地图view重叠?

问题描述:某个项目上使用高德地图插件,在浮动窗口打开一次高德地图,然后点击地图标记重新打开一个高德地图,发现显示两层地图View 之前打开在上层,并且不能操作

问题分析:高德地图的地图view的问题

解决方法 把之前 MapView 替换成 TextureMapView

问题五: 浮动窗口不显示?

问题描述:某项目,定制插件显示系统悬浮框,在target 28上不显示,在target 14上就能显示

错误信息

android.view.WindowManager$BadTokenException: Unable to add window android.view.ViewRootImpl$W@123e0ab -- permission denied for this window typ

问题分析:在不同target比较低的时候就能显示,目标版本比较高的时候就不显示,初步定位是高版本的是系统的升级过程中发生了变化,查看官网描述有关于悬浮框的更新。

官方描述:如果应用使用 SYSTEM_ALERT_WINDOW 权限并且尝试使用以下窗口类型之一来在其他应用和系统窗口上方显示提醒窗口:

TYPE_PHONE
TYPE_PRIORITY_PHONE
TYPE_SYSTEM_ALERT
TYPE_SYSTEM_OVERLAY
TYPE_SYSTEM_ERROR
…那么,这些窗口将始终显示在使用 TYPE_APPLICATION_OVERLAY 窗口类型的窗口下方。如果应用针对的是 Android 8.0,则应用会使用 TYPE_APPLICATION_OVERLAY 窗口类型来显示提醒窗口。

解决方法 根据官方描述,把之前的typeTYPE_PHONE类型在8.0以上修改TYPE_APPLICATION_OVERLAY
知识点:显示系统悬浮框,在6.0以上需要动态去申请悬浮框权限,在8.0以上要type类型修改为TYPE_APPLICATION_OVERLAY
申请悬浮框权限 :参考网上

if (Build.VERSION.SDK_INT >= 23) {
            if (!Settings.canDrawOverlays(this)) {
                Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                startActivityForResult(intent, 1);
            } else {
                //TODO do something you need
            }
        }
发布了100 篇原创文章 · 获赞 75 · 访问量 8万+

猜你喜欢

转载自blog.csdn.net/baidu_31956557/article/details/89299842
今日推荐