Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/191.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
共享对自定义路径的引用-Android_Android_Sharedpreferences - Fatal编程技术网

共享对自定义路径的引用-Android

共享对自定义路径的引用-Android,android,sharedpreferences,Android,Sharedpreferences,我想将SharedReferences xml保存在另一个地方,默认路径是应用程序包 我们可以为androidSharedReferences设置一个自定义路径并在该路径中使用它吗?不,你不能,因为在android中,每个应用程序都有自己的沙盒。您唯一可以做的事情是为SharedReferences文件设置名称(在这种情况下,如果您希望有不同的设置文件): 其中,prefName是设置文件的名称。不可以,因为在Android中,每个应用程序都有自己的沙盒。您唯一可以做的事情是为SharedRef

我想将SharedReferences xml保存在另一个地方,默认路径是应用程序包


我们可以为androidSharedReferences设置一个自定义路径并在该路径中使用它吗?

不,你不能,因为在android中,每个应用程序都有自己的沙盒。您唯一可以做的事情是为SharedReferences文件设置名称(在这种情况下,如果您希望有不同的设置文件):


其中,prefName是设置文件的名称。

不可以,因为在Android中,每个应用程序都有自己的沙盒。您唯一可以做的事情是为SharedReferences文件设置名称(在这种情况下,如果您希望有不同的设置文件):


其中,prefName是设置文件的名称。

您可以创建一个适配器以获取首选项

首先,创建一个接口
IPreferences
(如果您想将其更改回去或更改为另一种方法,这不是必需的,但会使您的生活更轻松):

(有些方法被省略,大多数是冗余的)

然后,使用xml存储类
XMLPreferences
实现

public class XMLPreferences implements IPreferences {
    private final String path;

    public XMLPreferences(String path) {
        this.path = path;
    }

    @Override
    public boolean contains(String key) {
        return getContentByKey(key) == null;
    }

    @Override
    public int getInt(String key, int defValue) {
        if( getContentByKey(key) == null)
            return defValue;
        return Integer.valueOf(key);
    }

    @Override
    public String getString(String key, String defValue) {
        if( getContentByKey(key) == null)
            return defValue;
        return defValue;
    }

    @Override
    public void putInt(String key, int value) {
        putContentByKey(key, value);
    }

    @Override
    public void putString(String key, String value) {
        putContentByKey(key, value);
    }

    private String getContentByKey(String key) {
        try {
            FileInputStream fileInputStream = new FileInputStream(path);
            DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
            Document dom = builder.parse(fileInputStream);
            Element root = dom.getDocumentElement();
            NodeList nodes = root.getElementsByTagName(key);
            if (nodes.getLength() > 0)
                return nodes.item(0).getTextContent();
        } catch (ParserConfigurationException | SAXException | IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    private void putContentByKey(String key, String content) {
        try {
            FileInputStream fileInputStream = new FileInputStream(path);
            DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
            Document dom = builder.parse(fileInputStream);
        Element root = dom.getDocumentElement();
            NodeList nodes = root.getElementsByTagName(key);
            if (nodes.getLength() > 0)
                nodes.item(0).setTextContent(content);
            else {
                Element newElement = dom.createElement(key);
                newElement.setTextContent(content);
                root.appendChild(newElement);
            }
            Transformer transformer = TransformerFactory.newInstance().newTransformer();
            Result output = new StreamResult(new File(path));
            Source input = new DOMSource(dom);
            transformer.transform(input, output);
        } catch (ParserConfigurationException | SAXException | IOException | TransformerException e) {
            e.printStackTrace();
        }
    }
}
最后,您可以调用以下命令:

IPreferences pref = new XMLPreferences(YOUR_PATH);
稍后,如果要更改实现,可以使用IPreferences实现一个新类。然后,您可以只更改初始化,而不更改其他部分

另外,这使用了DOM Praser,如果您有 大型XML文件。您可能需要使用其他XML Praser


您可以创建适配器以获取首选项

首先,创建一个接口
IPreferences
(如果您想将其更改回去或更改为另一种方法,这不是必需的,但会使您的生活更轻松):

(有些方法被省略,大多数是冗余的)

然后,使用xml存储类
XMLPreferences
实现

public class XMLPreferences implements IPreferences {
    private final String path;

    public XMLPreferences(String path) {
        this.path = path;
    }

    @Override
    public boolean contains(String key) {
        return getContentByKey(key) == null;
    }

    @Override
    public int getInt(String key, int defValue) {
        if( getContentByKey(key) == null)
            return defValue;
        return Integer.valueOf(key);
    }

    @Override
    public String getString(String key, String defValue) {
        if( getContentByKey(key) == null)
            return defValue;
        return defValue;
    }

    @Override
    public void putInt(String key, int value) {
        putContentByKey(key, value);
    }

    @Override
    public void putString(String key, String value) {
        putContentByKey(key, value);
    }

    private String getContentByKey(String key) {
        try {
            FileInputStream fileInputStream = new FileInputStream(path);
            DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
            Document dom = builder.parse(fileInputStream);
            Element root = dom.getDocumentElement();
            NodeList nodes = root.getElementsByTagName(key);
            if (nodes.getLength() > 0)
                return nodes.item(0).getTextContent();
        } catch (ParserConfigurationException | SAXException | IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    private void putContentByKey(String key, String content) {
        try {
            FileInputStream fileInputStream = new FileInputStream(path);
            DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
            Document dom = builder.parse(fileInputStream);
        Element root = dom.getDocumentElement();
            NodeList nodes = root.getElementsByTagName(key);
            if (nodes.getLength() > 0)
                nodes.item(0).setTextContent(content);
            else {
                Element newElement = dom.createElement(key);
                newElement.setTextContent(content);
                root.appendChild(newElement);
            }
            Transformer transformer = TransformerFactory.newInstance().newTransformer();
            Result output = new StreamResult(new File(path));
            Source input = new DOMSource(dom);
            transformer.transform(input, output);
        } catch (ParserConfigurationException | SAXException | IOException | TransformerException e) {
            e.printStackTrace();
        }
    }
}
最后,您可以调用以下命令:

IPreferences pref = new XMLPreferences(YOUR_PATH);
稍后,如果要更改实现,可以使用IPreferences实现一个新类。然后,您可以只更改初始化,而不更改其他部分

另外,这使用了DOM Praser,如果您有 大型XML文件。您可能需要使用其他XML Praser


非常感谢@Joshua这个答案的灵感来自于他的代码,我在同一个界面上添加了一些东西,并用Json实现了它

public interface IPreferences {
    boolean contains(String key);

    int getInt(String key, int defValue);
    String getString(String key, String defValue);
    boolean getBoolean(String key, boolean defValue); // added

    void putInt(String key, int value);
    void putBoolean(String key, boolean value); // added
    void putString(String key, String value);

    // easiness of use
    void put(String key, String value);
    void put(String key, int value);
    void put(String key, boolean value);
}
这是Json的实现:

public class MBJsonSharedPrefs implements IPreferences {

    String filePath;
    JSONObject mJSONObject;

    public MBJsonSharedPrefs(String filePath){
        this.filePath = filePath;
        try {
            if(!MBFileUtils.FileExists(filePath)){
                // this is important for the first time
                MBFileUtils.CreateFile(filePath, "{}"); // put empty json object
            }
            String json = MBFileUtils.ReadFile(filePath);
            mJSONObject = new JSONObject(json);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public boolean contains(String key) {
        if(mJSONObject== null) return false;
        return mJSONObject.has(key);
    }

    @Override
    public int getInt(String key, int defValue) {
        return tryParseInt(getContentByKey(key), defValue);
    }

    private int tryParseInt(String strVal, int defValue){
        if(strVal == null) return defValue;
        try{return Integer.parseInt(strVal);}
        catch (Exception e){return defValue;}
    }

    @Override
    public String getString(String key, String defValue) {
        String value = getContentByKey(key);
        return value==null?defValue:value;
    }

    @Override
    public boolean getBoolean(String key, boolean defValue) {
        String value = getContentByKey(key);
        return value==null?defValue:value.equals("t");
    }

    @Override
    public void putInt(String key, int value) {
        putContentByKey(key, value+"");
    }

    @Override
    public void put(String key, int value) {
        putInt(key, value);
    }

    @Override
    public void putString(String key, String value) {
        putContentByKey(key, value);
    }

    @Override
    public void put(String key, String value) {
        putString(key, value);
    }

    @Override
    public void putBoolean(String key, boolean value) {
        putContentByKey(key, value?"t":"f");
    }

    @Override
    public void put(String key, boolean value) {
        putBoolean(key, value);
    }

    public void commit() {
        if(mJSONObject == null) return;
        try {
            MBFileUtils.WriteToFile(mJSONObject.toString(), filePath);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void apply() {
        MBThreadUtils.DoOnBackground(new Runnable() {
            @Override
            public void run() {
                commit();
            }
        });
    }

    private String getContentByKey(String key) {
        if(mJSONObject == null) return null;
        if(!contains(key)) return null;
        try {
            return (String)mJSONObject.get(key);
        } catch (JSONException e) {
            e.printStackTrace();
            return null;
        }
    }

    private void putContentByKey(String key, String content) {
        if(mJSONObject == null) return;
        try {
            mJSONObject.put(key, content);
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }
}
我就是这样使用它的:

// getting string 
MBJsonSharedPrefs pref = new MBJsonSharedPrefs(pathToFile/settings.json).getString(KET_ID,"Default");
pref.apply(); // important to write to file
// putting string
MBJsonSharedPrefs pref = new MBJsonSharedPrefs(pathToFile/settings.json).putString(KET_ID,"111222333");
pref.apply(); 
// OR another way for putting string into the file
MBJsonSharedPrefs pref = new MBJsonSharedPrefs(pathToFile/settings.json).put(KET_ID,"111222333");
pref.apply();

这对我来说很有效,再次感谢@Joshua的回答非常感谢@Joshua这个答案的灵感来自他的代码,我在同一个界面上添加了一些东西,并用Json实现了它

public interface IPreferences {
    boolean contains(String key);

    int getInt(String key, int defValue);
    String getString(String key, String defValue);
    boolean getBoolean(String key, boolean defValue); // added

    void putInt(String key, int value);
    void putBoolean(String key, boolean value); // added
    void putString(String key, String value);

    // easiness of use
    void put(String key, String value);
    void put(String key, int value);
    void put(String key, boolean value);
}
这是Json的实现:

public class MBJsonSharedPrefs implements IPreferences {

    String filePath;
    JSONObject mJSONObject;

    public MBJsonSharedPrefs(String filePath){
        this.filePath = filePath;
        try {
            if(!MBFileUtils.FileExists(filePath)){
                // this is important for the first time
                MBFileUtils.CreateFile(filePath, "{}"); // put empty json object
            }
            String json = MBFileUtils.ReadFile(filePath);
            mJSONObject = new JSONObject(json);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public boolean contains(String key) {
        if(mJSONObject== null) return false;
        return mJSONObject.has(key);
    }

    @Override
    public int getInt(String key, int defValue) {
        return tryParseInt(getContentByKey(key), defValue);
    }

    private int tryParseInt(String strVal, int defValue){
        if(strVal == null) return defValue;
        try{return Integer.parseInt(strVal);}
        catch (Exception e){return defValue;}
    }

    @Override
    public String getString(String key, String defValue) {
        String value = getContentByKey(key);
        return value==null?defValue:value;
    }

    @Override
    public boolean getBoolean(String key, boolean defValue) {
        String value = getContentByKey(key);
        return value==null?defValue:value.equals("t");
    }

    @Override
    public void putInt(String key, int value) {
        putContentByKey(key, value+"");
    }

    @Override
    public void put(String key, int value) {
        putInt(key, value);
    }

    @Override
    public void putString(String key, String value) {
        putContentByKey(key, value);
    }

    @Override
    public void put(String key, String value) {
        putString(key, value);
    }

    @Override
    public void putBoolean(String key, boolean value) {
        putContentByKey(key, value?"t":"f");
    }

    @Override
    public void put(String key, boolean value) {
        putBoolean(key, value);
    }

    public void commit() {
        if(mJSONObject == null) return;
        try {
            MBFileUtils.WriteToFile(mJSONObject.toString(), filePath);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void apply() {
        MBThreadUtils.DoOnBackground(new Runnable() {
            @Override
            public void run() {
                commit();
            }
        });
    }

    private String getContentByKey(String key) {
        if(mJSONObject == null) return null;
        if(!contains(key)) return null;
        try {
            return (String)mJSONObject.get(key);
        } catch (JSONException e) {
            e.printStackTrace();
            return null;
        }
    }

    private void putContentByKey(String key, String content) {
        if(mJSONObject == null) return;
        try {
            mJSONObject.put(key, content);
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }
}
我就是这样使用它的:

// getting string 
MBJsonSharedPrefs pref = new MBJsonSharedPrefs(pathToFile/settings.json).getString(KET_ID,"Default");
pref.apply(); // important to write to file
// putting string
MBJsonSharedPrefs pref = new MBJsonSharedPrefs(pathToFile/settings.json).putString(KET_ID,"111222333");
pref.apply(); 
// OR another way for putting string into the file
MBJsonSharedPrefs pref = new MBJsonSharedPrefs(pathToFile/settings.json).put(KET_ID,"111222333");
pref.apply();

这对我来说很有效,再次感谢约书亚的回答,我正在做的简单的事情。启动时(在任何操作之前),我将我的私人首选项文件从我自己的位置复制到app.folders/shared_prefs的位置

关闭应用程序时,我将共享首选项复制回我的私人文件夹


我这样做是为了在需要完全清除旧的apk安装时,不会在apk卸载/安装之间丢失一些重要设置。

我正在做的简单事情。启动时(在任何操作之前),我将我的私人首选项文件从我自己的位置复制到app.folders/shared_prefs的位置

关闭应用程序时,我将共享首选项复制回我的私人文件夹


我这样做是为了在需要完全清除旧的apk安装时,不会在apk卸载/安装之间丢失一些重要的设置。

为什么不创建一个xml并存储它呢?为什么要使用
SharedReferences
?您不能为SharedReferences设置自定义路径,这是不可能的。照约书亚说的做。如果自定义路径上有一个xml文件,你也可以这样做…@Joshua如果可能,我为什么要再次重写它@例如,如果您想使用
SharedReferences
中的
getString(字符串键,字符串定义值)
。您可以编写一个名为
XMLPreferences
的类,并拥有一个方法
getString(String键,String defValue)
。这个方法实际上是从XML文件中查找并返回(如果存在)。在XML文件中,您可以像
YOUR_值
那样保存,或者像
YOUR_值
@MBH那样使用键作为标记名,我将为您编写一个长答案=)为什么不创建一个XML并存储它呢?为什么要使用
SharedReferences
?您不能为SharedReferences设置自定义路径,这是不可能的。照约书亚说的做。如果自定义路径上有一个xml文件,你也可以这样做…@Joshua如果可能,我为什么要再次重写它@例如,如果您想使用
SharedReferences
中的
getString(字符串键,字符串定义值)
。您可以编写一个名为
XMLPreferences
的类,并拥有一个方法
getString(String键,String defValue)
。这个方法实际上是从XML文件中查找并返回(如果存在)。在XML文件中,您可以像
您的_值
那样保存,或者像
您的_值
@MBH那样使用密钥作为标记名,我将为您编写一个长答案=)将共享首选项保存到SD卡,这并没有违反沙箱规则,因为通常我们可以在获得所需的参数的情况下将文件写入和读取到SD卡permission@MBH,这不安全,因为每个不同的应用程序都可以更改您的应用程序设置(这可能会导致一些破坏性的更改)。但是,如果您需要,您可以在这里看到答案:@Alexander您可以使用模式private将文件放入外部存储。将共享首选项保存到sdcard并没有违反沙箱规则,因为通常我们可以在获得所需权限的情况下将文件写入和读取到sdcardpermission@MBH,这是不安全的,因为每个不同的ap