搜档网
当前位置:搜档网 › Android开发之深入理解Android 7.0系统权限更改相关文档

Android开发之深入理解Android 7.0系统权限更改相关文档

Android开发之深入理解Android 7.0系统权限更改相关文档
Android开发之深入理解Android 7.0系统权限更改相关文档

Android开发之深入理解Android 7.0系统权限更改相关文档

一、深入理解FileProvider

FileProvider属于Android 7.0新增的一个类,该类位于v4包下,详情可见android.support.v4.content.FileProvider,使用方法类似与ContentProvider,简单概括为三个步骤,这里先以调用系统相机拍照并保存sdcard公共目录为例,演示使用过程:

在资源文件夹res/xml下新建file_provider.xml文件,文件声明权限请求的路径,代码如下:

在AndroidManifest.xml添加组件provider相关信息,类似组件activity,指定resource属性引用上一步创建的xml文件(后面会详细介绍各个属性的用法),代码如下:

android:name="android.support.v4.content.FileProvider"

android:authorities="@string/install_apk_path"

android:exported="false"

android:grantUriPermissions="true">

android:name="android.support.FILE_PROVIDER_PATHS"

android:resource="@xml/file_provider" />

最后一步,Java代码申请权限,使用新增的方法getUriForFile()和grantUriPermission(),代码如下(后面会详细介绍方法对应参数的使用):

if (Build.VERSION.SDK_INT > 23) {

/**Android 7.0以上的方式**/

Uri contentUri = getUriForFile(this, getString(R.string.install_apk_path), file);

grantUriPermission(getPackageName(), contentUri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION);

intent.putExtra(MediaStore.EXTRA_OUTPUT, contentUri);

}

修改build.gradle文件compileSdkVersion大于或等于24,targetSdkVersion等于24,使用Android 7.0模拟器运行Demo,效果图:

那么,我们已经了解Android 7.0系统权限申请的步骤,接下来说明每一个步骤需要注意的事项、相关方法参数的说明、属性的含义以及可以的申请权限目录(最后下载相关Demo)。

1.1 定义一个FileProvider

直接使用FileProvider本身或者它的子类,需要在AndroidManifest.xml文件中声明组件的相关属性,包括:

android:name,对应属性值:android.support.v4.content.FileProvider或者子类完整路径android:authorities,对应属性值是一个常量,通常定义的方式packagename.fileprovider,例如:cn.teachcourse.fileprovider

android:exported,对应属性值是一个boolean变量,设置为false

android:grantUriPermissions,对应属性值也是一个boolean变量,设置为true,允许获得文件临时的访问权限

...

...

android:name="android.support.v4.content.FileProvider"

android:authorities="com.mydomain.fileprovider"

android:exported="false"

android:grantUriPermissions="true">

...

...

想要关联res/xml文件夹下创建的file_provider.xml文件,需要在标签内,添加子标签,设置标签的属性值,包括:

android:name,对应属性值是一个固定的系统常量android.support.FILE_PROVIDER_PATHS android:resource,对应属性值指向我们的xml文件@xml/file_provider

android:name="android.support.v4.content.FileProvider"

android:authorities="com.mydomain.fileprovider"

android:exported="false"

android:grantUriPermissions="true">

android:name="android.support.FILE_PROVIDER_PATHS"

android:resource="@xml/file_provider" />

1.2 指定授予临时访问权限的文件目录

上一步说明了怎么定义一个FileProvider,这一步主要说明怎么定义一个@xml/file_provider 文件。Android Studio或Eclipse开发工具创建Android项目的时候默认不会创建res/xml文件夹,需要开发者手动创建,点击res文件夹新建目录,命名xml,如下图:

在xml文件中指定文件存储的区块和区块的相对路径,在根标签中添加子标签(稍后详细列出所有子标签),设置子标签的属性值,包括:

- name,是一个虚设的文件名(可以自由命名),对外可见路径的一部分,隐藏真实文件目录

- path,是一个相对目录,相对于当前的子标签根目录

- ,表示内部内存卡根目录,对应根目录等价于Context.getFilesDir(),查看完整路径:

/data/user/0/cn.teachcourse.demos/files

- 代码如下:

...

根标签下可以添加的子标签也是有限的,参考官网的开发文档,除了上述的提到的这个子标签外,还包括下面几个:

1. ,表示应用默认缓存根目录,对应根目录等价于getCacheDir(),查看完整路径:/data/user/0/cn.teachcourse.demos/cache

,表示外部内存卡根目录,对应根目录等价于

Environment.getExternalStorageDirectory(),

查看完整路径:/storage/emulated/0

,表示外部内存卡根目录下的APP公共目录,对应根目录等价于Context#getExternalFilesDir(String) Context.getExternalFilesDir(null),

查看完整路径:

/storage/emulated/0/Android/data/cn.teachcourse.demos/files/Download

,表示外部内存卡根目录下的APP缓存目录,对应根目录等价于Context.getExternalCacheDir(),查看完整路径:

/storage/emulated/0/Android/data/cn.teachcourse.demos/cache

最终,在file_provider.xml文件中,添加上述5种类型的临时访问权限的文件目录,代码如下:

name="int_root"

path="/" />

name="app_cache"

path="/" />

name="ext_root"

path="pictures/" />

name="ext_pub"

path="/" />

name="ext_cache"

path="/" />

1.3 生成指定文件的Content URI

Content URI方便与另一个APP应用程序共享同一个文件,共享的方式通过ContentResolver.openFileDescriptor获得一个ParcelFileDescriptor对象,读取文件内容。那么,如何生成一条完整的Content URI呢?TeachCourse总结后,概括为三个步骤,第一步:明确上述5种类型中的哪一种,第二步:明确指定文件的完整路径(包括目录、文件名),第三步:调用getUriForFile()方法生成URI

File imagePath = new File(Environment.getExternalStorageDirectory(), "download");

File newFile = new File(imagePath, "default_image.jpg");

Uri contentUri = getUriForFile(getContext(), "cn.teachcourse.fileprovider", newFile);

1.4 授予Content URI临时访问权限

上一步获得的Content URI,并没有获得指定文件的读写权限,想要获得文件的读写权限需要调用Context.grantUriPermission(package, Uri, mode_flags)方法,该方法向指定包名的应用程序申请获得读取或者写入文件的权限,参数说明如下:

package,指定应用程序的包名,Android Studio真正的包名指build.gradle声明的applicationId 属性值;getPackageName()指AndroidManifest.xml文件声明的package属性值,如果两者不一致,就不能提供getPackageName()获取包名,否则报错!

Uri,指定请求授予临时权限的URI,例如:contentUri

mode_flags,指定授予临时权限的类型,选择其中一个常量或两个:Intent.FLAG_GRANT_READ_URI_PERMISSION,Intent.FLAG_GRANT_WRITE_URI_PERMISSION

授予文件的临时读取或写入权限,如果不再需要了,TeachCourse该如何撤销授予呢?撤销权限有两种方式:第一种:通过调用revokeUriPermission()撤销,第二种:重启系统后自动撤销

1.5 对外提供可访问的Content URI

有多种方式可以向客户端APP提供可访问文件的Content URI,其中一种常用的方式是通过

发送Intent给需要启动的Activity,在重写的startActivityResult()方法中获取授予临时权限的Content URI或向用户提供可访问的接口来获取文件,后面的这种方式获取文件后转换成Content URI,以文章开头拍照的功能为例,TeachCourse想要在sdcard的公共目录pictures/查看已保存的照片,实现过程:

请求授予访问公共目录的权限,代码如下:

if (Build.VERSION.SDK_INT > 23) {

/**Android 7.0以上的方式**/

mStorageManager = this.getSystemService(StorageManager.class);

StorageV olume storageV olume = mStorageManager.getPrimaryStorageV olume();

Intent intent = storageV olume.createAccessIntent(Environment.DIRECTORY_PICTURES);

startActivityForResult(intent, REQUEST_CODE_GRAINT_URI);

}

在重写的startActivityResult()方法中获取授予临时权限的Content URI,代码如下:@Override

protected void onActivityResult(int requestCode, int resultCode, Intent data) {

super.onActivityResult(requestCode, resultCode, data);

switch (requestCode) {

case REQUEST_CODE_GRAINT_URI:

updateDirectoryEntries(data.getData());

Log.d(TAG, "onActivityResult:Uri= "+data.getData());

break;

}

}

查询Environment.DIRECTORY_PICTURES目录,返回的Content URI包含的文件和文件类型相关信息,代码如下:

private static final String[] DIRECTORY_SELECTION = new String[]{

DocumentsContract.Document.COLUMN_DISPLAY_NAME,

DocumentsContract.Document.COLUMN_MIME_TYPE,

DocumentsContract.Document.COLUMN_DOCUMENT_ID,

};

@TargetApi(Build.VERSION_CODES.LOLLIPOP)

private void updateDirectoryEntries(Uri uri) {

ContentResolver contentResolver = this.getContentResolver();

Uri docUri = DocumentsContract.buildDocumentUriUsingTree(uri,

DocumentsContract.getTreeDocumentId(uri));

Uri childrenUri = DocumentsContract.buildChildDocumentsUriUsingTree(uri,

DocumentsContract.getTreeDocumentId(uri));

try (Cursor docCursor = contentResolver

.query(docUri, DIRECTORY_SELECTION, null, null, null)) { while (docCursor != null && docCursor.moveToNext()) {

mPath_tv.setText(docCursor.getString(docCursor.getColumnIndex(

DocumentsContract.Document.COLUMN_DISPLAY_NAME)));

}

}

try (Cursor childCursor = contentResolver

.query(childrenUri, DIRECTORY_SELECTION, null, null, null)) { while (childCursor != null && childCursor.moveToNext()) {

String fileName = childCursor.getString(childCursor.getColumnIndex(

DocumentsContract.Document.COLUMN_DISPLAY_NAME));

String mimeType = childCursor.getString(childCursor.getColumnIndex(

DocumentsContract.Document.COLUMN_MIME_TYPE));

Log.e(TAG, "updateDirectoryEntries: "+fileName+"\n"+mimeType);

}

}

}

Android 7.0系统权限更改的第三点,简单的说:通过访问COLUMN_LOCAL_FILENAME,在Android 7.0系统上可能无法获取Demo效果图fileName 对应的文件路径,这时候可能触发异常SecurityException,打印的log信息,如下:

Caused by: https://www.sodocs.net/doc/7317442181.html,ng.SecurityException: COLUMN_LOCAL_FILENAME is deprecated; use ContentResolver.openFileDescriptor() instead

at

android.app.DownloadManager$CursorTranslator.getString(DownloadManager.java:1499) at

cn.teachcourse.download.DownloadManagerActivity.query(DownloadManagerActivity.java:244) at

cn.teachcourse.download.DownloadManagerActivity.access$100(DownloadManagerActivity.java: 34)

at

cn.teachcourse.download.DownloadManagerActivity$1.onReceive(DownloadManagerActivity.ja va:186)

at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:1122)

at android.os.Handler.handleCallback(Handler.java:751)

at android.os.Handler.dispatchMessage(Handler.java:95)

at android.os.Looper.loop(Looper.java:154)

at android.app.ActivityThread.main(ActivityThread.java:6077)

at https://www.sodocs.net/doc/7317442181.html,ng.reflect.Method.invoke(Native Method)

at

com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)

at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)

2.1 关于DownloadManager

DownloadManager是一个用于处理长时间HTTP请求的系统服务,客户端请求的URI 可能是将要下载的指定的文件,处于后台的下载管理器将控制着下载的任务,并监测下载的状态,在下载失败或连接改变以及系统重启后尝试重新下载。

如何初始化DownloadManager实例?首先调用getSystemService(String)方法,传入DOWNLOAD_SERVICE常量,来初始化DownloadManager实例,代码如下:mDownloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);

如何配置请求参数?首先需要使用到内部类DownloadManager.Request,查看源码学习该类的各个方法的使用,TeachCourse简单总结:该类主要用于配置一条新下载任务相关内容,这些内容包括下载任务的保存路径,下载任务所处的网络状态(WiFi或流量状态)和下载任务通知栏显示样式等等,代码如下:

/**

* 设置请求下载的数据

*/

private void initData() {

//Request内部类配置新下载任务相关内容,比如:保存路径,WiFi或流量状态,下载通知栏样式

request = new DownloadManager.Request(Uri.parse(mUrl + mFileName));

request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, mFileName);

request.setAllowedNetworkTypes(https://www.sodocs.net/doc/7317442181.html,WORK_MOBILE);

request.setTitle("正在下载应用程序");

request.setDescription("92回收,就爱回收APP");

request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE);

}

如何开启下载任务?下载任务参数配置完成后,就可以开启后台服务下载,同一个DownloadManager实例,可以开启多个下载任务,需要上一步中配置多条URI,每个下载任务分配唯一的id,代码如下:

/**

* 下载任务的唯一标识ID,用于查询下载文件的相关信息

*/

private void start() {

mDownloadUniqueId = mDownloadManager.enqueue(request);

mDownloadManager_btn.setText("正在下载。。。");

mDownloadManager_btn.setClickable(false);

}

DownloadManager通过两种状态的广播,第一种:任务下载完成后发送,广播拦截器过滤action是DownloadManager.ACTION_DOWNLOAD_COMPLETE;第二种:点击通知栏进度条后发送,广播拦截器过滤action是DownloadManager.ACTION_NOTIFICATION_CLICKED,代码如下:

/**

* 注册下载完成广播接收器,还可以注册其它监听器,比如:DownloadManager.ACTION_NOTIFICATION_CLICKED

*/

private void registerReceiverCompleted() {

IntentFilter intentFilter = new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE);

registerReceiver(mBroadcastReceiver, intentFilter);

}

/**

* 接收下载完成广播

*/

private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {

@Override

public void onReceive(Context context, Intent intent) {

long reference = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);

if (mDownloadUniqueId == reference) {

query(https://www.sodocs.net/doc/7317442181.html,ference);

mShowInformation_tv.setText(information);

mDownloadManager_btn.setText("点击下载");

mDownloadManager_btn.setClickable(true);

}

}

};

如何查询下载任务的相关信息?首先需要使用到内部类DownloadManager.Query,查看源码学习该类各个方法的使用,TeachCourse简单总结:该类正如文章开头样式的例子,通过分配的id查询下载任务相关的信息,这些信息包括文件类型、文件的Uri和文件的长度等,代码如下:

/**

* 查询下载任务相关的信息,比如:文件名、文件大小、文件类型等

*

* @param reference

*/

private void query(long reference) {

DownloadManager.Query query = new DownloadManager.Query();

/**指定查询条件**/

query.setFilterById(reference);

/**查询正在等待、运行、暂停、成功、失败状态的下载任务**/

query.setFilterByStatus(DownloadManager.STATUS_SUCCESSFUL);

Cursor cursor = mDownloadManager.query(query);

if (cursor.moveToFirst()) {

int fileId = cursor.getColumnIndex(DownloadManager.COLUMN_ID);

int fileTitleId = cursor.getColumnIndex(DownloadManager.COLUMN_TITLE);

int fileDescriptionId = cursor.getColumnIndex(DownloadManager.COLUMN_DESCRIPTION);

int fileTypeId = cursor.getColumnIndex(DownloadManager.COLUMN_MEDIA_TYPE);

int fileLengthId = cursor.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES);

int fileUriId = cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI);

/**过时的方式:DownloadManager.COLUMN_LOCAL_FILENAME**/

int fileNameId = cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_FILENAME);

int statusCodeId = cursor.getColumnIndex(DownloadManager.COLUMN_STA TUS);

int statusReasonId = cursor.getColumnIndex(DownloadManager.COLUMN_REASON);

int downloadSizeId = cursor.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR);

int lastModifiedTimeId = cursor.getColumnIndex(DownloadManager.COLUMN_LAST_MODIFIED_TIMESTAMP);

int mediaUriId = cursor.getColumnIndex(DownloadManager.COLUMN_MEDIAPROVIDER_URI);

String id = cursor.getString(fileId);

String fileTitle = cursor.getString(fileTitleId);

String description = cursor.getString(fileDescriptionId);

String type = cursor.getString(fileTypeId);

String length = cursor.getString(fileLengthId);

String statusCode = cursor.getString(statusCodeId);

String statusReason = cursor.getString(statusReasonId);

String downloadSize = cursor.getString(downloadSizeId);

String modifiedTime = cursor.getString(lastModifiedTimeId);

String mediaUri = cursor.getString(mediaUriId);

String fileUri = cursor.getString(fileUriId);

String fileName = https://www.sodocs.net/doc/7317442181.html,ull;

if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M) {

openFile(type, Uri.parse(fileUri));

fileName = Uri.parse(fileUri).getPath();

} else {

/**Android 7.0以上的方式:请求获取写入权限,这一步报错**/

fileName = cursor.getString(fileNameId);

openFile(type, Uri.parse(fileUri));

}

/**清空StringBuffer存储的数据**/

mStringBuffer.delete(0, mStringBuffer.length());

mStringBuffer.append("id:" + id + "\n");

mStringBuffer.append("fileTitle:" + fileTitle + "\n");

mStringBuffer.append("description:" + description + "\n");

mStringBuffer.append("type:" + type + "\n");

mStringBuffer.append("length:" + length + "\n");

mStringBuffer.append("fileName:" + fileName + "\n");

mStringBuffer.append("fileUri:" + fileUri + "\n");

mStringBuffer.append("statusCode:" + statusCode + "\n");

mStringBuffer.append("statusReason:" + statusReason + "\n");

mStringBuffer.append("downloadSize:" + downloadSize + "\n");

mStringBuffer.append("modifiedTime:" + modifiedTime + "\n");

mStringBuffer.append("mediaUri:" + mediaUri + "\n");

information = mStringBuffer.toString();

}

cursor.close();

}

代码加入判断语句,如果非Android 7.0系统继续访问COLUMN_LOCAL_FILENAME 获得文件存储的绝对路径(上面中间部分代码),openFile()方法代码如下:/**

* 根据文件的类型,指定可以打开的应用程序

*

* @param type

* @param uri

*/

private void openFile(String type, Uri uri) {

if (type.contains("image/")) {

try {

ParcelFileDescriptor descriptor = getContentResolver().openFileDescriptor(uri, "r");

FileDescriptor fileDescriptor = descriptor.getFileDescriptor();

Bitmap bitmap = BitmapFactory.decodeFileDescriptor(fileDescriptor);

mShowPic_iv.setVisibility(View.VISIBLE);

mShowPic_iv.setImageBitmap(bitmap);

} catch (FileNotFoundException e) {

e.printStackTrace();

}

}

}

现在,我们已经掌握了DownloadManager怎么实例化、怎么配置下载任务、怎么开启后台服务以及如何查询任务相关信息,想要实现一个应用程序版本更新就变得很简单,实现

多任务下载也不是难事,完整源码参考文章后台通过的Demo。

三、关于ParcelFileDescriptor和FileDescriptor总结

官网的文档推荐我们使用ContentResolver.openFileDescriptor()方法,获得一个ParcelFileDescriptor对象,再通过getFileDescriptor()方法返回一个FileDescriptor,它们之间的关系参考上面的代码。

FileDescriptor通常被称为文件描述符,可以理解成本地的一个文件,通过流的方式读取文件内容以及通过流的方式写入数据到文件,这里是读取或写入数据到FileDescriptor中,假如我们的Uri表示的是一个txt文件,获取FileDescriptor对象后,通过下面的代码读取txt 文件的内容:

FileInputStream fis = new FileInputStream(fd);

同理,写入数据到txt文件,代码如下:

FileOutputStream out = new FileOutputStream(fd);

out.write('写入数据到txt文件中');

out.close();

获取到输入流或输出流后,剩下的就是关于流的操作了,划分为:文件字节流、文件字符流、缓冲流、数组流等

3.1 改写上面的例子

openFile()方法使用封装好的decodeFileDescriptor(),查看BitmapFactory.decodeFileDescriptor()相关源码,学习如何读取文件描述符中的内容,这里TeachCourse根据读取流的方式,改写如下:

...

Bitmap bitmap = BitmapFactory.decodeStream(getStreamByFileDescriptor(fileDescriptor));

...

/**

* 通过流的方式读取内容

*

* @param fileDescriptor

* @return

*/

private InputStream getStreamByFileDescriptor(FileDescriptor fileDescriptor) { return new FileInputStream(fileDescriptor);

}

于是,可以对FileDescriptor进行简单的封装成writeData()和readData(),代码如下:

/**往FileDescriptor中写入数据

* @param fileDescriptor

* @param content

*/

private void writeData(FileDescriptor fileDescriptor, String content) { FileOutputStream fos = new FileOutputStream(fileDescriptor);

try {

fos.write(content.getBytes());

} catch (IOException e) {

e.printStackTrace();

} finally {

try {

fos.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}

/**从FileDescriptor中读取数据

* @param fileDescriptor

* @return

*/

private String readData(FileDescriptor fileDescriptor) {

FileInputStream fis = new FileInputStream(fileDescriptor);

byte[] b = https://www.sodocs.net/doc/7317442181.html,w byte[1024];

int read;

String content=null;

try {

while ((read = fis.read(b)) != -1) {

content = new String(b, 0, read);

}

} catch (IOException e) {

e.printStackTrace();

} finally {

try {

fis.close();

} catch (IOException e) {

e.printStackTrace();

}

}

return content;

}

总结:

Android 7.0系统的权限更改,包括三个方面,文章从第二方面开始讲解,着重介绍了FileProvider和DownloadManager两个类的使用,花了好长时间整理、测试和编辑,如果对你有帮忙,别忘了收藏和分享咯!

最新APP开发合同

上海幽思信息科技有限公司 APP开发合同 委托方(甲方): 公司地址: 法定代表人: 联系方式: 受托方(乙方): 公司地址: 法定代表人: 身份证号: 联系方式: 根据《中华人民共和国合同法》等相关法律的规定,甲、乙双方经友好协商,就委托乙方开发“软件”,以下简称“本软件”,一致同意签订如下合同。 一.合作内容与软件开发具体要求 甲方委托乙方开发“软件”,可以在IOS和ANDROID环境下运行,开发需求按照本合同附件中的APP开发要求确定。 二.合同期限 1、乙方UI需在本合同签订之日起日内完成。 2、乙方须在本软件UI完工之日起日内,乙方必须完成软件demo开发工作。 3、乙方须在本软件UI完工之日起日内,乙方必须完成软件的初步开发工作,并 且开始测试,在日内完成测试工作。 三.甲方权利与义务 1、甲方提出的本软件需求不含有反动、黄色以及违反国家法律规定的内容。 2、甲方拥有本软件的所有权利,包括但不限于以下权利:所有权、著作权、使用权、 复制权、发行权、出租权、署名权、翻译权、许可权、转让权等。乙方不享有以上 权利。 3、甲方为乙方提供在APP开发中必要的协助。 四.乙方责任 1、本软件是乙方自行研发,保证不是侵权软件。 2、功能和界面符合甲方要求。 3、乙方向甲方提供完整的本软件源代码。 4、乙方不得在APP中署名、以自身名义办理APP著作权的登记,乙方须协助甲方办理 本软件的著作权登记。

5、乙方不享有本软件的所有权,即乙方不享有本软件以下的权利(包括但不限于): 所有权、著作权、使用权、复制权、发行权、出租权、许可权、翻译权、转让权等。 6、乙方承诺不向其他公司、团体、个人等开发类似于本软件的软件。 7、乙方在交付软件时,对甲方提供免费的相关技术培训,培训结束后,应满足甲方工 作人员的相关资讯。 8、乙方每周须向甲方汇报开发进度,按照合同规定的时间完成项目,逾期超过7天, 乙方需赔付甲方项目总额的50%,逾期超过20天,乙方需赔付甲方项目总额的100%。 五.验收标准 1、验收标准:无内容错误或程序错误,包含双方约定的设计内容和功能模块。 2、验收合格:甲方应以书面方式签收,如甲方在规定日期内未书面签收也未提出异议 的,视为甲方验收合格。 3、验收合格后,根据合同的约定,乙方对甲方使用中的要求变动,做出必要调整,不 收取费用; 4、若甲方的改动超出合同要求,增加其他模块或功能,乙方应积极协助,适当收取费 用。 六.售后服务体系 1、售后服务期限为:本软件交付后六个月。对于软件重大问题,时间为交付后3年。 2、故障处理: 当本软件发生重大问题时,乙方应保证在12小时内排除故障。当本软件发生一般 问题时,乙方应保证在24小时内解决,并且不影响本软件的正常运行。 3、售后服务内容: 七.费用结算 1、本软件的开发总费用为人民币壹拾肆万伍仟元整(RMB:¥145000)。 2、费用支付:本合同签订后3个工作日内,甲方向乙方支付开发总费用的50%;本软 件交付后,甲方在7个工作日内向乙方支付开发总费用的50%。。 3、乙方在收到甲方的款项后,需向甲方开具正规商业发票。 八.法律适用与争议解决 1、甲、乙双方应以友好协商方式解决本合同履行过程中产生的争议与纠纷。如果甲、 乙双方协商无效,可以提交当地法院通过诉讼解决。 2、本合同之效力、解释、执行、争议解决等均适用于中华人民共和国法律,没有相关 规定的,参照通用国际商业惯例和(或)行业惯例。

权限说明大全

程序执行需要读取到安全敏感项必需在androidmanifest.xml中声明相关权限请求, 各种权限说明如下: android.permission.ACCESS_CHECKIN_PROPERTIES 允许读写访问”properties”表在checkin数据库中,改值可以修改上传( Allows read/write access to the “properties” table in the checkin database, to change values that get upload ed) android.permission.ACCESS_COARSE_LOCATION 允许一个程序访问CellID或WiFi热点来获取粗略的位置(Allows an application to access coarse (e.g., Cell-ID, WiFi) location) android.permission.ACCESS_FINE_LOCATION 允许一个程序访问精良位置(如GPS) (Allows an application to access fine (e.g., GPS) location) android.permission.ACCESS_LOCATION_EXTRA_COMMANDS 允许应用程序访问额外的位置提供命令(Allows an application to access extra location provider commands) android.permission.ACCESS_MOCK_LOCA TION 允许程序创建模拟位置提供用于测试(Allows an application to create mock location providers for testing) android.permission.ACCESS_NETWORK_STA TE 允许程序访问有关GSM网络信息(Allows applications to access information about networks) android.permission.ACCESS_SURFACE_FLINGER 允许程序使用SurfaceFlinger底层特性(Allows an application to use SurfaceF linger’s low level features) android.permission.ACCESS_WIFI_STATE 允许程序访问Wi-Fi网络状态信息(Allows applications to access information about Wi-Fi networks) android.permission.ADD_SYSTEM_SERVICE 允许程序发布系统级服务(Allows an application to publish system-level services). android.permission.BA TTERY_STATS 允许程序更新手机电池统计信息(Allows an application to update the collected battery statistics) android.permission.BLUETOOTH 允许程序连接到已配对的蓝牙设备(Allows applications to connect to paired bluetooth devices) android.permission.BLUETOOTH_ADMIN 允许程序发现和配对蓝牙设备(Allows applications to discover and pair bluetooth devices) android.permission.BRICK 请求能够禁用设备(非常危险)(Required to be able to disable the device (very *erous!).) android.permission.BROADCAST_PACKAGE_REMOVED 允许程序广播一个提示消息在一个应用程序包已经移除后(Allows an application to broadcast a notification that an application package has been removed) android.permission.BROADCAST_STICKY 允许一个程序广播常用intents(Allows an application to broadcast sticky intents) android.permission.CALL_PHONE

android系统开发--HAL层开发基础

android系统开发--HAL层开发基础 Android HAL层,即硬件抽象层,是Google响应厂家“希望不公开源码”的要求推出的新概念 1,源代码和目标位置 源代码:/hardware/libhardware目录,该目录的目录结构如下: /hardware/libhardware/hardware.c编译成libhardware.so,目标位置为/system/lib目录 /hardware/libhardware/include/hardware目录下包含如下头文件: hardware.h 通用硬件模块头文件 copybit.h copybit模块头文件 gralloc.h gralloc模块头文件 lights.h 背光模块头文件 overlay.h overlay模块头文件 qemud.h qemud模块头文件 sensors.h 传感器模块头文件 /hardware/libhardware/modules目录下定义了很多硬件模块 这些硬件模块都编译成xxx.xxx.so,目标位置为/system/lib/hw目录 2,HAL层的实现方式 JNI->通用硬件模块->硬件模块->内核驱动接口 具体一点:JNI->libhardware.so->xxx.xxx.so->kernel 具体来说:android frameworks中JNI调用/hardware/libhardware/hardware.c中定义的hw_get_module函数来获取硬件模块, 然后调用硬件模块中的方法,硬件模块中的方法直接调用内核接口完成相关功能 3,通用硬件模块(libhardware.so) (1)头文件为:/hardware/libhardware/include/hardware/hardware.h 头文件中主要定义了通用硬件模块结构体hw_module_t,声明了JNI调用的接口函数 hw_get_module hw_module_t定义如下: typedef struct hw_module_t { /** tag must be initialized to HARDWARE_MODULE_TAG */ uint32_t tag; /** major version number for the module */ uint16_t version_major; /** minor version number of the module */ uint16_t version_minor; /** Identifier of module */ const char *id; /** Name of this module */ const char *name;

app开发合同模板(ios、安卓)

APP应用开发合同书(安卓端iOS端) 项目名称: 委托人: (甲方) 研究开发人: (乙方) 签订地点: 签订日期:年月日 有效期限:年月日至年月日

依据《中华人民共和国合同法》及相关法律的规定,合同双方就【】项目(以下简称“委托项目”)的设计、开发、维护等事宜(委托/合作开发)(该委托项目属委托开发计划※),经协商一致,签订本合同。 本合同中所有提到的书面形式包括纸质书面、电子邮件形式; 本合同中所有提到的通知、确认、验收等,除本合同条款明确约定外,包括但不限于口头、电话、IM、截图、视频、书面及电子邮件等形式; 本合同中所有提到的接口标准包括:JSON、XML、WebService三种形式; 本合同中所有提到的UE是指用户体验,即产品原型图的交互设计; 本合同中所有提到的UI是指用户界面,即我们看到的界面的设计及美观程度; 本合同中所有提到的成果是指本合同履行过程中,乙方提交给甲方的关于委托项目的各阶段开发产物。 一、标的技术的内容、形式和要求: (一)甲方的权利和义务 1、甲方将与乙方积极沟通,向乙方提供详细的业务流程、文本、图片资料,以便乙方完成策 划、设计和开发等工作。甲方对其提供的资料真实性、合法性承担法律责任。甲方应在签订合同后的【5】个工作日内将委托项目开工所需要的基本资料(如LOGO源文件、业务流程、设计要求等相关电子或纸质版资料)以书面形式给到乙方; 2、本委托项目中涉及到需要甲方配合时(包括但不限于:接口调试、业务流程确认、产品原 型图确认、风格设计稿确认、验收、反馈等),甲方接到乙方需要相关配合通知后需在【24】小时内予以配合; 3、出现以上第1条及第2条情况时,此委托项目开发的计划表由双方重新协商,并且受制于 本合同第十三条违约条款的约束;

Android权限清单

允许读写访问"properties"表在checkin数据库中,改值可以修改上传 允许一个程序访问CellID或WiFi热点来获取粗略的位置 允许一个程序访问精良位置(如GPS) < uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" > 允许应用程序访问额外的位置提供命令 允许程序创建模拟位置提供用于测试 允许程序访问有关GSM网络信息 允许程序使用SurfaceFlinger底层特性 允许程序访问Wi-Fi网络状态信息 允许程序发布系统级服务 允许程序更新手机电池统计信息 允许程序连接到已配对的蓝牙设备 允许程序发现和配对蓝牙设备 请求能够禁用设备 允许程序广播一个提示消息在一个应用程序包已经移除后 允许一个程序广播常用intents

Android用户权限列表

我们在安装Android软件的时候,系统会提示该软件所需要的权限,相对于其他系统,android的权限非常多。我们在开发软件的时候,也需要声明相应的权限,比如希望软件能发短信,需要声明软件调用短信的权限,否则软件运行的时候就会报错。 Android的权限在AndroidManifest.xml文件里配置。AndroidManifest文件中有四个标签与permission有关,它们分别是 。其中最常用的是 ,当我们需要获取某个权限的时候就必须在我们的manifest文件中声明 。 [html]view plain copy 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. ... 11. 12. 的作用相似,两者之间的不同之处, 是android预定义的权限,是自己定义的权 限。 用的相对较少, 这两个标签就更少见了,简单说 就是声明一个标签,该标签代 表了一组permissions,而是为一组permissions声明了一个namespace。后面三个标签具体使用方法见后续文章。 定义方法如下:

android系统开发工作介绍

android系统开发工作介绍 一、android的开发工作 Android的开发分为三个类型:移植开发移动设备系统;android系统级开发和应用程序开发。 1、移植开发移动设备系统 2、Android系统级开发,指的是扩展android的框架或者是修改bug,这方面比较少,除非有些开发移动设备的厂商,比如做gps,可以往里面加入一些自己的特定系统东西,这可能导致一些不兼容。当然也可能是简单的修复bug,详细的内容后面还有说。 3、开发应用程序,这应该是比较主流的开发,也就是给android系统写应用程序。当然我们这里主要是研究android的framework如何给这些应用程序提供服务的。 总结一下,我们可以把android分为四个层次,从底层往上依次为:linux内核、C/C++库、java 框架和java应用程序。移植开发移动设备涉及到linux内核(包括其驱动);android系统级开发涉及到C/C++库的开发及给上层java框架;android应用程序开发就是调用java的框架写应用程序。 简单的从上到下,android应用程序需要有java框架支持,比如它要发送短信,就需要java 框架,java框架其实就是将C/C++库包装成为了一个JNI,而实现具体的功能是C/C++库,最后驱动硬件完成功能,这也就是linux内核部分。 所谓framework,也就是系统级开发,这将是本文的重点,虽然android的framework 开发比较少,但是对其了解后更有利于整体开发的进行,当然很多设备厂商还是非常需这要些的。 二、android系统架构

Linux内核及驱动、C/C++框架、java框架、java应用程序。 1)、Linux内核及驱动 其中linux内核及驱动是内核层的(本人对linux内核也有过痴迷的时候,就像现在android 痴迷一样),系统总是需要操作系统的支持的,比如内存管理、进程管网理、络协议栈等。 2)、android的C/C++框架 系统C库:用的是libc,没什么好说的,C程序员都知道。多媒体库SurFace Manager:显示子系统的管理器LibWebCore:web浏览器引擎,支持android浏览器SGL:skia图形库,底层的2D图形引擎 3D库:OpenGL FreeType:字体显示Android的运行环境,这个也应该属于这个框架里面的,android的虚拟机叫做Dalvik,运行环境就是由这个虚拟机和基础的java类库组成。 3)、android应用框架 提供一系列的服务和系统,包括视图、内容提供器、资源管理器、通知管理器活、动管理器。 视图非常丰富:list、grid、text box、button等。内容提供器是使得应用程序可以访问另一个程序的数据。资源管理器是提供访问非代码的资源访问,如布局文件。通知管理器,使得程序可以在状态栏中显示自定义的提示信息。活动管理器,用来管理程序生命周期。 4)、android应用程序Android所有的应用程序都是用java写的,当然现在好像也支持一些脚本语言,如 ruby,但是不支持C开发,所谓支持C开发是指jni的形式。 。。。。。。。。。

手机APP开发合同协议书

手机A P P开发合同协 议书 文稿归稿存档编号:[KKUY-KKIO69-OTM243-OLUI129-G00I-FDQS58-

手机客户端开发合同 甲方: 联系人: 联系电话: 乙方: 联系人: 联系电话: 甲、乙双方经友好协商,甲方委托乙方开发《》以下简称“本软件”,一致同意签订此《开发合同》,条款如下: 一、合作内容 1.APP制作 1.1提供适用于iOS及Android系统手机的APP手机客户端; 1.2搭建APP管理后台; 2.APP服务 2.1APP发布服务: 2.1.1APP发布至IOS系统及ANROID系统各一个应用市场; 2.1.2根据甲方的需求将APP发布至其他应用市场; 2.2APP运行服务 2.2.1APP运行的硬件环境; 2.2.2APP运行的软件系统; 2.3APP另付费升级服务: 2.3.1APP功能的更新升级;

2.3.2APP性能及视觉的更新升级; 2.3.3APP对终端设备的兼容升级。 注:更多需求,根据客户需求,另行订价。 2.4APP售后服务: 2.3.1APP使用培训; 2.3.2APP管理后台培训; 2.3.3APP使用咨询服务; 2.3.4APP下载二维码生成。 二、开发周期 1.开发流程 1.1需求确定 1.2App主要功能设计 1.3App的界面构思和设计 1.4大功能模块代码编写 1.5界面模块编写 1.6Demo确认 1.7UC美化 1.8上线前测试 1.9UI美化 1.10完成交付 2.服务条款

2.1合同签订之日起(__________)个工作日内甲方向乙方提供APP制作所需的素材; 2.2乙方在收到甲方全部素材后(__________)个工作日内向甲方交付APP并开始提供 相应的APP服务; 2.3甲方提交素材迟延,乙方交付APP的时间亦相应顺延; 2.4甲方确认接收APP的时日,为乙方向甲方提供APP服务的起始日。 三、验收标准 1.甲乙双方验收时,甲方按照需求标定的指标验收,没有指标的以运行甲方测试数据结果的正确与否为依据。 2.乙方完成软件工作,甲方应在七日内组织验收。 四、双方陈述及保证 1.双方均是根据中华人民共和国相关法律合法设立并有效存续的法人或经济体,同时完整地享有法定的民事权利能力和民事行为能力,能行使《开发合同》的权利和履行《开发合同》的义务。同时,双方在履行义务时,不违反任何法律,也不会侵犯乙方以外任何第三方的合法权益; 2.双方均拥有合法资质从事《开发合同》的合作; 3.双方的法定代表人或授权代表已获得法定资格或充分授权可代表签署《开发合同》。 五、甲乙双方的权利、义务

Android系统原理及开发要点详解.

内容简介 本书全面介绍开放的移动电话平台Android系统,包括Android系统中的Linux 驱动、本地框架、Java框架和Java应用4个层次。本书内容以知识性内容为纲,重点关注开发要点,各个部分内容注重相互照应,按照清晰的思路向读者介绍整个Android系统的原理和开发方法。 本书按照Android系统的框架和各个子系统的主线,重点介绍开发Android应用程序和构建硬件抽象层。其内容涵盖了Android应用程序开发和Android系统移植构建手机系统两大方面。 本书既适合从事Android各个层次开发的工程师阅读,也适合通用嵌入式Linux 系统的学习者使用。 本书购买地址:当当网卓越网中国互动出版网 作者简介 梁泉是移动系统开发资深工程师,在Android领域具有完备的知识和前沿的技术,长期从事一线开发工作。 韩超是中国大陆地区较早参与Android系统开发的人员之一,也是中国大陆的Androidin(机锋网开发社区的核心成员和重要组织者之一;也曾经引领大陆各种相关技术人员进入Android领域,并组织参与国内外的相关枝术交流。 前言 Android 是Google历经数年和投资数亿美元开发出来的智能手机系统,Google 也发起了围绕Android的组织——开放手机联盟,其英文全称为“Open Handset Alliance”。

随着各大移动终端生产商大力开发和生产基于Android的移动智能设 备,Android迅速得到业界和社会的认可,并成为整个产业的热点,基于Android平台的各类人才逐渐成为各大企业竞相争夺的焦点。 Android系统是一个开放的系统,任何公司、个人开发者、爱好者都可以参与其中。对于技术工作者,Android不仅是一个智能手机的系统,也可以作为学习嵌入式Linux系统的较完整的软件平台。 Android是一个较新的系统和技术,因此介绍Android的资料和书籍还比较少,尤其简体中文的书籍,相对更少。本书《Android系统原理及开发要点详解》是一本综合介绍Android系统的书,集合了Androidin社区多位专家作者的经验,精心编写而成。 Android 作为一个庞大的系统,包括了Linux操作系统、各种本地程序、虚拟机和运行环境、Java框架和Java应用程序多方面的内容。这对于初学者是一个非常大的挑战,因此对于学习、研究进而开发Android系统来说,掌握系统的脉络和使用恰当的学习方法是非常重要的,这也是本书的组织主旨。 本书特点为了适应Android系统的情况,本书在内容的编排和组织上具有以下一些重要特点。 保持完整性和层次性本书紧紧把握Android系统的4个层次,分章节介绍,并且有重点地介绍了Android整个系统的代码结构、编译系统、相关工具、各部分组织等全局性内容。这将让读者即使只花费较短的时间,也可以获得对Android 系统大致的感性理解。 提供清晰的框架Android是一个有数百兆大小的较大系统,各部分之间是有机联系的,这就要求Android的学习和开发者需要具有一些软件架构方面的知识。本书为Android整体和重点模块绘制了大量的框图,这样非常有利于帮助读者直观地理解系统。本书在讲述每一个部分时,均列出相关代码的路径,帮助读者对应着进行快速、高效地学习。

Android软件开发协议书

Andriod软件开发协议书 甲方: 乙方: 甲方委托乙方开发***手机客户端Andriod版软件,双方经过友好协商,为保障甲、乙双方的权益和义务,根据《中华人民共和国合同法》的相关规定,达成如下协议。 第一条:软件开发时间 在本合同签定完毕之日,30个日历日内主体部分开发完成,15个日历日内完成软件测试,所有功能都能够使用(具体功能参考《***手机终端软件开发说明》)。正式版交付后的90天为产品试运行期。 在本合同签定完毕之日起双方协议的开始时间,非经甲方书面同意,开发期限不得变更。 在开发过程中甲方如需要调整开发内容提前1个工作日通知乙方; 乙方不得无故拖延甲方进度,如果乙方无故拖延开发、或无法实现规定的功能要求,甲方有权要求返还开发款,取消本协议。 第二条:软件开发需求 软件功能开发根据《***手机终端软件开发说明》进行开发。乙

方开发过程中如有疑问,甲方有义务对软件功能需求进行解释,甲、乙双方均须签字确认)。 软件需支持Andriod2.2以上版本,和支持240X320、320X480、480X900,三种分辨率的终端版程序。 乙方在所开发的软件中不得设逻辑锁或其他类似限制性代码,如有发生,给甲方造成的损失,甲方有权诉诸法律要求乙方进行赔偿。 第三条:开发费用及支付方式: 1、软件开发总费用为:人民币¥元(大写:________元整),甲方共分三次支付给乙方。 2、自本协议签字之日起三个工作日内甲方向乙方支付第一期开发款人民币¥元(大写:________元整)(软件开发总额的20%); 3、软件完成全部开发工作,甲方进行验收测试通过,甲方向乙方支付第二期开发款¥元(大写:______元整)(软件开发总额的50%);付款时须签订《软件验收报告单》; 4、余下款项(软件开发总额的20%);作为试运行期售后服务保证金,在试运行期结束后无异议须全部付清,异议期为90个工作日。甲方不得无故拖延付款,如无故拖延乙方须视情况决定是否停止开发或服务,并且因此引起的损失由甲方自己承担。

Android permission 访问权限说明手册

Android permission 访问权限说明手册 tech.er 2011年2月12日 android平台上的权限许可分得很细,如果软件无法正常执行时,首先要检查是不是缺少相关的permission声明,以下就把permission 访问权限列举出来供大家参考。 程序执行需要读取到安全敏感项必需在androidmanifest.xml中声明相关权限请求, 完整列表如下: android.permission.ACCESS_CHECKIN_PROPERTIES 允许读写访问”properties”表在checkin数据库中,改值可以修改上传( Allows read/write access to the “properties” table in the checkin database, to change values that get uploaded) android.permission.ACCESS_COARSE_LOCATION 允许一个程序访问CellID或WiFi热点来获取粗略的位置(Allows an application to access coarse (e.g., Cell-ID, WiFi) location) android.permission.ACCESS_FINE_LOCATION 允许一个程序访问精良位置(如GPS) (Allows an application to access fine (e.g., GPS) location) android.permission.ACCESS_LOCATION_EXTRA_COMMANDS 允许应用程序访问额外的位置提供命令(Allows an application to access extra location provider commands) android.permission.ACCESS_MOCK_LOCATION 允许程序创建模拟位置提供用于测试(Allows an application to create mock location providers for testing) android.permission.ACCESS_NETWORK_STATE 允许程序访问有关GSM网络信息(Allows applications to access information about networks) android.permission.ACCESS_SURFACE_FLINGER 允许程序使用SurfaceFlinger底层特性(Allows an application to use SurfaceFlinger’s low level features) android.permission.ACCESS_WIFI_STATE 允许程序访问Wi-Fi网络状态信息(Allows applications to access information about Wi-Fi networks) android.permission.ADD_SYSTEM_SERVICE 允许程序发布系统级服务(Allows an application to publish system-level services). android.permission.BATTERY_STATS 允许程序更新手机电池统计信息(Allows an application to update the collected battery statistics) android.permission.BLUETOOTH

APP委托开发合同doc

APP委托开发合同doc App commissioned development contract doc 合同编号:XX-2020-01 甲方:___________________________乙方:___________________________ 签订日期:____ 年 ____ 月 ____ 日

APP委托开发合同doc 前言:合同是民事主体之间设立、变更、终止民事法律关系的协议。依法成立的合同,受法律保护。本文档根据合同内容要求和特点展开说明,具有实践指导意义,便于学习和使用,本文档下载后内容可按需编辑修改及打印。 合同编号: APP应用开发合同 甲方:(以下简称甲方) 地址: 法定代表人: 联系电话: 乙方:(以下简称乙方) 地址: 法定代表人: 联系电话: 甲、乙双方经友好协议,就甲方委托乙方开发 《》(以下简称“本软件”)的事宜达成一致并同意订本合同。

一、项目内容 1.甲方委托乙方开发的软件 《 》(以下简称“本软件”)可以在 □AppleIOS、□Android环境下运行的软件,软件需求(以下简称“需求”)双方协商确定。 2.本合同APP应用开发的栏目架构及相关功能开发细节 由《APP开发需求表》载明。 二、合同价款和付款方式 1.本合同总价款包括乙方相关的税费及软件开发期间办 理相关手续的所有费用。该价款为固定包干价,除上述款项外,甲方无需支付任何其它款项。 2.付款方式: 本次移动商务软件的开发总金额为元(大写:整),软件 开发之前甲方需要向乙方预付保证金元(大写:整),乙方 交付本移动商务软件当日,甲方验收合格后向乙方结清余款 元(大写:整)。

Android系统开发入门

Android系统开发入门 注:相信大家都知道Android的APP的是用Java写的,运行在Dalvik 虚拟机上,还有,Android的系统是基于Linux Kernel 2.6的。那么,要想深入了解Android系统的各种细节,当然少不了Linux Kernel 的知识了。阅读本文需要具备一定的C和JAVA语言基础,并且对linux 系统有一定了解。最好对C++也有一定的了解。 本文的内容是基于Android2.2版本平台,以一个设备(将系统内存模拟成一个带4字节寄存器的设备)为例,从底层驱动,到中间件,到上层应用程序全过程的代码实现。 所编写的代码例子,都可以在Android模拟器进行运行。但由于https://www.sodocs.net/doc/7317442181.html,在2011年9月份被人黑了无法访问,导致本人没有下载goldfish_defconfig,无法编译能在模拟器运行的kernel,故采用JZ4760BLYNX开发板运行代码例子。 搭建好JZ android编译环境,开始进行android系统开发之旅。 Android硬件抽象层(HAL)概要介绍和学习计划

Android的硬件抽象层,简单来说,就是对Linux内核驱动程序的封装,向上提供接口,屏蔽低层的实现细节。也就是说,把对硬件的支持分成了两层,一层放在用户空间(User Space),一层放在内核空间(Kernel Space),其中,硬件抽象层运行在用户空间,而Linux 内核驱动程序运行在内核空间。为什么要这样安排呢?把硬件抽象层和内核驱动整合在一起放在内核空间不可行吗?从技术实现的角度来看,是可以的,然而从商业的角度来看,把对硬件的支持逻辑都放在内核空间,可能会损害厂家的利益。我们知道,Linux内核源代码版权遵循GNU License,而Android源代码版权遵循Apache License,前者在发布产品时,必须公布源代码,而后者无须发布源代码。如果把对硬件支持的所有代码都放在Linux驱动层,那就意味着发布时要公开驱动程序的源代码,而公开源代码就意味着把硬件的相关参数和实现都公开了,在手机和平板市场竞争激烈的今天,这对厂家来说,损害是非常大的。因此,Android才会想到把对硬件的支持分成硬件抽象层和内核驱动层,内核驱动层只提供简单的访问硬件逻辑,例如读写硬件寄存器的通道,至于从硬件中读到了什么值或者写了什么值到硬件中的逻辑,都放在硬件抽象层中去了,这样就可以把商业秘密隐藏起来了。也正是由于这个分层的原因,Android被踢出了Linux内核主线代码树中。大家想想,Android放在内核空间的驱动程序对硬件的支持是不完整的,把Linux内核移植到别的机器上去时,由于缺乏硬件抽象层的支持,硬件就完全不能用了,这也是为什么说Android是开放系统而不是开源系统的原因。 撇开这些争论,学习Android硬件抽象层,对理解整个Android整个系统,都是极其有用的,因为它从下到上涉及到了Android系统的硬件驱动层、硬件抽象层、运行时库和应用程序框架层等等,下面这个图阐述了硬件抽象层在Android系统中的位置,以及它和其它层的关系: 在学习Android硬件抽象层的过程中,我们将会学习如何在内核空间编写硬件驱动程序、如何在硬件抽象层中添加接口支持访问硬件、如何在系统启动时提供硬件访问服务以及如何编写JNI使得可以通过Java接口来访问硬件,而作为中间的一个小插曲,我们还将学习一下如何在Android系统中添加一个C可执行程序来访问硬件驱动程序。由于这是一个系统的学习过程,本人将分成六个章节来描述每一个学习过程,包括:

手机APP开发合同

编号:_______________本资料为word版本,可以直接编辑和打印,感谢您的下载 手机APP开发合同 甲方:___________________ 乙方:___________________ 日期:___________________

甲方: 联系人: 联系电话: 乙方: 联系人: 联系电话: 甲、乙双方经友好协商,甲方委托乙方开发〈〈》以下简称“本软件”,致同意签订此〈〈开发合同》,条款如下: 一、合作内容 1. APP制作 1.1提供适用于iOS及Android系统手机的APP手机客户端; 1.2搭建APP管理后台; 2. APP服务 2.1 APP发布服务: 2.1.1 APP发布至IOS系统及ANROID系统各一个应用市场; 2.1.2根据甲方的需求将APP发布至其他应用市场; 2.2 APP运行服务 2.2.1 APP运行的硬件环境; 2.2.2 APP运行的软件系统; 2.3 APP另付费升级服务: 2.3.1 APP功能的更新升级; 2.3.2 APP性能及视觉的更新升级; 2.3.3 APP对终端设备的兼容升级。 注:更多需求,根据客户需求,另行订价。 2.4 APP售后服务: 2.3.1 APP使用培训; 2.3.2 APP管理后台培训; 2.3.3 APP使用咨询服务; 2.3.4 APP下载二维码生成。 二、开发周期 1. 开发流程 1.1需求确定 1.2 App主要功能设计 1.3 App的界面构思和设计 1.4大功能模块代码编写 1.5界面模块编写

1.6 Demo 确认 1.7 UC美化 1.8上线前测试 1.9 UI美化 1.10完成交付 2 .服务条款 2.1合同签订之日起()个工作日内甲方向乙方提供APP制作所需的素材; 2.2乙方在收到甲方全部素材后()个工作日内向甲方交付APP并开始提供 相应的APP服务; 2.3甲方提交素材迟延,乙方交付APP的时间亦相应顺延; 2.4甲方确认接收APP的时日,为乙方向甲方提供APP服务的起始日。 三、验收标准 1. 甲乙双方验收时,甲方按照需求标定的指标验收,没有指标的以运行甲方测试数据结果的正确与否为依据。 2. 乙方完成软件工作,甲方应在七日内组织验收。 四、双方陈述及保证 1. 双方均是根据中华人民共和国相关法律合法设立并有效存续的法人或经济体,同时完整 地享有法定的民事权利能力和民事行为能力,能行使〈〈开发合同》的权利和履行〈〈开发合同》 的义务。同时,双方在履行义务时,不违反任何法律,也不会侵犯乙方以外任何第三方的合法权益; 2. 双方均拥有合法资质从事〈〈开发合同》的合作; 3. 双方的法定代表人或授权代表已获得法定资格或充分授权可代表签署〈〈开发合同》。 五、甲乙双方的权利、义务 1. 甲方保证其产品或服务的内容不存在任何违法内容(诸如:黄色、反动信息内容及国家禁播,禁放内容等);其产品的收费信息有明确的提示,符合有关法律、法规、规章制度的要求; 2. 乙方在提供服务时获取的甲方各项信息,未经甲方同意不得泄漏给第三方,相关法律法规规定或国家政府部门要求的情况时除外; 六、保密条款 1. 双方保证,获得方根据〈〈开发合同》获知或获准使用的硬件、软件、程序、密码、商品

Android权限大全

Android权限大全 允许程序写入外部存储,如SD卡上写文件 录音 允许编写短信 允许读写系统设置项 允许程序读写系统安全敏感的设置项 允许程序写入Google Map服务数据 写入联系人,但不可读取 写入日程,但不可读取 写入网络GPRS接入点设置 允许程序在手机屏幕关闭后后台进程仍然运行 允许振动 允许程序使用SIP视频服务 允许程序请求验证从AccountManager 更新设备状态 显示系统窗口 入或修改订阅内容的数据库 访问订阅信息的数据库

相关主题