Android Config File

后端 未结 4 1773
野趣味
野趣味 2020-12-12 17:25

What is the best way and how to set up a config file for a application?

I want the application to be able to look into a text file on the sd card and pick out certa

4条回答
  •  有刺的猬
    2020-12-12 17:52

    If your application is going to be released to the public and if you have sensitive data in your config such as API keys or passwords I would suggest to use secure-preferences instead of SharedPreferences since ultimately SharedPreferences are stored in an XML in clear text and on a rooted phone it is very easy for an application to access another's shared preferences.

    By default it's not bullet proof security (in fact it's more like obfuscation of the preferences) but it's a quick win for incrementally making your android app more secure. For instance it'll stop users on rooted devices easily modifying your app's shared prefs. (link)

    I would suggest a few of other methods:

    Method 1: Use a *.properties file with Properties

    Pros:

    1. Easy to edit from whatever IDE you are using
    2. More secure: since it is compiled with your app
    3. Can easily be overridden if you use Build variants/Flavors
    4. You can also write in the config

    Cons:

    1. You need a context
    2. You can also write in the config (yes, it can also a be a con)
    3. (anything else?)

    First, create a config file: res/raw/config.properties and add some values:

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

    You can then easily access the values with something like this:

    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;
        }
    }
    

    Usage:

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

    Of course this could be optimized to read the config file once and get all values.

    Method 2: Use AndroidManifest.xml meta-data element:

    Personally I've never used this method because it doesn't seem very flexible.

    In your AndroidManifest.xml add something like:

    ...
    
        ...
    
        
        
    
    

    Now a function to retrieve the values:

    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;
    }
    

    Usage:

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

    Method 3: Use buildConfigField in your Flavor:

    I didn't find this in the official Android documentation/training but this blog article is very useful.

    Basically setting up a project Flavor (for example prod) and then in your app's build.gradle have something like:

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

    Usage:

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

提交回复
热议问题