Hallo Zusammen,
ich suche derzeit gutes Beispiel, um mir die Systematik für die Erstellung einer eigenen Preference.
In meiner jetzigen Lösung wird die Vorschau in den Settings nicht dargestellt und ich weiss nicht, wo mein
Fehler ist.
Ich habe bis jetzt eine SettingsFragment, welche die Standard-Preference Werte korrekt anzeigt.
Kurzer Ausschnitt
Code
public class SettingsFragment extends PreferenceFragmentCompat implements Preference.OnPreferenceChangeListener {
private EditTextPreference KeyAccountName;
private PasswordPreference KeyPassword;
private EditTextPreference KeyPlatName;
private EditTextPreference KeyDriverName;
Für die Klasse "PasswordPreference" habe ich folgende Klasse:
Code
public class PasswordPreference extends DialogPreference {
private String sPassword="";
private EditText Password =null;
private int mDialogLayoutResId = R.layout.password_pref_layout;
public PasswordPreference(Context context){
this(context, null);
}
public PasswordPreference(Context context, AttributeSet attrs) {
this(context, null,0);
}
public PasswordPreference(Context context, AttributeSet attrs,
int defStyleAttr) {
this(context, attrs, defStyleAttr, defStyleAttr);
}
public PasswordPreference(Context context, AttributeSet attrs,
int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
// setWidgetLayoutResource(mDialogLayoutResId);
setDialogLayoutResource(mDialogLayoutResId);
setPositiveButtonText(android.R.string.ok);
setNegativeButtonText(android.R.string.cancel);
}
/*
* Gets the text from the {@link SharedPreferences}.
*
* @return The current preference value.
*/
public String getText() {
return sPassword;
}
public String getPassword(){
return sPassword;
}
public void setPassword(String sPass){
sPassword=sPass;
persistString(sPassword);
}
@Override
public CharSequence getSummary() {
return super.getSummary();
}
@Override
public void setSummary(CharSequence sSum){
}
@Override
protected Object onGetDefaultValue(TypedArray a, int index) {
// Default value from attribute. Fallback value is set to 0.
return a.getString(index);
}
@Override
public int getDialogLayoutResource() {
return mDialogLayoutResId;
}
}
Alles anzeigen
Ebenso ein Klasse "PasswordPreferenceDialogFragmentCompat"
Code
public class PasswordPreferenceDialogFragmentCompat extends PreferenceDialogFragmentCompat {
EditText Password;
EditText ConfirmPassword;
EncryptedData encData = null;
private static final int SALT_BYTES = 8;
private static final int PBK_ITERATIONS = 1000;
private static final String ENCRYPTION_ALGORITHM = "AES/CBC/PKCS5Padding";
private static final String PBE_ALGORITHM = "PBEwithSHA256and128BITAES-CBC-BC";
private static final String USED_PASSWORD ="ParkPlatzHilfe!1234";
@Override
public void onDialogClosed(boolean positiveResult) {
String sPassword;
if(positiveResult) {
sPassword = Password.getText().toString();
// Get the related Preference and save the value
DialogPreference preference = getPreference();
if (preference instanceof PasswordPreference) {
PasswordPreference passwordPreference =
((PasswordPreference) preference);
// This allows the client to ignore the user value.
if (passwordPreference.callChangeListener(
sPassword)) {
// Save the value
passwordPreference.setPassword(sPassword);
}
}
}
}
public static PasswordPreferenceDialogFragmentCompat newInstance(
String key) {
final PasswordPreferenceDialogFragmentCompat
fragment = new PasswordPreferenceDialogFragmentCompat();
final Bundle b = new Bundle(1);
b.putString(ARG_KEY, key);
fragment.setArguments(b);
return fragment;
}
@Override
protected void onBindDialogView(View view) {
super.onBindDialogView(view);
Password= view.findViewById(R.id.editPassword);
// Get the password from the related Preference
String sPass = null;
DialogPreference preference = getPreference();
if (preference instanceof PasswordPreference) {
sPass=((PasswordPreference) preference).getPassword();
}
if(sPass != null){
Password.setText(sPass);
}
}
/*
String password = "ParkPlatzHilfe!1234";
byte[] data = sPassword.getBytes("UTF-8");
EncryptedData encData = encrypt(password, data);
byte[] decryptedData = decrypt(password, encData.salt, encData.iv, encData.encryptedData);
String decDataAsString = new String(decryptedData, "UTF-8");
*/
private static class EncryptedData {
public byte[] salt;
public byte[] iv;
public byte[] encryptedData;
}
private EncryptedData encrypt(String password, byte[] data) throws NoSuchPaddingException,
NoSuchAlgorithmException,
InvalidKeySpecException,
InvalidKeyException,
BadPaddingException,
IllegalBlockSizeException,
InvalidAlgorithmParameterException {
EncryptedData encData = new EncryptedData();
SecureRandom rnd = new SecureRandom();
encData.salt = new byte[SALT_BYTES];
encData.iv = new byte[16]; // AES block size
rnd.nextBytes(encData.salt);
rnd.nextBytes(encData.iv);
PBEKeySpec keySpec = new PBEKeySpec(password.toCharArray(), encData.salt, PBK_ITERATIONS);
SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance(PBE_ALGORITHM);
Key key = secretKeyFactory.generateSecret(keySpec);
Cipher cipher = Cipher.getInstance(ENCRYPTION_ALGORITHM);
IvParameterSpec ivSpec = new IvParameterSpec(encData.iv);
cipher.init(Cipher.ENCRYPT_MODE, key, ivSpec);
encData.encryptedData = cipher.doFinal(data);
return encData;
}
private byte[] decrypt(String password, byte[] salt, byte[] iv, byte[] encryptedData) throws NoSuchAlgorithmException,
InvalidKeySpecException,
NoSuchPaddingException,
InvalidKeyException,
BadPaddingException,
IllegalBlockSizeException,
InvalidAlgorithmParameterException {
PBEKeySpec keySpec = new PBEKeySpec(password.toCharArray(), salt, PBK_ITERATIONS);
SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance(PBE_ALGORITHM);
Key key = secretKeyFactory.generateSecret(keySpec);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
IvParameterSpec ivSpec = new IvParameterSpec(iv);
cipher.init(Cipher.DECRYPT_MODE, key, ivSpec);
return cipher.doFinal(encryptedData);
}
//return the password in asterisks
private String setAsterisks(int length) {
StringBuilder sb = new StringBuilder();
for (int s = 0; s < length; s++) {
sb.append("*");
}
return sb.toString();
}
}
Alles anzeigen
Hier der Ausschnitt aus der Preference.xml
Code
<com.example.android.parkhilfeclient.PasswordPreference
android:key="@string/key_Password"
android:dialogMessage="@string/prefs_summary_category_Password"
app:defaultValue="@string/pref_Password"
app:key="@string/key_Password"
app:summary="@string/pref_Password"
app:title="@string/prefs_summary_category_Password"/>
Das Ergebis ist jedenfalls, das in den Settings ein leerer Eintrag angezeigt wird und ich trotz setzen von Breakpoint nicht gefunden habe wo es klemmt.
Viele Grüße
R.