Android配置文件

问题描述 投票:33回答:4

什么是最好的方法以及如何为应用程序设置配置文件?

我希望应用程序能够查看SD卡上的文本文件并选择它需要的某些信息?

android configuration configuration-files
4个回答
8
投票

你可以使用shared preferences实现这一目标

有关如何在Google Android页面https://developer.android.com/guide/topics/data/data-storage.html#pref上使用共享首选项的详细指南


76
投票

如果您的应用程序将向公众发布,并且如果您的配置中包含敏感数据(如API密钥或密码),我建议使用secure-preferences而不是SharedPreferences,因为最终SharedPreferences以明文形式存储在XML中并且以root身份存储手机应用程序很容易访问其他人的共享首选项。

默认情况下,它不是防弹安全性(实际上它更像是对首选项进行模糊处理),但它可以让您的Android应用程序更加安全。例如,它会阻止用户在root用户设备上轻松修改应用的共享首选项。 (link

我会建议一些其他方法:

方法1:使用带有Properties的* .properties文件

优点:

  1. 可以从您正在使用的任何IDE轻松编辑
  2. 更安全:因为它是使用您的应用程序编译的
  3. 如果你使用Build variants/Flavors,很容易被覆盖
  4. 您也可以在配置中写入

缺点:

  1. 你需要一个上下文
  2. 你也可以在配置中写(是的,它也可以是骗局)
  3. (还要别的吗?)

首先,创建一个配置文件:res/raw/config.properties并添加一些值:

api_url=http://url.to.api/v1/
api_key=123456

然后,您可以使用以下内容轻松访问值:

package some.package.name.app;

import android.content.Context;
import android.content.res.Resources;
import android.util.Log;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

public final class Helper {
    private static final String TAG = "Helper";

    public static String getConfigValue(Context context, String name) {
        Resources resources = context.getResources();

        try {
            InputStream rawResource = resources.openRawResource(R.raw.config);
            Properties properties = new Properties();
            properties.load(rawResource);
            return properties.getProperty(name);
        } catch (Resources.NotFoundException e) {
            Log.e(TAG, "Unable to find the config file: " + e.getMessage());
        } catch (IOException e) {
            Log.e(TAG, "Failed to open config file.");
        }

        return null;
    }
}

用法:

String apiUrl = Helper.getConfigValue(this, "api_url");
String apiKey = Helper.getConfigValue(this, "api_key");

当然,这可以优化一次读取配置文件并获取所有值。

方法2:使用AndroidManifest.xml meta-data元素:

就个人而言,我从未使用过这种方法,因为它似乎不太灵活。

在你的AndroidManifest.xml中添加如下内容:

...
<application ...>
    ...

    <meta-data android:name="api_url" android:value="http://url.to.api/v1/"/>
    <meta-data android:name="api_key" android:value="123456"/>
</application>

现在是一个检索值的函数:

public static String getMetaData(Context context, String name) {
    try {
        ApplicationInfo ai = context.getPackageManager().getApplicationInfo(context.getPackageName(), PackageManager.GET_META_DATA);
        Bundle bundle = ai.metaData;
        return bundle.getString(name);
    } catch (PackageManager.NameNotFoundException e) {
        Log.e(TAG, "Unable to load meta-data: " + e.getMessage());
    }
    return null;
}

用法:

String apiUrl = Helper.getMetaData(this, "api_url");
String apiKey = Helper.getMetaData(this, "api_key");

方法3:在buildConfigField中使用Flavor

我没有在官方Android文档/培训中找到这个,但this blog article非常有用。

基本上设置一个项目Flavor(例如prod),然后在你的应用程序的build.gradle中有类似的东西:

productFlavors {
    prod {
        buildConfigField 'String', 'API_URL', '"http://url.to.api/v1/"'
        buildConfigField 'String', 'API_KEY', '"123456"'
    }
}

用法:

String apiUrl = BuildConfig.API_URL;
String apiKey = BuildConfig.API_KEY;

8
投票

如果您想存储应用程序的首选项,Android会为此提供SharedPreferencesHere is the link to official training resource.


1
投票

我最近遇到了这样的要求,在这里注意到,我是怎么做到的。

应用程序能够查看SD卡上的文本文件并选择它所需的某些信息

需求:

  1. 必须在SD卡上提供配置值(score_threshold)。所以有人可以在释放apk后更改值。
  2. 配置文件必须在android硬件的“/sdcard/config.txt”中可用。

config.txt文件内容是,

score_threshold=60

创建一个实用程序类Config.java,用于读写文本文件。

import android.util.Log;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Properties;

public final class Config {

    private static final String TAG = Config.class.getSimpleName();
    private static final String FILE_PATH = Environment.getExternalStorageDirectory().getAbsolutePath() + "/config.txt";
    private static Config sInstance = null;

    /**
     * Gets instance.
     *
     * @return the instance
     */
    public static Config getInstance() {
        if (sInstance == null) {
            synchronized (Config.class) {
                if (sInstance == null) {
                    sInstance = new Config();
                }
            }
        }
        return sInstance;
    }

    /**
     * Write configurations values boolean.
     *
     * @return the boolean
     */
    public boolean writeConfigurationsValues() {

        try (OutputStream output = new FileOutputStream(FILE_PATH)) {

            Properties prop = new Properties();

            // set the properties value
            prop.setProperty("score_threshold", "60");

            // save properties
            prop.store(output, null);

            Log.i(TAG, "Configuration stored  properties: " + prop);
            return true;
        } catch (IOException io) {
            io.printStackTrace();
            return false;
        }
    }

    /**
     * Get configuration value string.
     *
     * @param key the key
     * @return the string
     */
    public String getConfigurationValue(String key){
        String value = "";
        try (InputStream input = new FileInputStream(FILE_PATH)) {

            Properties prop = new Properties();

            // load a properties file
            prop.load(input);
            value = prop.getProperty(key);
            Log.i(TAG, "Configuration stored  properties value: " + value);
         } catch (IOException ex) {
            ex.printStackTrace();
        }
        return value;
    }
}

创建另一个实用程序类以便在第一次执行应用程序时编写配置文件,注意:必须为应用程序设置SD卡读/写权限。

public class ApplicationUtils {

  /**
  * Sets the boolean preference value
  *
  * @param context the current context
  * @param key     the preference key
  * @param value   the value to be set
  */
 public static void setBooleanPreferenceValue(Context context, String key, boolean value) {
     SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
     sp.edit().putBoolean(key, value).commit();
 }

 /**
  * Get the boolean preference value from the SharedPreference
  *
  * @param context the current context
  * @param key     the preference key
  * @return the the preference value
  */
 public static boolean getBooleanPreferenceValue(Context context, String key) {
     SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
     return sp.getBoolean(key, false);
 }

}

在您的主要活动中,onCreate()

if(!ApplicationUtils.getBooleanPreferenceValue(this,"isFirstTimeExecution")){
           Log.d(TAG, "First time Execution");
           ApplicationUtils.setBooleanPreferenceValue(this,"isFirstTimeExecution",true);
           Config.getInstance().writeConfigurationsValues();
}
// get the configuration value from the sdcard.
String thresholdScore = Config.getInstance().getConfigurationValue("score_threshold");
Log.d(TAG, "thresholdScore from config file is : "+thresholdScore );
© www.soinside.com 2019 - 2024. All rights reserved.