칵이닷
12.08.09
조회 수 7047
추천 수 6
댓글 7
전에 Hax빙글님께서 올려주셨던 퀵패널에 "모바일 데이터" 버튼 추가하기의 응용입니다.

deodex, odex 과정은 제가 전에 썼던 글 SystemUI.odex 수정 따라하기를 참고 하시면 되겠습니다.

다른 폰들은 가능한지 모르겠습니다. 
갤2 SKT UG26에서 작업하였습니다.
SystemUI.odex를 deodex 하여 SystemUIcomandroidsystemuistatusbarpolicy 안에SyncController.smali 가 있는 것과 소스코드에서 퀵패널 버튼들의 규칙성을 보고 만들었기 때문입니다.

우선 apk 파일을 수정합니다.
SystemUI.apk를 decompile합니다.
SystemUIresdrawable-hdpi 폴더에 버튼의 on, off, on과 off 전환 이미지로 쓰일 이미지를 넣어줍니다.
설명에서는 
tw_quick_panel_icon_sync_on.png(ON 버튼)
tw_quick_panel_icon_sync_off(OFF 버튼)
tw_quick_panel_icon_sync_dim.png(ON과 OFF 전환 표시 버튼)
를 넣었습니다.
SystemUI.apkreslayouttw_status_bar_expanded.xml 의 파일을 열어줍니다.

이런 부분을 보실 수 있습니다.
<LinearLayout 
  android:orientation="horizontal" android:id="@id/quickpanel_airplane_mode_btn_layout"
  android:visibility="gone" android:layout_width="wrap_content" 
  android:layout_height="fill_parent" android:layout_weight="1.0">
<ImageView 
        android:background="@drawable/tw_quicksetting_divider" android:layout_width="wrap_content"
        android:layout_height="fill_parent" />
<com.android.systemui.statusbar.policy.QuickSettingButton
            android:id="@id/quickpanel_airplane_mode_btn" android:background="@drawable/tw_quicksetting_bg"
            android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1.0"
            systemui:buttonText="@string/quickpanel_airplane_mode_text"
            systemui:onIcon="@drawable/tw_quick_panel_icon_airplane_on"
            systemui:offIcon="@drawable/tw_quick_panel_icon_airplane_off"
            systemui:dimIcon="@drawable/tw_quick_panel_icon_airplane_dim" />
</LinearLayout>
를 보실 수 있습니다.
이 부분을 복사하여
<LinearLayout 
  android:orientation="horizontal" android:id="@id/quickpanel_sync_btn_layout"
  android:visibility="gone" android:layout_width="wrap_content" android:layout_height="fill_parent"
  android:layout_weight="1.0">
<ImageView 
           android:background="@drawable/tw_quicksetting_divider" android:layout_width="wrap_content"
           android:layout_height="fill_parent" />
<com.android.systemui.statusbar.policy.QuickSettingButton
            android:id="@id/quickpanel_sync_btn" android:background="@drawable/tw_quicksetting_bg"
            android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1.0"
            systemui:buttonText="@string/quickpanel_sync_text"
            systemui:onIcon="@drawable/tw_quick_panel_icon_sync_on"
            systemui:offIcon="@drawable/tw_quick_panel_icon_sync_off"
            systemui:dimIcon="@drawable/tw_quick_panel_icon_sync_dim" />
</LinearLayout>
같이 만들어 줍니다. android:visibility="gone"이라고 되어 있어도 odex 에서 visible로 바꾸기 때문에 괜찮습니다.

SystemUI.apkresvaluesids.xml 에 다음을 넣어줍니다.
    <item type="id" name="quickpanel_sync_btn_layout">false</item>
quickpanel_sync_btn의 값은 찾아보시면 이미 포함되어 있습니다..
(삼성에서 의도적으로 빼내었다고 밖엔...)

SystemUI.apkresvaluespublic.xml 안에 
    <public type="id" name="quickpanel_sync_btn_layout" id="0x7f0f00dc" />
를 넣어줍니다. id의 값인 0x7f0f00dc는 겹치지 않게 넣어주시면 됩니다.
(겹칠꺼 같으시면 넣지 말고 컴파일 하셨다가 다시 decompile 하시면 값이 자동으로 등록되어 있는 것을 보실 수 있습니다.)
그리고     <public type="id" name="quickpanel_sync_btn" id="0x7f0f00cf" /> 값도 알아둡니다.

SystemUI.odex 파일을 deodex 합니다.

SystemUI.odexcomandroidsystemuistatusbarphonePhoneStatusBar.smali의 파일을 열어줍니다.

# static fields 안에
.field mSyncLayout:Landroid/widget/LinearLayout;
를 넣어줍니다.

그리고 
    .line 571
    .local v9, mMobileData:Lcom/android/systemui/statusbar/policy/MobileDataController;
    const v19, 0x7f0f00be

    move/from16 v0, v19

    invoke-virtual {v3, v0}, Lcom/android/systemui/statusbar/phone/ExpandedView;->findViewById(I)Landroid/view/View;

    move-result-object v19

    const/16 v20, 0x0

    invoke-virtual/range {v19 .. v20}, Landroid/view/View;->setVisibility(I)V

    .line 572
    .local v9, mMobileData:Lcom/android/systemui/statusbar/policy/MobileDataController;
    new-instance v12, Lcom/android/systemui/statusbar/policy/BrightnessController;

    const v19, 0x7f0f0099

    move/from16 v0, v19

    invoke-virtual {v3, v0}, Lcom/android/systemui/statusbar/phone/ExpandedView;->findViewById(I)Landroid/view/View;

    move-result-object v19

    check-cast v19, Lcom/android/systemui/statusbar/policy/ToggleSlider;

    move-object/from16 v0, v19

    invoke-direct {v12, v2, v0}, Lcom/android/systemui/statusbar/policy/BrightnessController;-><init>(Landroid/content/Context;Lcom/android/systemui/statusbar/policy/ToggleSlider;)V


    .line 577
    .end local v5           #mAirplaneMode:Lcom/android/systemui/statusbar/policy/AirplaneModeController;
    .end local v6           #mAutoRotation:Lcom/android/systemui/statusbar/policy/AutoRotateController;
    .end local v7           #mBluetooth:Lcom/android/systemui/statusbar/policy/BluetoothController;
    .end local v8           #mGps:Lcom/android/systemui/statusbar/policy/LocationController;
    .end local v9           #mMobileData:Lcom/android/systemui/statusbar/policy/MobileDataController;
    .end local v10           #mSilentMode:Lcom/android/systemui/statusbar/policy/SilentModeController;
    .end local v11           #mWifi:Lcom/android/systemui/statusbar/policy/WifiController;

를 찾아 .line 577 위에 다음과 같이 넣어줍니다.
라인번호는 비어있는 번호로 바꾸시면 됩니다.
0x7f0f00dc 의 값은 public.xml에서 quickpanel_sync_btn_layout의 값을 넣어주시면 됩니다.
0x7f0f00cf 의 값은 public.xml에서 quickpanel_sync_btn의 값을 넣어주시면 됩니다.
 
    .line 573
    const v19, 0x7f0f00dc 

    move/from16 v0, v19

    invoke-virtual {v3, v0}, Lcom/android/systemui/statusbar/phone/ExpandedView;->findViewById(I)Landroid/view/View;

    move-result-object v19

    check-cast v19, Landroid/widget/LinearLayout;

    move-object/from16 v0, v19

    move-object/from16 v1, p0

    iput-object v0, v1, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->mSyncLayout:Landroid/widget/LinearLayout;



    .line 574
    move-object/from16 v0, p0

    iget-object v0, v0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->mSyncLayout:Landroid/widget/LinearLayout;

    move-object/from16 v19, v0

    const/16 v20, 0x0

    invoke-virtual/range {v19 .. v20}, Landroid/widget/LinearLayout;->setVisibility(I)V



    .line 575
    .local v12mBrightness:Lcom/android/systemui/statusbar/policy/BrightnessController;
    new-instance v13, Lcom/android/systemui/statusbar/policy/SyncController;

    const v19, 0x7f0f00cf

    move/from16 v0, v19

    invoke-virtual {v3, v0}, Lcom/android/systemui/statusbar/phone/ExpandedView;->findViewById(I)Landroid/view/View;
    move-result-object v19

    check-cast v19, Lcom/android/systemui/statusbar/policy/QuickSettingButton;

    move-object/from16 v0, v19

    invoke-direct {v13, v2, v0}, Lcom/android/systemui/statusbar/policy/SyncController;-><init>(Landroid/content/Context;Lcom/android/systemui/statusbar/policy/QuickSettingButton;)V

그리고 
    .line 577
    .end local v5           #mAirplaneMode:Lcom/android/systemui/statusbar/policy/AirplaneModeController;
    .end local v6           #mAutoRotation:Lcom/android/systemui/statusbar/policy/AutoRotateController;
    .end local v7           #mBluetooth:Lcom/android/systemui/statusbar/policy/BluetoothController;
    .end local v8           #mGps:Lcom/android/systemui/statusbar/policy/LocationController;
    .end local v9           #mMobileData:Lcom/android/systemui/statusbar/policy/MobileDataController;
    .end local v10           #mSilentMode:Lcom/android/systemui/statusbar/policy/SilentModeController;
    .end local v11           #mWifi:Lcom/android/systemui/statusbar/policy/WifiController;
    .end local v12           #mBrightness:Lcom/android/systemui/statusbar/policy/BrightnessController;
    .end local v13           #mSync:Lcom/android/systemui/statusbar/policy/SyncController;
을 넣어주세요.
파란색으로 표시된 부분은 약간 수정이 필요한 부분 입니다. 이 예제는 모바일 데이터가 포함된 형태로 쓰였기 때문에 v12값을 이미 가지고 있습니다. 그래서 v13을 가지고 사용하였습니다. .line 571, 572의 진하게 표시된 부분과 .line 577에서 보시고 변수를 알맞게 바꾸시면 되겠습니다.

그리고 odex 만들기 해주시면 됩니다.
결과 

퀵패널의 버튼들의 소스코드를 비교해보면 공통점이 있었습니다.
이것을 비교해서 만들었구요. 
이렇게 비교하면 왜 비행모드 버튼이 안나오는지 알 수 있습니다.(소스에서 setVisibility 가 airplane에서는 빠져 있습니다.)

첨부파일은 갤2 SKT UG26 펌웨어의 SystemUI.odex 파일의 comandroidsystemuistatusbarphonePhoneStatusBar.smali 파일 안에서 각 버튼들의 소스를 비교하기 쉽게 모은 파일입니다. 각 버튼들의 소스를 복사하여 diff로 비교해보시면 이해하기 쉽습니다.

Extra Form
첨부
댓글 7
  • ?
    SkyMaP
    12.08.09
    좋은 팁 감사드립니다!! ㅎㅎ
  • ?
    RainbowFOX
    12.08.09
    무지 더운데 수고하십니다. 좋은 정보 감사드립니다.
  • ?
    Blue1004 : F★
    12.08.09
    오...좋은 강좌 감사합니다.^^
  • ?
    버튼하나 넣는데 엄청난 작업이 필요하군요..
    뭐 하나 만들려면 장인정신이 필요하네요
  • ?
    Azdesign : F★
    12.08.09
    앗~~ 칵이닷님~~~ 강좌 너무 감사합니다.^^ (이런강좌 너무 좋아요^^)
  • ?
    G프루
    13.02.12
    감사합니다~
  • ?
    뉴혤
    13.02.18
    좋은 팁 감사합니다 !~
댓글 쓰기 권한이 없습니다.
1