狀態列不彈出“已連線USB”的解決辦法
阿新 • • 發佈:2018-12-22
我們將Android5.1裝置與PC(計算機/電腦)連線時,USB計算機連線方式有:USB 儲存裝置、媒體裝置(MTP)、相機(PTP)、只充電。比如,我要使用 “USB儲存裝置” 這個USB連線方式:
那麼,狀態列會彈出,“已連線USB” 的通知,並且你可以點選進去,開啟USB儲存裝置:
將Android裝置與PC連線設定為 “USB儲存裝置” 模式,就是將Android裝置的內部儲存器掛載到PC,當做U盤使用。
---------------------------------------------分割線--------------------------------------------
現在在我們的工業平板上遇到狀態列不彈出“已連線USB”,那麼就不能開啟USB儲存裝置:
雖然,不使用“USB儲存裝置” 模式作為Android裝置與PC連線方式,“媒體裝置(MTP)”模式也可以在Android與PC之間進行資料傳輸;但是,有時候應用程式需要使用“USB儲存裝置”這個模式,APP新建的檔案/資料夾可以實時更新到PC,其他模式卻不行。因此,需要“USB儲存裝置” 模式能夠正常使用!
排查問題過程:
1. 查詢關鍵字
通過查詢關鍵字“已連線USB”,追蹤到frameworks/base/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java檔案。在updateUsbMassStorageNotification方法中,通過列印日誌發現 available 和 isStorageCanShared 值為false,導致“已連線USB”通知彈不出來!
2. 檔案對比
available 和 isStorageCanShared 值 與 volumes.getPath() 和 mStorageManager.getVolumeState(path); 相關,通過對比能夠正常使用“USB儲存裝置”的StorageNotification.java檔案,StorageNotification.java沒有異常。
3. 檢查配置檔案
需要檢查配置檔案是ProjectConfig.mk、<project>_defconfig,通過與正常的配置檔案進行對比檢查,發現如下異常:
在ProjectConfig.mk檔案中:
異常:MTK_MULTI_PARTITION_MOUNT_ONLY_SUPPORT = yes
MTK_OWNER_SDCARD_ONLY_SUPPORT = yes
MTK_SHARED_SDCARD = yes
正常:MTK_MULTI_PARTITION_MOUNT_ONLY_SUPPORT = no
MTK_OWNER_SDCARD_ONLY_SUPPORT = no
MTK_SHARED_SDCARD = no
在<project>_defconfig檔案中:
異常:CONFIG_MTK_SHARED_SDCARD=y
CONFIG_MTK_MULTI_PARTITION_MOUNT_ONLY_SUPPORT=y
正常:# CONFIG_MTK_SHARED_SDCARD is not set
# CONFIG_MTK_MULTI_PARTITION_MOUNT_ONLY_SUPPORT is not set
4. 問題處理
將上述ProjectConfig.mk、<project>_defconfig檔案中出現的問題進行修改:在ProjectConfig.mk檔案中:
MTK_MULTI_PARTITION_MOUNT_ONLY_SUPPORT = yes --> MTK_MULTI_PARTITION_MOUNT_ONLY_SUPPORT = no
MTK_OWNER_SDCARD_ONLY_SUPPORT = yes --> MTK_OWNER_SDCARD_ONLY_SUPPORT = no
MTK_SHARED_SDCARD = yes --> MTK_SHARED_SDCARD = no
在<project>_defconfig檔案中:
CONFIG_MTK_SHARED_SDCARD=y --> # CONFIG_MTK_SHARED_SDCARD is not se
CONFIG_MTK_MULTI_PARTITION_MOUNT_ONLY_SUPPORT=y --> # CONFIG_MTK_MULTI_PARTITION_MOUNT_ONLY_SUPPORT is not set
修改完成之後make clean,並且全部重新編譯Android5.1原始碼,將編譯好的原始碼,更新到我們的工業平板上,即可解決“USB儲存裝置” 模式不可用的問題。
那麼,狀態列會彈出,“已連線USB” 的通知,並且你可以點選進去,開啟USB儲存裝置:
將Android裝置與PC連線設定為 “USB儲存裝置” 模式,就是將Android裝置的內部儲存器掛載到PC,當做U盤使用。
---------------------------------------------分割線--------------------------------------------
現在在我們的工業平板上遇到狀態列不彈出“已連線USB”,那麼就不能開啟USB儲存裝置:
雖然,不使用“USB儲存裝置” 模式作為Android裝置與PC連線方式,“媒體裝置(MTP)”模式也可以在Android與PC之間進行資料傳輸;但是,有時候應用程式需要使用“USB儲存裝置”這個模式,APP新建的檔案/資料夾可以實時更新到PC,其他模式卻不行。因此,需要“USB儲存裝置” 模式能夠正常使用!
排查問題過程:
1. 查詢關鍵字
通過查詢關鍵字“已連線USB”,追蹤到frameworks/base/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java檔案。在updateUsbMassStorageNotification方法中,通過列印日誌發現 available 和 isStorageCanShared 值為false,導致“已連線USB”通知彈不出來!
2. 檔案對比
available 和 isStorageCanShared 值 與 volumes.getPath() 和 mStorageManager.getVolumeState(path); 相關,通過對比能夠正常使用“USB儲存裝置”的StorageNotification.java檔案,StorageNotification.java沒有異常。
- /**
- * Update the state of the USB mass storage notification
- */
- void updateUsbMassStorageNotification(boolean available) {
- boolean isStorageCanShared = isAbleToShare();
- Slog.d(TAG, "updateUsbMassStorageNotification - isStorageCanShared=" + isStorageCanShared + ",available=" + available);
- if( !mStorageManager.isUsbMassStorageEnabled() || mLastState.equals(Environment.MEDIA_BAD_REMOVAL) ) {
- /* Show "USB Connected" notification, if the system want it and there is more than one storage can be shared. */
- /* Like SHARED SD, there is an internal storage, but that can not be shared. So don't show notification. */
- if (available && isStorageCanShared) { // available 與 isStorageCanShared 的值都為false
- Slog.d(TAG, "updateUsbMassStorageNotification - [true]");
- Intent intent = new Intent();
- intent.setClass(mContext, com.android.systemui.usb.UsbStorageActivity.class);
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- PendingIntent pi = PendingIntent.getActivity(mContext, 0, intent, 0);
- setUsbStorageNotification(
- com.android.internal.R.string.usb_storage_notification_title,
- com.android.internal.R.string.usb_storage_notification_message,
- com.android.internal.R.drawable.stat_sys_data_usb,
- false, true, pi);
- } else if(!available && !isStorageCanShared || !mUmsAvailable) {
- /* Cancel "USB Connected" notification, if the system want to cancel it and there is no storage can be shared. */
- /* Like SD hot-plug, remove the external SD card, but still one storage can be shared. So don't cancel the notification. */
- Slog.d(TAG, "updateUsbMassStorageNotification - [false]");
- setUsbStorageNotification(0, 0, 0, false, false, null);
- } else {
- Slog.d(TAG, "updateUsbMassStorageNotification - Cannot as your wish!");
- /* When there is no partition to share (NOFS/BAD/...), invisible this notification */
- Intent intent = new Intent();
- intent.setClass(mContext, com.android.systemui.usb.UsbStorageActivity.class);
- PendingIntent pi = PendingIntent.getActivity(mContext, 0, intent, 0);
- setUsbStorageNotification(
- com.android.internal.R.string.usb_storage_stop_notification_title,
- com.android.internal.R.string.usb_storage_stop_notification_message,
- com.android.internal.R.drawable.stat_sys_warning, false, false, pi);
- }
- mLastConnected = available;
- } else {
- Slog.d(TAG, "updateUsbMassStorageNotification - UMS Enabled");
- }
- }
- private void onUsbMassStorageConnectionChangedAsync(boolean connected) {
- mUmsAvailable = connected;
- /*
- * Even though we may have a UMS host connected, we the SD card
- * may not be in a state for export.
- */
- int allowedShareNum = 0;
- String st = "";
- String path = "";
- StorageVolume[] volumes = mStorageManager.getVolumeList();
- if (volumes != null) {
- for (int i = 0; i < volumes.length; i++) {
- if (volumes[i].allowMassStorage() && !volumes[i].isEmulated()) {
- path = volumes[i].getPath();
- st = mStorageManager.getVolumeState(path);
- if (!(st.equals(Environment.MEDIA_REMOVED) || st.equals(Environment.MEDIA_CHECKING)|| st.equals(Environment.MEDIA_BAD_REMOVAL))) {
- /* got a truly sharable volume */
- allowedShareNum++;
- }
- }
- }
- }
- if(connected && allowedShareNum == 0){
- /* only changed connceted here */
- Slog.d(TAG, "change connected from true -> false");
- connected = false;
- }
- if (st != null) {
- if (DEBUG) Log.i(TAG, String.format("UMS connection changed to %s (media state %s), (path %s)",
- connected, st, path));
- Slog.d(TAG, "onUsbMassStorageConnectionChangedAsync - mLastState: " + mLastState + ", st: " + st + ", mLastConnected: " + mLastConnected+ ", connected: " + connected + ", path: " + path);
- if (!connected) {
- mUsbNotifications.clear();
- updateUsbMassStorageNotification(connected);
- Slog.d(TAG, "onUsbMassStorageConnectionChangedAsync - Disconnect");
- } else {
- String mCurrentFunctions = SystemProperties.get("sys.usb.config", "none");
- if (containsFunction(mCurrentFunctions, UsbManager.USB_FUNCTION_MASS_STORAGE)) {
- Slog.d(TAG, "onUsbMassStorageConnectionChangedAsync - Connect - UMS");
- if (mLastState.equals(st) && mLastConnected == connected && !mAlarmBootOff) {
- Slog.d(TAG, "onUsbMassStorageConnectionChangedAsync - Connect - UMS - Ignore");
- return;
- }
- updateUsbMassStorageNotification(connected);
- } else {
- Slog.d(TAG, "onUsbMassStorageConnectionChangedAsync - Connect - MTP");
- setUsbStorageNotification(0, 0, 0, false, false, null);
- mLastConnected = connected;
- }
- }
- }
- mLastConnected = connected;
- Slog.d(TAG, "onUsbMassStorageConnectionChangedAsync - mLastConnected: " + mLastConnected);
- }
3. 檢查配置檔案
需要檢查配置檔案是ProjectConfig.mk、<project>_defconfig,通過與正常的配置檔案進行對比檢查,發現如下異常:
在ProjectConfig.mk檔案中:
異常:MTK_MULTI_PARTITION_MOUNT_ONLY_SUPPORT = yes
MTK_OWNER_SDCARD_ONLY_SUPPORT = yes
MTK_SHARED_SDCARD = yes
正常:MTK_MULTI_PARTITION_MOUNT_ONLY_SUPPORT = no
MTK_OWNER_SDCARD_ONLY_SUPPORT = no
MTK_SHARED_SDCARD = no
在<project>_defconfig檔案中:
異常:CONFIG_MTK_SHARED_SDCARD=y
CONFIG_MTK_MULTI_PARTITION_MOUNT_ONLY_SUPPORT=y
正常:# CONFIG_MTK_SHARED_SDCARD is not set
# CONFIG_MTK_MULTI_PARTITION_MOUNT_ONLY_SUPPORT is not set
4. 問題處理
將上述ProjectConfig.mk、<project>_defconfig檔案中出現的問題進行修改:在ProjectConfig.mk檔案中:
MTK_MULTI_PARTITION_MOUNT_ONLY_SUPPORT = yes --> MTK_MULTI_PARTITION_MOUNT_ONLY_SUPPORT = no
MTK_OWNER_SDCARD_ONLY_SUPPORT = yes --> MTK_OWNER_SDCARD_ONLY_SUPPORT = no
MTK_SHARED_SDCARD = yes --> MTK_SHARED_SDCARD = no
在<project>_defconfig檔案中:
CONFIG_MTK_SHARED_SDCARD=y --> # CONFIG_MTK_SHARED_SDCARD is not se
CONFIG_MTK_MULTI_PARTITION_MOUNT_ONLY_SUPPORT=y --> # CONFIG_MTK_MULTI_PARTITION_MOUNT_ONLY_SUPPORT is not set
修改完成之後make clean,並且全部重新編譯Android5.1原始碼,將編譯好的原始碼,更新到我們的工業平板上,即可解決“USB儲存裝置” 模式不可用的問題。