android sip 开发中SipManager.newInstance()return null 解决方法

我在项目中使用google原生的sip电话api开发网络电话的过程中,在一般手机上没有问题,当我把项目迁移到香蕉派上去测试的时候发现sipmanager.newInstance()一直返回null。

折腾了半天发现并不是权限的问题,也不是系统版本的问题。

问题出在android.software.sip.voip.xml这个文件上。

文件内容:







   
   

在香蕉派的系统中的/system/etc/permissions文件夹下并没有这个文件

解决方法:将这个文件copy到此目录中去(需要设备root)

android sip 开发中SipManager.newInstance()return null 解决方法_第1张图片


分析原因:

我们看看SipManager.newInstance()方法

public static SipManager newInstance(Context context) {
    return (isApiSupported(context) ? new SipManager(context) : null);
}
首先会调用isApiSupported()方法判断设备是否支持sip

看看isApiSupported方法:

/**
 * Returns true if the SIP API is supported by the system.
 */
public static boolean isApiSupported(Context context) {
    return context.getPackageManager().hasSystemFeature(
            PackageManager.FEATURE_SIP);
}
执行了context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_SIP)方法
很不幸这是个抽象方法
public abstract boolean hasSystemFeature(String name);
找到其实现方法
services/java/com/android/server/pm/PackageManagerService.java
public boolean hasSystemFeature(String name) {
        synchronized (mPackages) {
            return mAvailableFeatures.containsKey(name);
        }
    }

在成员mAvailableFeatures中没有查找到PackageManager.FEATURE_SIP,返回flase。所以无法创建SipManager对象。在PackageManagerService类中,
成员变量mAvailableFeatures的值是通过读取/system/permissions下的xml文件进行设置的
 private void readPermissionsFromXml(File permFile) {
        FileReader permReader = null;
        try {
            permReader = new FileReader(permFile);
        } catch (FileNotFoundException e) {
            Slog.w(TAG, "Couldn't find or open permissions file " + permFile);
            return;
        }
	try {
            XmlPullParser parser = Xml.newPullParser();
            parser.setInput(permReader);


            XmlUtils.beginDocument(parser, "permissions");


            while (true) {
                XmlUtils.nextElement(parser);
                if (parser.getEventType() == XmlPullParser.END_DOCUMENT) {
                    break;
                }


                String name = parser.getName();
                if ("group".equals(name)) {
                    String gidStr = parser.getAttributeValue(null, "gid");
                    if (gidStr != null) {
                        int gid = Integer.parseInt(gidStr);
                        mGlobalGids = appendInt(mGlobalGids, gid);
                    } else {
                        Slog.w(TAG, " without gid at "
                                + parser.getPositionDescription());
                    }


                    XmlUtils.skipCurrentTag(parser);
                    continue;
                } else if ("permission".equals(name)) {
                    String perm = parser.getAttributeValue(null, "name");
                    if (perm == null) {
                        Slog.w(TAG, " without name at "
                                + parser.getPositionDescription());
                        XmlUtils.skipCurrentTag(parser);
                        continue;
                    }
                    perm = perm.intern();
                    readPermission(parser, perm);


                } else if ("assign-permission".equals(name)) {
                    String perm = parser.getAttributeValue(null, "name");
                    if (perm == null) {
                        Slog.w(TAG, " without name at "
                                + parser.getPositionDescription());
                        XmlUtils.skipCurrentTag(parser);
                        continue;
                    }
                    String uidStr = parser.getAttributeValue(null, "uid");
                    if (uidStr == null) {
                        Slog.w(TAG, " without uid at "
                                + parser.getPositionDescription());
                        XmlUtils.skipCurrentTag(parser);
                        continue;
                    }
                    int uid = Process.getUidForName(uidStr);
                    if (uid < 0) {
                        Slog.w(TAG, " with unknown uid \""
                                + uidStr + "\" at "
                                + parser.getPositionDescription());
                        XmlUtils.skipCurrentTag(parser);
                        continue;
                    }
                    perm = perm.intern();
                    HashSet perms = mSystemPermissions.get(uid);
                    if (perms == null) {
                        perms = new HashSet();
                        mSystemPermissions.put(uid, perms);
                    }
                    perms.add(perm);
                    XmlUtils.skipCurrentTag(parser);


                } else if ("library".equals(name)) {
                    String lname = parser.getAttributeValue(null, "name");
                    String lfile = parser.getAttributeValue(null, "file");
                    if (lname == null) {
                        Slog.w(TAG, " without name at "
                                + parser.getPositionDescription());
                    } else if (lfile == null) {
                        Slog.w(TAG, " without file at "
                                + parser.getPositionDescription());
                    } else {
                        //Log.i(TAG, "Got library " + lname + " in " + lfile);
                        mSharedLibraries.put(lname, lfile);
                    }
                    XmlUtils.skipCurrentTag(parser);
                    continue;


                } else if ("feature".equals(name)) {
                    String fname = parser.getAttributeValue(null, "name");
                    if (fname == null) {
                        Slog.w(TAG, " without name at "
                                + parser.getPositionDescription());
                    } else {
                        //Log.i(TAG, "Got feature " + fname);
                        FeatureInfo fi = new FeatureInfo();
                        fi.name = fname;
                        mAvailableFeatures.put(fname, fi);
                    }
                    XmlUtils.skipCurrentTag(parser);
                    continue;


                } else {
                    XmlUtils.skipCurrentTag(parser);
                    continue;
}
 
  


你可能感兴趣的:(android)