版權(quán)聲明:本文為博主原創(chuàng)文章(部分引用他人博文,已加上引用說(shuō)明),未經(jīng)博主允許不得轉(zhuǎn)載。http://www.lxweimin.com/p/f9c67a4b908e
轉(zhuǎn)載請(qǐng)標(biāo)明出處:
http://www.lxweimin.com/p/f9c67a4b908e
本文出自 AWeiLoveAndroid的博客
第一篇文章講了 Android適配全面總結(jié)(一)----屏幕適配
上一篇文章講了 Android適配全面總結(jié)(二)----版本適配
這一篇文章講一下 ROM適配。
Android是開(kāi)源的,不同的手機(jī)廠商都有自己定制的系統(tǒng),所以這就給開(kāi)發(fā)者帶來(lái)了ROM適配難題。在一些群里面經(jīng)常看到有人因?yàn)槭謾C(jī)適配問(wèn)題,說(shuō)這個(gè)手機(jī)坑,那個(gè)手機(jī)坑,其實(shí)那是沒(méi)有對(duì)ROM定制系統(tǒng)的一些變更了解,導(dǎo)致了盲目的說(shuō)出這些指責(zé)的話(huà)。如果你熟悉了,也就會(huì)少走很多彎路。下面這篇文章就來(lái)講一下幾個(gè)主流手機(jī)的ROM適配問(wèn)題。
一、手機(jī)平臺(tái)相關(guān)文檔
(一)小米
(1)文檔
1、小米開(kāi)發(fā)者文檔
2、開(kāi)發(fā)人員必看:《小米應(yīng)用開(kāi)發(fā)者文檔》 ,在這里可以找到在小米手機(jī)上開(kāi)發(fā)、分發(fā)應(yīng)用的相關(guān)文檔。
3、常見(jiàn)問(wèn)題
4、小米帳號(hào)場(chǎng)景化登錄
5、技術(shù)文檔
(二)華為
(1)文檔
1、 APK固件及分辨率適配說(shuō)明
2、 華為全面屏適配技術(shù)指導(dǎo)
3、 華為劉海屏手機(jī)安卓O版本適配指導(dǎo)
4、 谷歌強(qiáng)制升級(jí)TargetSdkVersion適配指導(dǎo)
5、 Android P版本非SDK接口管控特性解讀及適配指導(dǎo)
6、 Android P版本應(yīng)用兼容性適配技術(shù)指導(dǎo)
7、華為桌面角標(biāo)開(kāi)發(fā)指導(dǎo)書(shū)
(2)問(wèn)題
1、華為部分設(shè)備不打印Log
部分的華為設(shè)備工程模式下log是關(guān)閉的,華為部分設(shè)備不打印Log的解決方案:
1.如果是華為手機(jī),進(jìn)入撥號(hào)界面輸入:*#*#2846579#*#*進(jìn)入頁(yè)面設(shè)置。
2.如果是華為pad,進(jìn)入計(jì)算器輸入:()()2846579()()= 進(jìn)入頁(yè)面設(shè)置。
2、華為手機(jī)獲取拍照權(quán)限后拍照,返回值為空
問(wèn)題起源:
開(kāi)發(fā)中遇到了需要拍照和從圖庫(kù)中選擇圖片展示并上傳的功能,其他手機(jī)測(cè)試沒(méi)問(wèn)題,華為手機(jī)獲取拍照權(quán)限后拍照,返回值為空。
問(wèn)題分析:
原來(lái)是華為在7.0以后的系統(tǒng)中,對(duì)于拍照后返回的圖片也做了權(quán)限處理。所以說(shuō),華為7.0在拍照的時(shí)候,不僅要拿到拍照 CAMERA
的權(quán)限,還要拿到讀寫(xiě)文件的權(quán)限 WRITE_EXTERNAL_STORAGE
。
解決方法部分代碼如下:
//聲明兩個(gè)常量
public static final int MY_PERMISSIONS_REQUEST_CALL_PHONE = 0x0001;
public static final int MY_PERMISSIONS_REQUEST_CALL_PHONE2 = 0x0002;
//設(shè)置權(quán)限
public void setTakePhonePermissions(Context context) {
if (Build.VERSION.SDK_INT >= 23) {
int checkCallPhonePermission = ContextCompat.checkSelfPermission(context,
Manifest.permission.CAMERA);
if (checkCallPhonePermission != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(context, new String[]{Manifest.permission.CAMERA,}
, MY_PERMISSIONS_REQUEST_CALL_PHONE);
} else if (ContextCompat.checkSelfPermission(context,
Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(context,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA},
MY_PERMISSIONS_REQUEST_CALL_PHONE2);
} else {
takePhoto();
}
//小于23的不需要?jiǎng)討B(tài)權(quán)限
} else {
takePhoto();
}
}
3、華為Android7.0手機(jī)打開(kāi)攝像頭拍照閃退問(wèn)題。
4、華為手機(jī)Android8.0 使用代碼安裝APK閃退問(wèn)題
更新版本APK自動(dòng)安裝的時(shí)候,在安卓6.0、7.0下都OK,唯獨(dú)在華為安卓8.0手機(jī)閃退。
解決方案: 只要在Mainfest.xml 中加入請(qǐng)求安裝權(quán)限就OK了
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
- ★★ 關(guān)于閃退的小結(jié):
- 在Android 7.0(及以上)手機(jī)開(kāi)啟拍照功能,既要申請(qǐng)
CAMERA
權(quán)限,還要申請(qǐng)WRITE_EXTERNAL_STORAGE
權(quán)限。
- 在Android 7.0(及以上)手機(jī)開(kāi)啟拍照功能,既要申請(qǐng)
- Android 7.0(API24)以及以上版本不支持file://這種類(lèi)型的URI,而是使用content://這種類(lèi)型的URI。不然會(huì)報(bào)
android.os.FileUriExposedException
這個(gè)錯(cuò),使用Android 7.0(及以上)手機(jī)拍照功能時(shí),一定要注意這個(gè)api的變化。
- Android 7.0(API24)以及以上版本不支持file://這種類(lèi)型的URI,而是使用content://這種類(lèi)型的URI。不然會(huì)報(bào)
- 使用Android 8.0(及以上)手機(jī)更新安裝apk時(shí),在Mainfest.xml 中請(qǐng)求安裝權(quán)限
android.permission.REQUEST_INSTALL_PACKAGES
。
- 使用Android 8.0(及以上)手機(jī)更新安裝apk時(shí),在Mainfest.xml 中請(qǐng)求安裝權(quán)限
5、華為手機(jī)app閃退重啟清空l(shuí)og日志問(wèn)題
解決方案:
◆ 方式1(最全面的解決方案):
找到手機(jī)設(shè)置 ---> 最后的開(kāi)發(fā)人員選項(xiàng) ---> 在調(diào)試模塊,打開(kāi)USB調(diào)試。
還是調(diào)試模塊內(nèi),找到日志記錄器緩沖區(qū)大小,改為1M(也可選擇更大),
然后進(jìn)入撥號(hào)界面輸入:*#*#2846579#*#* ----> 選擇USB端口設(shè)置 ----> 選擇Google模式。
◆ 方式2:撥號(hào)鍵盤(pán) + 快捷鍵設(shè)置(這種方式不是所有l(wèi)og都能顯示)
進(jìn)入撥號(hào)界面輸入:*#*#2846579#*#*
依次選擇:后臺(tái)設(shè)置 ---> LOG設(shè)置 ---> AP 日志,重新啟動(dòng)手機(jī)。
◆ 方式3:錯(cuò)誤出現(xiàn)后,迅速拔掉USB線,這是一個(gè)拼手速的方法,成功率不敢保證。
6、關(guān)于華為手機(jī)App權(quán)限更改導(dǎo)致應(yīng)用重啟的坑(暫且我還沒(méi)有很好的解決方式)
問(wèn)題重現(xiàn):
- 1.當(dāng)我們?cè)谌A為手機(jī)上打開(kāi)一個(gè)應(yīng)用,將應(yīng)用退至后臺(tái)進(jìn)程中。
- 2.打開(kāi) “設(shè)置”去更改該應(yīng)用的權(quán)限(比如將“存儲(chǔ)”權(quán)限由授權(quán)狀態(tài)改為非授權(quán)狀態(tài))。
- 3.再將該應(yīng)用重新切換到前臺(tái),會(huì)發(fā)現(xiàn)應(yīng)用進(jìn)行了重新啟動(dòng)。 (在該app中,啟動(dòng)的時(shí)候,F(xiàn)ragmentManager仍然會(huì)持有原有的fragment。)
網(wǎng)上有人說(shuō)出了一種原因和一種 解決方案:當(dāng)應(yīng)用的權(quán)限發(fā)生變化的時(shí)候,華為手機(jī)發(fā)出廣播,導(dǎo)致應(yīng)用重新啟動(dòng)。 解決辦法(比較笨):在Activity的onCreate()方法中,根據(jù)FragmentManager獲取到已經(jīng)存在的fragment,并將它們移除掉。重新再創(chuàng)建一下需要展示的fragment
但是我想知道framework層是如何操作的?不知道有沒(méi)有大佬能夠分析一下源碼?
(三)魅族
(1)文檔
(四)oppo
(1)文檔
(2)問(wèn)題
2、關(guān)于開(kāi)發(fā)者選項(xiàng)
:
oppo手機(jī)的開(kāi)發(fā)者模式很惡心,開(kāi)啟“設(shè)置”》其他設(shè)置》開(kāi)發(fā)者選項(xiàng)》USB調(diào)試 待機(jī),然后狀態(tài)欄有個(gè)黃色的提醒窗口,提示10分鐘后自動(dòng)關(guān)閉開(kāi)發(fā)者選項(xiàng)。
3、關(guān)于驗(yàn)證碼
:
裝個(gè)應(yīng)用要驗(yàn)證碼,打開(kāi)開(kāi)發(fā)者選項(xiàng)需要驗(yàn)證碼。。很惡心。。
4、oppo手機(jī)的R9系列和A系列的5.1系統(tǒng)存在嚴(yán)重的bug,類(lèi)似以下這種的gc導(dǎo)致的釋放超時(shí)很多。
(五)vivo
(1)文檔
(2)問(wèn)題
- 關(guān)于as項(xiàng)目無(wú)法在vivo中安裝的問(wèn)題:
最近適配vivo手機(jī) 用的是vivo x9 發(fā)現(xiàn)應(yīng)用無(wú)法在手機(jī)上安裝 已經(jīng)打開(kāi)了開(kāi)發(fā)者模式還是不行,報(bào)以下錯(cuò):
【解決方案】
關(guān)掉Android Studio的Instant Run功能,然后把開(kāi)發(fā)者模式中的USB安全模式(在USB調(diào)試下面)和USB調(diào)試一起打開(kāi)。(其他手機(jī)遇到同樣問(wèn)題,也可以用這個(gè)方式解決。)
(六)錘子
(1)文檔
暫且沒(méi)找到相關(guān)文檔。。。
二、開(kāi)發(fā)中遇到的問(wèn)題在不同手機(jī)上的處理方式
(一)沉浸式狀態(tài)欄適配
- 這里講一下華為手機(jī)沉浸式狀態(tài)欄和虛擬鍵盤(pán)沖突問(wèn)題怎么解決:
由于字?jǐn)?shù)限制,詳細(xì)代碼請(qǐng)看我的github https://github.com/AweiLoveAndroid/Solve-StatusBar-VirtualKeyBoard
(二)沉浸式狀態(tài)欄圖標(biāo)的適配
- 2.2.1 小米MIUI系統(tǒng)適配
之前做沉浸式狀態(tài)欄,由于公司APP底色是白色,所以對(duì)MIUI進(jìn)行特殊處理。在MIUI V6及以上版本,調(diào)用MIUI的方法將狀態(tài)欄圖標(biāo)改為黑色。發(fā)現(xiàn)部分小米手機(jī),這樣的設(shè)置不管用,導(dǎo)致頭上一片白,狀態(tài)欄上的東西基本看不到。
調(diào)整過(guò)程中發(fā)現(xiàn)以下情況:
手機(jī)型號(hào) | MIUI版本 | Android版本 | 系統(tǒng)方法是否生效 | MIUI的方法是否生效 |
---|---|---|---|---|
紅米 NOTE 1LTE | MIUI 8 8.2.1穩(wěn)定版 | 4.4 | 否 | 生效 |
小米5 | MIUI 8 8.5.3穩(wěn)定版 | 7.0 | 否 | 生效 |
MI 3W | MIUI 9 7.9.14開(kāi)發(fā)版 | 6.0.1 | 生效 | 否 |
參考官方文檔: http://www.miui.com/thread-8946673-1-1.html
(三)應(yīng)用卸載然后安裝更新的適配
2.3.1 華為適配
華為手機(jī)程序卸載,安裝更新包,還是提醒更新包與安裝應(yīng)用簽名不一致。-
2.3.2 魅族適配
- 問(wèn)題1. 測(cè)試的簽名和你正式出包的簽名如果不一致就不能安裝,卸載應(yīng)用也沒(méi)用。
- 問(wèn)題2. 用as安裝過(guò)應(yīng)用,卸載后安裝正式的apk就安裝不了,用adb命令卸載后就行了。
(四)改變狀態(tài)欄字體顏色為黑色的適配
- 2.4.1 小米適配
/**
* 改變小米的狀態(tài)欄字體顏色為黑色,要求MIUI6以上
* tested on: MIUI V7 5.0 Redmi-Note3
*/
private void processMIUI(boolean lightStatusBar) throws Exception{
Window window = getWindow();
Class<? extends Window> clazz = window.getClass();
int darkModeFlag;
Class<?> layoutParams = Class.forName("android.view.MiuiWindowManager$LayoutParams");
Field field = layoutParams.getField("EXTRA_FLAG_STATUS_BAR_DARK_MODE");
darkModeFlag = field.getInt(layoutParams);
Method extraFlagField = clazz.getMethod("setExtraFlags", int.class, int.class);
extraFlagField.invoke(window,lightStatusBar ? darkModeFlag : 0, darkModeFlag);
}
- 2.4.2 魅族適配
/**
* 改變魅族的狀態(tài)欄字體為黑色,要求FlyMe4以上
*/
private void processFlyMe(boolean isLightStatusBar) throws Exception{
Window window = getWindow();
WindowManager.LayoutParams layoutParams = window.getAttributes();
Class<?> instance = Class.forName("android.view.MiuiWindowManager$LayoutParams");
int value = instance.getDeclaredField("MEIZU_FLAG_DARK_STATUS_BAR_ICON").getInt(layoutParams);
Field field = instance.getDeclaredField("meizuFlags");
field.setAccessible(true);
int origin = field.getInt(layoutParams);
if(isLightStatusBar){
field.set(layoutParams, origin | value);
}else{
field.set(layoutParams, -value | origin);
}
}
下面來(lái)一張示例圖:
(五)屏幕圓角實(shí)現(xiàn)和適配
- 實(shí)現(xiàn)原理:利用WindowManager將我們的圓角加到屏幕的四個(gè)角,圓角顏色設(shè)置為黑色,形成視覺(jué)圓角屏幕。
下面簡(jiǎn)單的把一些核心代碼講一下:
- 自定義圓角View,這里以左上角為例:
// top left
case Gravity.TOP | Gravity.LEFT:
path.moveTo(0.0f, 0.0f);
path.lineTo(0.0f, (float) h);
path.arcTo(new RectF(0.0f, 0.0f,
((float) w) * 2.0f, ((float) h) * 2.0f), 180.0f, 90.0f, true);
path.lineTo((float) w, 0.0f);
path.lineTo(0.0f, 0.0f);
path.close();
break;
- windowmanager在添加view的時(shí)候需要設(shè)置一個(gè)WindowManager.LayoutParams。下面初始化這個(gè)Params:
// window manager
manager = (WindowManager) this.getApplicationContext().getSystemService(Context.WINDOW_SERVICE);
params = new WindowManager.LayoutParams();
/*
系統(tǒng)提示類(lèi)型:7.0以前可以直接用TOAST的類(lèi)型,不用申請(qǐng)權(quán)限,直接添加
7.0以后不行了,需要申請(qǐng)SYSTEM_ALERT_WINDOW權(quán)限,window type最好
設(shè)置為ERROR 或者 PHONE
*/
if (Utilities.isCanUseToastType()) {
params.type = WindowManager.LayoutParams.TYPE_TOAST;
} else {
params.type = WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
}
params.format = 1;
params.flags = WindowManager.LayoutParams.FLAG_FULLSCREEN // 全屏
| WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS // 覆蓋到status bar
| WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION // 覆蓋到導(dǎo)航欄
// 以下屬性設(shè)置加載我們圓角window 不搶焦點(diǎn),不攔截事件
| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
| WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
params.alpha = 1.0f;
params.x = 0;
params.y = 0;
// 設(shè)置 大小為全屏
params.width = ViewUtil.getScreenSize(this).x;
params.height = ViewUtil.getScreenSize(this).y;
- 圓角加到屏幕上:
public void addCornerViewByPosition(String position){
boolean enable = true;
switch (position) {
case LEFT_TOP:
enable = leftTopEnable;
params.gravity = Gravity.TOP | Gravity.LEFT;
break;
case RIGHT_TOP:
enable = rightTopEnable;
params.gravity = Gravity.TOP | Gravity.RIGHT;
break;
case LEFT_BOTTOM:
enable = leftBottomEnable;
params.gravity = Gravity.BOTTOM | Gravity.LEFT;
break;
case RIGHT_BOTTOM:
enable = rightBottomEnable;
params.gravity = Gravity.BOTTOM | Gravity.RIGHT;
break;
}
CornerView corner = buildCorner(enable,params.gravity);
if(!corners.containsValue(corner)) {
corners.put(position, corner);
manager.addView(corner, params);
}
}
屏幕圓角實(shí)現(xiàn)和適配,詳細(xì)的可以點(diǎn)擊這里:http://mp.weixin.qq.com/s/h5qRvfgVj04f_xExTtrIHg
(六)在帶虛擬按鍵的手機(jī)上,虛擬按鍵會(huì)遮擋全屏圖片的底部的解決。
在做splash頁(yè)面的時(shí)候,通過(guò)windowBackground設(shè)置背景圖片,在帶虛擬按鍵的手機(jī)上,虛擬按鍵會(huì)遮擋圖片的底部,這個(gè)問(wèn)題的解決方式:
參考:http://blog.csdn.net/c15522627353/article/details/52452490
究竟如何適配Android底部虛擬按鍵,可以參考這篇博文:http://www.lxweimin.com/p/b499628e0ae0
(七)懸浮窗權(quán)限設(shè)置了,dialog還是不提示。
(八)在Nexus 手機(jī),原生Android 8.0上,使用掃碼的時(shí)候顯示的拍照預(yù)覽方向不正,有180度的旋轉(zhuǎn)并且變形的,解決方案:
private void surfaceIsChanged() {
if (mHolder.getSurface() == null) {
System.out.println("getSurface,nullnull");
return;
}
try {
mCamera.stopPreview();
} catch (Exception e) {
e.printStackTrace();
}
try {
Camera.Size previewSize = mCamera.getParameters().getPreviewSize();
int dataBufferSize = (int) (previewSize.height * previewSize.width
* (ImageFormat.getBitsPerPixel(mCamera.getParameters()
.getPreviewFormat()) / 8.0));
mCamera.addCallbackBuffer(new byte[dataBufferSize]);
mCamera.addCallbackBuffer(new byte[dataBufferSize]);
mCamera.addCallbackBuffer(new byte[dataBufferSize]);
mCamera.setPreviewDisplay(mHolder);
mCamera.setPreviewCallback(previewCallback);
mCamera.startPreview();
mCamera.autoFocus(autoFocusCallback);
// 核心代碼:根據(jù)照相的內(nèi)容進(jìn)行設(shè)置顯示方向。
Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
// DO your logic to get front or back camera...or loop through all avaialable.
int camIdx = 0;
Camera.getCameraInfo(camIdx, cameraInfo);
try {
// If using back camera then simply rotate what CameraInfo tells you.
if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK){
mCamera.setDisplayOrientation(cameraInfo.orientation);
}else{
// If using front camera note that image might be flipped
// to give users the impresion the are looking at a mirror.
mCamera.setDisplayOrientation( (360 - cameraInfo.orientation) % 360);
}
} catch (Exception e) {
e.printStackTrace();
}
//開(kāi)始掃描
// Toast.makeText(QRZbarActivity.this, "開(kāi)始掃描",Toast.LENGTH_SHORT).show();
// 打開(kāi)閃光燈,這個(gè)方法自己去實(shí)現(xiàn),這里不是重點(diǎn),就不寫(xiě)了。
autoOpenLight();
} catch (Exception e) {
Toast.makeText(BaseScanActivity.this, R.string.account_toast_not_open_camera,
Toast.LENGTH_SHORT).show();
// showTip("您未允許" + getResources().getString(R.string.app_name)
// + "訪問(wèn)您的相冊(cè)\n請(qǐng)?jiān)凇鞍踩行?-授權(quán)管理”中更改設(shè)置");
Log.d("DBG", "Error starting camera preview: " + e.getMessage());
}
}
這個(gè)解決方案來(lái)自:https://stackoverflow.com/questions/12017148/android-camera-setdisplayorientation90-fails-in-different-devices#
(九)獲取手機(jī)里所有存儲(chǔ)設(shè)備盤(pán)符,不同廠商手機(jī)的路徑可能不一樣。
問(wèn)題描述:華為手機(jī)很變態(tài),存儲(chǔ)路徑跟原生系統(tǒng)的不一樣,所以需要對(duì)其做特別處理。
解決方案: 需要用到一個(gè)被系統(tǒng)隱藏的方法,即StorageManager下的getVolumePaths()方法。具體通過(guò)反射可以得到,其中mPath、mRemovable、mEmulated、mState這幾個(gè)屬性是我們需要關(guān)注的。
具體代碼:
public class StorageUtils {
/*
獲取全部存儲(chǔ)設(shè)備信息封裝對(duì)象
*/
public static ArrayList<Volume> getVolume(Context context) {
ArrayList<Volume> list_storagevolume = new ArrayList<Volume>();
StorageManager storageManager = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE);
try {
Method method_volumeList = StorageManager.class.getMethod("getVolumeList");
method_volumeList.setAccessible(true);
Object[] volumeList = (Object[]) method_volumeList.invoke(storageManager);
if (volumeList != null) {
Volume volume;
for (int i = 0; i < volumeList.length; i++) {
try {
volume = new Volume();
volume.setPath((String) volumeList[i].getClass().getMethod("getPath").invoke(volumeList[i]));
volume.setRemovable((boolean) volumeList[i].getClass().getMethod("isRemovable").invoke(volumeList[i]));
volume.setState((String) volumeList[i].getClass().getMethod("getState").invoke(volumeList[i]));
list_storagevolume.add(volume);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
} else {
Log.e("null", "null-------------------------------------");
}
} catch (Exception e1) {
e1.printStackTrace();
}
return list_storagevolume;
}
/*
存儲(chǔ)設(shè)備信息封裝類(lèi)
*/
public static class Volume {
protected String path;
protected boolean removable;
protected String state;
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public boolean isRemovable() {
return removable;
}
public void setRemovable(boolean removable) {
this.removable = removable;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
}
}
測(cè)試代碼:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ArrayList<StorageUtils.Volume> list_volume = StorageUtils.getVolume(this);
for (int i=0;i<list_volume.size();i++){
Log.e(i+"","path:"+list_volume.get(i).getPath()+"----"+
"removable:"+list_volume.get(i).isRemovable()+"---"+
"state:"+list_volume.get(i).getState());
}
}
}
需要添加權(quán)限:<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
本文部分內(nèi)容引用了該博客: http://www.lxweimin.com/p/7609d5a62c45