Android 5 Lollipop compatibility

pull/146/head
M66B 7 years ago
parent be415c6a5f
commit ea895040f5

@ -75,6 +75,7 @@ Note that your contacts could unknowingly send malicious messages if they got in
* foreground service (FOREGROUND_SERVICE): to run a foreground service on Android 9 Pie and later, see also the next question * foreground service (FOREGROUND_SERVICE): to run a foreground service on Android 9 Pie and later, see also the next question
* prevent device from sleeping (WAKE_LOCK): to keep the device awake while synchronizing messages * prevent device from sleeping (WAKE_LOCK): to keep the device awake while synchronizing messages
* Optional: read your contacts (READ_CONTACTS): to autocomplete addresses and to show photos * Optional: read your contacts (READ_CONTACTS): to autocomplete addresses and to show photos
* USE_CREDENTIALS: needed to select accounts on Android version 5.1 Lollipop and before (not used on later Android versions)
* Optional: find accounts on the device (GET_ACCOUNTS): to use [OAuth](https://en.wikipedia.org/wiki/OAuth) instead of passwords * Optional: find accounts on the device (GET_ACCOUNTS): to use [OAuth](https://en.wikipedia.org/wiki/OAuth) instead of passwords
<a name="faq2"></a> <a name="faq2"></a>

@ -66,7 +66,6 @@ See also [this FAQ](https://github.com/M66B/open-source-email/blob/master/FAQ.md
* [IMAP IDLE](https://en.wikipedia.org/wiki/IMAP_IDLE) (push messages) supported * [IMAP IDLE](https://en.wikipedia.org/wiki/IMAP_IDLE) (push messages) supported
* Built with latest development tools and libraries * Built with latest development tools and libraries
* Android 6 Marshmallow or later required
## Screenshots ## Screenshots

@ -4,7 +4,7 @@ android {
compileSdkVersion 28 compileSdkVersion 28
defaultConfig { defaultConfig {
applicationId "eu.faircode.email" applicationId "eu.faircode.email"
minSdkVersion 23 minSdkVersion 21
targetSdkVersion 28 targetSdkVersion 28
versionCode 210 versionCode 210
versionName "1.210" versionName "1.210"

@ -7,6 +7,9 @@
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.READ_CONTACTS" /> <uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" /> <uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission
android:name="android.permission.USE_CREDENTIALS"
android:maxSdkVersion="22" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.WAKE_LOCK" /> <uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="com.android.vending.BILLING" /> <uses-permission android:name="com.android.vending.BILLING" />

@ -1,11 +1,15 @@
package eu.faircode.email; package eu.faircode.email;
import android.content.Intent; import android.content.Intent;
import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import androidx.annotation.RequiresApi;
public class ActivitySearch extends ActivityBase { public class ActivitySearch extends ActivityBase {
@Override @Override
@RequiresApi(api = Build.VERSION_CODES.M)
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);

@ -922,7 +922,7 @@ public class ActivityView extends ActivityBilling implements FragmentManager.OnB
os = new BufferedOutputStream(new FileOutputStream(file)); os = new BufferedOutputStream(new FileOutputStream(file));
int size = 0; int size = 0;
ConnectivityManager cm = context.getSystemService(ConnectivityManager.class); ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo ani = cm.getActiveNetworkInfo(); NetworkInfo ani = cm.getActiveNetworkInfo();
size += write(os, "active=" + ani + "\r\n\r\n"); size += write(os, "active=" + ani + "\r\n\r\n");

@ -1440,7 +1440,7 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
db.identity().setIdentityError(message.identity, null); db.identity().setIdentityError(message.identity, null);
NotificationManager nm = context.getSystemService(NotificationManager.class); NotificationManager nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
nm.cancel("send", message.identity.intValue()); nm.cancel("send", message.identity.intValue());
} else } else
EntityOperation.queue(db, message, EntityOperation.DELETE); EntityOperation.queue(db, message, EntityOperation.DELETE);

@ -23,6 +23,7 @@ import android.app.Application;
import android.app.Notification; import android.app.Notification;
import android.app.NotificationChannel; import android.app.NotificationChannel;
import android.app.NotificationManager; import android.app.NotificationManager;
import android.content.Context;
import android.os.Build; import android.os.Build;
import android.os.DeadSystemException; import android.os.DeadSystemException;
import android.os.RemoteException; import android.os.RemoteException;
@ -62,7 +63,7 @@ public class ApplicationEx extends Application {
private void createNotificationChannels() { private void createNotificationChannels() {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
NotificationManager nm = getSystemService(NotificationManager.class); NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
NotificationChannel service = new NotificationChannel( NotificationChannel service = new NotificationChannel(
"service", "service",

@ -808,7 +808,7 @@ public class FragmentAccount extends FragmentEx {
ServiceSynchronize.reload(getContext(), "save account"); ServiceSynchronize.reload(getContext(), "save account");
if (!synchronize) { if (!synchronize) {
NotificationManager nm = getContext().getSystemService(NotificationManager.class); NotificationManager nm = (NotificationManager) getContext().getSystemService(Context.NOTIFICATION_SERVICE);
nm.cancel("receive", account.id.intValue()); nm.cancel("receive", account.id.intValue());
} }
@ -1138,6 +1138,7 @@ public class FragmentAccount extends FragmentEx {
null, null,
null, null,
new String[]{provider.type}, new String[]{provider.type},
false,
null, null,
null, null,
null, null,

@ -528,7 +528,7 @@ public class FragmentCompose extends FragmentEx {
break; break;
case R.id.menu_link: case R.id.menu_link:
Uri uri = null; Uri uri = null;
ClipboardManager cbm = getContext().getSystemService(ClipboardManager.class); ClipboardManager cbm = (ClipboardManager) getContext().getSystemService(Context.CLIPBOARD_SERVICE);
if (cbm.hasPrimaryClip()) { if (cbm.hasPrimaryClip()) {
String link = cbm.getPrimaryClip().getItemAt(0).coerceToText(getContext()).toString(); String link = cbm.getPrimaryClip().getItemAt(0).coerceToText(getContext()).toString();
uri = Uri.parse(link); uri = Uri.parse(link);

@ -19,6 +19,7 @@ package eu.faircode.email;
Copyright 2018 by Marcel Bokhorst (M66B) Copyright 2018 by Marcel Bokhorst (M66B)
*/ */
import android.content.Context;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log; import android.util.Log;
@ -100,7 +101,7 @@ public class FragmentEx extends Fragment {
public void onDetach() { public void onDetach() {
super.onDetach(); super.onDetach();
InputMethodManager im = getContext().getSystemService(InputMethodManager.class); InputMethodManager im = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
View focused = getActivity().getCurrentFocus(); View focused = getActivity().getCurrentFocus();
if (focused != null) if (focused != null)
im.hideSoftInputFromWindow(focused.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS); im.hideSoftInputFromWindow(focused.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);

@ -171,7 +171,7 @@ public class FragmentOptions extends FragmentEx implements SharedPreferences.OnS
protected Void onLoad(Context context, Bundle args) { protected Void onLoad(Context context, Bundle args) {
DB db = DB.getInstance(context); DB db = DB.getInstance(context);
ConnectivityManager cm = context.getSystemService(ConnectivityManager.class); ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
boolean metered = (cm == null || cm.isActiveNetworkMetered()); boolean metered = (cm == null || cm.isActiveNetworkMetered());
for (Long id : db.message().getMessageWithoutPreview()) { for (Long id : db.message().getMessageWithoutPreview()) {

@ -371,14 +371,16 @@ public class FragmentSetup extends FragmentEx {
public void onResume() { public void onResume() {
super.onResume(); super.onResume();
PowerManager pm = getContext().getSystemService(PowerManager.class); PowerManager pm = (PowerManager) getContext().getSystemService(Context.POWER_SERVICE);
boolean ignoring = pm.isIgnoringBatteryOptimizations(BuildConfig.APPLICATION_ID); boolean ignoring = true;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
ignoring = pm.isIgnoringBatteryOptimizations(BuildConfig.APPLICATION_ID);
btnDoze.setEnabled(!ignoring); btnDoze.setEnabled(!ignoring);
tvDozeDone.setText(ignoring ? R.string.title_setup_done : R.string.title_setup_to_do); tvDozeDone.setText(ignoring ? R.string.title_setup_done : R.string.title_setup_to_do);
tvDozeDone.setCompoundDrawablesWithIntrinsicBounds(ignoring ? check : null, null, null, null); tvDozeDone.setCompoundDrawablesWithIntrinsicBounds(ignoring ? check : null, null, null, null);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
ConnectivityManager cm = getContext().getSystemService(ConnectivityManager.class); ConnectivityManager cm = (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
boolean saving = (cm.getRestrictBackgroundStatus() == ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED); boolean saving = (cm.getRestrictBackgroundStatus() == ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED);
btnData.setVisibility(saving ? View.VISIBLE : View.GONE); btnData.setVisibility(saving ? View.VISIBLE : View.GONE);
} }

@ -305,7 +305,10 @@ public class Helper {
} }
static Boolean isMetered(Context context) { static Boolean isMetered(Context context) {
ConnectivityManager cm = context.getSystemService(ConnectivityManager.class); ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.M)
return cm.isActiveNetworkMetered();
Network active = cm.getActiveNetwork(); Network active = cm.getActiveNetwork();
if (active == null) { if (active == null) {
@ -325,7 +328,6 @@ public class Helper {
Log.i(Helper.TAG, "isMetered: active not connected"); Log.i(Helper.TAG, "isMetered: active not connected");
return null; return null;
} }
NetworkCapabilities caps = cm.getNetworkCapabilities(active); NetworkCapabilities caps = cm.getNetworkCapabilities(active);
if (caps == null) { if (caps == null) {
Log.i(Helper.TAG, "isMetered: active no caps"); Log.i(Helper.TAG, "isMetered: active no caps");
@ -393,7 +395,8 @@ public class Helper {
return true; return true;
} }
static void connect(Context context, IMAPStore istore, EntityAccount account) throws MessagingException { static void connect(Context context, IMAPStore istore, EntityAccount account) throws
MessagingException {
try { try {
istore.connect(account.host, account.port, account.user, account.password); istore.connect(account.host, account.port, account.user, account.password);
} catch (AuthenticationFailedException ex) { } catch (AuthenticationFailedException ex) {
@ -467,18 +470,20 @@ public class Helper {
sb.append(String.format("Id: %s\r\n", Build.ID)); sb.append(String.format("Id: %s\r\n", Build.ID));
sb.append("\r\n"); sb.append("\r\n");
PowerManager pm = context.getSystemService(PowerManager.class); PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
boolean ignoring = pm.isIgnoringBatteryOptimizations(BuildConfig.APPLICATION_ID); boolean ignoring = true;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
ignoring = pm.isIgnoringBatteryOptimizations(BuildConfig.APPLICATION_ID);
sb.append(String.format("Battery optimizations: %b\r\n", !ignoring)); sb.append(String.format("Battery optimizations: %b\r\n", !ignoring));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
UsageStatsManager usm = context.getSystemService(UsageStatsManager.class); UsageStatsManager usm = (UsageStatsManager) context.getSystemService(Context.USAGE_STATS_SERVICE);
int bucket = usm.getAppStandbyBucket(); int bucket = usm.getAppStandbyBucket();
sb.append(String.format("Standby bucket: %d\r\n", bucket)); sb.append(String.format("Standby bucket: %d\r\n", bucket));
} }
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
ConnectivityManager cm = context.getSystemService(ConnectivityManager.class); ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
boolean saving = (cm.getRestrictBackgroundStatus() == ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED); boolean saving = (cm.getRestrictBackgroundStatus() == ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED);
sb.append(String.format("Data saving: %b\r\n", saving)); sb.append(String.format("Data saving: %b\r\n", saving));
} }

@ -46,7 +46,7 @@ public class JobDaily extends JobService {
.setPeriodic(CLEANUP_INTERVAL) .setPeriodic(CLEANUP_INTERVAL)
.setRequiresDeviceIdle(true); .setRequiresDeviceIdle(true);
JobScheduler scheduler = context.getSystemService(JobScheduler.class); JobScheduler scheduler = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
scheduler.cancel(Helper.JOB_DAILY); scheduler.cancel(Helper.JOB_DAILY);
if (scheduler.schedule(job.build()) == JobScheduler.RESULT_SUCCESS) if (scheduler.schedule(job.build()) == JobScheduler.RESULT_SUCCESS)
Log.i(Helper.TAG, "Scheduled daily job"); Log.i(Helper.TAG, "Scheduled daily job");

@ -31,6 +31,7 @@ import android.content.IntentFilter;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.database.Cursor; import android.database.Cursor;
import android.graphics.BitmapFactory;
import android.graphics.Color; import android.graphics.Color;
import android.graphics.drawable.Icon; import android.graphics.drawable.Icon;
import android.media.RingtoneManager; import android.media.RingtoneManager;
@ -65,6 +66,7 @@ import org.json.JSONException;
import org.jsoup.Jsoup; import org.jsoup.Jsoup;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import java.net.SocketException; import java.net.SocketException;
import java.net.SocketTimeoutException; import java.net.SocketTimeoutException;
import java.net.UnknownHostException; import java.net.UnknownHostException;
@ -172,7 +174,7 @@ public class ServiceSynchronize extends LifecycleService {
db.account().liveStats().observe(this, new Observer<TupleAccountStats>() { db.account().liveStats().observe(this, new Observer<TupleAccountStats>() {
@Override @Override
public void onChanged(@Nullable TupleAccountStats stats) { public void onChanged(@Nullable TupleAccountStats stats) {
NotificationManager nm = getSystemService(NotificationManager.class); NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
nm.notify(NOTIFICATION_SYNCHRONIZE, getNotificationService(stats).build()); nm.notify(NOTIFICATION_SYNCHRONIZE, getNotificationService(stats).build());
} }
}); });
@ -186,7 +188,7 @@ public class ServiceSynchronize extends LifecycleService {
@Override @Override
public void run() { public void run() {
try { try {
NotificationManager nm = getSystemService(NotificationManager.class); NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
Widget.update(ServiceSynchronize.this, messages.size()); Widget.update(ServiceSynchronize.this, messages.size());
@ -264,7 +266,7 @@ public class ServiceSynchronize extends LifecycleService {
stopForeground(true); stopForeground(true);
NotificationManager nm = getSystemService(NotificationManager.class); NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
nm.cancel(NOTIFICATION_SYNCHRONIZE); nm.cancel(NOTIFICATION_SYNCHRONIZE);
super.onDestroy(); super.onDestroy();
@ -553,18 +555,19 @@ public class ServiceSynchronize extends LifecycleService {
trash.setAction("trash:" + message.id); trash.setAction("trash:" + message.id);
PendingIntent piTrash = PendingIntent.getService(this, PI_TRASH, trash, PendingIntent.FLAG_UPDATE_CURRENT); PendingIntent piTrash = PendingIntent.getService(this, PI_TRASH, trash, PendingIntent.FLAG_UPDATE_CURRENT);
Notification.Action.Builder actionSeen = new Notification.Action.Builder( Notification.Action.Builder actionSeen = new Notification.Action.Builder(
Icon.createWithResource(this, R.drawable.baseline_visibility_24), R.drawable.baseline_visibility_24,
getString(R.string.title_action_seen), getString(R.string.title_action_seen),
piSeen); piSeen);
Notification.Action.Builder actionArchive = new Notification.Action.Builder( Notification.Action.Builder actionArchive = new Notification.Action.Builder(
Icon.createWithResource(this, R.drawable.baseline_archive_24), R.drawable.baseline_archive_24,
getString(R.string.title_action_archive), getString(R.string.title_action_archive),
piArchive); piArchive);
Notification.Action.Builder actionTrash = new Notification.Action.Builder( Notification.Action.Builder actionTrash = new Notification.Action.Builder(
Icon.createWithResource(this, R.drawable.baseline_delete_24), R.drawable.baseline_delete_24,
getString(R.string.title_action_trash), getString(R.string.title_action_trash),
piTrash); piTrash);
@ -627,7 +630,12 @@ public class ServiceSynchronize extends LifecycleService {
Uri photo = Uri.withAppendedPath( Uri photo = Uri.withAppendedPath(
ContactsContract.Contacts.CONTENT_URI, ContactsContract.Contacts.CONTENT_URI,
cursor.getLong(0) + "/photo"); cursor.getLong(0) + "/photo");
mbuilder.setLargeIcon(Icon.createWithContentUri(photo)); if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
InputStream is = ContactsContract.Contacts.openContactPhotoInputStream(
getContentResolver(), photo);
mbuilder.setLargeIcon(BitmapFactory.decodeStream(is));
} else
mbuilder.setLargeIcon(Icon.createWithContentUri(photo));
} }
} catch (SecurityException ex) { } catch (SecurityException ex) {
Log.e(Helper.TAG, ex + "\n" + Log.getStackTraceString(ex)); Log.e(Helper.TAG, ex + "\n" + Log.getStackTraceString(ex));
@ -728,7 +736,7 @@ public class ServiceSynchronize extends LifecycleService {
EntityLog.log(this, title + " " + Helper.formatThrowable(ex)); EntityLog.log(this, title + " " + Helper.formatThrowable(ex));
if ((ex instanceof SendFailedException) || (ex instanceof AlertException)) { if ((ex instanceof SendFailedException) || (ex instanceof AlertException)) {
NotificationManager nm = getSystemService(NotificationManager.class); NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
nm.notify(tag, 1, getNotificationError(title, ex).build()); nm.notify(tag, 1, getNotificationError(title, ex).build());
} }
@ -748,13 +756,13 @@ public class ServiceSynchronize extends LifecycleService {
!(ex instanceof MessagingException && ex.getCause() instanceof SocketTimeoutException) && !(ex instanceof MessagingException && ex.getCause() instanceof SocketTimeoutException) &&
!(ex instanceof MessagingException && ex.getCause() instanceof SSLException) && !(ex instanceof MessagingException && ex.getCause() instanceof SSLException) &&
!(ex instanceof MessagingException && "connection failure".equals(ex.getMessage()))) { !(ex instanceof MessagingException && "connection failure".equals(ex.getMessage()))) {
NotificationManager nm = getSystemService(NotificationManager.class); NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
nm.notify(tag, 1, getNotificationError(title, ex).build()); nm.notify(tag, 1, getNotificationError(title, ex).build());
} }
} }
private void monitorAccount(final EntityAccount account, final ServiceState state) throws NoSuchProviderException { private void monitorAccount(final EntityAccount account, final ServiceState state) throws NoSuchProviderException {
final PowerManager pm = getSystemService(PowerManager.class); final PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
final PowerManager.WakeLock wlAccount = pm.newWakeLock( final PowerManager.WakeLock wlAccount = pm.newWakeLock(
PowerManager.PARTIAL_WAKE_LOCK, BuildConfig.APPLICATION_ID + ":account." + account.id); PowerManager.PARTIAL_WAKE_LOCK, BuildConfig.APPLICATION_ID + ":account." + account.id);
try { try {
@ -880,7 +888,7 @@ public class ServiceSynchronize extends LifecycleService {
long delayed = now - account.last_connected; long delayed = now - account.last_connected;
if (delayed > ACCOUNT_ERROR_AFTER * 60 * 1000L) { if (delayed > ACCOUNT_ERROR_AFTER * 60 * 1000L) {
Log.i(Helper.TAG, "Reporting sync error after=" + delayed); Log.i(Helper.TAG, "Reporting sync error after=" + delayed);
NotificationManager nm = getSystemService(NotificationManager.class); NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
nm.notify("receive", account.id.intValue(), nm.notify("receive", account.id.intValue(),
getNotificationError(account.name, account.last_connected, ex, false).build()); getNotificationError(account.name, account.last_connected, ex, false).build());
} }
@ -894,7 +902,7 @@ public class ServiceSynchronize extends LifecycleService {
db.account().setAccountState(account.id, "connected"); db.account().setAccountState(account.id, "connected");
NotificationManager nm = getSystemService(NotificationManager.class); NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
nm.cancel("receive", account.id.intValue()); nm.cancel("receive", account.id.intValue());
EntityLog.log(this, account.name + " connected"); EntityLog.log(this, account.name + " connected");
@ -1222,7 +1230,7 @@ public class ServiceSynchronize extends LifecycleService {
registerReceiver(alarm, new IntentFilter(id)); registerReceiver(alarm, new IntentFilter(id));
// Keep alive // Keep alive
AlarmManager am = getSystemService(AlarmManager.class); AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
try { try {
while (state.running()) { while (state.running()) {
if (!istore.isConnected()) if (!istore.isConnected())
@ -1245,10 +1253,16 @@ public class ServiceSynchronize extends LifecycleService {
// Schedule keep alive alarm // Schedule keep alive alarm
EntityLog.log(this, account.name + " wait=" + account.poll_interval); EntityLog.log(this, account.name + " wait=" + account.poll_interval);
am.setAndAllowWhileIdle( if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M)
AlarmManager.RTC_WAKEUP, am.set(
System.currentTimeMillis() + account.poll_interval * 60 * 1000L, AlarmManager.RTC_WAKEUP,
pi); System.currentTimeMillis() + account.poll_interval * 60 * 1000L,
pi);
else
am.setAndAllowWhileIdle(
AlarmManager.RTC_WAKEUP,
System.currentTimeMillis() + account.poll_interval * 60 * 1000L,
pi);
try { try {
wlAccount.release(); wlAccount.release();
@ -1327,12 +1341,18 @@ public class ServiceSynchronize extends LifecycleService {
PendingIntent pi = PendingIntent.getBroadcast(ServiceSynchronize.this, 0, new Intent(id), 0); PendingIntent pi = PendingIntent.getBroadcast(ServiceSynchronize.this, 0, new Intent(id), 0);
registerReceiver(alarm, new IntentFilter(id)); registerReceiver(alarm, new IntentFilter(id));
AlarmManager am = getSystemService(AlarmManager.class); AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
try { try {
am.setAndAllowWhileIdle( if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M)
AlarmManager.RTC_WAKEUP, am.set(
System.currentTimeMillis() + CONNECT_BACKOFF_AlARM * 60 * 1000L, AlarmManager.RTC_WAKEUP,
pi); System.currentTimeMillis() + CONNECT_BACKOFF_AlARM * 60 * 1000L,
pi);
else
am.setAndAllowWhileIdle(
AlarmManager.RTC_WAKEUP,
System.currentTimeMillis() + CONNECT_BACKOFF_AlARM * 60 * 1000L,
pi);
try { try {
wlAccount.release(); wlAccount.release();
@ -1705,7 +1725,7 @@ public class ServiceSynchronize extends LifecycleService {
db.identity().setIdentityState(ident.id, "connected"); db.identity().setIdentityState(ident.id, "connected");
db.identity().setIdentityError(ident.id, null); db.identity().setIdentityError(ident.id, null);
NotificationManager nm = getSystemService(NotificationManager.class); NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
nm.cancel("send", message.identity.intValue()); nm.cancel("send", message.identity.intValue());
// Send message // Send message
@ -1779,7 +1799,7 @@ public class ServiceSynchronize extends LifecycleService {
long delayed = now - message.last_attempt; long delayed = now - message.last_attempt;
if (delayed > IDENTITY_ERROR_AFTER * 60 * 1000L) { if (delayed > IDENTITY_ERROR_AFTER * 60 * 1000L) {
Log.i(Helper.TAG, "Reporting send error after=" + delayed); Log.i(Helper.TAG, "Reporting send error after=" + delayed);
NotificationManager nm = getSystemService(NotificationManager.class); NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
nm.notify("send", message.identity.intValue(), getNotificationError(ident.name, ex).build()); nm.notify("send", message.identity.intValue(), getNotificationError(ident.name, ex).build());
} }
@ -2408,7 +2428,7 @@ public class ServiceSynchronize extends LifecycleService {
@Override @Override
public void onAvailable(Network network) { public void onAvailable(Network network) {
try { try {
ConnectivityManager cm = getSystemService(ConnectivityManager.class); ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
EntityLog.log(ServiceSynchronize.this, "Available " + network + " " + cm.getNetworkInfo(network)); EntityLog.log(ServiceSynchronize.this, "Available " + network + " " + cm.getNetworkInfo(network));
if (!started && suitableNetwork()) if (!started && suitableNetwork())
@ -2466,7 +2486,7 @@ public class ServiceSynchronize extends LifecycleService {
state = new ServiceState(); state = new ServiceState();
state.runnable(new Runnable() { state.runnable(new Runnable() {
PowerManager pm = getSystemService(PowerManager.class); PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wl = pm.newWakeLock( PowerManager.WakeLock wl = pm.newWakeLock(
PowerManager.PARTIAL_WAKE_LOCK, BuildConfig.APPLICATION_ID + ":main"); PowerManager.PARTIAL_WAKE_LOCK, BuildConfig.APPLICATION_ID + ":main");
private List<ServiceState> threadState = new ArrayList<>(); private List<ServiceState> threadState = new ArrayList<>();
@ -2512,7 +2532,7 @@ public class ServiceSynchronize extends LifecycleService {
private Observer<List<EntityOperation>> observer = new Observer<List<EntityOperation>>() { private Observer<List<EntityOperation>> observer = new Observer<List<EntityOperation>>() {
private List<Long> handling = new ArrayList<>(); private List<Long> handling = new ArrayList<>();
private ExecutorService executor = Executors.newSingleThreadExecutor(Helper.backgroundThreadFactory); private ExecutorService executor = Executors.newSingleThreadExecutor(Helper.backgroundThreadFactory);
PowerManager pm = getSystemService(PowerManager.class); PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wl = pm.newWakeLock( PowerManager.WakeLock wl = pm.newWakeLock(
PowerManager.PARTIAL_WAKE_LOCK, BuildConfig.APPLICATION_ID + ":outbox"); PowerManager.PARTIAL_WAKE_LOCK, BuildConfig.APPLICATION_ID + ":outbox");
@ -2640,7 +2660,7 @@ public class ServiceSynchronize extends LifecycleService {
queued++; queued++;
queue.submit(new Runnable() { queue.submit(new Runnable() {
PowerManager pm = getSystemService(PowerManager.class); PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wl = pm.newWakeLock( PowerManager.WakeLock wl = pm.newWakeLock(
PowerManager.PARTIAL_WAKE_LOCK, BuildConfig.APPLICATION_ID + ":manage"); PowerManager.PARTIAL_WAKE_LOCK, BuildConfig.APPLICATION_ID + ":manage");

Loading…
Cancel
Save