添加calendar.apk到android模拟器的尝试

   最近需要做一个android上面的calendar的项目。以前没有接触android相关的东西都要从头开始学习。

 

我尝试的方法

   弄了两天终于在ubuntu上面把android平台开发环境弄好了,在模拟器上写了两个小程序,熟悉了一下环境,想把android自带的calendar程序拿来看看,结果发现模拟器上面没有calendar程序,找了一下发现android源代码是有这个AP的,就把calendar工程用eclipse打开想直接编译成APK看看长得什么样子。结果打开发现一堆的错误,仔细看了一下发现是一些java相关的库没有加入到android.jar。

     好吧,自己动手,丰衣足食,参考了一下fix_android_sdk.py(http://code.google.com/p/android-scripting/source/browse/tools/fix_android_sdk.py?r=bd959f44d4b39cedfa156a361c3be033c2fc3433),写了一个函数自动编译calendar相关的java代码然后打包到adnroid.jar中去,把下面的代码保存成fix_android_sdk.py。然后运行

python fix_android_sdk.py "src_folder", "sdk_folder" 

就可以把calendar相关的代码加入到android.jar中去了.

测试了一下,这种添加方法,并没有把需要的库添加到模拟器上去,所以在运行的时候如果需要操作android.provider.calendar就会出问题。

解决办法,就是把calendar需要的库直接打包到calendar.apk中去,方法如下。

1. 把calendar需要的库打包成jar,修改fix_android_sdk.py单独生成一个jar(不加入到android.jar中)

2.在calendar工程中新建一个叫libs的packages,把单独生成的jar,添加到libs下面。

上面两步后,calendar基本上不crash了,但是从logcat中可以看到calendar还是找不到provider.calendar,这个应该是在AndroidManifest.xml中没有声明,所以系统找不到,我尝试来两种方法解决这个问题。

1.程序build system.img,用mmm命令把calendarprovider添加system.img中,这种方法我尝试可行,calendar工作起来没有什么问题

2.按照编译calendar的方法编译calendarprovider。

 

 

查了一下资料正确的添加方法是

在make  后

执行

. bulid/envsetup.sh

mmm /packages/apps/Calendar/

把生成的system.img, 替换sdk目录/platfroms/android-AOSP/images/ 下的system.img

这样这样calendar就直接被打包system.img中去了。

这样做后calendarprovider并不会被添加到SDK中,如果要在eclipse中使用,需要做下面的步骤

拷贝/out/target/common/obj /JAVA_LIBRARIES/framework_intermediates/classes.jar到SDK目录

然后

  1. Right-Click your project to open properties
  2. Java Build Path->Add Library->User Library->User Libraries->New
  3. Made up a name & check the “System Library” option
  4. Select the library you created->Add JARs
  5. Make sure all JARs you need are added to the project, and click OK

附fix_android_sdk.py代码

 

import os import re import shutil import subprocess import sys import zipfile def validate_source_and_sdk_locations(src_location, sdk_location): if not os.path.exists(src_location): print "Android source location is invaild" sys.exit(1) if not os.path.exists(sdk_location): print "SDK location is invaild" sys.exit(1) return os.path.join(sdk_location,'platforms','android-AOSP') def copy_sources(src_location,sdk_location): sdk = validate_source_and_sdk_locations(src_location,sdk_location) out = os.path.join(src_location, 'out') sources = os.path.join(sdk,'sources') if not os.path.exists(sources): os.makedirs(sources) print 'Copying sources from %s to %s' % (src_location, sources) written = {} for dir,subdirs,files in os.walk(src_location): if dir.startswith(out): continue for filename in [f for f in files if f.endswith('.java')]: source = os.path.join(dir,filename) with open(source) as f: for line in f: match = re.match(r'/s*package/s+([a-zA-Z0-9._]+);',line) if match: package_path = match.group(1).replace('.',os.sep) try: os.makedirs(os.path.join(sources,package_path)) except os.error: pass destination = os.path.join(sources,package_path,filename) if destination not in written: written[destination] = True shutil.copy(source,destination) break def add_android_os_exec(src_location, sdk_location): print 'Addind android.os.Exec to android.jar' sdk = validate_source_and_sdk_locations(src_location, sdk_location) sources = os.path.join(sdk,'sources') package_path = os.path.join(sdk,'sources','android','os') print 'Compiling android.os.Exec to %s' % package_path android_os_exec = os.path.join(src_location,'frameworks','base','core', 'java', 'android', 'os', 'Exec.java') cmd = 'javac -d %s %s' % (sources, android_os_exec) if subprocess.call(cmd.split()) != 0: print 'Compilation failed.' sys.exit(1) android_jar = os.path.join(sdk, 'android.jar') exec_class = os.path.join(package_path, 'Exec.class') print 'Adding %s to %s' % (exec_class, android_jar) zip = zipfile.Zipfile(android_jar, 'a') zip.write(exec_class, 'android/os/Exec.class') zip.close() def add_android_calendar(src_location, sdk_location): print 'Adding adnroid.provider.Calendar to android.jar' sdk = validate_source_and_sdk_locations(src_location, sdk_location) android_java_path = os.path.join(src_location, 'frameworks', 'base', 'core', 'java', 'android') dependence_java = ['provider/Calendar.java', 'content/CursorEntityIterator.java', 'pim/ICalendar.java','pim/EventRecurrence.java'] java_files = [os.path.join(android_java_path, file) for file in dependence_java] java_files.append(os.path.join(src_location,'frameworks/ex/common/java/com/android/common/Rfc822InputFilter.java')) java_files.append(os.path.join(src_location,'frameworks/ex/common/java/com/android/common/Rfc822Validator.java')) files_strs = " ".join(java_files) android_jar = os.path.join(sdk, 'android.jar') tmpdir = 'tmp_calendar' try: os.makedirs(tmpdir) except os.error: pass cmd = 'javac -d %s %s -classpath %s' %(tmpdir, files_strs, android_jar) if subprocess.call(cmd.split()) != 0: print 'Compilation failed' sys.exit(1) zip = zipfile.ZipFile(android_jar, 'a') for dir,subdirs,files in os.walk(tmpdir): for filename in [ f for f in files if f.endswith('.class')]: path = os.path.join(dir,filename) index = path.find('com/android') if index == -1: index = path.find('android') if index == -1: continue print 'Adding %s to android.jar in %s' % (path, path[index:]) zip.write(path, path[index:]) zip.close() if __name__ == '__main__': if len(sys.argv) == 3: src_location, sdk_location = sys.argv[1:3] else: print 'fix_android_sdk.py ' sys.exit(1) try: #copy_sources(src_location,sdk_location) #add_android_os_exec(src_location, sdk_location) add_android_calendar(src_location, sdk_location) except KeyboardInterrupt: print '/nAborted' else: print 'Done!' 

你可能感兴趣的:(android,android,calendar,path,frameworks,java,compilation)