GVKun编程网logo

Android定位(android定位api)

11

在这里,我们将给大家分享关于Android定位的知识,让您更了解android定位api的本质,同时也会涉及到如何更有效地android@android:Theme.Dialog和@android:W

在这里,我们将给大家分享关于Android定位的知识,让您更了解android定位api的本质,同时也会涉及到如何更有效地android @android:Theme.Dialog 和 @android:Widget.Button找不到、Android Gid定义、Android Studio – 使用依赖于另一个Android库的Android库构建Android项目、Android Studio,下载soruces android-27以定位最新的SDK的内容。

本文目录一览:

Android定位(android定位api)

Android定位(android定位api)

1.网络定位
    ip地址定位,(让ip地址和实际地址形成一个数据库)
    缺点:因为ip地址是动态分配的,会导致定位不准确
    
    
2.基站定位
    在每个地区都用,保证手机有信号,就可以定位到自己,其范围是几百米到几公里不等
    缺点:受地区限制,定位不准确
    
3.GPS .卫星定位
    目前大多数手机都拥有的Gps定位,就是卫星定位(美国卫星),中国有的定位系统是北斗星定位。
    卫星定位至少需要3颗卫星,GPS的定位用了24颗卫星。覆盖了90%区域。
    目前非常的流行,原因是定位准确,并且只要我们的智能手机有电,不用网络也是可以定位的(效果其实有影响)
    缺点:受云层,建筑等干扰
4.A-GPS辅助定位GPS,通过,网络和GPS共同定位,,一般Android手机都是这种定位。

    
  用一个简单的例子说明定位:
import java.util.List;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.app.Activity;

public class MainActivity extends Activity {

    private LocationManager lm;
    private LocationListener listener;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        lm = (LocationManager) getSystemService(LOCATION_SERVICE);
        // 获取手机所有的定位方式
        List<String> allProviders = lm.getAllProviders();
        listener = new LocationListener() {
            /**
             * 位置发生变化
             */
            @Override
            public void onLocationChanged(Location location) {
                String j = "经度:" + location.getLongitude();
                String w = "维度:" + location.getLatitude();
                String accuracy = "精确度"+location.getAccuracy();
                String altitude = "海拔"+location.getAltitude();
                System.out.println("j:===="+j+"w:===="+w+"10"+accuracy+"sasa"+altitude);
                
            }
 
            /**
             * 状态发生变化
             */
            @Override
            public void onStatusChanged(String provider, int status,
                    Bundle extras) {
                // TODO Auto-generated method stub

            }

            @Override
            public void onProviderEnabled(String provider) {
                // TODO Auto-generated method stub

            }

            @Override
            public void onProviderDisabled(String provider) {
                // TODO Auto-generated method stub

            }

        };
        
        //第一个参数是指以什么作为定位提供者(我选择的是GPS定位),
        // 最短更新时间
        // 最短更新距离
        // 定位的监听
        lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0,// 这里我用的是时时更新
                listener);
    }
    
    @Override
    protected void onDestroy() {
        // TODO Auto-generated method stub
        super.onDestroy();
        //可以去除监听
        lm.removeUpdates(listener);
    }

}

// 获取最佳的位置提供者
        Criteria criteria = new Criteria();
        criteria.setCostAllowed(true);// 是否允许付费(4G网络定位就是要付费的)
        criteria.setAccuracy(Criteria.ACCURACY_FINE);// 精确度一般就好,越高越耗电

        String bestProvider = lm.getBestProvider(criteria, true);
        
        
        
    经度: longitude  -180~180
    纬度: latitude  -90~90


    经度的起点为本初子午线,规定以过伦敦格林威治天文台的那条经线为0度经线,即本初子午线。
    
    --Zero


android @android:Theme.Dialog 和 @android:Widget.Button找不到

android @android:Theme.Dialog 和 @android:Widget.Button找不到

android @android :Theme.Dialog 和 @android :Widget.Button找不到是什么回事?

Android Gid定义

Android Gid定义

环境

AOSP 10

文件:

  • PackageParser.java#parseBaseApkCommon
 private Package parseBaseApkCommon(Package pkg, Set<String> acceptedTags, Resources res,
            XmlResourceParser parser, int flags, String[] outError) throws XmlPullParserException,
            IOException {
           // 此处省略...
            if (tagName.equals(TAG_PERMISSION_TREE)) {
                if (!parsePermissionTree(pkg, res, parser, outError)) {
                    return null;
                }
            } else if (tagName.equals(TAG_USES_PERMISSION)) {
                /* TAG_USES_PERMISSION = "uses-permission";
                 * parseUsesPermission() 解析权限
                 **/
                if (!parseUsesPermission(pkg, res, parser)) {
                    return null;
                }
            } else if (tagName.equals(TAG_USES_PERMISSION_SDK_M)
                    || tagName.equals(TAG_USES_PERMISSION_SDK_23)) {
                if (!parseUsesPermission(pkg, res, parser)) {
                    return null;
                }
            }
            .....
}
  • PackageParser.java#parseUsesPermission
private boolean parseUsesPermission(Package pkg, Resources res, XmlResourceParser parser)
            throws XmlPullParserException, IOException {
        //省略...
        XmlUtils.skipCurrentTag(parser);

        if (name == null) {
            return true;
        }

        if ((maxsdkVersion != 0) && (maxsdkVersion < Build.VERSION.RESOURCES_SDK_INT)) {
            return true;
        }

        // Only allow requesting this permission if the platform supports the given feature.
        if (requiredFeature != null && mCallback != null && !mCallback.hasFeature(requiredFeature)) {
            return true;
        }

        // Only allow requesting this permission if the platform doesn't support the given feature.
        if (requiredNotfeature != null && mCallback != null
                && mCallback.hasFeature(requiredNotfeature)) {
            return true;
        }

        int index = pkg.requestedPermissions.indexOf(name);
        if (index == -1) {
            // 添加权限:
            // PackageParser.Package.requestedPermissions
            // ArrayList<String> requestedPermissions = new ArrayList<String>();
            pkg.requestedPermissions.add(name.intern());
        } else {
            Slog.w(TAG, "Ignoring duplicate uses-permissions/uses-permissions-sdk-m: "
                    + name + " in package: " + pkg.packageName + " at: "
                    + parser.getPositionDescription());
        }

        return true;
}
  • SystemConfig.java#readPermissions

这里主要三个方法调用流程大概如下:
readPermissions(); ->readPermissionsFromXml()->readPermission()

    /* 构造函数读取vendor odm product odm下
     * 的/etc/sysconfig /etc/permissions下的xml文件
     **/
    SystemConfig() {
        // Read configuration from system
        readPermissions(Environment.buildpath(
                Environment.getRootDirectory(), "etc", "sysconfig"), ALLOW_ALL);

        // Read configuration from the old permissions dir
        readPermissions(Environment.buildpath(
                Environment.getRootDirectory(), "etc", "permissions"), ALLOW_ALL);

        ...
        readPermissions(Environment.buildpath(
                Environment.getvendorDirectory(), "etc", "sysconfig"), vendorPermissionFlag);
        readPermissions(Environment.buildpath(
                Environment.getvendorDirectory(), "etc", "permissions"),
        //  省略....
    }
    void readPermissions(File libraryDir, int permissionFlag) {
        // 省略...
        // Iterate over the files in the directory and scan .xml files
        File platformFile = null;
        for (File f : libraryDir.listFiles()) {
            if (!f.isFile()) {
                continue;
            }

            // We'll read platform.xml last
            if (f.getPath().endsWith("etc/permissions/platform.xml")) {
                platformFile = f;
                continue;
            }

            if (!f.getPath().endsWith(".xml")) {
                Slog.i(TAG, "Non-xml file " + f + " in " + libraryDir + " directory, ignoring");
                continue;
            }
            if (!f.canRead()) {
                Slog.w(TAG, "Permissions library file " + f + " cannot be read");
                continue;
            }
            // 解析xml函数
            readPermissionsFromXml(f, permissionFlag);
        }

        // Read platform permissions last so it will take precedence
        if (platformFile != null) {
            readPermissionsFromXml(platformFile, permissionFlag);
        }
    }
  • SystemConfig.java#readPermissionsFromXml

下面我们以/etc/permissions/platform.xml为例,先看xml内容

<permissions>
    <permission name="android.permission.BLUetoOTH_ADMIN" >
        <group gid="net_bt_admin" />
    </permission>

    <permission name="android.permission.BLUetoOTH" >
        <group gid="net_bt" />
    </permission>

    <permission name="android.permission.BLUetoOTH_STACK" >
        <group gid="bluetooth" />
        <group gid="wakelock" />
        <group gid="uhid" />
    </permission>
    // 省略....
</permissions>
    private void readPermissionsFromXml(File permFile, int permissionFlag) {
            // 省略...
            final boolean allowAll = permissionFlag == ALLOW_ALL;
            final boolean allowLibs = (permissionFlag & ALLOW_LIBS) != 0;
            // 权限处理

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

                String name = parser.getName();
                if (name == null) {
                    XmlUtils.skipCurrentTag(parser);
                    continue;
                }
                switch (name) {
                    case "group": {
                        if (allowAll) {
                            String gidStr = parser.getAttributeValue(null, "gid");
                            if (gidStr != null) {
                                int gid = android.os.Process.getGidForName(gidStr);
                                mGlobalgids = appendInt(mGlobalgids, gid);
                            } else {
                                Slog.w(TAG, "<" + name + "> without gid in " + permFile + " at "
                                        + parser.getPositionDescription());
                            }
                        } else {
                            logNotAllowedInPartition(name, permFile, parser);
                        }
                        XmlUtils.skipCurrentTag(parser);
                    } break;
                    case "permission": {
                        //对应上面的上面xml的permission 节点
                        if (allowPermissions) {
                            String perm = parser.getAttributeValue(null, "name");
                            if (perm == null) {
                                Slog.w(TAG, "<" + name + "> without name in " + permFile + " at "
                                        + parser.getPositionDescription());
                                XmlUtils.skipCurrentTag(parser);
                                break;
                            }
                            perm = perm.intern();
                            // perm = "android.permission.BLUetoOTH"
                            readPermission(parser, perm);
                        } else {
                            logNotAllowedInPartition(name, permFile, parser);
                            XmlUtils.skipCurrentTag(parser);
                        }
                    } break;
                    // 太多标签了,此处省略部分...
                    default: {
                        Slog.w(TAG, "Tag " + name + " is unkNown in "
                                + permFile + " at " + parser.getPositionDescription());
                        XmlUtils.skipCurrentTag(parser);
                    } break;
                }
            }
        } catch (XmlPullParserException e) {
            Slog.w(TAG, "Got exception parsing permissions.", e);
        } catch (IOException e) {
            Slog.w(TAG, "Got exception parsing permissions.", e);
        } finally {
            IoUtils.closeQuietly(permReader);
        }
        
        // Some devices can be field-converted to FBE, so offer to splice in
        // those features if not already defined by the static config
        if (StorageManager.isFileEncryptednativeOnly()) {
            addFeature(PackageManager.FEATURE_FILE_BASED_ENCRYPTION, 0);
            addFeature(PackageManager.FEATURE_SECURELY_REMOVES_USERS, 0);
        }

        // Help legacy devices that may not have updated their static config
        if (StorageManager.hasAdoptable()) {
            addFeature(PackageManager.FEATURE_ADOPTABLE_STORAGE, 0);
        }

        if (ActivityManager.isLowRamDeviceStatic()) {
            addFeature(PackageManager.FEATURE_RAM_LOW, 0);
        } else {
            addFeature(PackageManager.FEATURE_RAM_norMAL, 0);
        }

        for (String featureName : mUnavailableFeatures) {
            removeFeature(featureName);
        }
    }
  • SystemConfig.java#readPermission
    void readPermission(XmlPullParser parser, String name)
            throws IOException, XmlPullParserException {
        if (mPermissions.containsKey(name)) {
            throw new IllegalStateException("Duplicate permission deFinition for " + name);
        }

        final boolean perUser = XmlUtils.readBooleanAttribute(parser, "perUser", false);
        final PermissionEntry perm = new PermissionEntry(name, perUser);
        // 添加权限 perm
        mPermissions.put(name, perm);

        int outerDepth = parser.getDepth();
        int type;
        while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
               && (type != XmlPullParser.END_TAG
                       || parser.getDepth() > outerDepth)) {
            if (type == XmlPullParser.END_TAG
                    || type == XmlPullParser.TEXT) {
                continue;
            }

            String tagName = parser.getName();
            if ("group".equals(tagName)) {
                String gidStr = parser.getAttributeValue(null, "gid");
                if (gidStr != null) {
                    //通过name获取gid,设置perm.gid
                    int gid = Process.getGidForName(gidStr);
                    perm.gids = appendInt(perm.gids, gid);
                } else {
                    Slog.w(TAG, "<group> without gid at "
                            + parser.getPositionDescription());
                }
            }
            XmlUtils.skipCurrentTag(parser);
        }
}
jint android_os_Process_getGidForName(jnienv* env, jobject clazz, jstring name)
{
    if (name == NULL) {
        jniThrowNullPointerException(env, NULL);
        return -1;
    }

    const jchar* str16 = env->GetStringCritical(name, 0);
    String8 name8;
    if (str16) {
        name8 = String8(reinterpret_cast<const char16_t*>(str16),
                        env->GetStringLength(name));
        env->ReleaseStringCritical(name, str16);
    }

    const size_t N = name8.size();
    if (N > 0) {
        const char* str = name8.string();
        for (size_t i=0; i<N; i++) {
            if (str[i] < '0' || str[i] > '9') {// 不是数字
                struct grouP* grp = getgrnam(str);
                if (grp == NULL) {
                    return -1;
                }
                return grp->gr_gid;
            }
        }
        //name是数字,直接转换
        return atoi(str);
    }
    return -1;
}
  • bionic/libc/bionic/grp_pwd.cpp
static grouP* getgrnam_internal(const char* name, group_state_t* state) {
  grouP* grp = android_name_to_group(state, name);
  if (grp != nullptr) {
    return grp;
  }

  // /vendor/etc/passwd中查找
  if (vendor_group.FindByName(name, state)) {
    if (is_oem_id(state->group_.gr_gid)) {
      return &state->group_;
    }
  }

  // Handle OEM range.
  grp = oem_id_to_group(oem_id_from_name(name), state);
  if (grp != nullptr) {
    return grp;
  }
  // app id 转换成 gid
  return app_id_to_group(app_id_from_name(name, true), state);
}
static grouP* android_name_to_group(group_state_t* state, const char* name) {
  for (size_t n = 0; n < android_id_count; ++n) {
    if (!strcmp(android_ids[n].name, name)) {
      /*
       * android_ids数组定义在generated_android_ids.h
       * generated_android_ids.h是编译产物,路径在
       * ./out/soong/.intermediates/bionic/libc/generated_android_ids/gen/generated_android_ids.h
       * 由 system/core/libcutils/include/private/android_filesystem_config.h生成
       **/
       return android_iinfo_to_group(state, android_ids + n);
    }
  }
  return nullptr;
}

static grouP* android_iinfo_to_group(group_state_t* state,
                                     const android_id_info* iinfo) {
  snprintf(state->group_name_buffer_, sizeof(state->group_name_buffer_), "%s", iinfo->name);

  grouP* gr = &state->group_;
  gr->gr_name   = state->group_name_buffer_;
  gr->gr_gid    = iinfo->aid;
  gr->gr_mem[0] = gr->gr_name;
  return gr;
}

总结:

1.在 system/core/libcutils/include/private/android_filesystem_config.h中已经定义好预设关系

#define AID_SYstem 1000 /* system server */

#define AID_RAdio 1001           /* telephony subsystem, RIL */
#define AID_BLUetoOTH 1002       /* bluetooth subsystem */
#define AID_GRAPHICS 1003        /* graphics devices */
#define AID_INPUT 1004           /* input devices */

2.SystemConfig初始化中读取vedor,odm,product,根目录/etc/permissions/下的xml中的节点, 通过gid名字,例如bluetooth 查询gid,并保存在mPermissions变量中

3.最后在安装APP中通过解析apk中的manifest来添加用户组

总结

如果大家想添加自己的AID,我建议还是参考google的文档:
Android 自主访问控制
而不是直接去system/core/libcutils/include/private/android_filesystem_config.h中添加定义.虽然这样也可以,但是不建议.

操作如下:

frameworks/base/data/etc/platform.xml添加:

 
+    <permission name="android.permission.xx_SERVICE" >
+        <group gid="vendor_xx" />
+    </permission>

frameworks/base/core/res/AndroidManifest.xml中添加:

+ <permission android:name="android.permission.MCI_SERVICE"
+                android:protectionLevel="normal" />

device/xxx/xxx/config.fs中添加AID_${gid}

+++ b/device/mci/cutefish_k6/config.fs
@@ -19,6 +19,9 @@ value:2906
 [AID_vendOR_THERMAL]
 value:2907
 
+[AID_vendOR_XX]
+value:2908
+

重新编译就会系统就有vendOR_XX这个gid组了

测试代码:

+                PackageInfo pi= mPm.getPackageInfo(packageName,PackageManager.GET_PERMISSIONS);
+                for (String permission : pi.requestedPermissions) {
+                    if (permission == android.Manifest.permission.xx_SERVICE) {
+                        logd("nopd", "access " + packageName + " xx service");
+                        return true;
+                    }
+                }

Android Studio – 使用依赖于另一个Android库的Android库构建Android项目

Android Studio – 使用依赖于另一个Android库的Android库构建Android项目

我需要使用Gradle构建一个依赖于Android库项目A的Android项目,该项目取决于另一个Android库项目B.

到目前为止,我有以下内容:

Android项目:

的build.gradle:

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:0.5.+'
    }
}

apply plugin: 'android'

dependencies {
    compile project(':LibA')
}

android {
    compileSdkVersion 7
    buildToolsversion "17.0.0"
}

manifest.xml文件:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.cyborg.template"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="7"
        android:targetSdkVersion="7" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:name="com.cyborg.template.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

Android库A:

的build.gradle:

buildscript {
    repositories {
        mavenCentral()
    }

    dependencies {
        classpath 'com.android.tools.build:gradle:0.5.+'
    }
}

apply plugin: 'android-library'

dependencies {
    compile project(':LibB')
}


android {
    compileSdkVersion 7
    buildToolsversion "17.0.0"
} 

manifest.xml文件:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.lib.project.a"
          android:versionCode="1"
          android:versionName="1.0">

    <uses-sdk
            android:minSdkVersion="7"
            android:targetSdkVersion="7"/>

</manifest>

Android库B:

的build.gradle:

buildscript {
    repositories {
        mavenCentral()
    }

    dependencies {
        classpath 'com.android.tools.build:gradle:0.5.+'
    }
}

apply plugin: 'android-library'

android {
    compileSdkVersion 7
    buildToolsversion "17.0.0"
} 

manifest.xml文件:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.lib.project.b"
          android:versionCode="1"
          android:versionName="1.0">

    <uses-sdk
            android:minSdkVersion="7"
            android:targetSdkVersion="7"/>

</manifest>

在尝试构建Android项目时,Android studio报告了以下错误:

Gradle: Execution Failed for task ':LibA:processDebugManifest'.
  > Manifest merging Failed. See console for more info.

那个控制台在哪里我想搜索有关错误的更多信息?

我发现了一些关于这个错误的问题,但它似乎与我的情况不一样.

启示?

谢谢,
亚当.

解决方法:

该库的清单文件当前必须具有< application />节点,即使它是空的.

这是我们将在某些时候删除的限制,但现在,只需添加它.

Android Studio,下载soruces android-27以定位最新的SDK

Android Studio,下载soruces android-27以定位最新的SDK

要开始一个新项目,我想要定位最新的SDK(利用新的开始).
但是,我也希望能够访问Android源代码,以便能够读取android类的代码(比如AsyncTask,就像一个例子).
我在gradle上使用SDK 27并使用compileSdkVersion 27.
我尝试过不同的方式(如here,here和here所示),但我似乎无法下载这些来源.

当我尝试浏览像AsyncTask这样的Android类时,我收到消息:

Decompiled .class file, bytecode version: 52.0 (Java 8)
Sources for ‘Android API 27 Platform’ not found.

即使单击下载然后单击刷新(如果已经下载)链接(这是最直观的事情),我仍然看不到任何Android类的源代码.

这仅是API 27的问题.我可以下载所有其他API版本的源代码.

这是因为API 27是最新的吗?

我想避免使用目标26.是否可以下载这些来源?到目前为止,有没有人能够做到这一点?

如果到目前为止有人知道如何做到这一点,那将非常有帮助.谢谢.

我正在使用Android Studio 3.0,并且API 27源代码的下载选项不可用:

Sources for API 27 not available

No option to download sources

UPDATE

正如已接受的答案所示,问题是API级别27是当时的开发预览,问题随着时间的推移得到解决(一旦正式发布发生).在针对最新的可用API版本时,此更新可能对遇到类似问题的用户有用.

解决方法:

Is this because of API 27 being the latest one?

不,这是因为API Level 27是Android 8.1,目前处于开发者预览版中.

I want to avoid targeting 26

我不确定为什么,考虑到26级是与Android(8.0)最新产品版本相对应的API级别.

Is it possible to download those sources?

通常,在OS发布以最终形式发布之前,源不可通过IDE获得.

关于Android定位android定位api的介绍现已完结,谢谢您的耐心阅读,如果想了解更多关于android @android:Theme.Dialog 和 @android:Widget.Button找不到、Android Gid定义、Android Studio – 使用依赖于另一个Android库的Android库构建Android项目、Android Studio,下载soruces android-27以定位最新的SDK的相关知识,请在本站寻找。

本文标签: