mirror of
https://github.com/etesync/android
synced 2024-11-15 20:38:58 +00:00
Allow renaming of accounts
* allow renaming of accounts * always open AccountActivity, even if there are no services (so that users can delete the account from within DAVdroid)
This commit is contained in:
parent
900f1fd857
commit
fb7f974987
@ -8,17 +8,16 @@
|
||||
|
||||
package at.bitfire.davdroid.model;
|
||||
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.database.sqlite.SQLiteException;
|
||||
import android.database.sqlite.SQLiteOpenHelper;
|
||||
import android.os.Build;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.RequiresApi;
|
||||
|
||||
import java.util.logging.Level;
|
||||
|
||||
import aQute.service.reporter.Messages;
|
||||
import at.bitfire.davdroid.App;
|
||||
import lombok.Cleanup;
|
||||
|
||||
@ -186,4 +185,11 @@ public class ServiceDB {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void onRenameAccount(@NonNull SQLiteDatabase db, @NonNull String oldName, @NonNull String newName) {
|
||||
ContentValues values = new ContentValues(1);
|
||||
values.put(Services.ACCOUNT_NAME, newName);
|
||||
db.update(Services._TABLE, values, Services.ACCOUNT_NAME + "=?", new String[] { oldName });
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ package at.bitfire.davdroid.resource;
|
||||
|
||||
import android.accounts.Account;
|
||||
import android.content.ContentProviderClient;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.ContentUris;
|
||||
import android.content.ContentValues;
|
||||
import android.database.Cursor;
|
||||
@ -16,6 +17,7 @@ import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcel;
|
||||
import android.os.RemoteException;
|
||||
import android.provider.ContactsContract;
|
||||
import android.provider.ContactsContract.Groups;
|
||||
import android.provider.ContactsContract.RawContacts;
|
||||
import android.support.annotation.NonNull;
|
||||
@ -226,4 +228,14 @@ public class LocalAddressBook extends AndroidAddressBook implements LocalCollect
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// HELPERS
|
||||
|
||||
public static void onRenameAccount(@NonNull ContentResolver resolver, @NonNull String oldName, @NonNull String newName) throws RemoteException {
|
||||
@Cleanup("release") ContentProviderClient client = resolver.acquireContentProviderClient(ContactsContract.AUTHORITY);
|
||||
ContentValues values = new ContentValues(1);
|
||||
values.put(RawContacts.ACCOUNT_NAME, newName);
|
||||
client.update(RawContacts.CONTENT_URI, values, RawContacts.ACCOUNT_NAME + "=?", new String[] { oldName });
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -251,4 +251,5 @@ public class LocalCalendar extends AndroidCalendar implements LocalCollection {
|
||||
return new LocalCalendar[size];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -9,6 +9,8 @@
|
||||
package at.bitfire.davdroid.resource;
|
||||
|
||||
import android.accounts.Account;
|
||||
import android.content.ContentProviderClient;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
@ -164,4 +166,15 @@ public class LocalTaskList extends AndroidTaskList implements LocalCollection {
|
||||
return new LocalTaskList[size];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// HELPERS
|
||||
|
||||
public static void onRenameAccount(@NonNull ContentResolver resolver, @NonNull String oldName, @NonNull String newName) throws RemoteException {
|
||||
@Cleanup("release") ContentProviderClient client = resolver.acquireContentProviderClient(TaskProvider.ProviderName.OpenTasks.authority);
|
||||
ContentValues values = new ContentValues(1);
|
||||
values.put(Tasks.ACCOUNT_NAME, newName);
|
||||
client.update(Tasks.getContentUri(TaskProvider.ProviderName.OpenTasks.authority), values, Tasks.ACCOUNT_NAME + "=?", new String[] { oldName });
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ import android.accounts.AccountManagerCallback;
|
||||
import android.accounts.AccountManagerFuture;
|
||||
import android.accounts.AuthenticatorException;
|
||||
import android.accounts.OperationCanceledException;
|
||||
import android.app.Dialog;
|
||||
import android.app.LoaderManager;
|
||||
import android.content.AsyncTaskLoader;
|
||||
import android.content.ComponentName;
|
||||
@ -32,10 +33,12 @@ import android.graphics.drawable.Drawable;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
import android.provider.CalendarContract;
|
||||
import android.provider.ContactsContract;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.design.widget.Snackbar;
|
||||
import android.support.v4.app.DialogFragment;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.support.v7.widget.CardView;
|
||||
@ -50,6 +53,7 @@ import android.widget.AbsListView;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ListView;
|
||||
import android.widget.PopupMenu;
|
||||
import android.widget.ProgressBar;
|
||||
@ -72,6 +76,8 @@ import at.bitfire.davdroid.model.ServiceDB;
|
||||
import at.bitfire.davdroid.model.ServiceDB.Collections;
|
||||
import at.bitfire.davdroid.model.ServiceDB.OpenHelper;
|
||||
import at.bitfire.davdroid.model.ServiceDB.Services;
|
||||
import at.bitfire.davdroid.resource.LocalAddressBook;
|
||||
import at.bitfire.davdroid.resource.LocalTaskList;
|
||||
import at.bitfire.ical4android.TaskProvider;
|
||||
import lombok.Cleanup;
|
||||
|
||||
@ -136,6 +142,14 @@ public class AccountActivity extends AppCompatActivity implements Toolbar.OnMenu
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPrepareOptionsMenu(Menu menu) {
|
||||
MenuItem itemRename = menu.findItem(R.id.rename_account);
|
||||
// renameAccount is available for API level 21+
|
||||
itemRename.setVisible(Build.VERSION.SDK_INT >= 21);
|
||||
return super.onPrepareOptionsMenu(menu);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
@ -147,6 +161,9 @@ public class AccountActivity extends AppCompatActivity implements Toolbar.OnMenu
|
||||
intent.putExtra(AccountSettingsActivity.EXTRA_ACCOUNT, account);
|
||||
startActivity(intent);
|
||||
break;
|
||||
case R.id.rename_account:
|
||||
RenameAccountFragment.newInstance(account).show(getSupportFragmentManager(), null);
|
||||
break;
|
||||
case R.id.delete_account:
|
||||
new AlertDialog.Builder(AccountActivity.this)
|
||||
.setIcon(R.drawable.ic_error_dark)
|
||||
@ -172,7 +189,7 @@ public class AccountActivity extends AppCompatActivity implements Toolbar.OnMenu
|
||||
Intent intent;
|
||||
switch (item.getItemId()) {
|
||||
case R.id.refresh_address_books:
|
||||
if (accountInfo.carddav != null) {
|
||||
if (accountInfo != null && accountInfo.carddav != null) {
|
||||
intent = new Intent(this, DavService.class);
|
||||
intent.setAction(DavService.ACTION_REFRESH_COLLECTIONS);
|
||||
intent.putExtra(DavService.EXTRA_DAV_SERVICE_ID, accountInfo.carddav.id);
|
||||
@ -185,7 +202,7 @@ public class AccountActivity extends AppCompatActivity implements Toolbar.OnMenu
|
||||
startActivity(intent);
|
||||
break;
|
||||
case R.id.refresh_calendars:
|
||||
if (accountInfo.caldav != null) {
|
||||
if (accountInfo != null && accountInfo.caldav != null) {
|
||||
intent = new Intent(this, DavService.class);
|
||||
intent.setAction(DavService.ACTION_REFRESH_COLLECTIONS);
|
||||
intent.putExtra(DavService.EXTRA_DAV_SERVICE_ID, accountInfo.caldav.id);
|
||||
@ -298,12 +315,6 @@ public class AccountActivity extends AppCompatActivity implements Toolbar.OnMenu
|
||||
public void onLoadFinished(Loader<AccountInfo> loader, final AccountInfo info) {
|
||||
accountInfo = info;
|
||||
|
||||
if (accountInfo == null) {
|
||||
// account doesn't exist anymore
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
|
||||
CardView card = (CardView)findViewById(R.id.carddav);
|
||||
if (info.carddav != null) {
|
||||
ProgressBar progress = (ProgressBar)findViewById(R.id.carddav_refreshing);
|
||||
@ -415,10 +426,6 @@ public class AccountActivity extends AppCompatActivity implements Toolbar.OnMenu
|
||||
Services.ACCOUNT_NAME + "=?", new String[] { account.name },
|
||||
null, null, null);
|
||||
|
||||
if (cursor.getCount() == 0)
|
||||
// no services, account not useable
|
||||
return null;
|
||||
|
||||
while (cursor.moveToNext()) {
|
||||
long id = cursor.getLong(0);
|
||||
String service = cursor.getString(1);
|
||||
@ -545,6 +552,88 @@ public class AccountActivity extends AppCompatActivity implements Toolbar.OnMenu
|
||||
}
|
||||
|
||||
|
||||
/* DIALOG FRAGMENTS */
|
||||
|
||||
public static class RenameAccountFragment extends DialogFragment {
|
||||
|
||||
private final static String ARG_ACCOUNT = "account";
|
||||
|
||||
static RenameAccountFragment newInstance(@NonNull Account account) {
|
||||
RenameAccountFragment fragment = new RenameAccountFragment();
|
||||
Bundle args = new Bundle(1);
|
||||
args.putParcelable(ARG_ACCOUNT, account);
|
||||
fragment.setArguments(args);
|
||||
return fragment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
final Account oldAccount = getArguments().getParcelable(ARG_ACCOUNT);
|
||||
|
||||
final EditText editText = new EditText(getContext());
|
||||
editText.setText(oldAccount.name);
|
||||
|
||||
return new AlertDialog.Builder(getContext())
|
||||
.setTitle(R.string.account_rename)
|
||||
.setMessage(R.string.account_rename_new_name)
|
||||
.setView(editText)
|
||||
.setPositiveButton(R.string.account_rename_rename, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
final String newName = editText.getText().toString();
|
||||
|
||||
if (newName.equals(oldAccount.name))
|
||||
return;
|
||||
|
||||
final AccountManager accountManager = AccountManager.get(getContext());
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
|
||||
accountManager.renameAccount(oldAccount, newName,
|
||||
new AccountManagerCallback<Account>() {
|
||||
@Override
|
||||
public void run(AccountManagerFuture<Account> future) {
|
||||
App.log.info("Updating account name references");
|
||||
|
||||
// cancel running synchronization
|
||||
ContentResolver.cancelSync(oldAccount, null);
|
||||
|
||||
// update account name references in database
|
||||
@Cleanup OpenHelper dbHelper = new OpenHelper(getContext());
|
||||
ServiceDB.onRenameAccount(dbHelper.getWritableDatabase(), oldAccount.name, newName);
|
||||
|
||||
// update account_name of local contacts
|
||||
try {
|
||||
LocalAddressBook.onRenameAccount(getContext().getContentResolver(), oldAccount.name, newName);
|
||||
} catch(RemoteException e) {
|
||||
App.log.log(Level.SEVERE, "Couldn't propagate new account name to contacts provider");
|
||||
}
|
||||
|
||||
// calendar provider doesn't allow changing account_name of Events
|
||||
|
||||
// update account_name of local tasks
|
||||
try {
|
||||
LocalTaskList.onRenameAccount(getContext().getContentResolver(), oldAccount.name, newName);
|
||||
} catch(RemoteException e) {
|
||||
App.log.log(Level.SEVERE, "Couldn't propagate new account name to tasks provider");
|
||||
}
|
||||
|
||||
// synchronize again
|
||||
requestSync(new Account(newName, oldAccount.type));
|
||||
}
|
||||
}, null
|
||||
);
|
||||
getActivity().finish();
|
||||
}
|
||||
})
|
||||
.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
}
|
||||
})
|
||||
.create();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* USER ACTIONS */
|
||||
|
||||
private void deleteAccount() {
|
||||
@ -576,7 +665,7 @@ public class AccountActivity extends AppCompatActivity implements Toolbar.OnMenu
|
||||
}, null);
|
||||
}
|
||||
|
||||
private void requestSync() {
|
||||
protected static void requestSync(Account account) {
|
||||
String authorities[] = {
|
||||
ContactsContract.AUTHORITY,
|
||||
CalendarContract.AUTHORITY,
|
||||
@ -589,7 +678,10 @@ public class AccountActivity extends AppCompatActivity implements Toolbar.OnMenu
|
||||
extras.putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, true); // run immediately (don't queue)
|
||||
ContentResolver.requestSync(account, authority, extras);
|
||||
}
|
||||
}
|
||||
|
||||
private void requestSync() {
|
||||
requestSync(account);
|
||||
Snackbar.make(findViewById(R.id.parent), R.string.account_synchronizing_now, Snackbar.LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,10 @@
|
||||
android:title="@string/account_settings"
|
||||
app:showAsAction="ifRoom"/>
|
||||
|
||||
<item android:id="@+id/rename_account"
|
||||
android:title="@string/account_rename"
|
||||
app:showAsAction="never"/>
|
||||
|
||||
<item android:id="@+id/delete_account"
|
||||
android:title="@string/account_delete"
|
||||
app:showAsAction="never"/>
|
||||
|
@ -79,6 +79,9 @@
|
||||
<string name="account_synchronize_now">Jetzt synchronisieren</string>
|
||||
<string name="account_synchronizing_now">Synchronisation gestartet</string>
|
||||
<string name="account_settings">Konto-Einstellungen</string>
|
||||
<string name="account_rename">Konto umbenennen</string>
|
||||
<string name="account_rename_new_name">Ungespeicherte lokale Änderungen können verloren gehen. Nach dem Umbenennen muss neu synchronisiert werden. Neuer Kontoname:</string>
|
||||
<string name="account_rename_rename">Umbenennen</string>
|
||||
<string name="account_delete">Konto löschen</string>
|
||||
<string name="account_delete_confirmation_title">Konto wirklich löschen?</string>
|
||||
<string name="account_delete_confirmation_text">Alle Adressbücher, Kalender und Aufgabenlisten werden vom Gerät (nicht am Server) gelöscht.</string>
|
||||
|
@ -96,6 +96,9 @@
|
||||
<string name="account_synchronize_now">Synchronize now</string>
|
||||
<string name="account_synchronizing_now">Synchronizing now</string>
|
||||
<string name="account_settings">Account settings</string>
|
||||
<string name="account_rename">Rename account</string>
|
||||
<string name="account_rename_new_name">Unsaved local data may be dismissed. Re-synchronization is required after renaming. New account name:</string>
|
||||
<string name="account_rename_rename">Rename</string>
|
||||
<string name="account_delete">Delete account</string>
|
||||
<string name="account_delete_confirmation_title">Really delete account?</string>
|
||||
<string name="account_delete_confirmation_text">All local copies of address books, calendars and task lists will be deleted.</string>
|
||||
|
Loading…
Reference in New Issue
Block a user