在这里,我们将给大家分享关于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:Theme.Dialog 和 @android:Widget.Button找不到
- Android Gid定义
- Android Studio – 使用依赖于另一个Android库的Android库构建Android项目
- Android Studio,下载soruces android-27以定位最新的SDK
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 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项目
我需要使用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
要开始一个新项目,我想要定位最新的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源代码的下载选项不可用:
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的相关知识,请在本站寻找。
本文标签: