mirror of
https://github.com/etesync/android
synced 2025-03-25 03:45:46 +00:00
Add DavService for long-running operations
This commit is contained in:
parent
77c947da14
commit
fc29988dc6
@ -49,6 +49,7 @@
|
||||
android:label="@string/app_name"
|
||||
android:theme="@style/AppTheme"
|
||||
tools:ignore="UnusedAttribute">
|
||||
|
||||
<service
|
||||
android:name=".syncadapter.AccountAuthenticatorService"
|
||||
android:exported="false">
|
||||
@ -103,12 +104,18 @@
|
||||
android:resource="@xml/sync_tasks"/>
|
||||
</service>
|
||||
|
||||
<service
|
||||
android:name=".DavService"
|
||||
android:enabled="true">
|
||||
</service>
|
||||
|
||||
<activity
|
||||
android:name=".ui.AccountsActivity"
|
||||
android:label="@string/app_name"
|
||||
android:theme="@style/AppTheme.NoActionBar">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
@ -134,6 +141,7 @@
|
||||
android:label="@string/settings_title">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MANAGE_NETWORK_USAGE"/>
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
@ -148,6 +156,7 @@
|
||||
<activity
|
||||
android:name="de.duenndns.ssl.MemorizingActivity"
|
||||
android:theme="@android:style/Theme.Holo.Light.Dialog.NoActionBar"/>
|
||||
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
|
109
app/src/main/java/at/bitfire/davdroid/DavService.java
Normal file
109
app/src/main/java/at/bitfire/davdroid/DavService.java
Normal file
@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright © 2013 – 2016 Ricki Hirner (bitfire web engineering).
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the GNU Public License v3.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*/
|
||||
|
||||
package at.bitfire.davdroid;
|
||||
|
||||
import android.app.Service;
|
||||
import android.content.Intent;
|
||||
import android.os.Binder;
|
||||
import android.os.IBinder;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class DavService extends Service {
|
||||
|
||||
public static final String
|
||||
ACTION_REFRESH_COLLECTIONS = "refreshCollections",
|
||||
EXTRA_DAV_SERVICE_ID = "davServiceID";
|
||||
|
||||
private final IBinder binder = new InfoBinder();
|
||||
|
||||
private final Set<Long> runningRefresh = new HashSet<>();
|
||||
private final List<RefreshingStatusListener> refreshingStatusListeners = new LinkedList<>();
|
||||
|
||||
|
||||
@Override
|
||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||
String action = intent.getAction();
|
||||
long id = intent.getLongExtra(EXTRA_DAV_SERVICE_ID, -1);
|
||||
|
||||
switch (action) {
|
||||
case ACTION_REFRESH_COLLECTIONS:
|
||||
if (runningRefresh.add(id)) {
|
||||
new Thread(new RefreshCollections(id)).start();
|
||||
for (RefreshingStatusListener listener : refreshingStatusListeners)
|
||||
listener.onDavRefreshStatusChanged(id, true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return START_NOT_STICKY;
|
||||
}
|
||||
|
||||
|
||||
/* BOUND SERVICE PART
|
||||
for communicating with the activities
|
||||
*/
|
||||
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
return binder;
|
||||
}
|
||||
|
||||
public interface RefreshingStatusListener {
|
||||
void onDavRefreshStatusChanged(long id, boolean refreshing);
|
||||
}
|
||||
|
||||
public class InfoBinder extends Binder {
|
||||
public boolean isRefreshing(long id) {
|
||||
return runningRefresh.contains(id);
|
||||
}
|
||||
|
||||
public void addRefreshingStatusListener(RefreshingStatusListener listener, boolean callImmediate) {
|
||||
refreshingStatusListeners.add(listener);
|
||||
if (callImmediate)
|
||||
for (long id : runningRefresh)
|
||||
listener.onDavRefreshStatusChanged(id, true);
|
||||
}
|
||||
|
||||
public void removeRefreshingStatusListener(RefreshingStatusListener listener) {
|
||||
refreshingStatusListeners.remove(listener);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* ACTION RUNNABLES
|
||||
which actually do the work
|
||||
*/
|
||||
|
||||
private class RefreshCollections implements Runnable {
|
||||
final long serviceId;
|
||||
|
||||
RefreshCollections(long davServiceId) {
|
||||
this.serviceId = davServiceId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
Constants.log.debug("RefreshCollections.Runner STARTING {}", serviceId);
|
||||
try {
|
||||
Thread.currentThread().sleep(10000);
|
||||
} catch (InterruptedException e) {
|
||||
} finally {
|
||||
Constants.log.debug("RefreshCollections.Runner FINISHED {}", serviceId);
|
||||
runningRefresh.remove(serviceId);
|
||||
for (RefreshingStatusListener listener : refreshingStatusListeners)
|
||||
listener.onDavRefreshStatusChanged(serviceId, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -16,27 +16,44 @@ import android.accounts.AuthenticatorException;
|
||||
import android.accounts.OperationCanceledException;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
import android.app.LoaderManager;
|
||||
import android.content.AsyncTaskLoader;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.Loader;
|
||||
import android.content.ServiceConnection;
|
||||
import android.database.Cursor;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.os.IBinder;
|
||||
import android.support.v4.app.DialogFragment;
|
||||
import android.support.v4.content.res.ResourcesCompat;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.support.v7.widget.CardView;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.ProgressBar;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import at.bitfire.davdroid.Constants;
|
||||
import at.bitfire.davdroid.R;
|
||||
import at.bitfire.davdroid.DavService;
|
||||
import at.bitfire.davdroid.syncadapter.ServiceDB.*;
|
||||
import lombok.Cleanup;
|
||||
|
||||
public class AccountActivity extends AppCompatActivity implements Toolbar.OnMenuItemClickListener {
|
||||
public class AccountActivity extends AppCompatActivity implements Toolbar.OnMenuItemClickListener, ServiceConnection, DavService.RefreshingStatusListener, LoaderManager.LoaderCallbacks<AccountActivity.AccountInfo> {
|
||||
|
||||
public static final String EXTRA_ACCOUNT_NAME = "account_name";
|
||||
|
||||
Account account;
|
||||
private String accountName;
|
||||
private AccountInfo accountInfo;
|
||||
private DavService.InfoBinder davService;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
@ -46,7 +63,6 @@ public class AccountActivity extends AppCompatActivity implements Toolbar.OnMenu
|
||||
if (accountName == null)
|
||||
// invalid account name
|
||||
finish();
|
||||
account = new Account(accountName, Constants.ACCOUNT_TYPE);
|
||||
setTitle(accountName);
|
||||
|
||||
setContentView(R.layout.activity_account);
|
||||
@ -54,6 +70,24 @@ public class AccountActivity extends AppCompatActivity implements Toolbar.OnMenu
|
||||
Toolbar toolbar = (Toolbar)findViewById(R.id.carddav_menu);
|
||||
toolbar.inflateMenu(R.menu.carddav_actions);
|
||||
toolbar.setOnMenuItemClickListener(this);
|
||||
|
||||
toolbar = (Toolbar)findViewById(R.id.caldav_menu);
|
||||
toolbar.inflateMenu(R.menu.caldav_actions);
|
||||
toolbar.setOnMenuItemClickListener(this);
|
||||
|
||||
getLoaderManager().initLoader(0, getIntent().getExtras(), this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
bindService(new Intent(this, DavService.class), this, Context.BIND_AUTO_CREATE);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
unbindService(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -66,24 +100,18 @@ public class AccountActivity extends AppCompatActivity implements Toolbar.OnMenu
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.delete_account:
|
||||
DialogFragment frag = new DialogFragment() {
|
||||
@Override
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
return new AlertDialog.Builder(AccountActivity.this)
|
||||
.setIcon(R.drawable.ic_error_dark)
|
||||
.setTitle(R.string.account_delete_confirmation_title)
|
||||
.setMessage(R.string.account_delete_confirmation_text)
|
||||
.setNegativeButton(android.R.string.no, null)
|
||||
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
deleteAccount();
|
||||
}
|
||||
})
|
||||
.create();
|
||||
}
|
||||
};
|
||||
frag.show(getSupportFragmentManager(), null);
|
||||
new AlertDialog.Builder(AccountActivity.this)
|
||||
.setIcon(R.drawable.ic_error_dark)
|
||||
.setTitle(R.string.account_delete_confirmation_title)
|
||||
.setMessage(R.string.account_delete_confirmation_text)
|
||||
.setNegativeButton(android.R.string.no, null)
|
||||
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
deleteAccount();
|
||||
}
|
||||
})
|
||||
.show();
|
||||
break;
|
||||
default:
|
||||
return super.onOptionsItemSelected(item);
|
||||
@ -93,11 +121,155 @@ public class AccountActivity extends AppCompatActivity implements Toolbar.OnMenu
|
||||
|
||||
@Override
|
||||
public boolean onMenuItemClick(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.refresh_address_books:
|
||||
Intent intent = new Intent(this, DavService.class);
|
||||
intent.setAction(DavService.ACTION_REFRESH_COLLECTIONS);
|
||||
intent.putExtra(DavService.EXTRA_DAV_SERVICE_ID, accountInfo.cardDavService);
|
||||
startService(intent);
|
||||
break;
|
||||
case R.id.refresh_calendars:
|
||||
intent = new Intent(this, DavService.class);
|
||||
intent.setAction(DavService.ACTION_REFRESH_COLLECTIONS);
|
||||
intent.putExtra(DavService.EXTRA_DAV_SERVICE_ID, accountInfo.calDavService);
|
||||
startService(intent);
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/* SERVICE CONNECTION */
|
||||
|
||||
@Override
|
||||
public void onServiceConnected(ComponentName name, IBinder service) {
|
||||
davService = (DavService.InfoBinder)service;
|
||||
davService.addRefreshingStatusListener(this, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceDisconnected(ComponentName name) {
|
||||
davService.removeRefreshingStatusListener(this);
|
||||
davService = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDavRefreshStatusChanged(long id, boolean refreshing) {
|
||||
getLoaderManager().restartLoader(0, getIntent().getExtras(), this);
|
||||
}
|
||||
|
||||
|
||||
/* LOADERS AND LOADED DATA */
|
||||
|
||||
public static class AccountInfo {
|
||||
Long cardDavService;
|
||||
boolean cardDavRefreshing;
|
||||
|
||||
Long calDavService;
|
||||
boolean calDavRefreshing;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Loader<AccountInfo> onCreateLoader(int id, Bundle args) {
|
||||
return new AccountLoader(this, args.getString(EXTRA_ACCOUNT_NAME));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadFinished(Loader<AccountInfo> loader, AccountInfo info) {
|
||||
accountInfo = info;
|
||||
|
||||
CardView card = (CardView)findViewById(R.id.carddav);
|
||||
if (info.cardDavService != null) {
|
||||
ProgressBar progress = (ProgressBar)findViewById(R.id.carddav_refreshing);
|
||||
progress.setVisibility(info.cardDavRefreshing ? View.VISIBLE : View.GONE);
|
||||
} else
|
||||
card.setVisibility(View.GONE);
|
||||
|
||||
card = (CardView)findViewById(R.id.caldav);
|
||||
if (info.calDavService != null) {
|
||||
ProgressBar progress = (ProgressBar)findViewById(R.id.caldav_refreshing);
|
||||
progress.setVisibility(info.calDavRefreshing ? View.VISIBLE : View.GONE);
|
||||
} else
|
||||
card.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoaderReset(Loader<AccountInfo> loader) {
|
||||
}
|
||||
|
||||
private static class AccountLoader extends AsyncTaskLoader<AccountInfo> implements DavService.RefreshingStatusListener, ServiceConnection {
|
||||
private final String accountName;
|
||||
private final OpenHelper dbHelper;
|
||||
private DavService.InfoBinder davService;
|
||||
|
||||
public AccountLoader(Context context, String accountName) {
|
||||
super(context);
|
||||
this.accountName = accountName;
|
||||
dbHelper = new OpenHelper(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStartLoading() {
|
||||
getContext().bindService(new Intent(getContext(), DavService.class), this, Context.BIND_AUTO_CREATE);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStopLoading() {
|
||||
davService.removeRefreshingStatusListener(this);
|
||||
getContext().unbindService(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceConnected(ComponentName name, IBinder service) {
|
||||
davService = (DavService.InfoBinder)service;
|
||||
forceLoad();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceDisconnected(ComponentName name) {
|
||||
davService = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDavRefreshStatusChanged(long id, boolean refreshing) {
|
||||
forceLoad();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AccountInfo loadInBackground() {
|
||||
AccountInfo info = new AccountInfo();
|
||||
try {
|
||||
SQLiteDatabase db = dbHelper.getReadableDatabase();
|
||||
|
||||
@Cleanup Cursor cursor = db.query(
|
||||
Services._TABLE,
|
||||
new String[] { Services.ID, Services.SERVICE },
|
||||
Services.ACCOUNT_NAME + "=?", new String[] { accountName },
|
||||
null, null, null);
|
||||
while (cursor.moveToNext()) {
|
||||
long id = cursor.getLong(0);
|
||||
|
||||
String service = cursor.getString(1);
|
||||
if (Services.SERVICE_CARDDAV.equals(service)) {
|
||||
info.cardDavService = id;
|
||||
info.cardDavRefreshing = davService.isRefreshing(id);
|
||||
} else if (Services.SERVICE_CALDAV.equals(service)) {
|
||||
info.calDavService = id;
|
||||
info.calDavRefreshing = davService.isRefreshing(id);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
dbHelper.close();
|
||||
}
|
||||
return info;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* USER ACTIONS */
|
||||
|
||||
protected void deleteAccount() {
|
||||
Account account = new Account(accountName, Constants.ACCOUNT_TYPE);
|
||||
AccountManager accountManager = AccountManager.get(this);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= 22)
|
||||
|
@ -11,11 +11,14 @@ package at.bitfire.davdroid.ui;
|
||||
import android.accounts.Account;
|
||||
import android.accounts.AccountManager;
|
||||
import android.accounts.OnAccountsUpdateListener;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.ServiceConnection;
|
||||
import android.database.Cursor;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
import android.support.v4.app.ListFragment;
|
||||
import android.support.v4.app.LoaderManager;
|
||||
import android.support.v4.content.AsyncTaskLoader;
|
||||
@ -23,25 +26,30 @@ import android.support.v4.content.Loader;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.animation.AlphaAnimation;
|
||||
import android.view.animation.Animation;
|
||||
import android.widget.AbsListView;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.ListView;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import at.bitfire.davdroid.Constants;
|
||||
import at.bitfire.davdroid.DavService;
|
||||
import at.bitfire.davdroid.R;
|
||||
import at.bitfire.davdroid.syncadapter.ServiceDB;
|
||||
import at.bitfire.davdroid.syncadapter.ServiceDB.*;
|
||||
import at.bitfire.davdroid.syncadapter.ServiceDB.OpenHelper;
|
||||
import at.bitfire.davdroid.syncadapter.ServiceDB.Services;
|
||||
import lombok.Cleanup;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
public class AccountListFragment extends ListFragment implements OnAccountsUpdateListener, LoaderManager.LoaderCallbacks<List<AccountListFragment.AccountInfo>>, AdapterView.OnItemClickListener {
|
||||
|
||||
protected AccountManager accountManager;
|
||||
private AccountManager accountManager;
|
||||
private DavService.InfoBinder davService;
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
@ -85,6 +93,7 @@ public class AccountListFragment extends ListFragment implements OnAccountsUpdat
|
||||
getLoaderManager().restartLoader(0, null, this);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Loader<List<AccountInfo>> onCreateLoader(int id, Bundle args) {
|
||||
return new AccountLoader(getContext());
|
||||
@ -107,7 +116,8 @@ public class AccountListFragment extends ListFragment implements OnAccountsUpdat
|
||||
@RequiredArgsConstructor
|
||||
public static class AccountInfo {
|
||||
final Account account;
|
||||
boolean hasCardDAV, hasCalDAV;
|
||||
boolean isRefreshing;
|
||||
Long cardDavService, calDavService;
|
||||
}
|
||||
|
||||
|
||||
@ -131,20 +141,29 @@ public class AccountListFragment extends ListFragment implements OnAccountsUpdat
|
||||
TextView tv = (TextView)v.findViewById(R.id.account_name);
|
||||
tv.setText(info.account.name);
|
||||
|
||||
ProgressBar progressRefresh = (ProgressBar)v.findViewById(R.id.refreshing);
|
||||
progressRefresh.setVisibility(info.isRefreshing ? View.VISIBLE : View.GONE);
|
||||
|
||||
Animation blink = new AlphaAnimation(0, 1);
|
||||
blink.setDuration(400);
|
||||
blink.setRepeatMode(Animation.REVERSE);
|
||||
blink.setRepeatCount(Animation.INFINITE);
|
||||
|
||||
tv = (TextView)v.findViewById(R.id.carddav);
|
||||
tv.setVisibility(info.hasCardDAV ? View.VISIBLE : View.GONE);
|
||||
tv.setVisibility(info.cardDavService != null ? View.VISIBLE : View.GONE);
|
||||
tv.setAnimation(info.isRefreshing ? blink : null);
|
||||
|
||||
tv = (TextView)v.findViewById(R.id.caldav);
|
||||
tv.setVisibility(info.hasCalDAV ? View.VISIBLE : View.GONE);
|
||||
tv.setVisibility(info.calDavService != null ? View.VISIBLE : View.GONE);
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class AccountLoader extends AsyncTaskLoader<List<AccountInfo>> {
|
||||
final AccountManager accountManager;
|
||||
final OpenHelper dbHelper;
|
||||
private static class AccountLoader extends AsyncTaskLoader<List<AccountInfo>> {
|
||||
private final AccountManager accountManager;
|
||||
private final OpenHelper dbHelper;
|
||||
|
||||
public AccountLoader(Context context) {
|
||||
super(context);
|
||||
@ -159,6 +178,7 @@ public class AccountListFragment extends ListFragment implements OnAccountsUpdat
|
||||
|
||||
@Override
|
||||
public List<AccountInfo> loadInBackground() {
|
||||
Constants.log.info("AccountLoader RUNNING");
|
||||
List<AccountInfo> accounts = new LinkedList<>();
|
||||
try {
|
||||
SQLiteDatabase db = dbHelper.getReadableDatabase();
|
||||
@ -169,15 +189,17 @@ public class AccountListFragment extends ListFragment implements OnAccountsUpdat
|
||||
// query services of this account
|
||||
@Cleanup Cursor cursor = db.query(
|
||||
Services._TABLE,
|
||||
new String[] { Services.SERVICE },
|
||||
new String[] { Services.ID, Services.SERVICE },
|
||||
Services.ACCOUNT_NAME + "=?", new String[] { account.name },
|
||||
null, null, null);
|
||||
while (cursor.moveToNext()) {
|
||||
String service = cursor.getString(0);
|
||||
long id = cursor.getLong(0);
|
||||
|
||||
String service = cursor.getString(1);
|
||||
if (Services.SERVICE_CARDDAV.equals(service))
|
||||
info.hasCardDAV = true;
|
||||
info.cardDavService = id;
|
||||
if (Services.SERVICE_CALDAV.equals(service))
|
||||
info.hasCalDAV = true;
|
||||
info.calDavService = id;
|
||||
}
|
||||
|
||||
accounts.add(info);
|
||||
@ -187,6 +209,7 @@ public class AccountListFragment extends ListFragment implements OnAccountsUpdat
|
||||
}
|
||||
return accounts;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -12,8 +12,8 @@
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<ImageView
|
||||
android:src="@drawable/blue_sky_with_birds"
|
||||
android:scaleType="fitCenter"
|
||||
android:src="@drawable/sky_birds"
|
||||
android:scaleType="centerCrop"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_alignParentTop="true" />
|
||||
|
@ -28,6 +28,7 @@
|
||||
android:gravity="right|center_vertical">
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/refreshing"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:indeterminate="true"
|
||||
|
@ -18,19 +18,67 @@
|
||||
android:layout_marginBottom="@dimen/activity_vertical_margin">
|
||||
|
||||
<android.support.v7.widget.CardView
|
||||
android:id="@+id/carddav"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:cardElevation="8dp"
|
||||
>
|
||||
android:layout_marginBottom="16dp"
|
||||
app:cardElevation="8dp">
|
||||
|
||||
<android.support.v7.widget.Toolbar
|
||||
android:id="@+id/carddav_menu"
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:theme="@style/toolbar_theme"
|
||||
style="@style/toolbar_style"
|
||||
app:navigationIcon="@drawable/ic_people_light"
|
||||
app:title="CardDAV"/>
|
||||
android:orientation="vertical">
|
||||
|
||||
<android.support.v7.widget.Toolbar
|
||||
android:id="@+id/carddav_menu"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:theme="@style/toolbar_theme"
|
||||
style="@style/toolbar_style"
|
||||
app:navigationIcon="@drawable/ic_people_light"
|
||||
app:title="CardDAV"/>
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/carddav_refreshing"
|
||||
style="?android:attr/progressBarStyleHorizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone"
|
||||
android:indeterminate="true"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</android.support.v7.widget.CardView>
|
||||
|
||||
<android.support.v7.widget.CardView
|
||||
android:id="@+id/caldav"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:cardElevation="8dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<android.support.v7.widget.Toolbar
|
||||
android:id="@+id/caldav_menu"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:theme="@style/toolbar_theme"
|
||||
style="@style/toolbar_style"
|
||||
app:navigationIcon="@drawable/ic_people_light"
|
||||
app:title="CalDAV"/>
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/caldav_refreshing"
|
||||
style="?android:attr/progressBarStyleHorizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone"
|
||||
android:indeterminate="true"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</android.support.v7.widget.CardView>
|
||||
|
||||
|
20
app/src/main/res/menu/caldav_actions.xml
Normal file
20
app/src/main/res/menu/caldav_actions.xml
Normal file
@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright © 2013 – 2016 Ricki Hirner (bitfire web engineering).
|
||||
~ All rights reserved. This program and the accompanying materials
|
||||
~ are made available under the terms of the GNU Public License v3.0
|
||||
~ which accompanies this distribution, and is available at
|
||||
~ http://www.gnu.org/licenses/gpl.html
|
||||
-->
|
||||
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item android:id="@+id/refresh_calendars"
|
||||
android:title="@string/account_refresh_calendar_list"/>
|
||||
|
||||
<item android:id="@+id/add_calendar"
|
||||
android:title="@string/account_add_existing_calendar"/>
|
||||
<item android:id="@+id/create_calendar"
|
||||
android:title="@string/account_create_new_calendar"/>
|
||||
|
||||
</menu>
|
@ -9,12 +9,12 @@
|
||||
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item android:id="@+id/refresh"
|
||||
<item android:id="@+id/refresh_address_books"
|
||||
android:title="@string/account_refresh_address_book_list"/>
|
||||
|
||||
<item android:id="@+id/add"
|
||||
<item android:id="@+id/add_address_book"
|
||||
android:title="@string/account_add_existing_address_book"/>
|
||||
<item android:id="@+id/create"
|
||||
<item android:id="@+id/create_address_book"
|
||||
android:title="@string/account_create_new_address_book"/>
|
||||
|
||||
</menu>
|
@ -34,6 +34,9 @@
|
||||
<string name="account_refresh_address_book_list">Refresh address book list</string>
|
||||
<string name="account_add_existing_address_book">Add existing address book</string>
|
||||
<string name="account_create_new_address_book">Create new address book</string>
|
||||
<string name="account_refresh_calendar_list">Refresh calendar list</string>
|
||||
<string name="account_add_existing_calendar">Add existing calendar</string>
|
||||
<string name="account_create_new_calendar">Create new calendar</string>
|
||||
|
||||
<!-- MainActivity -->
|
||||
<string name="main_manage_accounts">Manage sync accounts</string>
|
||||
|
@ -76,7 +76,7 @@
|
||||
<item name="android:textColorSecondary">@color/white</item>
|
||||
</style>
|
||||
<style name="toolbar_style" parent="Widget.AppCompat.Toolbar">
|
||||
<item name="android:background">@color/davdroid_green</item>
|
||||
<item name="android:background">@color/davdroid_lightblue</item>
|
||||
<item name="titleTextColor">@color/white</item>
|
||||
</style>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user