什么是最好的方法以及如何为应用程序设置配置文件?
我希望应用程序能够查看SD卡上的文本文件并选择它需要的某些信息?
你可以使用shared preferences实现这一目标
有关如何在Google Android页面https://developer.android.com/guide/topics/data/data-storage.html#pref上使用共享首选项的详细指南
如果您的应用程序将向公众发布,并且如果您的配置中包含敏感数据(如API密钥或密码),我建议使用secure-preferences而不是SharedPreferences,因为最终SharedPreferences以明文形式存储在XML中并且以root身份存储手机应用程序很容易访问其他人的共享首选项。
默认情况下,它不是防弹安全性(实际上它更像是对首选项进行模糊处理),但它可以让您的Android应用程序更加安全。例如,它会阻止用户在root用户设备上轻松修改应用的共享首选项。 (link)
我会建议一些其他方法:
方法1:使用带有Properties的* .properties文件
优点:
缺点:
首先,创建一个配置文件: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;
如果您想存储应用程序的首选项,Android会为此提供SharedPreferences。 Here is the link to official training resource.
我最近遇到了这样的要求,在这里注意到,我是怎么做到的。
应用程序能够查看SD卡上的文本文件并选择它所需的某些信息
需求:
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 );