在Launcher中动态加载APK,之前有出现过java.lang.SecurityException的异常,
具体的异常信息如下:
09-05 19:05:55.033: E/AndroidRuntime(28637): java.lang.SecurityException: Given caller package com.zhao3546.time is not running in process ProcessRecord{41e74e50 28637:com.zhao3546.launcher/u0a10142}
解决过程参见这个文档:《某APK中使用了动态注册BroadcastReceiver,Launcher中动态加载此APK出现java.lang.SecurityException异常的解决方法》。
这两天我们基于Baidu的APK实现了一个简单的地图应用,在将其动态加载到Launcher中时,发现也遇到了同样的问题,之前的解决虽然可以解决此异常,
但是Baidu地图无法正常显示,看来只能尝试如何解决此异常了。
再重新根据“Given caller package” 关键字,搜索Android的源码,在 frameworks\base\services\java\com\android\server\am 下的 ActivityManagerService.java 中找到了这个异常出现的位置:
public Intent registerReceiver(IApplicationThread caller, String callerPackage, IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { enforceNotIsolatedCaller("registerReceiver"); int callingUid; int callingPid; synchronized(this) { ProcessRecord callerApp = null; if (caller != null) { callerApp = getRecordForAppLocked(caller); if (callerApp == null) { throw new SecurityException( "Unable to find app for caller " + caller + " (pid=" + Binder.getCallingPid() + ") when registering receiver " + receiver); } if (callerApp.info.uid != Process.SYSTEM_UID && !callerApp.pkgList.contains(callerPackage)) { ------------ throw new SecurityException("Given caller package " + callerPackage ------------ + " is not running in process " + callerApp); } callingUid = callerApp.info.uid; callingPid = callerApp.pid; } else { callerPackage = null; callingUid = Binder.getCallingUid(); callingPid = Binder.getCallingPid(); }
根据代码分析,是因为发起此请求的应用所在的进程不是系统进程,并且此进程的包名列表中,并不包含要注册的receiver对应的package名称。
根据此条件“callerApp.info.uid != Process.SYSTEM_UID && !callerApp.pkgList.contains(callerPackage)” ,要解决此问题,可以有两个方法:
1、发起调用方的进程是系统进程;
2、将动态加载的APK的包名发起此请求的进程的pkgList中;
第一个解决方法,对于普通应用来说,基本上实现不了;第二个解决方法,可以进一步研究Android源码找一下解决方法。
callerApp这个对象的类型是ProcessRecord类型的,此类中有如下方法:
/* * Return true if package has been added false if not */ public boolean addPackage(String pkg) { if (!pkgList.contains(pkg)) { pkgList.add(pkg); return true; } return false; }
只要我们在应用代码中,能获取到ProcessRecord对象即可,ActivityManagerService类有如下方法可以获取到ProcessRecord,但是package的方法,
final ProcessRecord getRecordForAppLocked( IApplicationThread thread) { if (thread == null) { return null; } int appIndex = getLRURecordIndexForAppLocked(thread); return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; }
ActivityManagerService类的继承关系如下:
public final class ActivityManagerService extends ActivityManagerNative implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback public abstract class ActivityManagerNative extends Binder implements IActivityManager
应用层要访问ActivityManagerService,必须要通过 ActivityManagerNative.getDefault() 来进行,得到的是一个IActivityManager的对象。
这个对象本身并不对外暴露getRecordForAppLocked()方法,即使暴露,而ProcessRecord类也是Package级别的类,只有同一个包下的类才能访问得到。
看来要走这条路,要对原生代码要做很大的改动才行。
比如Activity.java中要启动一个Activity,可以使用startActivityForResult方法,
public void startActivityForResult(Intent intent, int requestCode, Bundle options) { if (mParent == null) { Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity( this, mMainThread.getApplicationThread(), mToken, this, intent, requestCode, options);
然后又调用了Instrumentation的execStartActivity()方法,
public ActivityResult execStartActivity( Context who, IBinder contextThread, IBinder token, Fragment target, ...... try { intent.setAllowFds(false); intent.migrateExtraStreamToClipData(); int result = ActivityManagerNative.getDefault() .startActivity(whoThread, intent, intent.resolveTypeIfNeeded(who.getContentResolver()), token, target != null ? target.mWho : null, requestCode, 0, null, null, options); checkStartActivityResult(result, intent); } catch (RemoteException e) { } return null;
既然如下,要让此异常不出现,必须要修改framework的代码了,那直接直接注释掉如下代码看看效果:
/* if (callerApp.info.uid != Process.SYSTEM_UID && !callerApp.pkgList.contains(callerPackage)) { throw new SecurityException("Given caller package " + callerPackage + " is not running in process " + callerApp); } */
注释此段代码后,在Android代码的源码目录下,执行如下命令,编译出services.jar
mmm frameworks/base/services/java/
使用此jar替换 /system/framework 下的同名文件,重启Android,再测试,问题解决。
注意:services.jar是系统级的文件,要正常替换,请参考:《做自己的Android ROM,屏蔽对framework中的系统APK的签名检查》
A:android本身的机制,调节volume时不会去控制声卡上的寄存器,而是通过软件算法将volume调大或者调小。声卡控制的音频输出有好几路,每一路都有vol和gain控制着音量大小。
#cat /sys/class/sound/card0/device/RT5631/codec_reg →察看寄存器值
# tinymix 15 20 → Speaker Playback Volume设置为20
# tinymix 18 20 → HP Playback Volume设置为20
root@android:/# tinymix
Numberof controls: 82 ctl type num name value 0 ENUM 1 MIC1Mode Control Differential 1 INT 1 MIC1Boost 3 2 ENUM 1 MIC2Mode Control Differential 3 INT 1 MIC2Boost 3 4 ENUM 1 MONOINMode Control Differential 5 INT 2 MONOIN_RXCapture Volume 23 23 6 INT 2 AXICapture Volume 23 23 7 INT 2 PCMRecord Volume 255 255 8 BOOL 2 PCMRecord Switch On On 9 INT 2 PCMPlayback Volume 255 255 10 BOOL 2 PCMPlayback Switch On On 11 BOOL 1 AXO1Playback Switch On 12 BOOL 1 AXO2Playback Switch On 13 BOOL 2 OUTVOLChannel Switch On On 14 BOOL 2 SpeakerPlayback Switch On On 15 INT 2 SpeakerPlayback Volume 20 20 16 BOOL 1 MONOPlayback Switch Off 17 BOOL 2 HPPlayback Switch On On 18 INT 2 HPPlayback Volume 31 31 19 BOOL 1 DMICSwitch Off 20 BOOL 2 DMICCapture Switch Off Off 21 ENUM 1 SPKRatio Control 1.44x 22 BOOL 1 CallMode Switch Off 23 ENUM 1 HPRMux Right HPVOL 24 ENUM 1 HPLMux Left HPVOL 25 ENUM 1 MONOMux MONOMIX 26 ENUM 1 SPORMux SPORMIX 27 ENUM 1 SPOLMux SPOLMIX 28 BOOL 1 AXO2MIXMixer MIC1_BST1 Playback Switch Off 29 BOOL 1 AXO2MIXMixer MIC2_BST2 Playback Switch Off 30 BOOL 1 AXO2MIXMixer OUTVOLL Playback Switch Off 31 BOOL 1 AXO2MIXMixer OUTVOLR Playback Switch Off 32 BOOL 1 SPORMIXMixer SPKVOLL Playback Switch Off 33 BOOL 1 SPORMIXMixer SPKVOLR Playback Switch On 34 BOOL 1 MONOMIXMixer OUTVOLL Playback Switch Off 35 BOOL 1 MONOMIXMixer OUTVOLR Playback Switch Off 36 BOOL 1 SPOLMIXMixer SPKVOLL Playback Switch On 37 BOOL 1 SPOLMIXMixer SPKVOLR Playback Switch Off 38 BOOL 1 AXO1MIXMixer MIC1_BST1 Playback Switch Off 39 BOOL 1 AXO1MIXMixer MIC2_BST2 Playback Switch Off 40 BOOL 1 AXO1MIXMixer OUTVOLL Playback Switch On 41 BOOL 1 AXO1MIXMixer OUTVOLR Playback Switch Off 42 ENUM 1 RightSPKVOL Mux SPKMIXR 43 ENUM 1 RightHPVOL Mux OUTMIXR 44 ENUM 1 RightOUTVOL Mux OUTMIXR 45 ENUM 1 LeftOUTVOL Mux OUTMIXL 46 ENUM 1 LeftHPVOL Mux OUTMIXL 47 ENUM 1 LeftSPKVOL Mux SPKMIXL 48 BOOL 1 SPKMIXRMixer OUTMIXR Playback Switch Off 49 BOOL 1 SPKMIXRMixer DACR Playback Switch On 50 BOOL 1 SPKMIXRMixer MIC2_P Playback Switch Off 51 BOOL 1 SPKMIXRMixer RECMIXR Playback Switch Off 52 BOOL 1 OUTMIXRMixer VDAC Playback Switch Off 53 BOOL 1 OUTMIXRMixer AXIRVOL Playback Switch Off 54 BOOL 1 OUTMIXRMixer AXILVOL Playback Switch Off 55 BOOL 1 OUTMIXRMixer MONOIN_RXN Playback Switch Off 56 BOOL 1 OUTMIXRMixer MIC2_BST2 Playback Switch Off 57 BOOL 1 OUTMIXRMixer MIC1_BST1 Playback Switch Off 58 BOOL 1 OUTMIXRMixer DACR Playback Switch On 59 BOOL 1 OUTMIXRMixer RECMIXR Playback Switch Off 60 BOOL 1 OUTMIXRMixer RECMIXL Playback Switch Off 61 BOOL 1 OUTMIXLMixer RECMIXL Playback Switch Off 62 BOOL 1 OUTMIXLMixer RECMIXR Playback Switch Off 63 BOOL 1 OUTMIXLMixer DACL Playback Switch On 64 BOOL 1 OUTMIXLMixer MIC1_BST1 Playback Switch Off 65 BOOL 1 OUTMIXLMixer MIC2_BST2 Playback Switch Off 66 BOOL 1 OUTMIXLMixer MONOIN_RXP Playback Switch Off 67 BOOL 1 OUTMIXLMixer AXILVOL Playback Switch Off 68 BOOL 1 OUTMIXLMixer AXIRVOL Playback Switch Off 69 BOOL 1 OUTMIXLMixer VDAC Playback Switch Off 70 BOOL 1 SPKMIXLMixer RECMIXL Playback Switch Off 71 BOOL 1 SPKMIXLMixer MIC1_P Playback Switch Off 72 BOOL 1 SPKMIXLMixer DACL Playback Switch On 73 BOOL 1 SPKMIXLMixer OUTMIXL Playback Switch Off 74 BOOL 1 RECMIXRMixer MONOIN_RX Capture Switch On 75 BOOL 1 RECMIXRMixer AXIRVOL Capture Switch Off 76 BOOL 1 RECMIXRMixer MIC2_BST2 Capture Switch On 77 BOOL 1 RECMIXRMixer OUTMIXR Capture Switch Off 78 BOOL 1 RECMIXLMixer OUTMIXL Capture Switch Off 79 BOOL 1 RECMIXLMixer MIC1_BST1 Capture Switch On 80 BOOL 1 RECMIXLMixer AXILVOL Capture Switch Off 81 BOOL 1 RECMIXLMixer MONOIN_RX Capture Switch On
B:调试kernel、root;进入uboot命令行
最近在做13.56读卡设备,用了STC11F系列单片机。下面把我做的一些开发工具发上来供大家学习下!
① 将压缩包内的UV4.cdb直接替换C:\Keil\UV4目录下的UV4.cdb。
(压缩包内的UV4.cdb已经集合了 keil自带的数据库+STC数据库)
② 将压缩包内的 “STC”文件夹放到C:\Keil\C51\INC目录下。
(压缩包内的“STC”文件夹已经存放了STC所有系列的头文件)
下载的用于keil下的STC器件数据库更名为STC.CDB并拷贝到Keil/UV2或者UV3或UV4目录下。
4、打开Keil文件夹下的TOOLS.ini文件。
5、在[UV2]下键入CDB0="UV2\STC.CDB"("STC")或者CDB0="UV4\STC.CDB"("STC")或者CDB0="UV4\STC.CDB"("STC"),需要单独一行。
6、保存TOOLS.ini文件,添加完毕。
7、启动Keil,打开Options for Target '...'的Device页,
选择Database中“STC”,就可以选择STC单片机了,而且不会影响原来数据库的使用,这相当于另外增加了一个器件选型的数据库文件。
安装:C51V900.exe 与之前ARM的版本不冲突
第②步骤的作用:可以 单击右键 快捷插入STC对应的头文件。
例如:
文件CSDN下载地址 http://download.csdn.net/detail/wangfei447976098/6327529
2.小编后续会整理点13.56的资料发布在个人博客。望大家相互学习交流!
《追风星空》 新浪