1

在过去的两天里,我一直在探索在我自己的应用程序中使用私有三星框架的可能性,尤其是 /system/frameworks/seccamera.jar。还没有任何效果,所以我想知道这是否可能。

一些背景

我正在开发一个涉及扫描二维码的应用程序,因此非常依赖于相机的图像质量。因此,我正在努力从应用程序级别尽可能多地控制相机。大大提高扫描速度和可靠性的功能之一是相机进行点曝光测光的能力。但是,没有用于指定曝光测光模式的公共 API。

但是,使用 Galaxy Tab 2 上的内置相机应用程序,您可以指定几种曝光测光模式,其中包括点测光模式。所以我决定进一步调查。

我已经尝试过的

  1. 我使用 Eclipse 从 /system/frameworks 中提取了内置相机应用程序的 apk 和 odex 文件
  2. 我通过 baksmali 运行了 odex 文件,最后得到了一些 .smali 文件
  3. 我在它们中搜索“exposureMetering”并找到了一个类 com.sec.android.seccamera.SecCamera,它支持通过其参数内部类指定曝光测光模式
  4. 我确定该类位于 seccamera.jar (seccamera.odex) 中,因此我单独对其进行了 deodex:

    java -jar baksmali-1.3.3.jar --deodex seccamera.odex -o seccamera
    
  5. 然后我再次将它组合在一起:

    java -jar smali-1.3.3.jar seccamera/ -o seccamera.dex
    
  6. 最后我通过 dex2jar 运行 dex-file 来创建一个 jar 库:

    ../dex2jar-0.0.9.8/dex2jar.sh seccamera.dex
    

我将其作为外部 jar 链接到我的 Eclipse 项目。我发现 SecCamera 类具有与公共 android.hardware.Camera 几乎相同的 API,因此它使我的代码转换变得更加容易。

该项目构建没有错误,但是它在启动时几乎立即崩溃,并出现以下错误:

06-28 16:49:31.648: E/AndroidRuntime(2329): FATAL EXCEPTION: main
06-28 16:49:31.648: E/AndroidRuntime(2329): java.lang.NoClassDefFoundError: com.google.zxing.client.android.camera.PreviewCallback
06-28 16:49:31.648: E/AndroidRuntime(2329):     at com.google.zxing.client.android.camera.CameraManager.<init>(CameraManager.java:70)
06-28 16:49:31.648: E/AndroidRuntime(2329):     at com.treelev.biennale.MainActivity.onResume(MainActivity.java:212)
06-28 16:49:31.648: E/AndroidRuntime(2329):     at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1158)
06-28 16:49:31.648: E/AndroidRuntime(2329):     at android.app.Activity.performResume(Activity.java:4539)
06-28 16:49:31.648: E/AndroidRuntime(2329):     at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2448)
06-28 16:49:31.648: E/AndroidRuntime(2329):     at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2486)
06-28 16:49:31.648: E/AndroidRuntime(2329):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2000)
06-28 16:49:31.648: E/AndroidRuntime(2329):     at android.app.ActivityThread.access$600(ActivityThread.java:128)
06-28 16:49:31.648: E/AndroidRuntime(2329):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1161)
06-28 16:49:31.648: E/AndroidRuntime(2329):     at android.os.Handler.dispatchMessage(Handler.java:99)
06-28 16:49:31.648: E/AndroidRuntime(2329):     at android.os.Looper.loop(Looper.java:137)
06-28 16:49:31.648: E/AndroidRuntime(2329):     at android.app.ActivityThread.main(ActivityThread.java:4514)
06-28 16:49:31.648: E/AndroidRuntime(2329):     at java.lang.reflect.Method.invokeNative(Native Method)
06-28 16:49:31.648: E/AndroidRuntime(2329):     at java.lang.reflect.Method.invoke(Method.java:511)
06-28 16:49:31.648: E/AndroidRuntime(2329):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:790)
06-28 16:49:31.648: E/AndroidRuntime(2329):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:557)
06-28 16:49:31.648: E/AndroidRuntime(2329):     at dalvik.system.NativeStart.main(Native Method)

com.google.zxing.client.android.camera.PreviewCallback是我的项目类之一,是我从ZXing项目中借来的,所以很明显。我不得不改变它,所以它实现SecCamera.PreviewCallback而不是Camera.PreviewCallback. 也许这就是这里的罪魁祸首。

在该错误之前,还有一些其他警告:

06-28 16:49:31.625: I/dalvikvm(2329): Failed resolving Lcom/google/zxing/client/android/camera/PreviewCallback; interface 264 'Lcom/sec/android/seccamera/SecCamera$PreviewCallback;'
06-28 16:49:31.625: W/dalvikvm(2329): Link of class 'Lcom/google/zxing/client/android/camera/PreviewCallback;' failed
06-28 16:49:31.625: E/dalvikvm(2329): Could not find class 'com.google.zxing.client.android.camera.PreviewCallback', referenced from method com.google.zxing.client.android.camera.CameraManager.<init>
06-28 16:49:31.625: W/dalvikvm(2329): VFY: unable to resolve new-instance 111 (Lcom/google/zxing/client/android/camera/PreviewCallback;) in Lcom/google/zxing/client/android/camera/CameraManager;
06-28 16:49:31.625: D/dalvikvm(2329): VFY: replacing opcode 0x22 at 0x000c
06-28 16:49:31.632: I/dalvikvm(2329): Could not find method com.sec.android.seccamera.SecCamera.release, referenced from method com.google.zxing.client.android.camera.CameraManager.closeDriver
06-28 16:49:31.632: W/dalvikvm(2329): VFY: unable to resolve virtual method 1436: Lcom/sec/android/seccamera/SecCamera;.release ()V
06-28 16:49:31.632: D/dalvikvm(2329): VFY: replacing opcode 0x6e at 0x0007
06-28 16:49:31.632: I/dalvikvm(2329): Could not find method com.sec.android.seccamera.SecCamera.open, referenced from method com.google.zxing.client.android.camera.CameraManager.openDriver
06-28 16:49:31.632: W/dalvikvm(2329): VFY: unable to resolve static method 1435: Lcom/sec/android/seccamera/SecCamera;.open ()Lcom/sec/android/seccamera/SecCamera;
06-28 16:49:31.632: D/dalvikvm(2329): VFY: replacing opcode 0x71 at 0x0005
06-28 16:49:31.632: I/dalvikvm(2329): Could not find method com.sec.android.seccamera.SecCamera.setPreviewDisplay, referenced from method com.google.zxing.client.android.camera.CameraManager.openDriver
06-28 16:49:31.632: W/dalvikvm(2329): VFY: unable to resolve virtual method 1439: Lcom/sec/android/seccamera/SecCamera;.setPreviewDisplay (Landroid/view/SurfaceHolder;)V
06-28 16:49:31.632: D/dalvikvm(2329): VFY: replacing opcode 0x6e at 0x0016

那么,我在这里做错了什么?是否可以在我的自定义应用程序中使用私有框架(而不是修补现有应用程序)?

4

1 回答 1

1

when using external libs like that, you must inform the package manager to link them at run-time

in this case, you add the following xml to the <application> element in AndroidManifest.xml

<uses-library android:name="seccamera" />

android reads /system/etc/permissions/seccamera.xml at bootup, and maps the seccamera lib name to the file the xml mentions (/system/framework/seccamera.jar in this case)

then when you mark it as a used lib, the os will link that code in at run-time, and your free to use the classes

looks like you already figured out the hard part, making eclipse compile against it

as for 'stealing' the code, as long as you dont share the rebuilt seccamera.jar with anybody and only use it to reference the functions from your code (dont include it into the apk), i dont see any real problem

but samsung may change the API later without warning and break your app

you may also want to mark it as not required 1, or it will refuse to install on devices without that lib

于 2013-05-21T21:00:18.137 回答