Android Message Learning from MTK

Google Native Source Code  谷歌原生代码

设置中的SIM卡管理:SimManagementSettings    siminfo.mDisplayName

Q: 卡槽1插移动2G卡  卡槽2插联通3G卡  且手机、SIM卡、USIM卡都保存有联系人,手机中联系人进行导入导出、新建群组移动、删除等操作后,显示手机/移动卡中的联系人查看 ,显示手机中的联系人时移动卡里面的联系人也会显示 
A: 对于显示的联系人信息这个问题,目前的log中没有相关的信息。 
您在设置要显示的联系人时,请确认是否是设置成只显示Phone中的联系人,还是显示手机/移动卡中的联系人。 
另外,请按以下检查步骤查看各处的filter是否正确: 
(1). 设置要显示的联系人时,对应的可在AccountFilterActivity.java文件中的onItemClick()方法中 
final ContactListFilter filter = (ContactListFilter ) view.getTag; 
语句处下断点或加log,查看此处获得的filter信息是否正确。打印log时可以将filter中的账户名字和账户类型打印出来。 
(2). 在ContactBrowseListFragment.java文件的configureAdapter()方法中 
adapter.setFilter()处设置断点或加log,查看账户信息。 
此处会调用ContactEntryListAdapter.java文件的setFilter()方法设置DefaultContactListAdapter的filter,即联系人列表的过滤条件。 
(3). 在ContactEntryListAdapter.java文件的setFilter()中,可以下断点或加log查看设置的mFilter的accountName和accountType。 
(4). 在DefaultContactListAdapter.java文件的configureLoader()方法中 
ContactListFilter filter = getFilter(); 
语句后也可以打印log,查看得到的filter的信息是否是正常的。 

ALPS00524085
【预置条件】手机有3500以上的联系人
【操作步骤】桌面界面进入联系人,选择3500个联系人删除,按back键返回桌面界面 ,进入系统设置--日期和时间
--自动确定日期和时间--先点击使用GPS提供时间(此功能操作1分钟左右),再点击使用网络提供时间,最后选择关闭
【问题】手机出现黑屏大概1到3秒左右,弹出联系人无响应pop框
发生时间:15:58
【个人分析】
我个人进行5次测试,联系人约3500条,且按照测试步骤,未能复现。
从log中找到的是 anr问题 ANRManager: ANR in com.android.contacts (com.android.contacts/.activities.PeopleActivity)。但是这个anr产生的原因并不是联系人直接导致,是android 的核心进程died。从测试的描述中说 有系统黑屏现象,出现这种现象是因为cpu资源无法分配,然后系统将强制回收cpu资源,03-22 15:59:12.282  9935  9935 D AEE/AED : Android time :[2012-03-22 15:59:01.997] [15179.585]
03-22 15:59:12.282  9935  9935 D AEE/AED : CPU usage from 14772087ms to 44ms ago with 97% awake:。这个log 表明了cpu等待时间突然从 14772087ms to 44ms 。而此时联系人的后台删除任务无法继续进行。由于后台删除联系人时会更新状态栏的进度。在anr的信息中看到"AsyncTask #1"  prio=5 Thread id=91 WAITING 在等待。长时间等待会导致anr。不过该问题不能定性为是谁导致,暂时只能分析到联系人删除3500条需要长时间,而在这个过程中,如果出现android.process.acore 这个进程死掉,联系人免不了要出现无响应,且从本问题的log中找到了这个android.process.acore 进程死掉的信息。分析至此,仍然无法定位问题,由于是once现象,无法下手修改。 

MTK:从贵司提供的现有LOG来看,有发现疑点,贵司安装的com.tencent.tmsecure有cursorLeak, 
且该query的URI是content://com.android.contacts/data/phones, 这样会影响到acroe进程memory被吃掉。 
泄漏到一定程度,可能会导致其它查询contacts的进程的query变慢,或者是无返回结果等。贵司可以先将 
该程序移除掉,看能否复现该问题。还是需要贵司提供下db 文件来确定anr 的正真原因。 
03-22 16:01:00.683 3511 9601 E CursorLeakDetecter: PossibleCursorLeak:content://com.android.contacts/data/phones,QueryCounter:12
03-22 16:01:00.683 3511 9601 E CursorLeakDetecter: android.database.sqlite.DatabaseObjectNotClosedException: Application did not close the cursor or database object that was opened here 
03-22 16:01:00.683 3511 9601 E CursorLeakDetecter: at android.content.ContentResolver.query(ContentResolver.java:399) 
03-22 16:01:00.683 3511 9601 E CursorLeakDetecter: at android.content.ContentResolver.query(ContentResolver.java:316) 
03-22 16:01:00.683 3511 9601 E CursorLeakDetecter: at com.tencent.tmsecure.module.aresengine.DefaultSysDao$b.b(Unknown Source) 
03-22 16:01:00.683 3511 9601 E CursorLeakDetecter: at com.tencent.tmsecure.module.aresengine.DefaultSysDao.getAllContact(Unknown Source) 
03-22 16:01:00.683 3511 9601 E CursorLeakDetecter: at blx.run(Unknown Source) 


 Email中配置文件:res下面一个xml文件夹下面的 providers.xml 的文件。

GB平台相关性能确定:
1. UMTS Release 3GPP baseline Release :R7 
2. UMTS max downlink data rate :21Mbps 
3. UMTS max uplink data rate :5.6Mbps 
4. Cell Broadcast :Yes 
5. Fast Dormancy :Yes 
6. GSM Release 3GPP baseline Release :R5 
7. GSM Frequncy Bands 
7.1 GSM 850 Power Class :Power class 4 
7.2 GSM 900 Power Class :Power Class 4 
7.3 GSM 1800 Power Class :Power Class 1 
7.4 GSM 1900 Power Class :Power Class 1 
8. GSM Security 
8.1 GSM A5/3 :Yes 
8.2 Supported GEA :GEA1,2,3


 1. Voice Codec
           1.1  EFR Yes
           1.2   FR Yes
           1.3  HR Yes
           1.4   AMR NB Yes     支持AMR-NB八种速率:4.75,5.15,5.9,6.7,7.4,7.95,10.2,12.2kbps
             1.5 AMR WB Yes           支持AMR-WB九种速率:6.60,8.85,12.65,14.25,15.85,18.25,19.85,23.05,23.85kbps
2. Qaulity Enchance
           2.1  Noise Cancellation Yes
           2.2  Echo Cancellation Yes
3. Conference Call : Yes
4. USSD Yes
5. Multiple PDP context Support Yes
6. E911 Yes "E911是3GPP標準的測項, In House & SGS測試PASS需要确认拨打911时,手机端需要做的事"
 
BT 相关信息确认
             BT
                   Version 4.0
                   Profiles A2DP 1.2 AVRCP 1.0 HSP 1.2 opp 1.1 HFP 1.5 PBAP 1.0  HID 1.0
                  Power class Class1



Q: rom所剩不多,系统开始清理data下的缓存数据,如何阻止系统删除通话记录、日程记录、短信草稿
A: storage 很低的情况下,如果看不见通话记录、日程记录也是有可能的, 
因为这些信息是保存在DataBase中的,去操作DB是需要storage支持的, 
如果storage很低,可能会发生一些SQLite 相关的Exception,导致load 数据失败, 
从而APP看不见数据,但并不表示这些数据被删除了,只是load 不出来而已。 




Android现在是定时查询linux的流量统计的文件
定时查询的流程如下: 
NetworkStatsService.java: 
private void registerPollAlarmLocked() { 
try { 
if (mPollIntent != null) { 
mAlarmManager.remove(mPollIntent); 
} 

mPollIntent = PendingIntent.getBroadcast( 
mContext, 0, new Intent(ACTION_NETWORK_STATS_POLL), 0); 

final long currentRealtime = SystemClock.elapsedRealtime(); 
mAlarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME, currentRealtime, 
mSettings.getPollInterval(), mPollIntent); 
} catch (RemoteException e) { 
// ignored; service lives in system_server 
} 
} 


public void systemReady() { 
... 
// listen for periodic polling events 
final IntentFilter pollFilter = new IntentFilter(ACTION_NETWORK_STATS_POLL); 
mContext.registerReceiver(mPollReceiver, pollFilter, READ_NETWORK_USAGE_HISTORY, mHandler); 
... 
} 

private BroadcastReceiver mPollReceiver = new BroadcastReceiver() { 
@Override 
public void onReceive(Context context, Intent intent) { 
// on background handler thread, and verified UPDATE_DEVICE_STATS 
// permission above. 
performPoll(FLAG_PERSIST_ALL); 

// verify that we're watching global alert 
registerGlobalAlert(); 
} 
}; 

private void performPoll(int flags) { 
synchronized (mStatsLock) { 
mWakeLock.acquire(); 

// try refreshing time source when stale 
///M: USE_TRUESTED_TIME 
if (mTime.getCacheAge() > mSettings.getTimeCacheMaxAge() && USE_TRUESTED_TIME ) { 
mTime.forceRefresh(); 
} 

try { 
performPollLocked(flags); 
} finally { 
mWakeLock.release(); 
} 
} 
} 

/** 
* Periodic poll operation, reading current statistics and recording into 
* {@link NetworkStatsHistory}. 
*/ 
private void performPollLocked(int flags) { 
if (!mSystemReady) return; 
if (LOGV) Slog.v(TAG, "performPollLocked(flags=0x" + Integer.toHexString(flags) + ")" ); 

final long startRealtime = SystemClock.elapsedRealtime(); 

final boolean persistNetwork = (flags & FLAG_PERSIST_NETWORK) != 0; 
final boolean persistUid = (flags & FLAG_PERSIST_UID) != 0; 
final boolean persistForce = (flags & FLAG_PERSIST_FORCE) != 0; 

// TODO: consider marking "untrusted" times in historical stats 
///M: USE_TRUESTED_TIME 
final long currentTime = (mTime.hasCache() && USE_TRUESTED_TIME) ? mTime.currentTimeMillis() 
: System.currentTimeMillis(); 

try { 
// snapshot and record current counters; read UID stats first to 
// avoid overcounting dev stats. 
final NetworkStats uidSnapshot = getNetworkStatsUidDetail(); 
final NetworkStats xtSnapshot = mNetworkManager.getNetworkStatsSummaryXt(); 
final NetworkStats devSnapshot = mNetworkManager.getNetworkStatsSummaryDev(); 

mDevRecorder.recordSnapshotLocked(devSnapshot, mActiveIfaces, currentTime); 
mXtRecorder.recordSnapshotLocked(xtSnapshot, mActiveIfaces, currentTime); 
mUidRecorder.recordSnapshotLocked(uidSnapshot, mActiveIfaces, currentTime); 
mUidTagRecorder.recordSnapshotLocked(uidSnapshot, mActiveIfaces, currentTime); 
} catch (IllegalStateException e) { 
///M: modify 
Log.e(TAG, "problem reading network stats:"+e); 
return; 
} catch (RemoteException e) { 
// ignored; service lives in system_server 
return; 
} 

// persist any pending data depending on requested flags 
if (persistForce) { 
mDevRecorder.forcePersistLocked(currentTime); 
mXtRecorder.forcePersistLocked(currentTime); 
mUidRecorder.forcePersistLocked(currentTime); 
mUidTagRecorder.forcePersistLocked(currentTime); 
} else { 
if (persistNetwork) { 
mDevRecorder.maybePersistLocked(currentTime); 
mXtRecorder.maybePersistLocked(currentTime); 
} 
if (persistUid) { 
mUidRecorder.maybePersistLocked(currentTime); 
mUidTagRecorder.maybePersistLocked(currentTime); 
} 
} 

if (LOGV) { 
final long duration = SystemClock.elapsedRealtime() - startRealtime; 
Slog.v(TAG, "performPollLocked() took " + duration + "ms"); 
} 


///M: MTK-START Disable EventLog @{ 
/* if (mSettings.getSampleEnabled()) { 
// sample stats after each full poll 
performSampleLocked(); 
} 
*/ 
///@} 

// finally, dispatch updated event to any listeners 
final Intent updatedIntent = new Intent(ACTION_NETWORK_STATS_UPDATED); 
updatedIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 
mContext.sendBroadcastAsUser(updatedIntent, UserHandle.ALL, 
READ_NETWORK_USAGE_HISTORY); 
} 



如果要手动更新数据流量,也可以仿照DataUsageSummary.java中调用NetworkStatsService.forceUpdate(), 
不过如果调用过于频繁,可能会影响整机效率。 
@Override 
public void forceUpdate() { 
mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG); 
assertBandwidthControlEnabled(); 

final long token = Binder.clearCallingIdentity(); 
try { 
performPoll(FLAG_PERSIST_ALL); 
} finally { 
Binder.restoreCallingIdentity(token); 
} 
} 





系统不会清理com.android.providers.settings的数据库 
应该是说所有system 和APP 的私有数据都不会删除 
Rom在低于4M 的时候,只会删除/data/core“和”/data/system/dropbox 下面的部分 
因为这些是debug log 文件,另外还有一部分Cache里面保存的东西,这些东西相当于是运行中产生的temp file 
除此之外其他都不会删除,请知悉,谢谢。 


Q:当手机的ram不足时候,activitymanagerservice 和activitymanager 如何进行kill apps,请描述这个过程,和其中的关键函数。
A:请参考Lowmemorykiller.c(/kernel/driver/staging/android)里面的lowmem_shrink(),android的low memory killer就是从这里去杀进程


小区广播:
1.目前只有 AT&T和T-mobile 运营商支持CMAS。 
2.添加50等频道,请参考FAQ06820。 
3.MTK_CMAS_SUPPORT宏来控制CMAS。


彩信发送报告:
DeliveryReportActivity.java
queryStatusByRecipient()方法


彩信的UA:修改alps\mediatek\config\XXXX\custom.conf文件对应的mms有关的option


短信发送失败:
HQ-->从mobile log中看到多条Mms/Txn : messageFailedToSend(),uri=content://sms/282 error=0
打印,说明确实发送失败。又去查看radio 找对应的at发现01-01 16:24:00.859   236   252 D AT      : +CMS ERROR: 47 该log多次打印,说明也确实不能在网络上发送成功。

MTK-->对于发送短信时,modem 返回 CMS ERROR =47 的错误,从spec 定义的47 error 表示:CMSERROR: 47 Recources unavailable ,当网络比较差的时候,就会报47 的error。 报47 的error,一般是一段时间上网络比较差时,一旦出现47 的error,后续一段时间都是发送失败,并且报47 的error。 
隔一段时间,或者第二天再发送短信,应该就ok了。属于网络问题。

HQ-->当cms error 为47时,短信不可发送,那么此时通话和上网业务是否可用,短信,通话和上网是都用的是相同的通道?还有贵司可有文档来解释 cms error 的code 

MTK-->对于CMS error 47 的错误,短信不可发送,是不影响通话和上网业务的,因为短信走的是CS域,而通话走的也是cs域,但打电话时,向下 下发的命令是ECPI,对于CMS 的error 不是会影响ECPI的命令的。而上网是走PS 域的,在需要上网时,ps需要attach上,才能正常上网。如果有具体的网路的问题的话,就需要负责 网络模块的同仁分析了。 
对于cms error的解释,并没有相应文档,贵司可以查询 24.011 spec。 
对于CMS ERROR 47 : "Resources unavailable, unspecified". 
This cause is used to report a resource unavailable event only when no other cause applies. 


APN配置问题:
提供Log和截图步骤:
1、打开mobile log 
2、在Settings 中查看mms type的apn,并截图; 
3、在Settings中查看default type(browser apn)的apn,并截图 
4、pull 手机中的telephony.db 
5、修改default type(browser apn)的apn,并截图 
6、pull 手机中的telephony.db 
7、查看mms type的apn,并截图; 

相关代码文件:ApnEditor.java ApnSettings.java TelephonyProvider.java

信息已经被discard掉后,仍然被执行save的操作时抛出异常:
HQ-->在短信模块中的代码中WorkingMessage.java文件中的的saveAsMms(boolean notify)函数中有一个异常抛出
throw new IllegalStateException("save() called after discard()")
请问该异常是出现什么样的问题会抛出?

MTK-->这个异常从很早的版本开始就有了,是避免信息已经被discard掉后,仍然被执行save的操作。


短信发送和接收过程,对字符处理的详细过程: 
发送的时候,是在smsDispatcher.java的sendTextWithEncodingTpye()接口 ;里面会调用smsMessage.calculateLength()来编码,可以看看它的实现 
接收的时候,收到网络的PDU后,会调用smsMessage的parsePDU()来进行解码
一般信息用的是GSM7bit和UCS2来传输。

从Log中查看彩信发送和接收页数:
从发送端看出是几页: 
在net log里。搜索发送的pdu(MMS m-send-req ) 
打开该pdu.可以看到该pdu的smil文件,在该smil文件里。一个par对应一页。只要看有几个<par>标签就行了。 

从接收端看出接收的彩信是几页: 
在net log里。搜索接收的pdu(MMS m-retrieve-conf) 
同样打开该pdu.可以看到该pdu的smil文件,在该smil文件里。一个par对应一页。只要看有几个<par>标签就行了。 


短信发送编辑框(7bit)
发送后转化修改的地方还只是在应用层.不涉及有关7bit的编码.发送前转换成gsm7 bit是在framework里.




【FAQ09162】信息中的网址不能被正确识别提取,URL地址显示异常
FAQ代码段中的Pattern.CASE_INSENSITIVE就是忽略大小写,您只需将代码段替换掉Patterns.java中的相应部分即可。


对于OMA CP 的相关资料,请到DMS上 去搜 Omacp 关键字即可。 
如参考DMS上以下路径的 文档Omacp_Customization_Guide_Document.doc : 
/SW/3G Phone Data/Smart Phone/Standard Package/MT6572 SW Doc Package/Application/Browser 


mms中的 query 数据库的操作都是异步的



Messaging里的表情有两部分: 
1. Google default表情字符 
这部分没有改动原样保留,Google原生的是21个,请查看packages/apps/mms/res/values/arrays.xml 里面,有个array叫default_smiley_texts,这21个就是google default的表情。 

2. MTK扩展表情字符 
这部分符号其他手机很可能是不支持的。但这些表情对应的字符组合是经过UI特别设计的,每个字符组合本身传达的意思可以和表情吻合。 

因为输入法只是帮忙将字符表情中的字符一次性输入到输入框中,如果您通过第三方输入法(如华为输入法)输入的表情符号不在上述表情符号中,那么就无法显示出对应的表情图标,而是显示字符组合,而这些字符组合也是会表达一定含义的,并非完全无意义的乱码。所以不会影响用户对短信的基本理解。 
MTK扩展表情字符的资源放在以下目录:alps/packages/apps/mms/res/drawalbe-nodpi 


删除SIM卡中的信息时无法一次性删除完全
删除的信息中包含长短信。因为长短信在SIM卡上面显示是合并起来显示的,所以每次删除都只是删除它的其中一片,所以需要删除几次才能删除完。 
如果一定要解决这个问题,以下提供一个解法,让长短信每片短信都单独显示出来,这样全选的时候就可以将所有短信都选中。 
SmsProvider.java这支文件: 

1. 将getAllMessagesFromIcc()和getAllMessagesFromIcc(int slotId)函数中的如下变量固定为false. 
boolean showInOne = false; 

2. getConcatSmsIndexAndBody(ArrayList<SmsMessage> messages, int index)函数: 

(1) 删除messages.set(i, null);这行代码 

(2)在 int concatCount = concatMsg.size();这行代码后添加一行代码:
/// 
for (int k = 0; k < concatCount; k++) { 
SmsMessage sms = concatMsg.get(k); 
SmsHeader smsHeader = sms.getUserDataHeader(); 
Xlog.d(TAG, " refNumber:" + smsHeader.concatRef.refNumber); 
Xlog.d(TAG, " index:" + sms.getIndexOnIcc()); 
Xlog.d(TAG, " seqNumber:" + smsHeader.concatRef.seqNumber); 
} 
/ 



(3) 在smsBody.append(sms.getDisplayMessageBody());这行代码后添加一行代码: 
messages.remove(sms);//mtkxxx 


多用户权限
<uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
这个权限是与多用户相关的权限.一般情况下,android只有单用户.但是目前在某些特殊的测试case下,需要多用户的权限.因为底linux本身是多用户的OS. 
这个权限本身对应用层来说并不能做什么事.只是android fw 有对这个做检查.如果不加的话.fw是不允许采用多用户的形式运行这个apk. 



禁止使用卡2数据业务
请参考[FAQ09298] 如何禁止卡2建立数据连接 
中的 
// 若仅仅不让卡2上网,但又不影响卡2彩信的使用,还需要加上判断当前是不是彩信apn 

if(mGsmPhone .getMySimId()== PhoneConstants.GEMINI_SIM_2 

/* && !PhoneConstants.APN_TYPE_MMS.equals(apnType)*/){ 


7bit  编辑框中和发送后
要进行有损编码。可以参考FAQ08878. 
其它没有在编码表里的,以空格方式发送可以按以下方式修改: 
一,在GsmAlphabet.countGsmSeptets((CharSequence s, boolean use7bitOnly))这个方法的第一行添加一行: 
use7bitOnly=true; 
(注意:该方法在GsmAlphabet里有三种重载形式,请误加错.) 
二,在 GsmAlphabet的public static byte[] stringToGsm7BitPacked(String data, int startingSeptetOffset, 
boolean throwException, int languageTable, int languageShiftTable) 
throws EncodeException {(注意该文件里很多这个方法的重载,请不要修改错方法)里: 

在该方法的第一行添加:throwException=false;
faq已经阅读 我司的需求是要求 自发自收时,发出的那条和收到的那条显示一致,贵司的这种该法好像不能满足。
有损压缩的话,一旦通过faq的方法修改后,就无法还原了。贵司是希望在输入某个字符后,显示出来就已经是有损压缩后的对应字母是吗?而不仅是发送出去才进行有损编码。

贵司可以在composemessageactivity.java的mTextEditorWatcher里的onTextChanged把字符替换掉. 
比如在onTextChanged里增加s=s.toString().replaceAll("a","*");.就会把a替换成*号. 



彩信重发
【操作步骤】信息--编辑彩信--发送--设置为飞行模式(断开网络)--返回信息发送界面查看状态
【实际结果】短彩信会一直显示发送中,不会提示发送失败
【预期结果】应会显示发送失败图标
彩信在发送过程中切换到飞行模式,会执行重发功能。 
目前代码中默认MMS重发次数为5次,在代码DefaultRetryScheme.java中通过如下变量设定: 
Private static final int[] sDefaultRetryScheme ={ 
0, 1*60*1000, 5*60*1000, 10*60*1000, 30*60*1000}; 
即如果彩信发送失败,会在0分钟,1分钟后,5分钟后,10分钟后,30分钟后重新发送,5次都发送失败后,将不再尝试发送,且将该彩信标志为发送失败状态。用户可以根据实际情况调整sDefaultRetryScheme的定义从而来调整重发次数和时间。在重发功能未完成之前,手机一起会显示正在发送的界面,一定要等到重发执行完成之后,才会提示发送失败。 
以上是MTK功能设计如此


 普通小区广播铃音在任何情景模式都可以响起
cb用的是平台的notification.使用该notification是会受静音影响的.不建议贵司修改.如要修改,在来cb的时候,就不能使用notification进行播放铃声了.
至于如何让铃声不受静音影响.贵司可以尝试以下方法: 
静音模式下,会将受静音影响的铃声类型的音量设为0,如果希望某种铃声不受静音模式的影响,可以先做如下修改: 

1,AudioService.java:中 mRingerModeAffectedStreams保存着静音模式时会影响的streamType,因此如果希望某种类型的声音在静音模式下也能够有声音,就应该将其从mRingerModeAffectedStreams移出: 
1)如,希望通知铃STREAM_NOTIFCATION声在静音下不受影响,添加如下一句: 
private void readPersistedSettings() { 
..... 
mRingerModeAffectedStreams &= ~(1 << AudioSystem.STREAM_SYSTEM_ENFORCED);/*Add this line*/ 
Settings.System.putIntForUser(cr, 
Settings.System.MODE_RINGER_STREAMS_AFFECTED, 
mRingerModeAffectedStreams, 
UserHandle.USER_CURRENT 
2) private class SettingsObserver extends ContentObserver { 
.... 
public void onChange(boolean selfChange) { 
....  
ringerModeAffectedStreams&= ~(1 << AudioSystem.STREAM_SYSTEM_ENFORCED);/*Add this line*/ 
if (ringerModeAffectedStreams != mRingerModeAffectedStreams) { 
/* 
* Ensure all stream types that should be affected by ringer mode 
* are in the proper state. 
*/ 
mRingerModeAffectedStreams = ringerModeAffectedStreams; 
setRingerModeInt(getRingerMode(), false); 
} 


2,对应的播放铃声时就是用上面从mRingerModeAffectedStreams移出不受静音影响的类型,如上面将AudioSystem.STREAM_SYSTEM_ENFORCED从mRingerModeAffectedStreams移出不受静音影响,则Application中使用ringtone播放时设置的streamtype为STREAM_SYSTEM_ENFORCED。

3,贵司可以在CBMessagingNotification.updateNotification的适当位置添加播放铃声的code.比如: 
AudioProfileManager mProfileManager = (AudioProfileManager) context.getSystemService(Context.AUDIOPROFILE_SERVICE); 
String mActiveProfileKey = mProfileManager.getActiveProfileKey(); 
if(mActiveProfileKey!=null){ 
Log.d("mtk_debug", " MessagingNotification.updateNotification 1241 mActiveProfileKey="+mActiveProfileKey); // modify by mtk_debug 2013-12-18; 
if(mActiveProfileKey.equals("mtk_audioprofile_silent")){ 
Log.d("mtk_debug", " MessagingNotification.updateNotification 1243 "); // modify by mtk_debug 2013-12-18; 
// Ringtone r=RingtoneManager.getRingtone(context, Uri.parse(NotificationPreferenceActivity.NOTIFICATION_RINGTONE),7);
// 
Ringtone r = new Ringtone(context, true); 
r.setStreamType(AudioSystem.STREAM_SYSTEM_ENFORCED); 
Log.d("mtk_debug", " MessagingNotification.updateNotification 1253 ringtoneStr="+ringtoneStr); // modify by mtk_debug 2013-12-18; 
r.setUri(Uri.parse(ringtoneStr)); 
r.play(); 
Log.d("mtk_debug", " MessagingNotification.updateNotification 1246 "); // modify by mtk_debug 2013-12-18; 
}




user版本要默认开启mtklog

按照FAQ07631 里面所讲: 
修改手机 /system/etc/ mtklog-config.prop 里的内容为: 

com.mediatek.log.mobile.enabled = true 

com.mediatek.log.modem.enabled = true 

com.mediatek.log.net.enabled = true


短信匹配要求
(this requirement only for 704/02,706/03,708/02,708/020)
two different groups of number with same last 8 bit numbers, show the same person in contacts,  ask for that, messages split displaying.
8 后8位相同的2个不同号码,联系人显示为同一个人,但要求收到短信时分开两条显示
会根据一定的规则分两条显示。
这个问题我们客户提供了一种方案,请帮忙评估下这个方案的可行性!
方案:会话chat list号码后8位匹配,但是前缀以最后一条短信为准,自动更换回信的号码。(如短信chat list为302+A,但是最新的一条短信号码是301+A,则自动回复到301+A上而不是302+A上)【Samsung方案】,所有后8位相同的号码都在同一个会话中。
优点:不影响号码匹配需求;
缺点:所有后8位相同的号码会在同一个会话中;

贵司的方案是可行的: 
“只有收到一条信息时才替换为最新的号码”这个方案,是可行的。 
考虑到收到一条信息生成thread id的逻辑是特殊的,会走SmsProvider的逻辑,所以可以对该段逻辑做修改,而且还不会影响到其他的生成thread的逻辑 
具体做法: 
定位到SmsProvider.java中getSingleAddressId()方法,当从db中匹配到联系人时,用新的联系人替换,并返回替换后的id 

请修改 SmsProvider.java 的 getSingleAddressId()方法,当从db中匹配到联系人时 即在 cursor = db.query("canonical_address", CANONICAL_ADDRESS_COLUMNS_2, selection, selectionArgs, null, null,null); 之后,若cursor有匹配到,就将当前的地址 refinedAddress 保存到 CanonicalAddressesColumns.ADDRESS 即可替换掉原来的address 值,再返回这个id:retVal 即可。 
还请贵司自行修改并验证。

下面是我在getSingleAddressId()里面做的修改,请帮忙看看有没有问题。
private long getSingleAddressId(String address, SQLiteDatabase db) {
boolean isEmail = Mms.isEmailAddress(address);
boolean isPhoneNumber = Mms.isPhoneNumber(address);
/** M: We lowercase all email addresses, but not addresses that aren't numbers, because
* that would incorrectly turn an address such as "My Vodafone" into "my vodafone"
* and the thread title would be incorrect when displayed in the UI.*/
String refinedAddress = isEmail ? address.toLowerCase() : address;
String selection = "address=?";
String[] selectionArgs;
long retVal = -1L;
if (!isPhoneNumber || (address != null && address.length() > NORMAL_NUMBER_MAX_LENGTH)) {
selectionArgs = new String[] { refinedAddress };
} else {
boolean useStrictPhoneNumberComparation = getContext().getResources().getBoolean(
com.android.internal.R.bool.config_use_strict_phone_number_comparation);
selection += " OR " + String.format(Locale.ENGLISH, "PHONE_NUMBERS_EQUAL(address, ?, %d)",
(useStrictPhoneNumberComparation ? 1 : 0));
selectionArgs = new String[] { refinedAddress, refinedAddress };
}
Cursor cursor = null;

try {
cursor = db.query("canonical_addresses", CANONICAL_ADDRESSES_COLUMNS_2,
selection, selectionArgs, null, null, null);

if (cursor.getCount() == 0) {
retVal = insertCanonicalAddresses(db, refinedAddress);
MmsLog.d(TAG, "getSingleAddressId: insert new canonical_address for " + address + ", _id=" + retVal);
return retVal;
} else {
while (cursor.moveToNext()) {
String currentNumber = cursor.getString(cursor.getColumnIndexOrThrow(CanonicalAddressesColumns.ADDRESS));
MmsLog.d(TAG, "getSingleAddressId(): currentNumber != null ? " + (currentNumber != null));
if (currentNumber != null) {
if (refinedAddress.equals(currentNumber) || currentNumber.length() <= NORMAL_NUMBER_MAX_LENGTH) {
retVal = cursor.getLong(cursor.getColumnIndexOrThrow(CanonicalAddressesColumns._ID));
MmsLog.d(TAG, "getSingleAddressId(): get exist id=" + retVal);
//qiyanlong add
ContentValues contentValues = new ContentValues();
contentValues.put(CanonicalAddressesColumns.ADDRESS, refinedAddress);
db.update("canonical_addresses", contentValues, "_id="+ retVal,null);
MmsLog.d(TAG, "getSingleAddressId() refinedAddress =" + refinedAddress);
//end
break;
}
}
}
if (retVal == -1) {
retVal = insertCanonicalAddresses(db, refinedAddress);
}
}
} finally {
if (cursor != null) {
cursor.close();
}
}
return retVal;
}







取消勾选小区广播后,关开机小区广播又自动开启

由于CMAS是紧急小区广播,那么每次开机都会去做两件事:1.activate cb 2.enable CMAS channel 以保证CMAS的接收。而如果是只是添加普通SMS CB,则不会每次都开启。
开机部分的CB部分 log,以供参考: 

Frame #: Time: 938557 Local Time: 18:15:22:600 2013/01/01 Message: [AT_I p46, s9]AT+CSCB? 
Frame #: Time: 938557 Local Time: 18:15:22:600 2013/01/01 Message: [AT_R p46, s9]+CSCB: 1,"","0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,32,33,34,35,36,15",1 
Frame #: Time: 941987 Local Time: 18:15:38:430 2013/01/01 Message: [AT_I p45, s8]AT+CSCB? 
Frame #: Time: 941987 Local Time: 18:15:38:430 2013/01/01 Message: [AT_R p45, s8]+CSCB: 1,"","0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,32,33,34,35,36,15",1 
Frame #: Time: 943134 Local Time: 18:15:43:723 2013/01/01 Message: [AT_I p46, s9]AT+CSCB? 
Frame #: Time: 943134 Local Time: 18:15:43:723 2013/01/01 Message: [AT_R p46, s9]+CSCB: 1,"","0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,32,33,34,35,36,15",1 
Frame #: Time: 943134 Local Time: 18:15:43:723 2013/01/01 Message: [AT_I p46, s9]AT+CSCB=0, "", "0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,32,33,34,35,36,15" 
Frame #: Time: 943166 Local Time: 18:15:43:871 2013/01/01 Message: [AT_I p46, s9]AT+CSCB? 
Frame #: Time: 943166 Local Time: 18:15:43:871 2013/01/01 Message: [AT_R p46, s9]+CSCB: 0,"","0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,32,33,34,35,36,15",1 
Frame #: Time: 943166 Local Time: 18:15:43:871 2013/01/01 Message: [AT_I p46, s9]AT+CSCB=1, "", "0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,32,33,34,35,36,15" 
Frame #: Time: 943216 Local Time: 18:15:44:101 2013/01/01 Message: [AT_I p46, s9]AT+CSCB=0, "4370-4381" 
Frame #: Time: 943243 Local Time: 18:15:44:226 2013/01/01 Message: [AT_I p46, s9]AT+CSCB=0, "", "", 1 
Frame #: Time: 943256 Local Time: 18:15:44:286 2013/01/01 Message: [AT_I p46, s9]AT+CSCB? 
Frame #: Time: 943256 Local Time: 18:15:44:286 2013/01/01 Message: [AT_R p46, s9]+CSCB: 0,"4370-4381","",1 
Frame #: Time: 943256 Local Time: 18:15:44:286 2013/01/01 Message: [AT_I p46, s9]AT+CSCB=0, "4370-4381", "" 
Frame #: Time: 967718 Local Time: 18:17:37:178 2013/01/01 Message: [AT_I p45, s8]AT+CSCB? 
Frame #: Time: 967718 Local Time: 18:17:37:178 2013/01/01 Message: [AT_R p45, s8]+CSCB: 0,"4370-4381","0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,32,33,34,35,36,15",1 



小区广播答疑
无SIM卡也能收CB,这是目前的设计行为, 
因为很多小区广播是紧急预警的,例如地震、气象等紧急信息,像拨打紧急电话类似,不插卡也要可以work 不可以关掉。所以只要手机能连上网络(比如拨打112等,能拨打紧急电话的网络),运营商发出CB,手机就能正常接收CB,请知悉。 

这个是所有运营商发出的小区广播都可以接收到吗,应该是一些特殊频道的才可以接收吧? 
-> 手机注册到哪家运营商的网络,就可以接收到其发出的小区广播。 

我们知道有几个特殊的频道是预报海啸,地震的,但我们内网是50频道,为什么也可以接收? 
-> 其实小区广播接收与SIM卡并无关系,只要注册到网络,就可以接收到运营商下发的广播。既然贵司已经预置了50频道,那么肯定可以接收。不过插入SIM卡可以进行小区广播的相关设置,比如设置小区广播语言及频道。 


【MT6572GB】【AW290华为】接收小区广播后,mms 异常中止  Android 2.3
发现小区广播空指针,(CBMessageListActivity.java:210):
03-26 09:32:14.809  5437  5437 E AndroidRuntime: Caused by: java.lang.NullPointerException
03-26 09:32:14.809  5437  5437 E AndroidRuntime: at com.android.mms.ui.CBMessageListActivity.initialize(CBMessageListActivity.java:210)
03-26 09:32:14.809  5437  5437 E AndroidRuntime: at com.android.mms.ui.CBMessageListActivity.onCreate(CBMessageListActivity.java:199)
03-26 09:32:14.809  5437  5437 E AndroidRuntime: at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1149)
03-26 09:32:14.809  5437  5437 E AndroidRuntime: at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1793)
03-26 09:32:14.809  5437  5437 E AndroidRuntime: ... 11 more
空的原因是mConversation为空,查看代码,发现mConversation为空的原因是 CBMessageListActivity.java中的initActivityState()函数的bundle不为空,直接return,不去获取mConversation对象了。
同时发现在CBMessageListActivity 无onsaveInsanceState函数重写.
查看贵司4.2的代码,发现贵司有进行onsaveInsanceState的重写,并且记录了thread id在bundle中。同时在initActivityState对bundle进行判断,如果bundle不为空则读取thread id,但是在我司2.3的code上当bundle 不为空,则return。正式这个return导致问题出现。
请贵司释放2.3的对应的解决code。

请参考以下进行修改: 
在CBMessageListActivity.java 文件开头先定义一个宏 THREADID: 
private static final String THREADID = "thread_id"; 
再修改: 
1. 修改方法: 
private void initActivityState(Bundle bundle, Intent intent) { 
long threadId = 0; 
if (bundle != null) { 
// TODO process bundle != null 
// return; 
threadId = bundle.getLong(THREADID, 0); 
}else{ 

threadId = intent.getLongExtra(THREADID , 0); 
} 
// If we have been passed a thread_id, use that to find our 
// conversation. 
// long threadId = intent.getLongExtra("thread_id", 0); 
if (threadId > 0) { 
mConversation = Conversation.get(this, threadId, false); 
} else { 
Uri intentData = intent.getData(); 
if (intentData != null) { 
// try to get a conversation based on the data URI passed to our intent. 
mConversation = Conversation.get(this, intent.getData(), false); 
} else { 
mConversation = Conversation.createNew(this); 
} 
} 
} 



2. 添加onSaveInstanceState()方法: 
@Override 
public void onSaveInstanceState(Bundle outState) { 
super.onSaveInstanceState(outState); 
// save the current thread id 
outState.putLong(THREADID, mConversation.getThreadId()); 
Xlog.i(LogTag.CB, "saved thread id:" + mConversation.getThreadId()); 
} 




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值