问题描述:我在一个 app 中调用PowerManager 中的接口时,编译ok, 但运行时崩溃了。检查 log 出现下述错误。
: FATAL EXCEPTION: main
: java.lang.SecurityException: Neither user 10050 nor current process has android.permission.DEVICE_POWER.
: at android.os.Parcel.readException(Parcel.java:1425)
: at android.os.Parcel.readException(Parcel.java:1379)
: at android.os.IPowerManager$Stub$Proxy.preventScreenOn(IPowerManager.java:637)
: at com.android.camera.Camera$PostDrawListener.onPostDraw(Camera.java:1968)
: at android.view.ViewTreeObserver.dispatchOnPostDraw(ViewTreeObserver.java:760)
: at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2320)
: at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2118)
: at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1136)
: at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4631)
: at android.view.Choreographer$CallbackRecord.run(Choreographer.java:747)
: at android.view.Choreographer.doCallbacks(Choreographer.java:567)
: at android.view.Choreographer.doFrame(Choreographer.java:536)
: at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:733)
: at android.os.Handler.handleCallback(Handler.java:615)
: at android.os.Handler.dispatchMessage(Handler.java:92)
: at android.os.Looper.loop(Looper.java:153)
: at android.app.ActivityThread.main(ActivityThread.java:5104)
: at java.lang.reflect.Method.invokeNative(Native Method)
: at java.lang.reflect.Method.invoke(Method.java:511)
: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:821)
: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:584)
: at dalvik.system.NativeStart.main(Native Method)
调用代码如下所示:
private class PostDrawListener implements android.view.ViewTreeObserver.OnPostDrawListener {
public boolean onPostDraw() {
// 监听到绘图完成
try {
mPowerManagerService.preventScreenOn(false); // 调用电源管理的接口,点亮屏幕
} catch (RemoteException e) {
Log.w(TAG, "mPowerManagerService.preventScreenOn() failed: " + e);
}
return true;
}
}
跟据出错信息的提示来看,应该是没有权限导致。
但是我分明已经在 AndroidManifest.xml 中添加了该权限啊
<user-permission android:name="android.permission.DEVICE_POWER"/>
上网搜索,有人反馈说是该问题是由于该应用未获得系统签名。
了解了一下签名,有如下几种:
1、testkey:普通APK,默认情况下使用。
2、platform:该APK完成一些系统的核心功能。经过对系统中存在的文件夹的访问测试,这种方式编译出来的APK所在进程的UID为system。
3、shared:该APK需要和home/contacts进程共享数据。
4、media:该APK是media/download系统中的一环。
需要修改两处地方:
第一,在 android.mk 文件中将LOCAL_CERTIFICATE 改为系统签名,即如下
LOCAL_CERTIFICATE := platform
第二,在 AndroidManifest.xml 文件中将 manifest 的android:sharedUserId 属性改为android.uid.system,如下所示:
<manifest android:versionCode="40000"
android:versionName="1.1.40000"
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.gallery3d"
android:sharedUserId="android.uid.system">
再编译,就ok了。
虽然编译运行都ok,但是估计还会有潜在的风险。
参考文献:
http://blog.csdn.net/a345017062/article/details/6236263
http://www.ophonesdn.com/forum/thread-5094-8-1.html