1
0
Fork 0
mirror of https://github.com/M66B/FairEmail.git synced 2025-01-01 04:35:57 +00:00

Added Gmail wizard

This commit is contained in:
M66B 2019-09-21 21:53:54 +02:00
parent 85e2374c90
commit 0bffc2b0f4
6 changed files with 548 additions and 264 deletions

View file

@ -114,7 +114,9 @@ public class ActivitySetup extends ActivityBase implements FragmentManager.OnBac
static final int REQUEST_EXPORT = 3;
static final int REQUEST_IMPORT = 4;
static final int REQUEST_CHOOSE_ACCOUNT = 5;
static final int REQUEST_DONE = 6;
static final String ACTION_QUICK_GMAIL = BuildConfig.APPLICATION_ID + ".ACTION_QUICK_GMAIL";
static final String ACTION_QUICK_SETUP = BuildConfig.APPLICATION_ID + ".ACTION_QUICK_SETUP";
static final String ACTION_VIEW_ACCOUNTS = BuildConfig.APPLICATION_ID + ".ACTION_VIEW_ACCOUNTS";
static final String ACTION_VIEW_IDENTITIES = BuildConfig.APPLICATION_ID + ".ACTION_VIEW_IDENTITIES";
@ -296,6 +298,7 @@ public class ActivitySetup extends ActivityBase implements FragmentManager.OnBac
LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(this);
IntentFilter iff = new IntentFilter();
iff.addAction(ACTION_QUICK_GMAIL);
iff.addAction(ACTION_QUICK_SETUP);
iff.addAction(ACTION_VIEW_ACCOUNTS);
iff.addAction(ACTION_VIEW_IDENTITIES);
@ -1004,6 +1007,12 @@ public class ActivitySetup extends ActivityBase implements FragmentManager.OnBac
return channel;
}
private void onViewGmail(Intent intent) {
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.content_frame, new FragmentGmail()).addToBackStack("quick");
fragmentTransaction.commit();
}
private void onViewQuickSetup(Intent intent) {
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.content_frame, new FragmentQuickSetup()).addToBackStack("quick");
@ -1116,7 +1125,9 @@ public class ActivitySetup extends ActivityBase implements FragmentManager.OnBac
public void onReceive(Context context, Intent intent) {
if (getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.STARTED)) {
String action = intent.getAction();
if (ACTION_QUICK_SETUP.equals(action))
if (ACTION_QUICK_GMAIL.equals(action))
onViewGmail(intent);
else if (ACTION_QUICK_SETUP.equals(action))
onViewQuickSetup(intent);
else if (ACTION_VIEW_ACCOUNTS.equals(action))
onViewAccounts(intent);

View file

@ -0,0 +1,429 @@
package eu.faircode.email;
/*
This file is part of FairEmail.
FairEmail is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
FairEmail is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FairEmail. If not, see <http://www.gnu.org/licenses/>.
Copyright 2018-2019 by Marcel Bokhorst (M66B)
*/
import android.Manifest;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.accounts.AccountManagerCallback;
import android.accounts.AccountManagerFuture;
import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.provider.ContactsContract;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ScrollView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import static android.accounts.AccountManager.newChooseAccountIntent;
import static android.app.Activity.RESULT_OK;
public class FragmentGmail extends FragmentBase {
private ViewGroup view;
private ScrollView scroll;
private Button btnGrant;
private TextView tvGranted;
private EditText etName;
private Button btnSelect;
private ContentLoadingProgressBar pbSelect;
private TextView tvError;
@Override
@Nullable
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
setSubtitle(R.string.title_setup_quick);
setHasOptionsMenu(true);
view = (ViewGroup) inflater.inflate(R.layout.fragment_gmail, container, false);
scroll = view.findViewById(R.id.scroll);
// Get controls
btnGrant = view.findViewById(R.id.btnGrant);
tvGranted = view.findViewById(R.id.tvGranted);
etName = view.findViewById(R.id.etName);
btnSelect = view.findViewById(R.id.btnSelect);
pbSelect = view.findViewById(R.id.pbSelect);
tvError = view.findViewById(R.id.tvError);
List<String> permissions = new ArrayList<>();
permissions.add(Manifest.permission.READ_CONTACTS); // profile
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O)
permissions.add(Manifest.permission.GET_ACCOUNTS);
// Wire controls
btnGrant.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
requestPermissions(permissions.toArray(new String[0]), ActivitySetup.REQUEST_CHOOSE_ACCOUNT);
}
});
btnSelect.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivityForResult(
Helper.getChooser(getContext(), newChooseAccountIntent(
null,
null,
new String[]{"com.google"},
false,
null,
null,
null,
null)),
ActivitySetup.REQUEST_CHOOSE_ACCOUNT);
}
});
// Initialize
Helper.setViewsEnabled(view, false);
pbSelect.setVisibility(View.GONE);
tvError.setVisibility(View.GONE);
boolean granted = true;
for (String permission : permissions)
if (!hasPermission(permission)) {
granted = false;
break;
}
setGranted(granted);
return view;
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.menu_quick_setup, menu);
super.onCreateOptionsMenu(menu, inflater);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_help:
onMenuHelp();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
private void onMenuHelp() {
Bundle args = new Bundle();
args.putString("name", "SETUP.md");
FragmentDialogMarkdown fragment = new FragmentDialogMarkdown();
fragment.setArguments(args);
fragment.show(getChildFragmentManager(), "help");
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
boolean granted = true;
for (int i = 0; i < permissions.length; i++)
granted = (granted && grantResults[i] == PackageManager.PERMISSION_GRANTED);
setGranted(granted);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case ActivitySetup.REQUEST_CHOOSE_ACCOUNT:
if (resultCode == Activity.RESULT_OK && data != null)
onAccountSelected(data);
break;
case ActivitySetup.REQUEST_DONE:
finish();
break;
}
}
private void setGranted(boolean granted) {
btnGrant.setEnabled(!granted);
tvGranted.setVisibility(granted ? View.VISIBLE : View.GONE);
if (granted) {
try (Cursor cursor = getContext().getContentResolver().query(
ContactsContract.Profile.CONTENT_URI,
new String[]{ContactsContract.Profile.DISPLAY_NAME}, null, null, null)) {
if (cursor != null && cursor.moveToFirst()) {
int colDisplay = cursor.getColumnIndex(ContactsContract.Profile.DISPLAY_NAME);
etName.setText(cursor.getString(colDisplay));
}
} catch (Throwable ex) {
Log.e(ex);
}
}
etName.setEnabled(granted);
btnSelect.setEnabled(granted);
}
private void onAccountSelected(Intent data) {
String name = data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME);
String type = data.getStringExtra(AccountManager.KEY_ACCOUNT_TYPE);
AccountManager am = AccountManager.get(getContext());
Account[] accounts = am.getAccountsByType(type);
for (final Account account : accounts)
if (name.equals(account.name)) {
am.getAuthToken(
account,
MailService.getAuthTokenType(type),
new Bundle(),
getActivity(),
new AccountManagerCallback<Bundle>() {
@Override
public void run(AccountManagerFuture<Bundle> future) {
try {
Bundle bundle = future.getResult();
String token = bundle.getString(AccountManager.KEY_AUTHTOKEN);
if (token == null)
throw new IllegalArgumentException("no token");
Log.i("Got token");
onAuthorized(name, token);
} catch (Throwable ex) {
Log.e(ex);
tvError.setText(Helper.formatThrowable(ex));
new Handler().post(new Runnable() {
@Override
public void run() {
scroll.smoothScrollTo(0, tvError.getBottom());
}
});
}
}
},
null);
break;
}
}
private void onAuthorized(String user, String password) {
Bundle args = new Bundle();
args.putString("name", etName.getText().toString());
args.putString("user", user);
args.putString("password", password);
new SimpleTask<Void>() {
@Override
protected void onPreExecute(Bundle args) {
etName.setEnabled(false);
btnSelect.setEnabled(false);
pbSelect.setVisibility(View.VISIBLE);
}
@Override
protected void onPostExecute(Bundle args) {
etName.setEnabled(true);
btnSelect.setEnabled(true);
pbSelect.setVisibility(View.GONE);
}
@Override
protected Void onExecute(Context context, Bundle args) throws Throwable {
String name = args.getString("name");
String user = args.getString("user");
String password = args.getString("password");
if (!user.contains("@"))
throw new IllegalArgumentException(
context.getString(R.string.title_email_invalid, user));
String domain = user.split("@")[1];
EmailProvider provider = EmailProvider.fromDomain(context, domain, EmailProvider.Discover.ALL);
List<EntityFolder> folders;
String aprotocol = provider.imap.starttls ? "imap" : "imaps";
try (MailService iservice = new MailService(context, aprotocol, null, false, true)) {
iservice.connect(provider.imap.host, provider.imap.port, MailService.AUTH_TYPE_GMAIL, user, password);
folders = iservice.getFolders();
if (folders == null)
throw new IllegalArgumentException(
context.getString(R.string.title_setup_no_settings, domain));
}
String iprotocol = provider.smtp.starttls ? "smtp" : "smtps";
try (MailService iservice = new MailService(context, iprotocol, null, false, true)) {
iservice.connect(provider.smtp.host, provider.smtp.port, MailService.AUTH_TYPE_GMAIL, user, password);
}
DB db = DB.getInstance(context);
try {
db.beginTransaction();
EntityAccount primary = db.account().getPrimaryAccount();
// Create account
EntityAccount account = new EntityAccount();
account.host = provider.imap.host;
account.starttls = provider.imap.starttls;
account.port = provider.imap.port;
account.auth_type = MailService.AUTH_TYPE_GMAIL;
account.user = user;
account.password = password;
account.name = provider.name;
account.synchronize = true;
account.primary = (primary == null);
account.created = new Date().getTime();
account.last_connected = account.created;
account.id = db.account().insertAccount(account);
args.putLong("account", account.id);
EntityLog.log(context, "Gmail account=" + account.name);
// Create folders
for (EntityFolder folder : folders) {
folder.account = account.id;
folder.id = db.folder().insertFolder(folder);
EntityLog.log(context, "Gmail folder=" + folder.name + " type=" + folder.type);
}
// Set swipe left/right folder
for (EntityFolder folder : folders)
if (EntityFolder.TRASH.equals(folder.type))
account.swipe_left = folder.id;
else if (EntityFolder.ARCHIVE.equals(folder.type))
account.swipe_right = folder.id;
db.account().updateAccount(account);
if (TextUtils.isEmpty(name))
name = user.split("@")[0];
// Create identity
EntityIdentity identity = new EntityIdentity();
identity.name = name;
identity.email = user;
identity.account = account.id;
identity.host = provider.smtp.host;
identity.starttls = provider.smtp.starttls;
identity.port = provider.smtp.port;
identity.auth_type = MailService.AUTH_TYPE_GMAIL;
identity.user = user;
identity.password = password;
identity.synchronize = true;
identity.primary = true;
identity.id = db.identity().insertIdentity(identity);
args.putLong("identity", identity.id);
EntityLog.log(context, "Gmail identity=" + identity.name + " email=" + identity.email);
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
ServiceSynchronize.reload(getContext(), "Gmail");
return null;
}
@Override
protected void onExecuted(Bundle args, Void data) {
FragmentDialogDone fragment = new FragmentDialogDone();
fragment.setArguments(args);
fragment.setTargetFragment(FragmentGmail.this, ActivitySetup.REQUEST_DONE);
fragment.show(getFragmentManager(), "quick:done");
}
@Override
protected void onException(Bundle args, Throwable ex) {
Log.e(ex);
tvError.setText(Helper.formatThrowable(ex));
new Handler().post(new Runnable() {
@Override
public void run() {
scroll.smoothScrollTo(0, tvError.getBottom());
}
});
}
}.execute(this, args, "setup:gmail");
}
public static class FragmentDialogDone extends FragmentDialogBase {
@NonNull
@Override
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
return new AlertDialog.Builder(getContext())
.setMessage(R.string.title_setup_quick_success)
.setPositiveButton(R.string.title_review, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
Bundle args = getArguments();
long account = args.getLong("account");
LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(getContext());
lbm.sendBroadcast(
new Intent(ActivitySetup.ACTION_EDIT_ACCOUNT)
.putExtra("id", account)
.putExtra("pop", false));
sendResult(RESULT_OK);
}
})
.setNegativeButton(android.R.string.cancel, null)
.create();
}
}
}

View file

@ -80,8 +80,6 @@ public class FragmentQuickSetup extends FragmentBase {
private Group grpSetup;
private static final int REQUEST_DONE = 1;
@Override
@Nullable
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
@ -363,15 +361,14 @@ public class FragmentQuickSetup extends FragmentBase {
} else {
FragmentDialogDone fragment = new FragmentDialogDone();
fragment.setArguments(args);
fragment.setTargetFragment(FragmentQuickSetup.this, REQUEST_DONE);
fragment.setTargetFragment(FragmentQuickSetup.this, ActivitySetup.REQUEST_DONE);
fragment.show(getFragmentManager(), "quick:done");
}
}
@Override
protected void onException(final Bundle args, Throwable ex) {
Log.i("Quick ex=" + Helper.formatThrowable(ex, false));
Log.e(ex);
if (ex instanceof IllegalArgumentException || ex instanceof UnknownHostException)
tvError.setText(ex.getMessage());
else
@ -411,7 +408,7 @@ public class FragmentQuickSetup extends FragmentBase {
try {
switch (requestCode) {
case REQUEST_DONE:
case ActivitySetup.REQUEST_DONE:
finish();
break;
}

View file

@ -20,12 +20,6 @@ package eu.faircode.email;
*/
import android.Manifest;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.accounts.AccountManagerCallback;
import android.accounts.AccountManagerFuture;
import android.accounts.AccountsException;
import android.app.Activity;
import android.app.Dialog;
import android.content.ComponentName;
import android.content.Context;
@ -33,14 +27,12 @@ import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.graphics.drawable.Drawable;
import android.net.ConnectivityManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.PowerManager;
import android.provider.ContactsContract;
import android.provider.Settings;
import android.view.LayoutInflater;
import android.view.Menu;
@ -56,21 +48,12 @@ import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.widget.PopupMenu;
import androidx.constraintlayout.widget.Group;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.Observer;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import androidx.preference.PreferenceManager;
import com.google.android.material.snackbar.Snackbar;
import java.io.IOException;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import static android.accounts.AccountManager.newChooseAccountIntent;
public class FragmentSetup extends FragmentBase {
private ViewGroup view;
@ -185,12 +168,12 @@ public class FragmentSetup extends FragmentBase {
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(getContext());
switch (item.getItemId()) {
case R.string.title_setup_gmail:
onGmail();
lbm.sendBroadcast(new Intent(ActivitySetup.ACTION_QUICK_GMAIL));
return true;
case R.string.title_setup_other:
LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(getContext());
lbm.sendBroadcast(new Intent(ActivitySetup.ACTION_QUICK_SETUP));
return true;
default:
@ -426,17 +409,11 @@ public class FragmentSetup extends FragmentBase {
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
boolean granted = true;
for (int i = 0; i < permissions.length; i++)
if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
if (Manifest.permission.READ_CONTACTS.equals(permissions[i]))
setContactsPermission(true);
} else
granted = false;
if (requestCode == ActivitySetup.REQUEST_CHOOSE_ACCOUNT)
if (granted)
selectAccount();
}
}
private void setContactsPermission(boolean granted) {
@ -449,235 +426,6 @@ public class FragmentSetup extends FragmentBase {
btnPermissions.setEnabled(!granted);
}
private void onGmail() {
List<String> permissions = new ArrayList<>();
permissions.add(Manifest.permission.READ_CONTACTS); // profile
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O)
permissions.add(Manifest.permission.GET_ACCOUNTS);
boolean granted = true;
for (String permission : permissions)
if (!hasPermission(permission)) {
granted = false;
break;
}
if (granted)
selectAccount();
else
new AlertDialog.Builder(getContext())
.setMessage(R.string.title_setup_gmail_rationale)
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
requestPermissions(permissions.toArray(new String[0]), ActivitySetup.REQUEST_CHOOSE_ACCOUNT);
}
})
.setNegativeButton(android.R.string.cancel, null)
.show();
}
private void selectAccount() {
Log.i("Select account");
startActivityForResult(
Helper.getChooser(getContext(), newChooseAccountIntent(
null,
null,
new String[]{"com.google"},
false,
null,
null,
null,
null)),
ActivitySetup.REQUEST_CHOOSE_ACCOUNT);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case ActivitySetup.REQUEST_CHOOSE_ACCOUNT:
if (resultCode == Activity.RESULT_OK && data != null)
onAccountSelected(data);
break;
}
}
private void onAccountSelected(Intent data) {
String name = data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME);
String type = data.getStringExtra(AccountManager.KEY_ACCOUNT_TYPE);
AccountManager am = AccountManager.get(getContext());
Account[] accounts = am.getAccountsByType(type);
for (final Account account : accounts)
if (name.equals(account.name)) {
Snackbar.make(view, R.string.title_authorizing, Snackbar.LENGTH_LONG).show();
am.getAuthToken(
account,
MailService.getAuthTokenType(type),
new Bundle(),
getActivity(),
new AccountManagerCallback<Bundle>() {
@Override
public void run(AccountManagerFuture<Bundle> future) {
try {
Bundle bundle = future.getResult();
String token = bundle.getString(AccountManager.KEY_AUTHTOKEN);
Log.i("Got token");
onAuthorized(name, token);
} catch (Throwable ex) {
if (ex instanceof AccountsException || ex instanceof IOException) {
Log.w(ex);
if (getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.STARTED))
Snackbar.make(view, Helper.formatThrowable(ex), Snackbar.LENGTH_LONG).show();
} else
Helper.unexpectedError(getFragmentManager(), ex);
}
}
},
null);
break;
}
}
private void onAuthorized(String user, String password) {
Bundle args = new Bundle();
args.putString("user", user);
args.putString("password", password);
new SimpleTask<Void>() {
@Override
protected Void onExecute(Context context, Bundle args) throws Throwable {
String user = args.getString("user");
String password = args.getString("password");
if (!user.contains("@"))
throw new IllegalArgumentException(
context.getString(R.string.title_email_invalid, user));
String domain = user.split("@")[1];
EmailProvider provider = EmailProvider.fromDomain(context, domain, EmailProvider.Discover.ALL);
List<EntityFolder> folders;
String aprotocol = provider.imap.starttls ? "imap" : "imaps";
try (MailService iservice = new MailService(context, aprotocol, null, false, true)) {
iservice.connect(provider.imap.host, provider.imap.port, MailService.AUTH_TYPE_GMAIL, user, password);
folders = iservice.getFolders();
if (folders == null)
throw new IllegalArgumentException(
context.getString(R.string.title_setup_no_settings, domain));
}
String iprotocol = provider.smtp.starttls ? "smtp" : "smtps";
try (MailService iservice = new MailService(context, iprotocol, null, false, true)) {
iservice.connect(provider.smtp.host, provider.smtp.port, MailService.AUTH_TYPE_GMAIL, user, password);
}
DB db = DB.getInstance(context);
try {
db.beginTransaction();
EntityAccount primary = db.account().getPrimaryAccount();
// Create account
EntityAccount account = new EntityAccount();
account.host = provider.imap.host;
account.starttls = provider.imap.starttls;
account.port = provider.imap.port;
account.auth_type = MailService.AUTH_TYPE_GMAIL;
account.user = user;
account.password = password;
account.name = provider.name;
account.synchronize = true;
account.primary = (primary == null);
account.created = new Date().getTime();
account.last_connected = account.created;
account.id = db.account().insertAccount(account);
args.putLong("account", account.id);
EntityLog.log(context, "Gmail account=" + account.name);
// Create folders
for (EntityFolder folder : folders) {
folder.account = account.id;
folder.id = db.folder().insertFolder(folder);
EntityLog.log(context, "Gmail folder=" + folder.name + " type=" + folder.type);
}
// Set swipe left/right folder
for (EntityFolder folder : folders)
if (EntityFolder.TRASH.equals(folder.type))
account.swipe_left = folder.id;
else if (EntityFolder.ARCHIVE.equals(folder.type))
account.swipe_right = folder.id;
db.account().updateAccount(account);
String name = user.split("@")[0];
try (Cursor cursor = context.getContentResolver().query(
ContactsContract.Profile.CONTENT_URI,
new String[]{ContactsContract.Profile.DISPLAY_NAME}, null, null, null)) {
if (cursor != null && cursor.moveToFirst()) {
int colDisplay = cursor.getColumnIndex(ContactsContract.Profile.DISPLAY_NAME);
name = cursor.getString(colDisplay);
}
} catch (Throwable ex) {
Log.e(ex);
}
// Create identity
EntityIdentity identity = new EntityIdentity();
identity.name = name;
identity.email = user;
identity.account = account.id;
identity.host = provider.smtp.host;
identity.starttls = provider.smtp.starttls;
identity.port = provider.smtp.port;
identity.auth_type = MailService.AUTH_TYPE_GMAIL;
identity.user = user;
identity.password = password;
identity.synchronize = true;
identity.primary = true;
identity.id = db.identity().insertIdentity(identity);
args.putLong("identity", identity.id);
EntityLog.log(context, "Gmail identity=" + identity.name + " email=" + identity.email);
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
ServiceSynchronize.reload(getContext(), "Gmail");
return null;
}
@Override
protected void onExecuted(Bundle args, Void data) {
FragmentQuickSetup.FragmentDialogDone fragment = new FragmentQuickSetup.FragmentDialogDone();
fragment.setArguments(args);
fragment.show(getFragmentManager(), "gmail:done");
}
@Override
protected void onException(Bundle args, Throwable ex) {
if (ex instanceof IllegalArgumentException || ex instanceof UnknownHostException)
Snackbar.make(view, ex.getMessage(), Snackbar.LENGTH_LONG).show();
else
Snackbar.make(view, Helper.formatThrowable(ex, false), Snackbar.LENGTH_LONG).show();
}
}.execute(this, args, "setup:gmail");
}
public static class FragmentDialogDoze extends FragmentDialogBase {
@NonNull
@Override

View file

@ -0,0 +1,100 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/scroll"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="12dp"
android:scrollbarStyle="outsideOverlay"
tools:context=".ActivitySetup">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/tvHint"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/title_setup_gmail_rationale"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
android:textStyle="italic"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/btnGrant"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:tag="disable"
android:text="@string/title_setup_grant"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvHint" />
<TextView
android:id="@+id/tvGranted"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:drawableStart="@drawable/baseline_check_24"
android:drawablePadding="6dp"
android:text="@string/title_setup_done"
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
android:textColor="?android:attr/textColorPrimary"
app:layout_constraintBottom_toBottomOf="@id/btnGrant"
app:layout_constraintStart_toEndOf="@id/btnGrant"
app:layout_constraintTop_toTopOf="@id/btnGrant" />
<EditText
android:id="@+id/etName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:autofillHints="name"
android:hint="@string/title_identity_name"
android:imeOptions="actionNext"
android:inputType="textPersonName|textCapWords"
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/btnGrant">
<requestFocus />
</EditText>
<Button
android:id="@+id/btnSelect"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:tag="disable"
android:text="@string/title_setup_select_account"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/etName" />
<eu.faircode.email.ContentLoadingProgressBar
android:id="@+id/pbSelect"
style="@style/Base.Widget.AppCompat.ProgressBar"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_marginStart="12dp"
android:indeterminate="true"
app:layout_constraintBottom_toBottomOf="@id/btnSelect"
app:layout_constraintStart_toEndOf="@id/btnSelect"
app:layout_constraintTop_toTopOf="@id/btnSelect" />
<TextView
android:id="@+id/tvError"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:autoLink="web"
android:text="error"
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
android:textColor="?attr/colorWarning"
android:textIsSelectable="true"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/btnSelect" />
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>

View file

@ -138,6 +138,7 @@
<string name="title_setup_gmail" translatable="false">Gmail</string>
<string name="title_setup_other">Other provider</string>
<string name="title_setup_gmail_rationale">Please grant permissions to select an account and read your name</string>
<string name="title_setup_select_account">Select account</string>
<string name="title_setup_instructions">Setup instructions</string>
<string name="title_setup_no_settings">No settings found for domain \'%1$s\'</string>
<string name="title_setup_quick_success">An account and an identity have successfully been added</string>
@ -418,8 +419,6 @@
<string name="title_pop_support">The POP3 protocol supports downloading and deleting messages only. So, it will not be possible to mark message favorite, move messages, etc. POP3 will use more battery power than IMAP. Therefore, consider using the IMAP protocol whenever possible.</string>
<string name="title_activesync_support">ActiveSync is not supported</string>
<string name="title_oauth_support">OAuth is not supported</string>
<string name="title_authorize">Authorize</string>
<string name="title_authorizing">Authorizing &#8230;</string>
<string name="title_review">Review</string>
<string name="title_synchronize_now">Synchronize now</string>