tk.wasdennnoch.androidn_ify.ui.emergency.preferences.ContactPreference.java Source code

Java tutorial

Introduction

Here is the source code for tk.wasdennnoch.androidn_ify.ui.emergency.preferences.ContactPreference.java

Source

/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * 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 tk.wasdennnoch.androidn_ify.ui.emergency.preferences;

import android.Manifest;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.preference.Preference;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.text.BidiFormatter;
import android.text.TextDirectionHeuristics;
import android.view.View;

import com.android.internal.annotations.VisibleForTesting;

import tk.wasdennnoch.androidn_ify.R;
import tk.wasdennnoch.androidn_ify.extracted.settingslib.CircleFramedDrawable;
import tk.wasdennnoch.androidn_ify.ui.emergency.EmergencyContactManager;

/**
 * A {@link Preference} to display or call a contact using the specified URI string.
 */
@SuppressWarnings("deprecation")
public class ContactPreference extends Preference {

    private EmergencyContactManager.Contact mContact;
    @Nullable
    private RemoveContactPreferenceListener mRemoveContactPreferenceListener;
    @Nullable
    private AlertDialog mRemoveContactDialog;

    /**
     * Listener for removing a contact.
     */
    public interface RemoveContactPreferenceListener {
        /**
         * Callback to remove a contact preference.
         */
        void onRemoveContactPreference(ContactPreference preference);
    }

    /**
     * Instantiates a ContactPreference that displays an emergency contact, taking in a Context and
     * the Uri.
     */
    public ContactPreference(Context context, @NonNull Uri contactUri) {
        super(context);
        setOrder(DEFAULT_ORDER);

        setUri(contactUri);

        setWidgetLayoutResource(R.layout.preference_user_delete_widget);
        setPersistent(false);
    }

    public void setUri(@NonNull Uri contactUri) {
        if (mContact != null && !contactUri.equals(mContact.getContactUri()) && mRemoveContactDialog != null) {
            mRemoveContactDialog.dismiss();
        }

        mContact = EmergencyContactManager.getContact(getContext(), contactUri);

        setTitle(mContact.getName());
        setKey(mContact.getContactUri().toString());
        String summary = mContact.getPhoneType() == null ? mContact.getPhoneNumber()
                : String.format(getContext().getResources().getString(R.string.phone_type_and_phone_number),
                        mContact.getPhoneType(), BidiFormatter.getInstance().unicodeWrap(mContact.getPhoneNumber(),
                                TextDirectionHeuristics.LTR));
        setSummary(summary);

        // Update the message to show the correct name.
        if (mRemoveContactDialog != null) {
            mRemoveContactDialog
                    .setMessage(String.format(getContext().getString(R.string.remove_contact), mContact.getName()));
        }

        //TODO: Consider doing the following in a non-UI thread.
        Drawable icon;
        if (mContact.getPhoto() != null) {
            icon = new CircleFramedDrawable(mContact.getPhoto(),
                    (int) getContext().getResources().getDimension(R.dimen.circle_avatar_size));
        } else {
            icon = getContext().getResources().getDrawable(R.drawable.ic_person_black_24dp);
        }
        setIcon(icon);
    }

    /** Listener to be informed when a contact preference should be deleted. */
    public void setRemoveContactPreferenceListener(RemoveContactPreferenceListener removeContactListener) {
        mRemoveContactPreferenceListener = removeContactListener;
        if (mRemoveContactPreferenceListener == null) {
            mRemoveContactDialog = null;
            return;
        }
        if (mRemoveContactDialog != null) {
            return;
        }
        // Create the remove contact dialog
        AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
        builder.setNegativeButton(getContext().getString(R.string.cancel), null);
        builder.setPositiveButton(getContext().getString(R.string.remove), new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialogInterface, int which) {
                if (mRemoveContactPreferenceListener != null) {
                    mRemoveContactPreferenceListener.onRemoveContactPreference(ContactPreference.this);
                }
            }
        });
        builder.setMessage(String.format(getContext().getString(R.string.remove_contact), mContact.getName()));
        mRemoveContactDialog = builder.create();
    }

    @Override
    protected void onBindView(View view) {
        super.onBindView(view);
        View deleteContactIcon = view.findViewById(R.id.delete_contact);
        if (mRemoveContactPreferenceListener == null) {
            deleteContactIcon.setVisibility(View.GONE);
        } else {
            deleteContactIcon.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    showRemoveContactDialog(null);
                }
            });

        }
    }

    public Uri getContactUri() {
        return mContact.getContactUri();
    }

    @VisibleForTesting
    EmergencyContactManager.Contact getContact() {
        return mContact;
    }

    @VisibleForTesting
    AlertDialog getRemoveContactDialog() {
        return mRemoveContactDialog;
    }

    /**
     * Calls the contact.
     */
    public void callContact() {
        Intent callIntent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + mContact.getPhoneNumber()));
        if (ActivityCompat.checkSelfPermission(getContext(),
                Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
            // TODO: Consider calling
            //    ActivityCompat#requestPermissions
            // here to request the missing permissions, and then overriding
            //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
            //                                          int[] grantResults)
            // to handle the case where the user grants the permission. See the documentation
            // for ActivityCompat#requestPermissions for more details.
            return;
        }
        getContext().startActivity(callIntent);
    }

    /**
     * Displays a contact card for the contact.
     */
    public void displayContact() {
        Intent contactIntent = new Intent(Intent.ACTION_VIEW);
        contactIntent.setData(mContact.getContactLookupUri());
        getContext().startActivity(contactIntent);
    }

    /** Shows the dialog to remove the contact, restoring it from {@code state} if it's not null. */
    private void showRemoveContactDialog(Bundle state) {
        if (mRemoveContactDialog == null) {
            return;
        }
        if (state != null) {
            mRemoveContactDialog.onRestoreInstanceState(state);
        }
        mRemoveContactDialog.show();
    }

    @Override
    protected Parcelable onSaveInstanceState() {
        final Parcelable superState = super.onSaveInstanceState();
        if (mRemoveContactDialog == null || !mRemoveContactDialog.isShowing()) {
            return superState;
        }
        final SavedState myState = new SavedState(superState);
        myState.isDialogShowing = true;
        myState.dialogBundle = mRemoveContactDialog.onSaveInstanceState();
        return myState;
    }

    @Override
    protected void onRestoreInstanceState(Parcelable state) {
        if (state == null || !state.getClass().equals(SavedState.class)) {
            // Didn't save state for us in onSaveInstanceState
            super.onRestoreInstanceState(state);
            return;
        }
        SavedState myState = (SavedState) state;
        super.onRestoreInstanceState(myState.getSuperState());
        if (myState.isDialogShowing) {
            showRemoveContactDialog(myState.dialogBundle);
        }
    }

    private static class SavedState extends BaseSavedState {
        boolean isDialogShowing;
        Bundle dialogBundle;

        public SavedState(Parcel source) {
            super(source);
            isDialogShowing = source.readInt() == 1;
            dialogBundle = source.readBundle(getClass().getClassLoader());
        }

        @Override
        public void writeToParcel(Parcel dest, int flags) {
            super.writeToParcel(dest, flags);
            dest.writeInt(isDialogShowing ? 1 : 0);
            dest.writeBundle(dialogBundle);
        }

        public SavedState(Parcelable superState) {
            super(superState);
        }

        public static final Parcelable.Creator<SavedState> CREATOR = new Parcelable.Creator<SavedState>() {
            public SavedState createFromParcel(Parcel in) {
                return new SavedState(in);
            }

            public SavedState[] newArray(int size) {
                return new SavedState[size];
            }
        };
    }
}