package de.tum.in.tumcampusapp.activities;
import android.Manifest;
import android.app.AlertDialog;
import android.content.ContentProviderOperation;
import android.content.DialogInterface;
import android.content.OperationApplicationException;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.RemoteException;
import android.provider.ContactsContract;
import android.provider.ContactsContract.CommonDataKinds;
import android.provider.ContactsContract.CommonDataKinds.Email;
import android.provider.ContactsContract.CommonDataKinds.Note;
import android.provider.ContactsContract.CommonDataKinds.Organization;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.provider.ContactsContract.CommonDataKinds.Photo;
import android.provider.ContactsContract.CommonDataKinds.StructuredName;
import android.provider.ContactsContract.CommonDataKinds.Website;
import android.provider.ContactsContract.Data;
import android.provider.ContactsContract.RawContacts;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ImageView;
import android.widget.TextView;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import de.tum.in.tumcampusapp.R;
import de.tum.in.tumcampusapp.activities.generic.ActivityForAccessingTumOnline;
import de.tum.in.tumcampusapp.auxiliary.HTMLStringBuffer;
import de.tum.in.tumcampusapp.auxiliary.Utils;
import de.tum.in.tumcampusapp.models.tumo.Contact;
import de.tum.in.tumcampusapp.models.tumo.Employee;
import de.tum.in.tumcampusapp.models.tumo.Group;
import de.tum.in.tumcampusapp.models.tumo.Person;
import de.tum.in.tumcampusapp.models.tumo.Room;
import de.tum.in.tumcampusapp.models.tumo.TelSubstation;
import de.tum.in.tumcampusapp.tumonline.TUMOnlineConst;
/**
* Activity to show information about an person at TUM.
*/
public class PersonsDetailsActivity extends ActivityForAccessingTumOnline<Employee> {
private static final String[] PERMISSIONS_CONTACTS = {Manifest.permission.WRITE_CONTACTS};
private Employee mEmployee;
private MenuItem mContact;
public PersonsDetailsActivity() {
super(TUMOnlineConst.PERSON_DETAILS, R.layout.activity_personsdetails);
}
private static void addContact(Collection<ContentProviderOperation> ops, int rawContactID, Contact contact, boolean work) {
if (contact != null) {
// Add work telefon number
if (contact.getTelefon() != null) {
ops.add(ContentProviderOperation.newInsert(Data.CONTENT_URI)
.withValueBackReference(Data.RAW_CONTACT_ID, rawContactID)
.withValue(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE)
.withValue(Phone.NUMBER, contact.getTelefon())
.withValue(Phone.TYPE, work ? Phone.TYPE_WORK : Phone.TYPE_HOME)
.build());
}
// Add work mobile number
if (contact.getMobilephone() != null) {
ops.add(ContentProviderOperation.newInsert(Data.CONTENT_URI)
.withValueBackReference(Data.RAW_CONTACT_ID, rawContactID)
.withValue(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE)
.withValue(Phone.NUMBER, contact.getMobilephone())
.withValue(Phone.TYPE, work ? Phone.TYPE_WORK_MOBILE : Phone.TYPE_MOBILE)
.build());
}
// Add work fax number
if (contact.getFax() != null) {
ops.add(ContentProviderOperation.newInsert(Data.CONTENT_URI)
.withValueBackReference(Data.RAW_CONTACT_ID, rawContactID)
.withValue(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE)
.withValue(Phone.NUMBER, contact.getFax())
.withValue(Phone.TYPE, work ? Phone.TYPE_FAX_WORK : Phone.TYPE_FAX_HOME)
.build());
}
// Add website
if (contact.getHomepage() != null) {
ops.add(ContentProviderOperation.newInsert(Data.CONTENT_URI)
.withValueBackReference(Data.RAW_CONTACT_ID, rawContactID)
.withValue(Data.MIMETYPE, Website.CONTENT_ITEM_TYPE)
.withValue(Website.URL, contact.getHomepage())
.withValue(Website.TYPE, work ? Website.TYPE_WORK : Website.TYPE_HOME)
.build());
}
}
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// get person from staff activity
Bundle bundle = this.getIntent().getExtras();
Person person = (Person) bundle.getSerializable("personObject");
// make sure not both person is not null (error occurred)
if (person == null) {
// no query text specified
Utils.showToast(this, R.string.no_person_set);
return;
}
// Sets the current name as a title
setTitle(person.getName() + ' ' + person.getSurname());
requestHandler.setParameter("pIdentNr", person.getId());
super.requestFetch();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
getMenuInflater().inflate(R.menu.menu_add_contact, menu);
mContact = menu.findItem(R.id.action_add_contact);
if (mEmployee == null) {
mContact.setVisible(false);
}
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int i = item.getItemId();
if (i == R.id.action_add_contact) {
if (mEmployee != null) {
addContact(mEmployee);
}
return true;
} else {
return super.onOptionsItemSelected(item);
}
}
@Override
public void onFetch(Employee rawResponse) {
mEmployee = rawResponse;
displayResults(mEmployee);
mContact.setVisible(true);
showLoadingEnded();
}
/**
* Displays all relevant information about the given employee in the user
* interface (UI).
*
* @param employee The employee whose information should be displayed.
*/
private void displayResults(Employee employee) {
// add the employee's counterfeit
ImageView imageView = (ImageView) this.findViewById(R.id.ivImage);
Bitmap image = employee.getImage();
if (image == null) {
image = BitmapFactory.decodeResource(getResources(),
R.drawable.photo_not_available);
}
imageView.setImageBitmap(image);
// use a custom string buffer that helps us with line feeds and
// formatting
HTMLStringBuffer contentText = new HTMLStringBuffer();
TextView tvDetails1 = (TextView) findViewById(R.id.tvDetails1);
// get the right gender
if (employee.getGender() != null
&& employee.getGender().equals(Person.MALE)) {
contentText.append(getString(R.string.mr) + ' ');
} else if (employee.getGender() != null
&& employee.getGender().equals(Person.FEMALE)) {
contentText.append(getString(R.string.mrs) + ' ');
}
// add title if available
if (employee.getTitle() != null) {
contentText.append(employee.getTitle() + ' ');
}
// add name
contentText.append(employee.getName() + ' ' + employee.getSurname());
tvDetails1.setText(contentText.toString());
// start new information section
contentText.clear();
TextView tvDetails2 = (TextView) findViewById(R.id.tvDetails2);
// add all groups the employee belongs to
List<Group> groups = employee.getGroups();
if (groups != null) {
for (Group group : groups) {
if (group != null) {
contentText.appendField(getString(R.string.function),
group.getTitle());
contentText.appendField(getString(R.string.group), group.getOrg()
+ " ("
+ group.getId()
+ ")<br />");
}
}
}
tvDetails2.setText(Utils.fromHtml(contentText.toString()),
TextView.BufferType.SPANNABLE);
// start new section
contentText.clear();
TextView tvDetails3 = (TextView) findViewById(R.id.tvDetails3);
// add contact information, if available
contentText.appendField(getString(R.string.email), employee.getEmail());
contentText.appendField(getString(R.string.homepage), employee
.getBusinessContact().getHomepage());
List<TelSubstation> substations = employee.getTelSubstations();
if (substations != null) {
for (int i = 0; i < substations.size(); i++) {
if (substations.get(i) != null) {
contentText.appendField(getString(R.string.phone) + ' '
+ i + 1, substations.get(i).getNumber());
}
}
}
contentText.appendField(getString(R.string.mobile_phone), employee
.getBusinessContact().getMobilephone());
contentText.appendField(getString(R.string.add_info), employee
.getBusinessContact().getAdditionalInfo());
tvDetails3.setText(Utils.fromHtml(contentText.toString()),
TextView.BufferType.SPANNABLE);
// start new section
contentText.clear();
TextView tvDetails4 = (TextView) findViewById(R.id.tvDetails4);
contentText.appendField(getString(R.string.office_hours),
employee.getConsultationHours());
// add all rooms
List<Room> rooms = employee.getRooms();
if (rooms != null && !rooms.isEmpty()) {
contentText.appendField(getString(R.string.room), rooms.get(0)
.getLocation() + " (" + rooms.get(0).getNumber() + ')');
}
tvDetails4.setText(Utils.fromHtml(contentText.toString()),
TextView.BufferType.SPANNABLE);
}
/**
* Adds the given employee to the users contact list
*
* @param employee Object to insert into contacts
*/
private void addContact(Employee employee) {
if (!isPermissionGranted(0)) {
return;
}
ArrayList<ContentProviderOperation> ops = new ArrayList<>();
int rawContactID = ops.size();
// Adding insert operation to operations list
// to insert a new raw contact in the table ContactsContract.RawContacts
ops.add(ContentProviderOperation.newInsert(RawContacts.CONTENT_URI)
.withValue(RawContacts.ACCOUNT_TYPE, null)
.withValue(RawContacts.ACCOUNT_NAME, null)
.build());
// Add full name
ops.add(ContentProviderOperation.newInsert(Data.CONTENT_URI)
.withValueBackReference(Data.RAW_CONTACT_ID, rawContactID)
.withValue(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE)
.withValue(StructuredName.PREFIX, employee.getTitle())
.withValue(StructuredName.GIVEN_NAME, employee.getName())
.withValue(StructuredName.FAMILY_NAME, employee.getSurname())
.build());
// Add e-mail address
if (employee.getEmail() != null) {
ops.add(ContentProviderOperation.newInsert(Data.CONTENT_URI)
.withValueBackReference(Data.RAW_CONTACT_ID, rawContactID)
.withValue(Data.MIMETYPE, CommonDataKinds.Email.CONTENT_ITEM_TYPE)
.withValue(CommonDataKinds.Email.DATA, employee.getEmail())
.withValue(CommonDataKinds.Email.TYPE, Email.TYPE_WORK)
.build());
}
List<TelSubstation> substations = employee.getTelSubstations();
if (substations != null) {
for (TelSubstation sub : substations) {
ops.add(ContentProviderOperation.newInsert(Data.CONTENT_URI)
.withValueBackReference(Data.RAW_CONTACT_ID, rawContactID)
.withValue(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE)
.withValue(Phone.NUMBER, sub.getNumber())
.withValue(Phone.TYPE, Phone.TYPE_WORK)
.build());
}
}
// Add work: telefon, mobile, fax, website
addContact(ops, rawContactID, employee.getBusinessContact(), true);
// Add home: telefon, mobile, fax, website
addContact(ops, rawContactID, employee.getPrivateContact(), false);
// Add organisations
if (employee.getGroups() != null) {
for (Group group : employee.getGroups()) {
ops.add(ContentProviderOperation.newInsert(Data.CONTENT_URI)
.withValueBackReference(Data.RAW_CONTACT_ID, rawContactID)
.withValue(Data.MIMETYPE, CommonDataKinds.Organization.CONTENT_ITEM_TYPE)
.withValue(CommonDataKinds.Organization.COMPANY, group.getOrg())
.withValue(Data.MIMETYPE, CommonDataKinds.Organization.CONTENT_ITEM_TYPE)
.withValue(CommonDataKinds.Organization.TITLE, group.getTitle())
.withValue(Data.MIMETYPE, CommonDataKinds.Organization.CONTENT_ITEM_TYPE)
.withValue(CommonDataKinds.Organization.TYPE, Organization.TYPE_WORK).build());
}
}
// Add office hours
StringBuilder notes = new StringBuilder();
if (employee.getConsultationHours() != null) {
notes.append(getString(R.string.office_hours))
.append(": ")
.append(employee.getConsultationHours());
}
// add all rooms
List<Room> rooms = employee.getRooms();
if (rooms != null && !rooms.isEmpty()) {
if (!notes.toString().isEmpty()) {
notes.append('\n');
}
notes.append(getString(R.string.room))
.append(": ")
.append(rooms.get(0).getLocation())
.append(" (")
.append(rooms.get(0).getNumber())
.append(')');
}
// Finally add notes
if (!notes.toString().isEmpty()) {
ops.add(ContentProviderOperation.newInsert(Data.CONTENT_URI)
.withValueBackReference(Data.RAW_CONTACT_ID, rawContactID)
.withValue(Data.MIMETYPE, Note.CONTENT_ITEM_TYPE)
.withValue(Note.NOTE, notes.toString())
.build());
}
// Add image
Bitmap bitmap = employee.getImage();
if (bitmap != null) { // If an image is selected successfully
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 75, stream);
// Adding insert operation to operations list
// to insert Photo in the table ContactsContract.Data
ops.add(ContentProviderOperation.newInsert(Data.CONTENT_URI)
.withValueBackReference(Data.RAW_CONTACT_ID, rawContactID)
.withValue(Data.IS_SUPER_PRIMARY, 1)
.withValue(Data.MIMETYPE, Photo.CONTENT_ITEM_TYPE)
.withValue(CommonDataKinds.Photo.PHOTO, stream.toByteArray())
.build());
try {
stream.flush();
} catch (IOException e) {
Utils.log(e);
}
}
// Executing all the insert operations as a single database transaction
try {
getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
Utils.showToast(this, R.string.contact_added);
} catch (RemoteException | OperationApplicationException e) {
Utils.log(e);
}
}
/**
* Check Calendar permission for Android 6.0
*
* @param id the request id
* @return If the contacts permission was granted
*/
private boolean isPermissionGranted(int id) {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_CONTACTS) == PackageManager.PERMISSION_GRANTED) {
return true;
} else {
// Provide an additional rationale to the user if the permission was not granted
// and the user would benefit from additional context for the use of the permission.
// For example, if the request has been denied previously.
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_CONTACTS)) {
// Display an AlertDialog with an explanation and a button to trigger the request.
new AlertDialog.Builder(this)
//.setMessage(getString(R.string.permission_calendar_explanation))
.setMessage("Lorem Ipsum")
.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
ActivityCompat
.requestPermissions(PersonsDetailsActivity.this, PERMISSIONS_CONTACTS, id);
}
}).show();
} else {
ActivityCompat.requestPermissions(this, PERMISSIONS_CONTACTS, id);
}
}
return false;
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
//Check if we got all Calendar permissions
for (int result : grantResults) {
if (result != PackageManager.PERMISSION_GRANTED) {
return;
}
}
//Rerun the interrupted action
addContact(mEmployee);
}
}