com.newtifry.android.SourceEditor2.java Source code

Java tutorial

Introduction

Here is the source code for com.newtifry.android.SourceEditor2.java

Source

/**
 * Newtifry for Android.
 * 
 * Copyright 2011 Daniel Foote
 *
 * Licensed under the Apache License, Version 2.0 (the 'License');
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an 'AS IS' BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.newtifry.android;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;

import org.json.JSONException;

import com.actionbarsherlock.app.SherlockPreferenceActivity;
import com.actionbarsherlock.view.MenuItem;
import com.google.android.gcm.GCMRegistrar;
import com.newtifry.android.database.NewtifryMessage;
import com.newtifry.android.database.NewtifrySource;
import com.newtifry.android.remote.BackendRequest;
import com.newtifry.android.remote.BackendResponse;
import com.newtifry.android.R;

import static com.newtifry.android.CommonUtilities.TAG;
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.preference.CheckBoxPreference;
import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceChangeListener;
import android.preference.Preference.OnPreferenceClickListener;
import android.text.Html;
import android.util.Log;
import android.widget.Toast;

@SuppressWarnings("deprecation")
public class SourceEditor2 extends SherlockPreferenceActivity {
    private final SourceEditor2 thisActivity = this;
    private NewtifrySource source = null;
    public static SourceEditor2ORMPreferencesMapper preferenceMapper = null;
    CheckBoxPreference serverEnabled;
    Preference titlePreference;
    Preference sourceKey;
    Preference preferenceTest;
    Preference localEnablePreference;
    CheckBoxPreference localEnablePreferenceCheckBox;
    Preference sourceNotificationPreference;
    ListPreference sourceColorPreference;

    public class SourceEditor2ORMPreferencesMapper implements SharedPreferences {
        protected List<OnSharedPreferenceChangeListener> listeners = new LinkedList<OnSharedPreferenceChangeListener>();

        public SourceEditor2ORMPreferencesMapper() {
        }

        public NewtifrySource getSource() {
            return thisActivity.source;
        }

        public boolean contains(String key) {
            Map<String, ?> values = this.getAll();
            return values.containsKey(key);
        }

        public Editor edit() {
            return new Editor();
        }

        public Map<String, ?> getAll() {
            Map<String, Object> values = new HashMap<String, Object>();
            values.put(Preferences.SOURCE_SERVER, thisActivity.source.getServerEnabled());
            values.put(Preferences.SOURCE_LOCAL, thisActivity.source.getLocalEnabled());
            values.put(Preferences.SOURCE_NOTIFICATION, thisActivity.source.getNotification());
            values.put(Preferences.SOURCE_USE_NOTIFIER_PRO, thisActivity.source.getNotifierPro());
            values.put(Preferences.SOURCE_VIBRATE_NOTIFY, thisActivity.source.getVibrate());
            values.put(Preferences.SOURCE_LED_FLASH, thisActivity.source.getLedFlash());
            values.put(Preferences.SOURCE_SPEAK_MESSAGE, thisActivity.source.getSpeakMessage());
            values.put(Preferences.SOURCE_GLOBAL, thisActivity.source.getUseGlobalNotification());
            values.put(Preferences.SOURCE_RINGTONE, thisActivity.source.getRingtone());
            values.put(Preferences.SOURCE_TITLE, thisActivity.source.getTitle());
            values.put(Preferences.SOURCE_SOURCE_COLOR, thisActivity.source.getSourceColor());
            return values;
        }

        public boolean getBoolean(String key, boolean defValue) {
            // source_server_enable
            // source_local_enable
            // source_notification
            // source_usenotifierpro
            // source_ringtone
            // source_vibrate
            // source_ledflash
            // source_speakmessage
            if (key.equals(Preferences.SOURCE_SERVER)) {
                return thisActivity.source.getServerEnabled();
            } else if (key.equals(Preferences.SOURCE_LOCAL)) {
                return thisActivity.source.getLocalEnabled();
            } else if (key.equals(Preferences.SOURCE_NOTIFICATION)) {
                return thisActivity.source.getNotification();
            } else if (key.equals(Preferences.SOURCE_USE_NOTIFIER_PRO)) {
                return thisActivity.source.getNotifierPro();
            } else if (key.equals(Preferences.SOURCE_VIBRATE_NOTIFY)) {
                return thisActivity.source.getVibrate();
            } else if (key.equals(Preferences.SOURCE_LED_FLASH)) {
                return thisActivity.source.getLedFlash();
            } else if (key.equals(Preferences.SOURCE_SPEAK_MESSAGE)) {
                return thisActivity.source.getSpeakMessage();
            } else if (key.equals(Preferences.SOURCE_GLOBAL)) {
                return thisActivity.source.getUseGlobalNotification();
            }

            return false;
        }

        public float getFloat(String key, float defValue) {
            // No floats available.
            return 0;
        }

        public int getInt(String key, int defValue) {
            // No int's available.
            return 0;
        }

        public long getLong(String key, long defValue) {
            // No longs available.
            return 0;
        }

        public String getString(String key, String defValue) {
            // source_customringtone
            // source_title
            if (key.equals(Preferences.SOURCE_TITLE)) {
                return thisActivity.source.getTitle();
            } else if (key.equals(Preferences.SOURCE_RINGTONE)) {
                return thisActivity.source.getRingtone();
            } else if (key.equals(Preferences.SOURCE_SOURCE_COLOR)) {
                return thisActivity.source.getSourceColor();
            }

            return null;
        }

        public void registerOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener listener) {
            this.listeners.add(listener);
        }

        public void unregisterOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener listener) {
            this.listeners.remove(listener);
        }

        public class Editor implements SharedPreferences.Editor {

            public android.content.SharedPreferences.Editor clear() {
                // Not applicable for this object.
                return null;
            }

            public boolean commit() {
                thisActivity.source.save(thisActivity);
                return true;
            }

            public android.content.SharedPreferences.Editor putBoolean(String key, boolean value) {
                // NOTE: This is not transactionally safe as it modifies the parent's object.
                // source_server_enable
                // source_local_enable
                // source_notification
                // source_usenotifierpro
                // source_ringtone
                // source_vibrate
                // source_ledflash
                // source_speakmessage
                // source_global
                if (key.equals(Preferences.SOURCE_SERVER)) {
                    thisActivity.source.setServerEnabled(value);
                } else if (key.equals(Preferences.SOURCE_LOCAL)) {
                    thisActivity.source.setLocalEnabled(value);
                } else if (key.equals(Preferences.SOURCE_NOTIFICATION)) {
                    thisActivity.source.setNotification(value);
                } else if (key.equals(Preferences.SOURCE_USE_NOTIFIER_PRO)) {
                    thisActivity.source.setNotifierPro(value);
                } else if (key.equals(Preferences.SOURCE_VIBRATE_NOTIFY)) {
                    thisActivity.source.setVibrate(value);
                } else if (key.equals(Preferences.SOURCE_LED_FLASH)) {
                    thisActivity.source.setLedFlash(value);
                } else if (key.equals(Preferences.SOURCE_SPEAK_MESSAGE)) {
                    thisActivity.source.setSpeakMessage(value);
                } else if (key.equals(Preferences.SOURCE_GLOBAL)) {
                    thisActivity.source.setUseGlobalNotification(value);
                }

                return this;
            }

            public android.content.SharedPreferences.Editor putFloat(String key, float value) {
                // No floats to set.
                return this;
            }

            public android.content.SharedPreferences.Editor putInt(String key, int value) {
                // No ints to set.
                return this;
            }

            public android.content.SharedPreferences.Editor putLong(String key, long value) {
                // No longs to set.
                return this;
            }

            public android.content.SharedPreferences.Editor putString(String key, String value) {
                // NOTE: This is not transactionally safe as it modifies the parent's object.            
                // source_customringtone
                // source_title
                if (key.equals(Preferences.SOURCE_TITLE)) {
                    thisActivity.source.setTitle(value);
                } else if (key.equals(Preferences.SOURCE_RINGTONE)) {
                    thisActivity.source.setRingtone(value);
                } else if (key.equals(Preferences.SOURCE_SOURCE_COLOR)) {
                    thisActivity.source.setSourceColor(value);
                }

                return this;
            }

            public android.content.SharedPreferences.Editor remove(String key) {
                // Nothing to do here - this doesn't make sense.
                return this;
            }

            public void apply() {
                thisActivity.source.save(thisActivity);
            }

            public android.content.SharedPreferences.Editor putStringSet(String arg0, Set<String> arg1) {
                // TODO Auto-generated method stub
                return null;
            }
        }

        public Set<String> getStringSet(String arg0, Set<String> arg1) {
            // TODO Auto-generated method stub
            return null;
        }
    }

    public SharedPreferences getSharedPreferences(String name, int mode) {
        return SourceEditor2.preferenceMapper;
    }

    /** Called when the activity is first created. */
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getSource();
        SourceEditor2.preferenceMapper = new SourceEditor2ORMPreferencesMapper();

        this.addPreferencesFromResource(R.xml.source_preference_editor2);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);

        // Find and attach the onclick handlers.
        titlePreference = this.findPreference(Preferences.SOURCE_TITLE);
        titlePreference.setOnPreferenceChangeListener(immediateServerChangeListener);

        Preference serverEnabledPreference = this.findPreference(Preferences.SOURCE_SERVER);
        serverEnabledPreference.setOnPreferenceChangeListener(immediateServerChangeListener);
        serverEnabled = (CheckBoxPreference) serverEnabledPreference;

        localEnablePreference = this.findPreference(Preferences.SOURCE_LOCAL);
        localEnablePreference.setOnPreferenceChangeListener(localEnablePreferenceCheckListener);
        localEnablePreferenceCheckBox = (CheckBoxPreference) localEnablePreference;

        sourceKey = this.findPreference(Preferences.SOURCE_KEY);

        preferenceTest = this.findPreference(Preferences.SOURCE_TEST);
        preferenceTest.setOnPreferenceClickListener(testClickHandler);

        sourceColorPreference = (ListPreference) this.findPreference(Preferences.SOURCE_SOURCE_COLOR);
        sourceColorPreference.setOnPreferenceChangeListener(sourceColorChangeListener);

        sourceNotificationPreference = thisActivity.findPreference(Preferences.SOURCE_NOTIFICATION_SETTINGS);

        Preference sourceEmailKeyPreference = this.findPreference(Preferences.SOURCE_EMAIL);
        sourceEmailKeyPreference.setOnPreferenceClickListener(emailClickHandler);

        Preference messagesPreference = this.findPreference(Preferences.SOURCE_MESSAGES);
        messagesPreference.setOnPreferenceClickListener(messagesClickHandler);

        Preference deletePreference = this.findPreference(Preferences.SOURCE_DELETE);
        deletePreference.setOnPreferenceClickListener(deleteClickHandler);

    }

    OnPreferenceChangeListener sourceColorChangeListener = new OnPreferenceChangeListener() {
        public boolean onPreferenceChange(Preference preference, Object newValue) {
            updateSourcecolor((String) newValue);
            return true;
        }
    };

    @SuppressLint("NewApi")
    public void updateSourcecolor(String value) {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
            if (value.equals("default")) {
                sourceColorPreference.setSummary(getString(R.string.froyo_color_summary));

            } else {
                String hexColor = Integer.toHexString(Color.parseColor(value));
                String html = "<font color=\"#" + hexColor.substring(hexColor.length() - 6, 8) + "\">"
                        + getString(R.string.froyo_color_summary) + "</font>";
                sourceColorPreference.setSummary(Html.fromHtml(html));
            }
            return;
        }

        String uri = "drawable/icon_color_" + value;
        int imageResource = getResources().getIdentifier(uri, null, getPackageName());
        Drawable icon = getResources().getDrawable(imageResource);
        sourceColorPreference.setIcon(icon);
    }

    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
    }

    public void onResume() {
        super.onResume();

        // Reload our source data.
        this.source = null;
        // And finally, update the screen.
        this.loadFromSource(this.getSource());
    }

    public void onPause() {
        super.onPause();
    }

    /**
     * Load this activity from the given source.
     * @param source
     */
    public void loadFromSource(NewtifrySource source) {

        // Create a new preferences mapper with updated source data.
        SourceEditor2.preferenceMapper = new SourceEditor2ORMPreferencesMapper();

        titlePreference.setSummary(source.getTitle());
        sourceKey.setSummary(source.getSourceKey());
        // Force update the server enabled preference.
        serverEnabled.setChecked(source.getServerEnabled());
        //      sourceColorPreference.setValue(source.getSourceColor());
        updateSourcecolor(source.getSourceColor());

        this.toggleLocalEnablePreferences(source.getLocalEnabled());
        this.toggleServerEnable(source.getServerEnabled());
    }

    /**
     * Save this source.
     */
    /*   
       public void save( View view )
       {
          // User clicked save button.
          // Prepare the new local object.
          SourceEditor2.source = null;
          NewtifrySource source = this.getSource();
              
          EditText title = (EditText) findViewById(R.id.detail_title);
          source.setTitle(title.getText().toString());
              
          CheckBox serverEnable = (CheckBox) findViewById(R.id.detail_serverenable);
          source.setServerEnabled(serverEnable.isChecked());
          CheckBox localEnable = (CheckBox) findViewById(R.id.detail_localenable);
          source.setLocalEnabled(localEnable.isChecked());
              
          // Now, send the updates to the server. On success, save the changes locally.
          BackendRequest request = new BackendRequest("/sources/edit");
          request.add("id", source.getServerId().toString());
          request.add("title", source.getTitle());
          if( source.getServerEnabled() )
          {
     request.add("enabled", "on");
          }
              
          request.addMeta("source", source);
          request.addMeta("operation", "save");
              
          request.setHandler(handler);
              
          request.startInThread(this, getString(R.string.source_saving_to_server), source.getAccountName());
       }
    */

    // Crude: determine what thing we changed based on the object's t
    /**
     * A listener for changes that must occur immediately on the server.
     */
    OnPreferenceChangeListener immediateServerChangeListener = new OnPreferenceChangeListener() {
        public boolean onPreferenceChange(Preference preference, Object newValue) {
            // Crude: determine what thing we changed based on the object's type.
            // CAUTION: This won't work if we need to send more than a string or boolean to the server.
            BackendRequest request = new BackendRequest("/sources/edit");
            request.add("id", thisActivity.getSource().getServerId().toString());

            if (newValue instanceof String) {
                // Set the title.
                request.add("title", (String) newValue);
                if (thisActivity.getSource().getServerEnabled()) {
                    request.add("enabled", "on");
                }
            } else if (newValue instanceof Boolean) {
                request.add("title", thisActivity.getSource().getTitle());
                // Set the server enabled value.
                Boolean boolValue = (Boolean) newValue;
                if (boolValue) {
                    request.add("enabled", "on");
                }
            }

            request.addMeta("source", thisActivity.getSource());
            request.addMeta("operation", "save");

            request.setHandler(handler);

            request.startInThread(thisActivity, getString(R.string.source_saving_to_server),
                    thisActivity.getSource().getAccountName());

            // Prevent the change from occuring here.
            return false;
        }
    };

    /**
     * Toggle the server source enabled.
     */
    public void toggleServerEnable(boolean serverEnabled) {
        // if enable enable only source and test
        // if disable : disable all
        localEnablePreference.setEnabled(serverEnabled);
        if (serverEnabled && !localEnablePreferenceCheckBox.isChecked()) {
            serverEnabled = false;
        }
        sourceNotificationPreference.setEnabled(serverEnabled);
        preferenceTest.setEnabled(serverEnabled);
    }

    /**
     * Toggle the local source enabled.
     */
    OnPreferenceChangeListener localEnablePreferenceCheckListener = new OnPreferenceChangeListener() {
        public boolean onPreferenceChange(Preference preference, Object newValue) {
            thisActivity.toggleLocalEnablePreferences((Boolean) newValue);
            return true;
        }
    };

    public void toggleLocalEnablePreferences(boolean localEnabled) {
        sourceNotificationPreference.setEnabled(localEnabled);
        preferenceTest.setEnabled(localEnabled);
    }

    /**
     * Delete this source.
     */
    OnPreferenceClickListener deleteClickHandler = new OnPreferenceClickListener() {
        public boolean onPreferenceClick(Preference preference) {
            // User clicked delete button.
            // Confirm that's what they want.
            new AlertDialog.Builder(thisActivity).setTitle(getString(R.string.delete_source))
                    .setMessage(getString(R.string.delete_source_message))
                    .setPositiveButton(getString(R.string.delete), new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int whichButton) {
                            // Fire it off to the delete source function.
                            deleteSource(thisActivity.getSource());
                        }
                    }).setNegativeButton(getString(R.string.cancel), new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int whichButton) {
                            // No need to take any action.
                        }
                    }).show();

            return true;
        }
    };

    /**
     * Send a request to the backend to delete the source.
     * @param source
     */
    public void deleteSource(NewtifrySource source) {
        // Now, send the updates to the server. On success, save the changes locally.
        BackendRequest request = new BackendRequest("/sources/delete");
        request.add("id", source.getServerId().toString());
        request.addMeta("operation", "delete");
        request.addMeta("source", getSource());
        request.setHandler(handler);

        request.startInThread(this, getString(R.string.source_deleting_from_server), source.getAccountName());
    }

    /**
     * Send a request to the backend to test this source.
     * @param view
     */
    OnPreferenceClickListener testClickHandler = new OnPreferenceClickListener() {
        public boolean onPreferenceClick(Preference preference) {
            if (BuildConfig.DEBUG) {
                // generate localy a message
                NewtifrySource source = getSource();
                NewtifryMessage message = NewtifryMessage.fromDebug(thisActivity, 6443258397851648L,
                        source.getServerId(), 1); // long serverId, long sourceId, int priority
                message.save(thisActivity);
                return true;
            }
            BackendRequest request = new BackendRequest("/sources/test");
            request.add("id", getSource().getServerId().toString());
            request.addMeta("operation", "test");
            // v2.3.2
            request.add("deviceid", GCMRegistrar.getRegistrationId(thisActivity.getApplicationContext()));
            request.add("language", Locale.getDefault().getDisplayLanguage(Locale.US));
            request.addMeta("source", getSource());
            request.setHandler(handler);

            request.startInThread(thisActivity, getString(R.string.source_testing_with_server),
                    source.getAccountName());

            return true;
        }
    };

    /**
     * Email the source key to someone.
     */
    OnPreferenceClickListener emailClickHandler = new OnPreferenceClickListener() {
        public boolean onPreferenceClick(Preference preference) {
            // User wants to email the key to someone.
            final Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);
            emailIntent.setType("plain/text");
            emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT,
                    getString(R.string.source_key_email_subject));
            emailIntent.putExtra(android.content.Intent.EXTRA_TEXT,
                    String.format(getString(R.string.source_key_email_body), getSource().getSourceKey()));
            thisActivity.startActivity(Intent.createChooser(emailIntent, "Send key via email"));

            return true;
        }
    };

    /**
     * View the messages of this source.
     */
    OnPreferenceClickListener messagesClickHandler = new OnPreferenceClickListener() {
        public boolean onPreferenceClick(Preference preference) {
            Intent intent = new Intent(thisActivity, MessageList.class);
            intent.putExtra("sourceId", thisActivity.getSource().getId());
            startActivity(intent);
            return true;
        }
    };

    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            // Fetch out the response.
            BackendResponse response = (BackendResponse) msg.obj;

            // Was it successful?
            if (response.isError()) {
                // No, not successful.
                Toast.makeText(thisActivity, response.getError() + getString(R.string.try_again), Toast.LENGTH_LONG)
                        .show();
            } else {
                try {
                    // Fetch out metadata.
                    BackendRequest request = response.getRequest();
                    NewtifrySource source = (NewtifrySource) request.getMeta("source");

                    String operation = (String) request.getMeta("operation");

                    if (operation.equals("save")) {
                        // Load the source from the server information. We assume the server is correct.
                        source.fromJSONObject(response.getJSON().getJSONObject("source"));

                        // Save it to the database.
                        source.save(thisActivity);

                        Toast.makeText(thisActivity, getString(R.string.source_save_success), Toast.LENGTH_SHORT)
                                .show();

                        // Reload the parent activity.
                        thisActivity.source = null;
                        thisActivity.loadFromSource(thisActivity.getSource());
                    } else if (operation.equals("delete")) {
                        // Delete from local.
                        source.delete(thisActivity);

                        // Let the user know we're done.
                        Toast.makeText(thisActivity, getString(R.string.source_delete_success), Toast.LENGTH_SHORT)
                                .show();

                        // And exit this activity.
                        thisActivity.finish();
                    } else if (operation.equals("test")) {
                        // The server has been asked to test us.
                        Toast.makeText(thisActivity, getString(R.string.source_test_success), Toast.LENGTH_SHORT)
                                .show();
                    }
                } catch (JSONException e) {
                    // The response doesn't look like we expected.
                    Log.d(TAG, "Invalid response from server: " + e.getMessage());
                    Toast.makeText(thisActivity, getString(R.string.server_invalid_response), Toast.LENGTH_LONG)
                            .show();
                }
            }
        }
    };

    /**
     * Fetch the account that this source list is for.
     * 
     * @return
     */
    public NewtifrySource getSource() {
        if (this.source == null) {
            // Get the source from the intent.
            // We store it in a private variable to save us having to query the
            // DB each time.
            Intent sourceIntent = getIntent();
            this.source = NewtifrySource.FACTORY.get(this, sourceIntent.getLongExtra("sourceId", 0));
        }

        return this.source;
    }

    /**
     * When the home button is hit...
     */
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case android.R.id.home:
            finish();
            /*
                        Intent intent = new Intent(getBaseContext(), SourceList.class);
                        intent.putExtra("account",this.getSource().getAccountName());
                        startActivity(intent);
            */
            return true;
        }

        return super.onOptionsItemSelected((android.view.MenuItem) item);
    }
}