Android T 实现简易的 USB Mode Select 需求

Android T 实现 USB Mode Select 需求

一、实现效果

在这里插入图片描述

二、主要实现思路

在手机连接 USB 发生/取消通知的同时,控制弹窗 Dialog 的显示/消失。

三、主要代码实现

连接 USB 发送/取消的主要实现是在 UsbDeviceManager.java 类中。类路径如下:

system/frameworks/base/services/usb/java/com/android/server/usb/UsbDeviceManager.java

具体修改代码如下:

//add for bug start {
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.DialogInterface;
import android.view.WindowManager;
import android.view.Gravity;
// add for bug end }


/**
 * UsbDeviceManager manages USB state in device mode.
 */
public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObserver {
    
    private static final String ADB_NOTIFICATION_CHANNEL_ID_TV = "usbdevicemanager.adb.tv";

    //add for bug start {
    private static UsbHandler mHandler;

    private static AlertDialog mServiceDialog = null;
    //add for bug end }
    
    private final Object mLock = new Object();

    
        protected void updateUsbNotification(boolean force) {
            if (mNotificationManager == null || !mUseUsbNotification
                    || ("0".equals(getSystemProperty("persist.charging.notify", "")))) {
                return;
            }

            // Dont show the notification when connected to a USB peripheral
            // and the link does not support PR_SWAP and DR_SWAP
            if (mHideUsbNotification && !mSupportsAllCombinations) {
                if (mUsbNotificationId != 0) {
                    mNotificationManager.cancelAsUser(null, mUsbNotificationId,
                            UserHandle.ALL);
                    mUsbNotificationId = 0;
                    Slog.d(TAG, "Clear notification");
                }
                return;
            }

            int id = 0;
            int titleRes = 0;
            Resources r = mContext.getResources();
            CharSequence message = r.getText(
                    com.android.internal.R.string.usb_notification_message);
            if (mAudioAccessoryConnected && !mAudioAccessorySupported) {
                titleRes = com.android.internal.R.string.usb_unsupported_audio_accessory_title;
                id = SystemMessage.NOTE_USB_AUDIO_ACCESSORY_NOT_SUPPORTED;
            } 
            ....
            ....
            } else if (mHostConnected && mSinkPower && (mUsbCharging || mUsbAccessoryConnected)) {
                titleRes = com.android.internal.R.string.usb_charging_notification_title;
                id = SystemMessage.NOTE_USB_CHARGING;
            }
            if (id != mUsbNotificationId || force) {
                // clear notification if title needs changing
                if (mUsbNotificationId != 0) {
                    mNotificationManager.cancelAsUser(null, mUsbNotificationId,
                            UserHandle.ALL);
                    Slog.d(TAG, "Clear notification");
                    mUsbNotificationId = 0;
                    // add for bug start {
                    if (mServiceDialog != null){
                        mServiceDialog.dismiss();
                        mServiceDialog = null;
                    }
                    // add for bug end }
                }
                // Not relevant for automotive and watch.
                if ((mContext.getPackageManager().hasSystemFeature(
                        PackageManager.FEATURE_AUTOMOTIVE)
                        || mContext.getPackageManager().hasSystemFeature(
                        PackageManager.FEATURE_WATCH))
                        && id == SystemMessage.NOTE_USB_CHARGING) {
                    mUsbNotificationId = 0;
                    return;
                }

                if (id != 0) {
                    CharSequence title = r.getText(titleRes);
                    PendingIntent pi;
                    String channel;

                    ....
                    ....    
                    Slog.d(TAG, "push notification:" + title);
                    mUsbNotificationId = id;
                }
            }
        }

        // add for bug start {
        public void showDialog(Context context){
            final String USBModeStr[] = context.getResources().getStringArray(com.android.internal.R.array.spro_usb_mode);
            AlertDialog.Builder dialog = new AlertDialog.Builder(context);
            dialog.setTitle(context.getResources().getString(com.android.internal.R.string.usb_mode_tittle));
            dialog.setSingleChoiceItems(USBModeStr, 0 ,
                    new DialogInterface.OnClickListener(){
                        @Override
                        public void onClick(DialogInterface dialog, int which){
                            Slog.d(TAG, "----------USBModeStr------------" + USBModeStr[which]);
                            switch (which){
                                case 1:
                                    mHandler.sendMessage(MSG_SET_CURRENT_FUNCTIONS, UsbManager.FUNCTION_MTP);
                                    break;
                                case 2:
                                    mHandler.sendMessage(MSG_SET_CURRENT_FUNCTIONS, UsbManager.FUNCTION_PTP);
                                    break;
                                default:
                                    mHandler.sendMessage(MSG_SET_CURRENT_FUNCTIONS, UsbManager.FUNCTION_NONE);
                                    break;
                            }
                            dialog.dismiss();
                        }
                    }
            );
            dialog.setPositiveButton(context.getResources().getString(com.android.internal.R.string.usb_mode_cancel),
                    new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int id) {
                            dialog.cancel();
                        }
                    });
            mServiceDialog = dialog.create();
            mServiceDialog.getWindow().setType(
                    WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY);
            mServiceDialog.getWindow().setGravity(Gravity.BOTTOM);
            if (mServiceDialog != null && !mServiceDialog.isShowing()) {
                mServiceDialog.show();
            }
        }

        // add for bug end }
    
    	
            protected void updateAdbNotification(boolean force) {
            if (mNotificationManager == null) return;
            final int id = SystemMessage.NOTE_ADB_ACTIVE;

            if (isAdbEnabled() && mConnected) {
                if ("0".equals(getSystemProperty("persist.adb.notify", ""))) return;

                if (force && mAdbNotificationShown) {
                    mAdbNotificationShown = false;
                    mNotificationManager.cancelAsUser(null, id, UserHandle.ALL);
                }

                if (!mAdbNotificationShown) {
                    Notification notification = AdbNotifications.createNotification(mContext,
                            AdbTransportType.USB);
                    mAdbNotificationShown = true;
                    mNotificationManager.notifyAsUser(null, id, notification, UserHandle.ALL);

                    // add for bug start {
                    showDialog(mContext);
                    // add for bug end }
                }
            } else if (mAdbNotificationShown) {
                mAdbNotificationShown = false;
                mNotificationManager.cancelAsUser(null, id, UserHandle.ALL);
            }
        }
}
3.2、添加 string 资源
添加英文资源

frameworks\base\core\res\res\values\strings.xml

<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     ... ... 
    <!--start usb mode by wj-->
    <string name="usb_mode_tittle">Use USB for</string>
    <string name="usb_mode_charging_only">Charging only</string>
    <string name="usb_mode_mtp">File Transfer(MTP)</string>
    <string name="usb_mode_ptp">Transfer Photos(PTP)</string>
    <string name="usb_mode_cancel">Cancel</string>
    <!--end usb mode by wj-->
     ... ... 
</resources>

添加中文资源

frameworks\base\core\res\res\values-zh-rCN\strings.xml

<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     ... ... 
    <!--start usb mode by-->
    <string name="usb_mode_tittle">USB 用途</string>
    <string name="usb_mode_charging_only">仅限充电</string>
    <string name="usb_mode_mtp">传输文件(MTP)</string>
    <string name="usb_mode_ptp">传输照片(PTP)</string>
    <string name="usb_mode_cancel">取消</string>
    <!--end usb mode by -->
     ... ... 
</resources>
3.3、添加引用的数组资源

因为3种 USB mode,引用了数组资源,所以需要在Framework层添加数组资源。

Framework中添加数组主要修改valuesarrays.xml文件frameworks\base\core\res\res\values\arrays.xml
添加内容如下:

</resources> 
    ... ...
    <!-- add for bug start -->
    <string-array name="spro_usb_mode">
        <item>@string/usb_mode_charging_only</item>
        <item>@string/usb_mode_mtp</item>
        <item>@string/usb_mode_ptp</item>
    </string-array>
    <!-- add for bug end -->
</resources>

3.4、修改Framwork 资源,需要添加symbol,否则无法引用

Framework中添加资源后,由于无法像Eclipse或者Androd Studio那样自动生成R.java文件,需要在symbols.xml文件中手动添加自己的资源文件名,否则会导致无法根据com.android.internal.R.**引用所需的字符串资源。
symbols.xml主要在valuse文件夹下,详细路径为frameworks\base\core\res\res\values\symbols.xml

添加内容如下:

<resources>
     ... ... 
  <!--start usb mode by wj-->
  <java-symbol type="string" name="usb_mode_tittle" />
  <java-symbol type="string" name="usb_mode_charging_only" />
  <java-symbol type="string" name="usb_mode_mtp" />
  <java-symbol type="string" name="usb_mode_ptp" />
  <java-symbol type="string" name="usb_mode_cancel" />
  <java-symbol type="array" name="spro_usb_mode" />
  <!--end usb mode by wj-->
     ... ... 
</resources>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值