为您推荐:
精华内容
最热下载
问答
  • 5星
    3.58MB qq_41316046 2021-06-19 10:12:54
  • 197KB xiayiye5 2018-03-19 16:59:43
  • 43KB weixin_38715831 2020-08-27 02:57:53
  • 61KB weixin_38655496 2021-01-04 02:48:58
  • 65KB weixin_38519619 2020-09-02 22:49:59
  • 637KB a_zhon 2018-04-25 23:16:17
  • 183KB weixin_38546608 2020-08-31 13:10:05
  • 76KB weixin_38713039 2021-01-03 14:09:55
  • 7.41MB Scxioi0 2020-10-04 20:26:24
  • Android提供了多种选择来保存永久性的数据,根据不同的需求来使用不同的保存方式,一般情况下,保存数据的方式有下面几种:SharedPreferences内部存储外部存储SQLite网络连接下面主要来看一下前四种数据保存方式。...

    Android提供了多种选择来保存永久性的数据,根据不同的需求来使用不同的保存方式,一般情况下,保存数据的方式有下面几种:

    SharedPreferences

    内部存储

    外部存储

    SQLite

    网络连接

    下面主要来看一下前四种数据保存方式。

    SharedPreferences

    SharedPreferences(以下简称SP)以键值对形式进行存储,数据以xml形式存储在/data/data/项目包名/shared_prefs/xml.xml中。一般来说,SP只能存储基本类型的数据,如:布尔类型、浮点型、整形及字符串,默认情况下,SP保存的文件是应用的私有文件,其他应用(和用户)不能访问这些文件,SP的使用方式及源码解析详见:

    http://blog.csdn.net/u013700502/article/details/53635499

    SP不支持多进程之间通信,多进程之间使用可能会导致数据异常,替代SP的一种方式:https://github.com/grandcentrix/tray

    内部存储

    直接在设备的内部存储中保存文件。默认情况下,保存到内部存储的文件是应用的私有文件,其他应用(和用户)不能访问这些文件。 当用户卸载应用时,这些文件也会被移除。

    String FILENAME = "hello_file.txt";

    String string = "hello world!";

    FileOutputStream fos = null;

    try {

    fos = openFileOutput(FILENAME, Context.MODE_PRIVATE);

    fos.write(string.getBytes());

    fos.close();

    } catch (FileNotFoundException e) {

    e.printStackTrace();

    } catch (IOException e) {

    e.printStackTrace();

    }

    我们在/data/data/项目包名/files/下可以看到已经成功创建了相应文件并且把数据写进去了:

    fc86210c61a3?utm_campaign=haruki

    S80114-23015717.jpg

    其他方法(都在Context类中):

    getFilesDir() 获取在其中存储内部文件的文件系统目录的绝对路径。

    返回路径为:/data/data/com.xxx.xxx/files

    getDir()

    在您的内部存储空间内创建(或打开现有的)目录。如:

    getDir("mq", Context.MODE_PRIVATE).getAbsolutePath()

    返回结果: /data/data/com.xxx.xxx/app_mq, 我们看到系统自动给我们的文件名前加了”app_”

    deleteFile()

    删除保存在内部存储的文件。如:

    deleteFile("mq")

    删除/data/data/com.xxx.xxx/files目录中对应mq的文件,如果存在并删除成功,返回true;反之返回false

    fileList()

    返回应用当前保存的一系列文件。

    同样也是列出/data/data/com.xxx.xxx/files目录下的所有的文件

    外部存储

    每个兼容 Android 的设备都支持可用于保存文件的共享“外部存储”。 该存储可能是可移除的存储介质(例如 SD 卡)或内部(不可移除)存储。 保存到外部存储的文件是全局可读取文件,而且,在计算机上启用 USB 大容量存储以传输文件后,可由用户修改这些文件。存储分为两种,一种是应用卸载后,存储数据也会被删除,一种永久存储,即使应用被卸载,存储的数据依然存在:

    (1)通过context.getExternalFilesDir(null).getPath()来获得,得到的路径是/storage/emulated/0/Android/data/package_name/, 当应用卸载后,存储数据也会被删除。下面一段话来自google文档描述:

    如果处理的文件不适合其他应用使用(例如仅供自己应用使用的图形纹理或音效),则应该通过调用 getExternalFilesDir() 来使用外部存储上的私有存储目录。此方法还会采用 type 参数指定子目录的类型(例如 DIRECTORY_MOVIES)。 如果您不需要特定的媒体目录,请传递 null 以接收应用私有目录的根目录。

    从 Android 4.4 开始,读取或写入应用私有目录中的文件不再需要 READ_EXTERNAL_STORAGE 或 WRITE_EXTERNAL_STORAGE 权限。 因此,您可以通过添加 maxSdkVersion 属性来声明,只能在较低版本的 Android 中请求该权限:

    android:maxSdkVersion="18" />

    ...

    注:当用户卸载您的应用时,此目录及其内容将被删除。此外,系统媒体扫描程序不会读取这些目录中的文件,因此不能从 MediaStore 内容提供程序访问这些文件。 同样,不应将这些目录用于最终属于用户的媒体,例如使用您的应用拍摄或编辑的照片或用户使用您的应用购买的音乐等 — 这些文件应保存在公共目录中。

    除了context.getExternalFilesDir()之外,还有getExternalCacheDir(),文件将保存到/storage/emulated/0/Android/data/package_name/cache目录下,当文件不再需要时,记得把缓存文件删除。

    (2)永久存储,即使应用被卸载,存储的数据依然存在,存储路径如:/storage/emulated/0/mDiskCache,可以通过Environment.getExternalStorageDirectory().getAbsolutePath() + “/mDiskCache” 来获得路径。

    数据库SQLite

    Android 提供了对 SQLite 数据库的完全支持。应用中的任何类(不包括应用外部的类)均可按名称访问您所创建的任何数据库。

    关于SQLite的介绍、基本使用以及升级策略,请移步:

    http://blog.csdn.net/u013700502/article/details/78764917

    网络连接

    使用网络(如果可用)来存储和检索有关自己的网络服务的数据。 要执行网络操作,请使用以下包中的类:

    • java.net.*

    • android.net.*

    引用

    展开全文
    weixin_42359449 2021-06-03 03:14:50
  • 6.04MB shaonianpiaofei 2015-11-24 12:24:20
  • 45KB weixin_38618819 2020-08-29 01:58:12
  • 391KB han1202012 2021-05-18 12:53:16
  • 13.54MB zach_z 2018-06-20 23:33:54
  • 7.09MB daihuili161 2020-11-24 19:40:58
  • 内部存储空间的私有目录 路径:data/data/包名 外部存储空间的私有目录 路径:/storage/emulated/0/Android/data/包名 外部存存储空间的公共目录 路径:/storage/emulated/0...

    开个头

    数据存储在我们android开发中是不可避免的,而且,我们也都知道数据存储的方式,文件存储,SharedPreference,数据库存储等。但是应该也有一部分人, 只是知道这些存储方式,或者说只知道怎么用,但是不知道具体被保存在什么地方。本篇文章将详细分析这三种存储方式。
    算了不卖关子了,其实,在我看来数据存储,或者说数据的持久化,就分为两类。内部存储,外部存储。然后接下来开始我们的表演。

    内部存储空间

    路径:data/data/包名

    1 、getFileDir()

    路径:data/data/包名/file

        /**
         * Returns the absolute path to the directory on the filesystem where files
         * created with {@link #openFileOutput} are stored.
         * <p>
         * The returned path may change over time if the calling app is moved to an
         * adopted storage device, so only relative paths should be persisted.
         * <p>
         * No additional permissions are required for the calling app to read or
         * write files under the returned path.
         *
         * @return The path of the directory holding application files.
         * @see #openFileOutput
         * @see #getFileStreamPath
         * @see #getDir
         */
        public abstract File getFilesDir();

    通过官方注释我们可以看到,这个方法返回一个绝对路径,这个绝对路径是有openFilePutput()方法创建的文件。重要的是最后一句,当在这个路径下调用程序来进行读写操作的时候,是不需要任何额外的权限的。也就是说,我们在使用内部存储的方法存储数据的时候,不需要用在manifest文件中声明权限,也不需要考虑android6.0的运行时权限的。想想还是很happy滴

    1.1 openFileOutput()

    根据上面的介绍我们知道了,这个方法是用来创建一个内部存储的文件的。

        /**
         * Open a private file associated with this Context's application package
         * for writing. Creates the file if it doesn't already exist.
         * <p>
         * No additional permissions are required for the calling app to read or
         * write the returned file.
         *
         * @param name The name of the file to open; can not contain path
         *            separators.
         * @param mode Operating mode.
         * @return The resulting {@link FileOutputStream}.
         * @see #MODE_APPEND
         * @see #MODE_PRIVATE
         * @see #openFileInput
         * @see #fileList
         * @see #deleteFile
         * @see java.io.FileOutputStream#FileOutputStream(String)
         */
        public abstract FileOutputStream openFileOutput(String name, @FileMode int mode)
            throws FileNotFoundException;

    再看官方的注释,打开一个和应用程序包名相关联的私有文件来写入。如果文件不存在就会创建这个文件。并且又说明了进行读写操作的时候是不用任何权限的。

    这个方法需要传两个参数,第一个参数就是你想要创建文件的文件名,注意不能包含”/”斜杠符号。
    第二个参数是操作模式。官方给我们了两种模式选择:

        /**
         * File creation mode: for use with {@link #openFileOutput}, if the file
         * already exists then write data to the end of the existing file
         * instead of erasing it.
         * @see #openFileOutput
         * 文件创建模式,在openFileOuput方法中使用,如果文件存在,那么会在已存在的文件后面接着写入数据,而不是删除已存在的数据。
         */
        public static final int MODE_APPEND = 0x8000;
       /**
         * File creation mode: the default mode, where the created file can only
         * be accessed by the calling application (or all applications sharing the
         * same user ID).
         * 文件创建模式,默认的模式,用这个模式创建的文件只能被当前调用的应用程序访问。(或者所有拥有相同UID的应用,
         * 这个UID其实就是每个进程的UID,也就是说同一进程访问,这里涉及到多进程的知识,在此不详细展开了)
         */
        public static final int MODE_PRIVATE = 0x0000;
    小试一下 写入数据
        private void createInternalPathHxy() {
            try {
                //用MODE_PRIVAT模式,创建一个hxy.txt文件
                FileOutputStream outputStream = openFileOutput("hxy.txt", MODE_PRIVATE);
                //创建一个Usr对象(实现了Serializable接口,来让User对象可以通过流写入)
                User user = new User("hxy", 23);
                //下面的就没么好说的了,写入方法和冲刷方法
                outputStream.write(user.toString().getBytes());
                outputStream.flush();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    而且,我并没有在Mainfest文件中声明任何权限。由于内部存储空间必须有root的android机才对用户可见,所以我们用as的虚拟机运行程序,通过DeviceFileExplorer看下写入的结果。
    这里写图片描述
    可以看到,基本和我们预想的都一样。既然写入成功了,那我们看下读取的方法吧。

    1.2 openFileInput()
        /**
         * Open a private file associated with this Context's application package
         * for reading.
         *
         * @param name The name of the file to open; can not contain path
         *             separators.
         *
         * @return The resulting {@link FileInputStream}.
         *
         * @see #openFileOutput
         * @see #fileList
         * @see #deleteFile
         * @see java.io.FileInputStream#FileInputStream(String)
         */
        public abstract FileInputStream openFileInput(String name)
            throws FileNotFoundException;

    官方注释,打开一个和程序包名相关联的私有文件来读取。这个方法只有一个参数,就是要打开的文件名,这个文件名也不能包含“/”斜杠符号。

    小试一下 读取
        在读取数据之前,我们修改了写入的代码,来看看是否会覆盖之前的内容而不是在后面添加
        // User user = new User("hxy", 23);
         User user = new User("xavier", 111);
    
        private void getDataFromInternalPath() {
            try {
                //用StringBuilder来接收数据,而不是用String+=的方法。
                StringBuilder sb = new StringBuilder();
                //每次读取1024个byte的数据
                byte[] bytes = new byte[1024];
                FileInputStream inputStream = openFileInput("hxy.txt");
                int len = 0;
                while ((len = inputStream.read(bytes)) != -1) {
                    sb.append(new String(bytes, 0, len));
                }
                Log.e("读取到的数据", sb.toString());
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        //打印结果如下,确实是覆盖了之前的内容。
        08-24 07:52:49.190 15360-15360/com.example.hxytest E/读取到的数据: User{name='xavier', age=111}
    1.3 其他API

    下面连个方法就不详细介绍了,一个是删除内部存储文件,一个是获取内部存储文件的列表方法。(只能操作file文件夹下的文件)

        /**
         * Delete the given private file associated with this Context's
         * application package.
         *
         * @param name The name of the file to delete; can not contain path
         *             separators.
         *
         * @return {@code true} if the file was successfully deleted; else
         *         {@code false}.
         *
         * @see #openFileInput
         * @see #openFileOutput
         * @see #fileList
         * @see java.io.File#delete()
         */
        public abstract boolean deleteFile(String name);
       /**
         * Returns an array of strings naming the private files associated with
         * this Context's application package.
         *
         * @return Array of strings naming the private files.
         *
         * @see #openFileInput
         * @see #openFileOutput
         * @see #deleteFile
         */
        public abstract String[] fileList();

    2、getCacheDir()

    路径:data/data/包名/cache
    获取内部存储空间的缓存路径。他并没有类似openFileOutput和openFileInput的方法也没偶遇delete和fileList的方法。所以如果要往这个文件夹下写入文件就要用一般用到的File file = new File(); 先创建一个文件,然后再利用FileOutputStream往文件里写入数据。这个好像用的挺少的,可能是因为当系统内存不足时,会把他整个目录删掉吧。

    3、getDir()

        /**
         * Retrieve, creating if needed, a new directory in which the application
         * can place its own custom data files.  You can use the returned File
         * object to create and access files in this directory.  Note that files
         * created through a File object will only be accessible by your own
         * application; you can only set the mode of the entire directory, not
         * of individual files.
         * <p>
         * The returned path may change over time if the calling app is moved to an
         * adopted storage device, so only relative paths should be persisted.
         * <p>
         * Apps require no extra permissions to read or write to the returned path,
         * since this path lives in their private storage.
         *
         * @param name Name of the directory to retrieve.  This is a directory
         * that is created as part of your application data.
         * @param mode Operating mode.
         *
         * @return A {@link File} object for the requested directory.  The directory
         * will have been created if it does not already exist.
         *
         * @see #openFileOutput(String, int)
         */
        public abstract File getDir(String name, @FileMode int mode);

    这个方法其实是直接在内部存储空间创建文件夹的方法。

    File dir = getDir("xavier", MODE_PRIVATE);

    这里写图片描述
    这个文件夹是和上面所说的file和cache是同级的。而且我们发现他会自动往我们的“xavier”参数前,加一个app_,这个需要注意一下,但是并不影响我们还是通过”xavier”来访问”app_xavier”。
    往这个自定义文件夹里面写入文件的方法如下。

        private void writeToFile() {
            try {
                File dir = getDir("xavier", MODE_PRIVATE);
                File file = new File(dir, "hxy2.txt");
                FileOutputStream outputStream = new FileOutputStream(file);
                User user = new User("xavier", 111);
                outputStream.write(user.toString().getBytes());
                outputStream.flush();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    可以看到确实吧hxy2.txt写入倒了内存中。
    这里写图片描述
    小结
    1、内部存储空间的路径为data/data/包名
    2、内部存储空间只有file文件夹下的读,写,删,操作系统给我们提供了。
    3、内部存储空间的文件都是只能本程序访问,其他程序没有权限访问。
    4、内部存储空间的文件 在应用被卸载的时候会被一并删除,更新的时候不会。
    5、访问内部存储空间,并不需要任何的权限。
    6、内部存储空间其实就是手机的内存,所以不能往这里面存入太大的文件,不然手机没有内存就无法正常使用了。
    7、cache与files的差别在于,如果手机的内部存储空间不够了,会自行选择cache目录进行删除,因此,不要把重要的文件放在cache文件里面,可以放置在files里面

    4、SharedPreference

    相信很多开发者对于这种存储方式都不陌生。但是,你知道sharedPreference是以什么样的方式保存的吗?你知道有几种获取SharedPreference对象的方法吗?你知道。。。
    用的最多的应该就是,直接getSharedPrederence(name,mode)获取sp对象,然后进行存储或者读取操作。其实这个方法是调用的Context类的方法。

    Context.java
        /**
         * Retrieve and hold the contents of the preferences file 'name', returning
         * a SharedPreferences through which you can retrieve and modify its
         * values.  Only one instance of the SharedPreferences object is returned
         * to any callers for the same name, meaning they will see each other's
         * edits as soon as they are made.
         * 检索和保存这个偏好文件"name"的内容,返回一个SharedPreferences的对象通过这个对象,
         * 可以检索和修改他的值。每次调用这个方法,如果name一样,那么返回的SharedPreferences对象也一样。
         *
         * @param name Desired preferences file. If a preferences file by this name
         * does not exist, it will be created when you retrieve an
         * editor (SharedPreferences.edit()) and then commit changes (Editor.commit()).
         * 要请求的偏好文件。如果当前name命名的偏好文件不存在,那么当通过获取一个editor对象,并且调用commit()方法
         * 那么这个name命名的文件将会被创建。
         * @param mode Operating mode.
         *
         * @return The single {@link SharedPreferences} instance that can be used
         *         to retrieve and modify the preference values.
         *
         * @see #MODE_PRIVATE
         */
        public abstract SharedPreferences getSharedPreferences(String name, @PreferencesMode int mode);

    官方注释,有这么几个点需要我们注意

    1、SharedPreferences对于每个name来说是单例模式。
    2、偏好文件,在editor.commit()方法之后才会被创建,getSharedPreferences方法是不会创建 名字为name的偏好文件的。
    3、关于mode参数。我们一般都取MODE_PRIVATE,这里的MODE_PRIVATE 和上面openFileOutput方法里的MODE_PRIVATE 是一个意思。而且,官方已经废除了MODE_WORLD_READABLEMODE_WORLD_WRITEABLE 这两个参数意思分别是允许其他应用读取和写入我们的sharedPreferences,官方也是为用户的安全着想,废除了危险的操作模式。

    private void sharedPreferences() {
        SharedPreferences sp1 = getSharedPreferences("hxy", MODE_PRIVATE);
        SharedPreferences sp2 = getSharedPreferences("hxy", MODE_PRIVATE);
        SharedPreferences sp3 = getSharedPreferences("hxy", MODE_PRIVATE);
        Log.e("sp", "sp1" + sp1.toString());
        Log.e("sp", "sp2" + sp2.toString());
        Log.e("sp", "sp3" + sp3.toString());
    }
    
    08-29 05:52:28.494 9647-9647/com.example.hxytest E/sp: sp1android.app.SharedPreferencesImpl@dfe8a50
    08-29 05:52:29.886 9647-9647/com.example.hxytest E/sp: sp2android.app.SharedPreferencesImpl@dfe8a50
    08-29 05:52:31.645 9647-9647/com.example.hxytest E/sp: sp3android.app.SharedPreferencesImpl@dfe8a50

    根据代码和打印的Log日志我们可以证明第一条。
    下图我们可以看到,我们的内部存储空间多了一个文件夹shared_prefs,这个文件夹其实就是所有通过SharedPreferences方法存储数据的文件夹,就是说通过SharedPreferences保存的数据都在shared_prefs文件夹里面。但是该文件夹是个空的,里面并没有我们想要创建的”hxy”这个文件,所以也证明了第二条。
    这里写图片描述

    4.1 存储sp和读取sp

    这些都是大家经常用的操作,就简单看下代码和结果。

        private void putSharedPreferences() {
            SharedPreferences sp = getSharedPreferences("hxy", MODE_PRIVATE);
            SharedPreferences.Editor edit = sp.edit();
            edit.putString("userName", "xavier");
            edit.putInt("age", 23);
            edit.apply();
    //        boolean commit = edit.commit();
        }
    
        private void getSp() {
            SharedPreferences sp = getSharedPreferences("hxy", MODE_PRIVATE);
            String userName = sp.getString("userName", "");
            int age = sp.getInt("age", 0);
            Log.e("sp", "userName == " + userName + " , age == " + age);
        }
    
        Log日志:
        08-29 06:32:41.663 29764-29764/com.example.hxytest E/sp: userName == xavier , age == 23

    Log日志表示我们成功读取到了数据,这里需要注意的是,edit.apply()和edit.commit(),代码中也可以看到commit()方法是有个boolean类型的返回值的,用来表示使用正常写入了数据。这两个方法的区别是,apply()是异步的,commit()是同步的,写入文件毕竟是个IO操作,所以及时写入的数据量很少,为了不阻塞我们的UI线程,一般还是推荐使用apply()方法来提交。
    这里写图片描述
    可以看到,系统是通过xml文件的方式存储sp的,而且也成功吧hxy.xml写入到了shared_prefs文件夹里。

    4.2 其他方法获取SharedPreferences

    上面的方法是通过Context类里面的Context.getSharedPreferences(name,mode)方法来获取的。其实还可以通过Activity的getPreferences(mode)方法和PreferenceManager.getDefaultSharedPreferences(context)来获取。

    private void putSharedPreferencesByPreferenceManager() {
            SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
            SharedPreferences.Editor edit = sp.edit();
            edit.putString("saveType", "preferenceManager");
            edit.apply();
        }
    
        private void putSharedPreferencesByActivity() {
            SharedPreferences sp = getPreferences(MODE_PRIVATE);
            SharedPreferences.Editor edit = sp.edit();
            edit.putString("saveType", "activity");
            edit.apply();
        }

    这里写图片描述
    这个结果也是显而易见的。Activity.getPreferences(mode)方法会以当前类名为文件名,来存储sp。
    PreferenceManager.getDefaultSharedPreferences(context)会以当前包名+”_preferences”为文件名,来存储sp。

    5 数据库存储

    目前android数据库存储的方式,也是被广泛应用了,但是应该已经没有人还通过SQLiteOpenHelper 调用getWritableDatabase()或者getReadableDatabase()方法获取到SQLiteDatabase 然后再 增删改查。。。都开始使用第三口方框架 比如 greenDAORealmActiveAndroid 等。

    但是,通过原生的数据库操作sqlite的方法,其数据库.db文件,默认是保存在内部存储空间的 databases 文件夹里。在此也不进行演示了。

    总结

    通过以上的分析,我想大家应该对以上的数据存储方式有了更清晰的认识。而且上面的存储方式其最终文件都保存在了系统内存内部,所以,我在开头把他们都归结为内部存储方式就是这样来的。

    如有错误,欢迎指正~

    展开全文
    xy4_android 2018-08-29 15:56:26
  • 文件存储Android中最基本的一种数据存储方式,它与java中的文件存储类似,都是通过I/O流的形式把数据原封不动的存储到文档中 Android中的文件存储分为内部存储和外部存储 2、SharedPreferences的使用 ...

    1、文件存储简介
    Android中的数据存储方式有五种,分别是文件存储、sharedpreferences、sqlite数据库、contentprovider以及网络存储

    • 文件存储是Android中最基本的一种数据存储方式,它与java中的文件存储类似,都是通过I/O流的形式把数据原封不动的存储到文档中
    • Android中的文件存储分为内部存储和外部存储

    在这里插入图片描述
    2、SharedPreferences的使用

    • SharedPreferences是Android平台上一个轻量级的存储类,用于存储一些
      应用程序的配置参数,例如用户名、密码、自定义参数的设置等。
    • SharedPreferences中存储的数据是以key/value键值对的形式保存在XML文件中,该文件位于“data/data/<packagename>/shared_prefs"文件夹中。

    参数返回
    页面之间传递参数:
    1.构建Intent
    //1.返回结果的跳转
    Intent intentanew Intent(MainActivity.this,Main2Activity.class);
    //任务核:线程
    startActivityForResult(intent,666);
    2.设置接收返回结果
    brotected void onActivityResult(int requestcode, int resultcode, anullable Intent data)
    super.onActivityResult(requestcode,resultcode,data);
    if(requestcode666&&resultcodeRESULT_OK){
    tv.setText(data.getstringExtra(“data”));
    system.out.println("返回成功");
    }

    3、 SharedPreferences的使用

    ·存储数据
    ·SharedPreferences sp=getSharedPreferences("data",MODE_PRIVATE);
    · Editor editor=sp.edit();
    ·editor.putString("name","传智播客");
    ·editor.putInt("age",8);
    ·editor.commit():
    ·取出数据
    ·SharedPreferences sp=context.getSharedPreferences();
    ·String data=sp.getString("name","");
    ·编辑数据
    ·SharedPreferences sp=context.getSharedPreferences();
    ·Editor editor=sp.edit();
    ·editor.remove("name"):
    ·editor.clear();
    ·editor.commit();
    

    总结:
    1.SharedPreferences
    ·SharedPreferences是Android平台上一个轻量级的存储类,用于存储一些应用程序的配置参数,例如用户名、
    密码、自定义参数的设置等。
    存储数据
    sharedpreferences sp = getsharedPreferences (“data”, MODE_PRIVATE);
    Editor editor=sp.editO;
    editor.putstring("name","传智播客");
    editor.putInt(“age”,8);
    editor.commit();
    取出数据
    SharedPreferences sp = context.getsharedpreferences O;
    string data = sp.getstring(“name”,"");
    编辑数据
    SharedPreferences sp=context.getsharedpreferences O;
    Editor editor=sp.editO;
    editor.remove(“name”);
    editor.clear();
    editor.commito;

    展开全文
    weizhishude 2021-02-23 15:07:22
  • 40KB weixin_38576392 2020-08-26 21:00:45
  • 40KB weixin_38610682 2020-09-02 01:00:54
  • 1.59MB wenwei19861106 2013-01-09 08:02:25
  • 8.85MB weixin_43624626 2020-04-23 00:47:50
  • Android 文件存储Android 图片存储 。

            因 Android1 1谷歌禁止使用requestLegacyExternalStorage ,故将存储方式分为两种方式来进行文件存储。

            存储你的应用打算与其他应用共享的文件,包括媒体、文档和其他文件。在这里咱们将图片保存至图库(共享文件)。

    需要存储权限

        private void saveBitmap() {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                // 检查该权限是否已经获取
                int i = ContextCompat.checkSelfPermission(FileStorageActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
                // 权限是否已经 授权 GRANTED---授权  DINIED---拒绝
                if (i != PackageManager.PERMISSION_GRANTED) {
                    // 如果没有授予该权限,就去提示用户请求
                    startRequestPermission();
                } else {
                    resourceBitmap();
                }
            } else {
                resourceBitmap();
            }
        }


    保存数据
     

        private void resourceBitmap() {
            Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.ceshi);
            boolean isSave = PictureStorageUtils.isSaveImage(this, bitmap, "sccgx");
            Log.e("File","isSave:"+isSave);
        }
        
    /**
     * 功能描述:将图片文件保存至本地
     */  
    public class PictureStorageUtils {
        public static boolean isSaveImage(Context context, Bitmap bm, String name) {
            boolean isSave;
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                //大于等于android 10
                isSave = saveImageQ(context, bm, name);
            } else {
                isSave = saveImage(context, bm, name);
            }
            return isSave;
        }
    
        private static boolean saveImage(Context context, Bitmap outB, String name) {
            String imgName = name.isEmpty()?String.valueOf(System.currentTimeMillis()):name;
            //File.separator就是文件路径
            String fileName = Environment.getExternalStorageDirectory() + File.separator + "DCIM"
                    + File.separator + "demo" + File.separator;
            try {
                File file = new File(fileName);
                if (!file.exists()) {
                    file.mkdirs();
                }
                Log.e("File","saveAndGetImage:" + file);
                File filePath = new File(file + "/" + imgName + ".png");
                Log.e("File","filePath:" + filePath);
                FileOutputStream out = new FileOutputStream(filePath); //保存到本地,格式为JPEG
                if (outB.compress(Bitmap.CompressFormat.PNG, 100, out)) {
                    out.flush();
                    out.close();
                }
                Log.e("File","saveAndGetImage:END");
                //刷新图库
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {//高于22版本要手动授权
                    // 检查该权限是否已经获取
                    int i = ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE);
                    // 权限是否已经 授权 GRANTED---授权  DINIED---拒绝
                    if (i != PackageManager.PERMISSION_GRANTED) {
                        // 提示用户应该去应用设置界面手动开启权限
                    } else {
                        context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(filePath)));
                    }
                } else {
                    context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(filePath)));
                }
                return true;
            } catch (FileNotFoundException e) {
                Log.e("File","FileNotFoundException e.toString: " + e.toString());
                e.printStackTrace();
                return false;
            } catch (IOException e) {
                Log.e("File","IOException e.toString: " + e.toString());
                e.printStackTrace();
                return false;
            }
        }
    
        //功能描述:Android10及以上保存图片到相册
        @RequiresApi(api = Build.VERSION_CODES.Q)
        private static boolean saveImageQ(Context context, Bitmap image, String name) {
            long mImageTime = System.currentTimeMillis();
            String mImageFileName = name.isEmpty()?String.valueOf(mImageTime):name;
            final ContentValues values = new ContentValues();
            values.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_DCIM
                    + File.separator + "demo"); //图库(DCIM)中显示的文件夹名。
            values.put(MediaStore.MediaColumns.DISPLAY_NAME, mImageFileName);
            values.put(MediaStore.MediaColumns.MIME_TYPE, "image/png");
            values.put(MediaStore.MediaColumns.DATE_ADDED, mImageTime / 1000);
            values.put(MediaStore.MediaColumns.DATE_MODIFIED, mImageTime / 1000);
            values.put(MediaStore.MediaColumns.DATE_EXPIRES, (mImageTime + DateUtils.DAY_IN_MILLIS) / 1000);
            values.put(MediaStore.MediaColumns.IS_PENDING, 1);
            Log.e("File",values.get(MediaStore.MediaColumns.RELATIVE_PATH).toString());
            ContentResolver resolver = context.getContentResolver();
            final Uri uri = resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
            try {
                //写下我们文件的数据
                try (OutputStream out = resolver.openOutputStream(uri)) {
                    if (!image.compress(Bitmap.CompressFormat.PNG, 100, out)) {
                        throw new IOException("Failed to compress");
                    }
                }
                //一切都很顺利
                values.clear();
                values.put(MediaStore.MediaColumns.IS_PENDING, 0);
                values.putNull(MediaStore.MediaColumns.DATE_EXPIRES);
                resolver.update(uri, values, null, null);
                return true;
            } catch (IOException e) {
                Log.e("File",e.getMessage());
                return false;
            }
        }
    }

    测试机:Galaxy A8s

            图片保存路径:Galaxy A8s\Phone\DCIM\demo

    测试机:Pixel XL API 31(AS模拟器)

            图片保存路径:/storage/emulated/0/DCIM/demo/sccgx.png

     

    展开全文
    g984160547 2021-05-17 18:16:31
  • 100KB weixin_38645133 2021-01-03 13:29:19
  • weixin_26950847 2021-06-02 20:17:18
  • wulianghuan 2013-02-24 22:18:10
  • 10.48MB u011027547 2021-11-15 09:56:01
  • weixin_35732062 2020-08-15 17:21:22

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 416,069
精华内容 166,427
关键字:

android文件存储方式