一、来电归属地没有出来
sprd\packages\apps\InCallUI\src\com\sprd\incallui\geocode\GeocodeHelper.java
private static final String KEY = "ro.device.support.geocode";
private static final boolean SUPPORT_SPRD_GROCODE = SystemProperties.getBoolean(KEY, true) && (OperatorUtils.IS_CMCC || OperatorUtils.IS_CUCC);
//SystemProperties.getBoolean(KEY, true),获取ro.device.support.geocode的属性值默认为true
//(OperatorUtils.IS_CMCC || OperatorUtils.IS_CUCC):这个sprd本意实现是想判断是联通还是移动,实际打log出来插入移动 OperatorUtils.IS_CMCC获取的值也是false.
private static final boolean SUPPORT_SPRD_GROCODE = SystemProperties.getBoolean(KEY, true); //zxw modify
二、按照一的做了,还是没有出来,
sprd\packages\apps\InCallUI\src\com\android\incallui\CallCardFragment.java@Overridepublic void onViewCreated(View view, Bundle savedInstanceState) {super.onViewCreated(view, savedInstanceState);.../* SPRD: for call geocode @ { */mGeocodeView = (TextView)view.findViewById(R.id.geocode);Log.d("zxw","setPrimary mGeocodeView = " + mGeocodeView);//打log发现mGeocodeView为空,没有显示来电归属地...}
那么在哪里加入mGeocodeView?
还在CallCardFragment.java,onCreateView有加载layout文件
@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {super.onCreateView(inflater, container, savedInstanceState);mDensity = getResources().getDisplayMetrics().density;View view;// SPRD: add for Universe UIif(SprdUtils.PIKEL_UI_SUPPORT) {view = inflater.inflate(R.layout.call_card_sprd_pikel, container, false);mSimManager = SimManager.get(getActivity());} else if (SprdUtils.UNIVERSE_UI_SUPPORT){view = inflater.inflate(R.layout.call_card_sprd, container, false);mSimManager = SimManager.get(getActivity());} else {view = inflater.inflate(R.layout.call_card, container, false);}return view;}
后面通过分析是走的call_card_sprd_pikel.xml文件,然后在call_card_sprd_pikel.xml会搜到
layout="@layout/primary_call_info_sprd_pikel"/>
所以在primary_call_info_sprd_pikel.xml增加mGeocodeView 控件
sprd\packages\apps\InCallUI\res\layout\primary_call_info_sprd_pikel.xml
加在LinearLayout phoneNumber后面,其实后面发现这样加并不合理,因为屏的分辨率比较小,这样call的状态放到下面去了,看不到了。
后面改成callStateLabel和geocode用LinearLayout包起来,做一行显示
<TextView android:id="@+id/geocode"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_horizontal"android:textColor="@color/incall_main_info_text_color_sprd"android:textSize="@dimen/call_status_text_size"android:singleLine="true"/>callStateLabel和geocode用LinearLayout包起来,做一行显示;
<RelativeLayoutandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"><LinearLayoutandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_horizontal"android:orientation="horizontal"><TextView android:id="@+id/geocode"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_horizontal"android:textColor="@color/incall_main_info_text_color_sprd"android:textSize="@dimen/call_status_text_size"android:singleLine="true"/><TextView android:id="@+id/callStateLabel"android:layout_width="wrap_content"android:layout_height="wrap_content"android:textSize="@dimen/call_status_text_size"android:textColor="@color/incall_main_info_text_color_sprd"android:layout_marginRight="@dimen/call_button_margin_vertical"android:singleLine="true"android:ellipsize="end"/></LinearLayout><!-- Elapsed time indication for a call in progress. --><TextView android:id="@+id/elapsedTime"android:layout_width="wrap_content"android:layout_height="wrap_content"android:textColor="@color/incall_main_info_text_color_sprd"android:singleLine="true"android:textSize="@dimen/call_status_text_size"android:visibility="gone"android:layout_toRightOf="@id/callStateLabel"/><!-- Call type indication: a special label and/or brandingfor certain kinds of calls (like "Internet call" for a SIP call.) --><TextView android:id="@+id/callTypeLabel"android:layout_width="wrap_content"android:layout_height="wrap_content"android:textColor="@color/incall_main_info_text_color_sprd"android:maxLines="1"android:ellipsize="end"android:visibility="gone" /></RelativeLayout>
三、发现还是没有问题。
sprd\packages\apps\InCallUI\src\com\sprd\incallui\geocode\GeocodeHelper.java
public static void getGeocodeMessage(TextView view, String number) {if (isSupportSprdGeocode()) {Log.d(TAG,"zxw getGeocodeMessage number = " + number);if(!TextUtils.isEmpty(number)){GeocodeAsyncTask task = new GeocodeAsyncTask(view, number);task.execute();}} else {Log.w(TAG, " Can not support sprd geocode !");}}
加个log,发现number为空,导致TextUtils.isEmpty(number)为true,!TextUtils.isEmpty(number)为false,导致GeocodeAsyncTask异步线程没有跑进去。
调试时可以赋值一个number: number = new String(“13510678888”);
然后搜索GeocodeHelper,看在哪里会调用GeocodeHelper的getGeocodeMessage方法
sprd\packages\apps\InCallUI\src\com\android\incallui\CallCardFragment.java@Overridepublic void setPrimary(String number, String name, boolean nameIsNumber, String label,Drawable photo, boolean isConference, boolean isGeneric, boolean isSipCall,boolean isRealNoName, String googleGeocode) {Log.d(this, "Setting primary call");if (isConference) {name = getConferenceString(isGeneric);photo = getConferencePhoto(isGeneric);nameIsNumber = false;}Log.d("zxw","setPrimary mGeocodeView = " + mGeocodeView);/* SPRD: Modify for bug789304 @{ */if (mGeocodeView != null) {Log.d("zxw","setPrimary googleGeocode = " + googleGeocode + ",TextUtils.isEmpty(googleGeocode) = " + TextUtils.isEmpty(googleGeocode));if (!TextUtils.isEmpty(googleGeocode)){mGeocodeView.setVisibility(View.VISIBLE);mGeocodeView.setText(googleGeocode);} else if (GeocodeHelper.isSupportSprdGeocode()) {mGeocodeView.setVisibility(View.VISIBLE);GeocodeHelper.getGeocodeMessage(mGeocodeView, nameIsNumber ? name : number); //zxw }else {mGeocodeView.setVisibility(View.GONE);}}
其实在定义CallCardFragment时,
public class CallCardFragment extends BaseFragment<CallCardPresenter, CallCardPresenter.CallCardUi>implements CallCardPresenter.CallCardUi {sprd\packages\apps\InCallUI\src\com\android\incallui\CallCardPresenter.java 有CallCardUi接口的定义public interface CallCardUi extends Ui {void setVisible(boolean on);void setPrimary(String number, String name, boolean nameIsNumber, String label,Drawable photo, boolean isConference, boolean isGeneric, boolean isSipCall,boolean isRealNoName, String googleGeocode); //Modify for bug789304void setSecondary(boolean show, String name, boolean nameIsNumber, String label,Drawable photo, boolean isConference, boolean isGeneric);void setSecondary(boolean show, String number, String name, boolean nameIsNumber, String label,Drawable photo, boolean isConference, boolean isGeneric);void setSecondaryImage(Drawable image);//@orig setCallState(int, Call.DisconnectCause, boolean, String, String);void setCallState(int phoneId, int state, Call.DisconnectCause cause, boolean bluetoothOn,String gatewayLabel, String gatewayNumber);void setPrimaryCallElapsedTime(boolean show, String duration);void setPrimaryName(String name, boolean nameIsNumber, boolean isRealNoName);void setPrimaryImage(Drawable image);void setPrimaryPhoneNumber(String phoneNumber);void setPrimaryLabel(String label);void displayPhoneView(boolean show);}
在CallCardPresenter.java里会发现
private void updatePrimaryDisplayInfo(ContactCacheEntry entry, boolean isConference) {Log.d(TAG, "Update primary display " + entry);final CallCardUi ui = getUi();if (ui == null || mPrimary == null) {// TODO: May also occur if search result comes back after ui is destroyed. Look into// removing that case completely.Log.d(TAG, "updatePrimaryDisplayInfo called but ui or primary call is null!");return;}final boolean isGenericConf = isGenericConference(mPrimary);if (entry != null) {final String name = getNameForCall(entry);final String number = isConference ? mPrimary.getNumber() : getNumberForCall(entry);final String googleGeocode = getGeocodeForCall(entry);final boolean nameIsNumber = name != null && name.equals(entry.number);Log.d(TAG, "zxw updatePrimaryDisplayInfo number = " + number + ",nameIsNumber" + nameIsNumber + ",isConference" + isConference);ui.setPrimary(number, name, nameIsNumber, entry.label, entry.photo,isConference, isGenericConf, entry.isSipCall, entry.isRealNoName, googleGeocode);//zxw 调用CallCardFragment的setPrimary} else {ui.setPrimary(mPrimary.getNumber(), null, false, null, null, isConference,isGenericConf, false, false, null);}}
在CallCardPresenter.java里会发现,会发现因为已经用了sprd的来电归属,所以GeocodeHelper.isSupportGoogleGeocode()一直为false,没有传递contactInfo.number,而是一个name进去,这就是为什么在前面number为空。换成sprd的
private static String getNameForCall(ContactCacheEntry contactInfo) {
//if (TextUtils.isEmpty(contactInfo.name) && GeocodeHelper.isSupportGoogleGeocode()) {
if (TextUtils.isEmpty(contactInfo.name) && GeocodeHelper.isSupportSprdGeocode()) {//zxw modify
return contactInfo.number;
}
return contactInfo.name;
}
四,这个GeocodeAsyncTask任务跑起来了,但doInBackground里执行cursor = context.getContentResolver().query(uri, new String[] {
“province”, “city”
}, number, null, null);报错
D GecodeHelper: zxw doInBackground
01-01 08:02:58.829 1165 1941 W System.err: java.lang.SecurityException: Permission Denial: opening provider com.sprd.providers.geocode.GeocodeProvider from ProcessRecord{41c6e318 1165:com.android.incallui/u0a22} (pid=1165, uid=10022) that is not exported from uid 10012
01-01 08:02:58.829 1165 1941 W System.err: at android.os.Parcel.readException(Parcel.java:1465)
01-01 08:02:58.829 1165 1941 W System.err: at android.os.Parcel.readException(Parcel.java:1419)
01-01 08:02:58.829 660 715 D Settings: newValuesVersion = 15
01-01 08:02:58.829 1165 1941 W System.err: at android.app.ActivityManagerProxy.getContentProvider(ActivityManagerNative.java:2993)
01-01 08:02:58.829 660 715 D Settings: mValues.get(name) = null
01-01 08:02:58.829 1165 1941 W System.err: at android.app.ActivityThread.acquireProvider(ActivityThread.java:4735)
01-01 08:02:58.829 1165 1941 W System.err: at android.app.ContextImpl A p p l i c a t i o n C o n t e n t R e s o l v e r . a c q u i r e U n s t a b l e P r o v i d e r ( C o n t e x t I m p l . j a v a : 2253 ) 01 − 0108 : 02 : 58.82911651941 W S y s t e m . e r r : a t a n d r o i d . c o n t e n t . C o n t e n t R e s o l v e r . a c q u i r e U n s t a b l e P r o v i d e r ( C o n t e n t R e s o l v e r . j a v a : 1425 ) 01 − 0108 : 02 : 58.82911651941 W S y s t e m . e r r : a t a n d r o i d . c o n t e n t . C o n t e n t R e s o l v e r . q u e r y ( C o n t e n t R e s o l v e r . j a v a : 445 ) 01 − 0108 : 02 : 58.82911651941 W S y s t e m . e r r : a t a n d r o i d . c o n t e n t . C o n t e n t R e s o l v e r . q u e r y ( C o n t e n t R e s o l v e r . j a v a : 404 ) 01 − 0108 : 02 : 58.82911651941 W S y s t e m . e r r : a t c o m . s p r d . i n c a l l u i . g e o c o d e . G e o c o d e H e l p e r ApplicationContentResolver.acquireUnstableProvider(ContextImpl.java:2253) 01-01 08:02:58.829 1165 1941 W System.err: at android.content.ContentResolver.acquireUnstableProvider(ContentResolver.java:1425) 01-01 08:02:58.829 1165 1941 W System.err: at android.content.ContentResolver.query(ContentResolver.java:445) 01-01 08:02:58.829 1165 1941 W System.err: at android.content.ContentResolver.query(ContentResolver.java:404) 01-01 08:02:58.829 1165 1941 W System.err: at com.sprd.incallui.geocode.GeocodeHelper ApplicationContentResolver.acquireUnstableProvider(ContextImpl.java:2253)01−0108:02:58.82911651941WSystem.err:atandroid.content.ContentResolver.acquireUnstableProvider(ContentResolver.java:1425)01−0108:02:58.82911651941WSystem.err:atandroid.content.ContentResolver.query(ContentResolver.java:445)01−0108:02:58.82911651941WSystem.err:atandroid.content.ContentResolver.query(ContentResolver.java:404)01−0108:02:58.82911651941WSystem.err:atcom.sprd.incallui.geocode.GeocodeHelperGeocodeAsyncTask.doInBackground(GeocodeHelper.java:69)
01-01 08:02:58.829 1165 1941 W System.err: at com.sprd.incallui.geocode.GeocodeHelper$GeocodeAsyncTask.doInBackground(GeocodeHelper.java:51)
01-01 08:02:58.829 1165 1941 W System.err: at android.os.AsyncTask 2. c a l l ( A s y n c T a s k . j a v a : 288 ) 01 − 0108 : 02 : 58.829832979 D d a l v i k v m : G C F O R A L L O C f r e e d 166 K , 1501 − 0108 : 02 : 58.82911651941 W S y s t e m . e r r : a t j a v a . u t i l . c o n c u r r e n t . F u t u r e T a s k . r u n ( F u t u r e T a s k . j a v a : 237 ) 01 − 0108 : 02 : 58.82911651941 W S y s t e m . e r r : a t a n d r o i d . o s . A s y n c T a s k 2.call(AsyncTask.java:288) 01-01 08:02:58.829 832 979 D dalvikvm: GC_FOR_ALLOC freed 166K, 15% free 3317K/3872K, paused 23ms, total 23ms 01-01 08:02:58.829 1165 1941 W System.err: at java.util.concurrent.FutureTask.run(FutureTask.java:237) 01-01 08:02:58.829 1165 1941 W System.err: at android.os.AsyncTask 2.call(AsyncTask.java:288)01−0108:02:58.829832979Ddalvikvm:GCFORALLOCfreed166K,1501−0108:02:58.82911651941WSystem.err:atjava.util.concurrent.FutureTask.run(FutureTask.java:237)01−0108:02:58.82911651941WSystem.err:atandroid.os.AsyncTaskSerialExecutor 1. r u n ( A s y n c T a s k . j a v a : 231 ) 01 − 0108 : 02 : 58.82911651941 W S y s t e m . e r r : a t j a v a . u t i l . c o n c u r r e n t . T h r e a d P o o l E x e c u t o r . r u n W o r k e r ( T h r e a d P o o l E x e c u t o r . j a v a : 1112 ) 01 − 0108 : 02 : 58.82911651941 W S y s t e m . e r r : a t j a v a . u t i l . c o n c u r r e n t . T h r e a d P o o l E x e c u t o r 1.run(AsyncTask.java:231) 01-01 08:02:58.829 1165 1941 W System.err: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) 01-01 08:02:58.829 1165 1941 W System.err: at java.util.concurrent.ThreadPoolExecutor 1.run(AsyncTask.java:231)01−0108:02:58.82911651941WSystem.err:atjava.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)01−0108:02:58.82911651941WSystem.err:atjava.util.concurrent.ThreadPoolExecutorWorker.run(ThreadPoolExecutor.java:587)
解决:
sprd\packages\providers\ContactsProvider\AndroidManifest.xml
<provider android:name="com.sprd.providers.geocode.GeocodeProvider"android:authorities="gecode_location"android:syncable="false" android:multiprocess="false"android:exported="true"> //之前android:exported="false",允许跨进程通信</provider>
五、读取数据库时,中文为乱码
(1)SQlite中存取的是中文字符时,直接使用cursor.getString读取数据,读出来的数据会出现乱码,此时需要进行一定的转换。
下面是一种有效的读取方法,先以二进制数据从SQLite中读出,再用uft-8对中文进行编码
byte[] procincetemp = cursor.getBlob(cursor.getColumnIndex(“province”));
byte[] citytemp = cursor.getBlob(cursor.getColumnIndex(“city”));
String procince = new String(procincetemp, “utf-8”);
String city = new String(citytemp, “utf-8”);
但是这样就可以正确地显示中文字符,而不是乱码。但需要注意一点就是,这种转换后的字符,结尾多了空格符,需要使用trim函数去除掉
procince = procince.trim();
city = city.trim();
(2)这种方法也可以解决中文字符串乱码
public static String toUtf8(String str) {
String temp = null;
try {
temp = new String(str.getBytes(“UTF-8”), “UTF-8”);
} catch (Exception e) {
e.printStackTrace();
}
return temp;
}
result = toUtf8(result); //将result中文乱码转化为utf-8
六、总结
sprd\packages\apps\InCallUI\src\com\sprd\incallui\geocode\GeocodeHelper.java: context.getContentResolver(…).query --> //context.getContentResolver的query
packages\providers\ContactsProvider\src\com\sprd\providers\geocode\GeocodeProvider.java: Cursor query(…) --> //GeocodeProvider的query
packages\providers\ContactsProvider\src\com\sprd\providers\geocode\GeocodeProvider.java: qb.query(…) //SQLiteQueryBuilder的query