Android SD卡檢測和SP資料儲存不及時解決方案

單燦燦發表於2017-04-11

這個星期在改下載的Demo與TV移動飛框框架,所以時間比較緊。估計一週後會開源這兩個框架,今天先來一個技術含量不高的SD卡的檢測與判斷和Sp資料儲存遇到問題與解決方案。

這篇文章的SD卡檢測的情況包含的比較多,你也可以利用相近的方法,來判斷是否是U盤的插拔(主要是針對TV,核心方法可以利用到手機)。

比較難的就是在SD卡插拔的時候判斷是否是SD卡,因為U盤插拔的廣播和記憶體卡是一樣的。

廢話不多說,上程式碼。

SD卡的檢查與監測

public class SdcardActivity extends AppCompatActivity {
    BroadcastReceiver mRefresh;
    TextView mTextView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        registerRefreshBroadcast();

        mTextView = (TextView) findViewById(R.id.textsdcrd);
        //  /mnt/external_sd     /mnt/shell/emulated
        if (getPath().equals("/mnt/external_sd")) {
            mTextView.setText("SD卡:  已掛載");
        } else {
            mTextView.setText("SD卡:  未掛載");
        }

    }


    @SuppressLint("SdCardPath")
    public String getPath() {
        String sdcard_path = null;
        String sd_default = Environment.getExternalStorageDirectory()
                .getAbsolutePath();
        Log.d("text", sd_default);
        if (sd_default.endsWith("/")) {
            sd_default = sd_default.substring(0, sd_default.length() - 1);
        }
        // 得到路徑
        try {
            Runtime runtime = Runtime.getRuntime();
            Process proc = runtime.exec("mount");
            InputStream is = proc.getInputStream();
            InputStreamReader isr = new InputStreamReader(is);
            String line;
            BufferedReader br = new BufferedReader(isr);
            while ((line = br.readLine()) != null) {
                if (line.contains("secure"))
                    continue;
                if (line.contains("asec"))
                    continue;
                if (line.contains("fat") && line.contains("/mnt/")) {
                    String columns[] = line.split(" ");
                    if (columns != null && columns.length > 1) {
                        if (sd_default.trim().equals(columns[1].trim())) {
                            continue;
                        }
                        sdcard_path = columns[1];
                    }
                } else if (line.contains("fuse") && line.contains("/mnt/")) {
                    String columns[] = line.split(" ");
                    if (columns != null && columns.length > 1) {
                        if (sd_default.trim().equals(columns[1].trim())) {
                            continue;
                        }
                        sdcard_path = columns[1];
                    }
                }
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        Log.d("text", sdcard_path);
        return sdcard_path;
    }


    public void registerRefreshBroadcast() {
        IntentFilter mFilter = new IntentFilter();

        mFilter.addAction(Intent.ACTION_MEDIA_EJECT); //移除

        mFilter.addAction(Intent.ACTION_MEDIA_MOUNTED);//掛載
        mFilter.addDataScheme("file");
        mRefresh = new BroadcastReceiver() {
            public void onReceive(Context context, Intent intent) {
                String action = intent.getAction();


                if (action.equals(Intent.ACTION_MEDIA_MOUNTED)) {//補丁廣播
                    Log.e("localProduct7", "intent.getData().getPath() 139 ;" + intent.getData().getPath());
                    if (intent.getData().getPath().equals("/mnt/external_sd")) {
                        mTextView.setText("SD卡:  已掛載");

                    }

                } else if (action.equals(Intent.ACTION_MEDIA_EJECT)) {

                    if (intent.getData().getPath().equals("/mnt/external_sd")) {
                        mTextView.setText("SD卡:  未掛載");
                    }


                }
            }
        };

        registerReceiver(mRefresh, mFilter);


    }
}

上面就是我們讀取SD卡以及檢測SD卡的狀態的程式碼。

SP資料儲存不及時與解決方案

很多時候我們的SP資料並不能及時的得到儲存,尤其在遇到斷電等其他突發情況。那麼我就來給大家提一個技巧吧。

/*
* sp工具類,趕快寫好處理
*/

public class SPUtils {


    public SPUtils() {
        /* cannot be instantiated */
    }

    /**
     * 儲存在手機裡面的檔名
     */
    public static final String FILE_NAME = "shancancan";

    /**
     * 儲存資料的方法,我們需要拿到儲存資料的具體型別,然後根據型別呼叫不同的儲存方法
     *
     * @param context
     * @param key
     * @param object
     */
    public static void put(Context context, String key, Object object) {

        SharedPreferences sp = context.getSharedPreferences(FILE_NAME,
                Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sp.edit();

        if (object instanceof String) {
            editor.putString(key, (String) object);
        } else if (object instanceof Integer) {
            editor.putInt(key, (Integer) object);
        } else if (object instanceof Boolean) {
            editor.putBoolean(key, (Boolean) object);
        } else if (object instanceof Float) {
            editor.putFloat(key, (Float) object);
        } else if (object instanceof Long) {
            editor.putLong(key, (Long) object);
        } else {
            editor.putString(key, object.toString());
        }

        SharedPreferencesCompat.apply(editor);
     }

    /**
     * 得到儲存資料的方法,我們根據預設值得到儲存的資料的具體型別,然後呼叫相對於的方法獲取值
     *
     * @param context
     * @param key
     * @param defaultObject
     * @return
     */
    public static Object get(Context context, String key, Object defaultObject) {
        SharedPreferences sp = context.getSharedPreferences(FILE_NAME,
                Context.MODE_PRIVATE);


        if (defaultObject instanceof String) {
            return sp.getString(key, (String) defaultObject);
        } else if (defaultObject instanceof Integer) {
            return sp.getInt(key, (Integer) defaultObject);
        } else if (defaultObject instanceof Boolean) {
            return sp.getBoolean(key, (Boolean) defaultObject);
        } else if (defaultObject instanceof Float) {
            return sp.getFloat(key, (Float) defaultObject);
        } else if (defaultObject instanceof Long) {
            return sp.getLong(key, (Long) defaultObject);
        }

        return null;
    }

    /**
     * 移除某個key值已經對應的值
     *
     * @param context
     * @param key
     */
    public static void remove(Context context, String key) {
        SharedPreferences sp = context.getSharedPreferences(FILE_NAME,
                Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sp.edit();
        editor.remove(key);
        SharedPreferencesCompat.apply(editor);

    }

    /**
     * 清除所有資料
     *
     * @param context
     */
    public static void clear(Context context) {
        SharedPreferences sp = context.getSharedPreferences(FILE_NAME,
                Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sp.edit();
        editor.clear();
        SharedPreferencesCompat.apply(editor);

    }

    /**
     * 查詢某個key是否已經存在
     *
     * @param context
     * @param key
     * @return
     */
    public static boolean contains(Context context, String key) {
        SharedPreferences sp = context.getSharedPreferences(FILE_NAME,
                Context.MODE_PRIVATE);
        return sp.contains(key);
    }

    /**
     * 返回所有的鍵值對
     *
     * @param context
     * @return
     */
    public static Map<String, ?> getAll(Context context) {
        SharedPreferences sp = context.getSharedPreferences(FILE_NAME,
                Context.MODE_PRIVATE);
        return sp.getAll();
    }

    /**
     * 建立一個解決SharedPreferencesCompat.apply方法的一個相容類
     *
     * @author changmingshan
     */
    private static class SharedPreferencesCompat {
        private static final Method sApplyMethod = findApplyMethod();

        /**
         * 反射查詢apply的方法
         *
         * @return
         */
        @SuppressWarnings({"unchecked", "rawtypes"})
        private static  Method findApplyMethod() {
            try {
                Class clz = SharedPreferences.Editor.class;
                return clz.getMethod("apply");
            } catch (NoSuchMethodException e) {
            }

            return null;
        }

        /**
         * 如果找到則使用apply執行,否則使用commit
         *
         * @param editor
         */
        public static void apply(SharedPreferences.Editor editor) {
            try {
                if (sApplyMethod != null) {
                    sApplyMethod.invoke(editor);
                    return;
                }
            } catch (IllegalArgumentException e) {
            } catch (IllegalAccessException e) {
            } catch (InvocationTargetException e) {
            }
            editor.commit();
            try {
                Runtime.getRuntime().exec("sync");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}

我這裡面是封裝了apply方法,apply涉及到sp的資料修改,在修改後一定要加:

  try {
                Runtime.getRuntime().exec("sync");
            } catch (IOException e) {
                e.printStackTrace();
            }

這句程式碼非常重要,可以及時儲存你的資料!這句話的意思和adb shell sync的意思是一樣的。

相關文章