火凹吧 关注:2贴子:48
  • 8回复贴,共1

收藏│向phone.apk中添加来电归属地功能〔需要一定基础〕

只看楼主收藏回复

转自机锋论坛


IP属地:安徽来自Android客户端1楼2013-10-29 22:40回复
    下面的例子是以WQY-CM637-XT720中Phone.apk为例,加入来电归属地功能的。
    首先说明的是,此教程为高级教程,像如何搭建编译环境、如何反编译、如何回编译、如何进行系统签名、使用哪些工具等,由于本教程已经很长了,因而就不做说明了,本教程适合高手操作,小白建议路过,但其中的技巧、关键注意事项等仍然值得学习。
    另外需要说明的,本教程中使用了系统原有变量,因而需要对apk框架结构、Dalvik代码、Java源代码相当熟悉,才能理解各步的含义,许多步骤所写代码实际上是结合原有代码的基础上编写的,不同Phone.apk中代码不同,上下文代码不能直接复制过去。
    第三还说明的是,这是系列高级教程,而且是独此一家,为尊重作者WQY88的劳动,如果转载请注明出处,一经发现乱喷乱转,立即删帖并不再发布任何其他高级教程,比如关机菜单快速重启功能实现,比如双向通话录音功能实现,如何解决来电错位,将apk链接动态加入设置,如何高级调试apk,如何添加省电代码,如何添加极速代码,如何用apk即时生成脚本并运行(当然我不准备编写木马,呵呵),如何高级移植其他ROM功能(包括三星、里程碑等其他ROM)等等,将会永无发布之日。
    一、向res文件中加入相关布局及变量
    思路,先将有来电归属功能的Phone.apk与原生的Phone.apk都反编译,再用Beyond软件进行比对,查找与phoneLocview等关键词有关的项目进行相应的添加操作
    1、反编译原生Phone.apk,进入res目录,将其他语言删除(方便编译,如果真的需要以后可以再加入进来)
    2、向values\public.xml中添加相关代码
    (1)根据id项的最大id值是7f0600a8,于是添加
    <public type="id" name="phoneLocview" id="0x7f0600a9" />
    (2)根据string最大id是7f0b0203,于是继续添加
    <public type="string" name="phoneloc_view" id="0x7f0b0204" />
    <public type="string" name="phoneloc_view_sum" id="0x7f0b0205" />
    3、向values\string.xml中添加相关代码,直接在最后加上
    <string name="phoneloc_view">Chinese phone location</string>
    <string name="phoneloc_view_sum">Chinese phone location will be shown on in-call screen</string>
    4、向values\ids.xml中添加相关代码,位置没有特殊要求
    <item type="id" name="phoneLocview">false</item>
    5、向xml\call_feature_setting.xml中添加代码
    <CheckBoxPreference android:persistent="false" android:title="@string/phoneloc_view" android:key="china_phoneloc_view" android:summary="@string/phoneloc_view_sum" />
    6、向layout\call_card_person_info.xml中添加代码
    <TextView android:textAppearance="?android:textAppearanceSmall" android:textSize="18.0sp" android:textColor="?android:textColorSecondary" android:id="@id/phoneLocview" android:layout_width="wrap_content" android:layout_height="wrap_content" android:singleLine="true" />
    此时,最好回编译一下看有没有差错,如果存在差错,一般是变量缺少或者最大id没有添加正确,最大id之后要连续,而且是16进制,9之后是a,一定要注意。I


    IP属地:安徽来自Android客户端2楼2013-10-29 22:41
    回复
      二、、向smali文件中加入相关代码
      思路,将有来电归属功能的Phone.apk与原生的Phon.apk中的Classes.dex用压缩软件提取出来,然后用dex2jar软件转换成jar文件,再用jdgui.exe文件查看源代码,如果有必要可以将其相关代码复制出来用Beyond软件进行文本比较,在此基础上将上步反编译的代码进行比较,对照修改,注意每改一处最好回编译一下,看是否有差错,以便及时改过来。经研究location中的代码,发现只需要修改CallCard.smali与CallFeaturesSetting.smali这两个文件即可
      7、将有来电归属功能的Phone.apk反编译得到的location文件夹复制到com\android\phone目录下。反编译查看不FC。
      8、在Beyong中查找view及phoneloc关键词,进行如下操作
      (1)修改com\android\phone\CallFeaturesSetting.smali文件
      ①找到.field private static final CATEGORY_BLACK/java/lang/String; = "cat_black_list"在其后面加上
      .field private static final CHINA_PHONELOC_VIEW/java/lang/String; = "china_phoneloc_view"
      ②在.field static mLeftHand:Z后面加上
      .field public static mLocview:Z
      ③在.field mChangingVMorFwdDueToProviderChange:Z后面加上
      .field private mChinaPhonelocview/android/preference/CheckBoxPreference;
      ④查找关键词.method private init(Landroid/content/Context;Landroid/content/SharedPreferences;)V
      在const/4 v14, 0x0与const-string v13, "button_vibrate_outgoing"之间加上
      const-string v13, "china_phoneloc_view"
      move-object/from16 v0, p2
      move-object v1, v13
      move v2, v15
      invoke-interface {v0, v1, v2}, Landroid/content/SharedPreferences;->getBoolean(Ljava/lang/String;Z)Z
      move-result v13
      sput-boolean v13, Lcom/android/phone/CallFeaturesSetting;->mLocview:Z
      ⑤在 .line 1512
      invoke-virtual {p0}, Lcom/android/phone/CallFeaturesSetting;->getApplicationContext()Landroid/content/Context;
      move-result-object v4
      invoke-virtual {p0}, Lcom/android/phone/CallFeaturesSetting;->getApplicationContext()Landroid/content/Context;
      move-result-object v5
      invoke-static {v5}, Landroid/preference/PreferenceManager;->getDefaultSharedPreferences(Landroid/content/Context;)Landroid/content/SharedPreferences;
      move-result-object v5与
      .line 1513
      const-string v4, "button_vibrate_outgoing"之间添加
      invoke-direct {p0, v4, v5}, Lcom/android/phone/CallFeaturesSetting;->init(Landroid/content/Context;Landroid/content/SharedPreferences;)V
      .line 1506
      const-string v4, "china_phoneloc_view"
      invoke-virtual {v3, v4}, Landroid/preference/PreferenceScreen;->findPreference(Ljava/lang/CharSequence;)Landroid/preference/Preference;
      move-result-object v4
      check-cast v4, Landroid/preference/CheckBoxPreference;
      iput-object v4, p0, Lcom/android/phone/CallFeaturesSetting;->mChinaPhonelocview/android/preference/CheckBoxPreference;
      iget-object v4, p0, Lcom/android/phone/CallFeaturesSetting;->mChinaPhonelocview/android/preference/CheckBoxPreference;
      sget-boolean v5, Lcom/android/phone/CallFeaturesSetting;->mLocview:Z
      invoke-virtual {v4, v5}, Landroid/preference/CheckBoxPreference;->setChecked(Z)V
      ⑥找到 .line 2009
      .local v1, outState/android/content/SharedPreferences$Editor;在其后与
      const-string v3, "button_vibrate_outgoing"之间添加
      const-string v3, "china_phoneloc_view"
      iget-object v4, p0, Lcom/android/phone/CallFeaturesSetting;->mChinaPhonelocview/android/preference/CheckBoxPreference;
      invoke-virtual {v4}, Landroid/preference/CheckBoxPreference;->isChecked()Z
      move-result v4
      invoke-interface {v1, v3, v4}, Landroid/content/SharedPreferences$Editor;->putBoolean(Ljava/lang/String;Z)Landroid/content/SharedPreferences$Editor;
      以上每加一步,最好看一下能否回编译,其中有些变量直接使用已存在变量进行重新调用,并没有增加变量,因而要回编译后,再dex2jar,再用jdgui查看是否达到效果。I


      IP属地:安徽来自Android客户端3楼2013-10-29 22:47
      回复
        (2)修改com\android\phone\CallCard.smali文件
        ①在.field private mOrganization/android/widget/TextView;后面添加
        .field private mPhoneLocview/android/widget/TextView;
        ② 在 .line 538
        move-object/from16 v0, p0与
        iget-object v0, v0, Lcom/android/phone/CallCard;->mLabel/android/widget/TextView;之间添加
        iget-object v0, v0, Lcom/android/phone/CallCard;->mPhoneLocviewandroid/widget/TextView;
        move-object/from16 v16, v0
        move-object/from16 v0, p0
        iget v0, v0, Lcom/android/phone/CallCard;->mRotarySelectorHintTextResId:I
        move/from16 v17, v0
        invoke-static/range {v17 .. v17}, Ljava/lang/String;->valueOf(I)Ljava/lang/String;
        move-result-object v17
        invoke-static/range {v17 .. v17}, Lcom/android/phone/location/PhoneLocation;->getCityFromPhone(Ljava/lang/String;)Ljava/lang/String;
        move-result-object v17
        invoke-virtual/range {v16 .. v17}, Landroid/widget/TextView;->setText(Ljava/lang/CharSequence;)V
        .line 544
        move-object/from16 v0, p0
        iget-object v0, v0, Lcom/android/phone/CallCard;->mPhoneLocviewandroid/widget/TextView;
        move-object/from16 v16, v0
        invoke-virtual/range {p0 .. p0}, Lcom/android/phone/CallCard;->getResources()Landroid/content/res/Resources;
        move-result-object v17
        move-object/from16 v0, p0
        iget v0, v0, Lcom/android/phone/CallCard;->mRotarySelectorHintColorResId:I
        move/from16 v18, v0
        invoke-virtual/range {v17 .. v18}, Landroid/content/res/Resources;->getColor(I)I
        move-result v17
        invoke-virtual/range {v16 .. v17}, Landroid/widget/TextView;->setTextColor(I)V
        .line 545
        move-object/from16 v0, p0
        iget-object v0, v0, Lcom/android/phone/CallCard;->mPhoneLocviewandroid/widget/TextView;
        move-object/from16 v16, v0
        const/16 v17, 0x0
        invoke-virtual/range {v16 .. v17}, Landroid/widget/TextView;->setVisibility(I)V
        .line 547
        move-object/from16 v0, p0
        ③在 .line 1262
        iget-object v1, p0, Lcom/android/phone/CallCard;->mPhoneNumberandroid/widget/TextView;
        invoke-virtual {v1, v3}, Landroid/widget/TextView;->setVisibility(I)V与
        iget-object v1, p0, Lcom/android/phone/CallCard;->mLabelandroid/widget/TextView;之间添加
        iget-object v1, p0, Lcom/android/phone/CallCard;->mPhoneLocviewandroid/widget/TextView;
        invoke-virtual {v1, v3}, Landroid/widget/TextView;->setVisibility(I)V
        ④找到.method private updateDisplayForPerson(Lcom/android/internal/telephony/CallerInfo;IZLcom/android/internal/telephony/Call;)V将其下面的.locals 17改为
        .locals 20 #Add 3 var
        ⑥在 .line 1028
        .local v9, personUriandroid/net/Uri;与
        const/4 v15, 0x0
        .line 1029
        .local v15, socialStatusTextjava/lang/String;之间添加
        const/16 v19, 0x0
        const/16 v17, 0x0
        .line 1042
        .local v17, nullinfo:Z
        #const/4 v15, 0x0
        .line 1044
        #.local v15, locview:ZI


        IP属地:安徽来自Android客户端4楼2013-10-29 22:49
        回复
          ⑦在 iget-object v0, v0, Lcom/android/phone/CallCard;->mPhoneNumberandroid/widget/TextView;
          move-object v3, v0
          const/4 v4, 0x0
          invoke-virtual {v3, v4}, Landroid/widget/TextView;->setVisibility(I)V与
          iget-object v0, v0, Lcom/android/phone/CallCard;->mLabelandroid/widget/TextView;之间修改并添加
          invoke-static {v11}, Lcom/android/phone/location/PhoneLocation;->getCityFromPhone(Ljava/lang/String;)Ljava/lang/String;
          move-result-object v3
          if-eqz v3, :cond_22
          move-object/from16 v0, p0
          iget-object v0, v0, Lcom/android/phone/CallCard;->mPhoneLocview:Landroid/widget/TextView;
          move-object v3, v0
          invoke-static {v11}, Lcom/android/phone/location/PhoneLocation;->getCityFromPhone(Ljava/lang/String;)Ljava/lang/String;
          move-result-object v4
          invoke-virtual {v3, v4}, Landroid/widget/TextView;->setText(Ljava/lang/CharSequence;)V
          .line 1127
          move-object/from16 v0, p0
          iget-object v0, v0, Lcom/android/phone/CallCard;->mPhoneLocview:Landroid/widget/TextView;
          move-object v3, v0
          move-object/from16 v0, p0
          iget v0, v0, Lcom/android/phone/CallCard;->mTextColorDefaultSecondary:I
          move v4, v0
          invoke-virtual {v3, v4}, Landroid/widget/TextView;->setTextColor(I)V
          const/16 v19, 0x1
          :cond_22
          :goto_4
          if-eqz v17, :cond_33 #v12-->v17
          if-eqz v13, :cond_33
          invoke-virtual/range {p4 .. p4}, Lcom/android/internal/telephony/Call;->isGeneric()Z
          move-result v3
          if-nez v3, :cond_33
          invoke-static/range {v13 .. v13}, Lcom/android/phone/location/PhoneLocation;->getCityFromPhone(Ljava/lang/String;)Ljava/lang/String;
          move-result-object v3
          if-eqz v3, :cond_33
          move-object/from16 v0, p0
          iget-object v0, v0, Lcom/android/phone/CallCard;->mPhoneLocview:Landroid/widget/TextView;
          move-object v3, v0
          invoke-static/range {v13 .. v13}, Lcom/android/phone/location/PhoneLocation;->getCityFromPhone(Ljava/lang/String;)Ljava/lang/String;
          move-result-object v4
          invoke-virtual {v3, v4}, Landroid/widget/TextView;->setText(Ljava/lang/CharSequence;)V
          move-object/from16 v0, p0
          iget-object v0, v0, Lcom/android/phone/CallCard;->mPhoneLocview:Landroid/widget/TextView;
          move-object v3, v0
          move-object/from16 v0, p0
          iget v0, v0, Lcom/android/phone/CallCard;->mTextColorDefaultSecondary:I
          move v4, v0
          invoke-virtual {v3, v4}, Landroid/widget/TextView;->setTextColor(I)V
          .line 1128
          const/16 v19, 0x1
          :cond_33
          if-eqz v19, :cond_d
          move-object/from16 v0, p0
          iget-object v0, v0, Lcom/android/phone/CallCard;->mPhoneLocview:Landroid/widget/TextView;
          move-object v3, v0
          const/4 v4, 0x0
          invoke-virtual {v3, v4}, Landroid/widget/TextView;->setVisibility(I)V
          :goto_55
          if-eqz v12, :cond_e
          invoke-virtual/range {p4 .. p4}, Lcom/android/internal/telephony/Call;->isGeneric()Z
          move-result v3
          if-nez v3, :cond_e
          move-object/from16 v0, p0
          ⑧在 iget-object v0, v0, Lcom/android/internal/telephony/CallerInfo;->phoneNumber:Ljava/lang/String;
          move-object v13, v0
          .restart local v13 #name:Ljava/lang/String;与
          goto/16 :goto_0
          .line 1063 之间添加
          const/16 v17, 0x1
          ⑨在 invoke-virtual {v3, v4}, Landroid/widget/TextView;->setVisibility(I)V
          goto/16 :goto_4
          .line 1131
          :cond_d
          move-object/from16 v0, p0与
          move-object v3, v0
          const/16 v4, 0x8
          invoke-virtual {v3, v4}, Landroid/widget/TextView;->setVisibility(I)V之间添加并修改为
          iget-object v0, v0, Lcom/android/phone/CallCard;->mPhoneLocview:Landroid/widget/TextView;
          并在刚才的 move-object v3, v0
          const/16 v4, 0x8
          invoke-virtual {v3, v4}, Landroid/widget/TextView;->setVisibility(I)V与
          .line 1144
          :cond_e之间继续修改为
          goto/16 :goto_55I


          IP属地:安徽来自Android客户端5楼2013-10-29 22:50
          回复
            ⑩找到 invoke-direct {p0, p1, v0}, Lcom/android/phone/CallCard;->dispatchPopulateAccessibilityEvent(Landroid/view/accessibility/AccessibilityEvent;Landroid/view/View;)V
            iget-object v0, p0, Lcom/android/phone/CallCard;->mLabel:Landroid/widget/TextView;并在二者之间添加
            iget-object v0, p0, Lcom/android/phone/CallCard;->mPhoneLocview:Landroid/widget/TextView;
            invoke-direct {p0, p1, v0}, Lcom/android/phone/CallCard;->dispatchPopulateAccessibilityEvent(Landroid/view/accessibility/AccessibilityEvent;Landroid/view/View;)V
            ⑾在 .line 194
            const v0, 0x7f0600a9
            invoke-virtual {p0, v0}, Lcom/android/phone/CallCard;->findViewById(I)Landroid/view/View;
            move-result-object v0
            check-cast v0, Landroid/widget/TextView;与
            iput-object v0, p0, Lcom/android/phone/CallCard;->mLabel:Landroid/widget/TextView;
            .line 195
            const v0, 0x7f060029之间添加
            iput-object v0, p0, Lcom/android/phone/CallCard;->mPhoneLocview:Landroid/widget/TextView;
            .line 198
            const v0, 0x7f060027
            invoke-virtual {p0, v0}, Lcom/android/phone/CallCard;->findViewById(I)Landroid/view/View;
            move-result-object v0
            check-cast v0, Landroid/widget/TextView;
            最后别忘记将有来电归属地功能的Phone中的location文件夹复制过去。
            修改完毕,每一步的修改,都重新调用了原有的变量,个别地方添加了两个变量,每一步都及时回编译,并dex2jar,然后用jdgui对比查看是否达到源码的效果。
            经回编译后,用platform签名后,正常运行,能显示来电归属地,点选设置-通话设置,功能正常,比CM7多了一个未接来电Led显示。I


            IP属地:安徽来自Android客户端6楼2013-10-29 22:51
            回复
              这篇教程并不通用,供借鉴用。有些地方不够完善,但写教程本来就不容易,难免疏忽。
              其中第一大步是在通话设置里添加是否显示来电归属地选项,个人感觉可以不做,但要修改location文件夹里的smali代码,去掉其中的几个判断语句。
              第二大步是重点,不能出错。另外location里用到libphoneloc-jn2.so文件,没有的话要把它加到system/lib里。
              由于不明原因,虽然改好了,可是没显示,有时间再检查一下。I


              IP属地:安徽来自Android客户端7楼2013-10-29 23:05
              回复
                我选的是v880的拨号器
                http://w删ww.romzhijia.net/romdetail/607DB7D2-274A-4580-A40A-E6741EC762B5
                转载地址
                http://b删bs.gfan.com/forum.php?mod=viewthread&tid=5662261&page=&mobile=yesI


                IP属地:安徽来自Android客户端8楼2013-10-29 23:09
                回复
                  卧槽,总算知道失败原因了,一是联想蛋疼的手机号码格式,二是没添加cm的来电归属地数据文件phoneloc.dat到system;/usr/share


                  IP属地:安徽9楼2014-01-20 16:20
                  回复