2018-08-02 13:33:06 +00:00
|
|
|
package eu.faircode.email;
|
|
|
|
|
|
|
|
/*
|
2018-08-14 05:53:24 +00:00
|
|
|
This file is part of FairEmail.
|
2018-08-02 13:33:06 +00:00
|
|
|
|
2018-08-14 05:53:24 +00:00
|
|
|
FairEmail is free software: you can redistribute it and/or modify
|
2018-08-02 13:33:06 +00:00
|
|
|
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.
|
|
|
|
|
2018-10-29 10:46:49 +00:00
|
|
|
FairEmail is distributed in the hope that it will be useful,
|
2018-08-02 13:33:06 +00:00
|
|
|
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
|
2018-10-29 10:46:49 +00:00
|
|
|
along with FairEmail. If not, see <http://www.gnu.org/licenses/>.
|
2018-08-02 13:33:06 +00:00
|
|
|
|
2018-12-31 08:04:33 +00:00
|
|
|
Copyright 2018-2019 by Marcel Bokhorst (M66B)
|
2018-08-02 13:33:06 +00:00
|
|
|
*/
|
|
|
|
|
2019-04-12 06:20:24 +00:00
|
|
|
import android.app.ActivityManager;
|
2018-08-02 13:33:06 +00:00
|
|
|
import android.app.Application;
|
2018-08-15 07:40:18 +00:00
|
|
|
import android.app.Notification;
|
|
|
|
import android.app.NotificationChannel;
|
2019-03-17 18:06:51 +00:00
|
|
|
import android.app.NotificationChannelGroup;
|
2018-08-15 07:40:18 +00:00
|
|
|
import android.app.NotificationManager;
|
2018-12-09 17:49:52 +00:00
|
|
|
import android.content.Context;
|
2019-03-27 10:37:27 +00:00
|
|
|
import android.content.SharedPreferences;
|
|
|
|
import android.content.res.Configuration;
|
2019-03-17 17:18:53 +00:00
|
|
|
import android.media.Ringtone;
|
|
|
|
import android.media.RingtoneManager;
|
|
|
|
import android.net.Uri;
|
2018-10-15 06:02:56 +00:00
|
|
|
import android.os.Build;
|
|
|
|
import android.os.DeadSystemException;
|
2019-05-06 17:19:37 +00:00
|
|
|
import android.os.Handler;
|
2018-09-14 05:41:02 +00:00
|
|
|
import android.os.RemoteException;
|
2019-03-13 13:42:33 +00:00
|
|
|
import android.webkit.CookieManager;
|
2018-08-03 18:07:12 +00:00
|
|
|
|
2019-05-10 06:53:45 +00:00
|
|
|
import androidx.annotation.NonNull;
|
2019-04-17 18:21:44 +00:00
|
|
|
import androidx.annotation.RequiresApi;
|
2019-05-06 11:59:26 +00:00
|
|
|
import androidx.preference.PreferenceManager;
|
2019-04-17 18:21:44 +00:00
|
|
|
|
2019-05-10 09:46:11 +00:00
|
|
|
import com.bugsnag.android.BeforeNotify;
|
2019-05-10 06:53:45 +00:00
|
|
|
import com.bugsnag.android.BeforeSend;
|
|
|
|
import com.bugsnag.android.Bugsnag;
|
2019-05-10 09:46:11 +00:00
|
|
|
import com.bugsnag.android.Error;
|
2019-05-10 06:53:45 +00:00
|
|
|
import com.bugsnag.android.Report;
|
2019-05-10 20:33:47 +00:00
|
|
|
import com.sun.mail.iap.ConnectionException;
|
2019-05-11 20:03:52 +00:00
|
|
|
import com.sun.mail.iap.ProtocolException;
|
2019-05-10 06:53:45 +00:00
|
|
|
|
2019-03-17 17:18:53 +00:00
|
|
|
import org.json.JSONArray;
|
|
|
|
import org.json.JSONException;
|
|
|
|
import org.json.JSONObject;
|
|
|
|
|
2018-08-11 04:41:26 +00:00
|
|
|
import java.io.File;
|
2019-05-10 15:00:50 +00:00
|
|
|
import java.io.FileNotFoundException;
|
2018-08-11 04:41:26 +00:00
|
|
|
import java.io.FileWriter;
|
|
|
|
import java.io.IOException;
|
2019-05-11 13:28:55 +00:00
|
|
|
import java.net.SocketTimeoutException;
|
2019-05-10 09:46:11 +00:00
|
|
|
import java.util.ArrayList;
|
2019-03-17 17:18:53 +00:00
|
|
|
import java.util.Arrays;
|
|
|
|
import java.util.Collections;
|
2018-12-19 11:51:27 +00:00
|
|
|
import java.util.Date;
|
2019-03-17 17:18:53 +00:00
|
|
|
import java.util.List;
|
2019-03-27 10:37:27 +00:00
|
|
|
import java.util.Locale;
|
2019-05-11 07:21:48 +00:00
|
|
|
import java.util.concurrent.TimeoutException;
|
2019-03-17 17:18:53 +00:00
|
|
|
|
2019-05-10 13:44:36 +00:00
|
|
|
import javax.mail.MessagingException;
|
|
|
|
|
2018-08-02 13:33:06 +00:00
|
|
|
public class ApplicationEx extends Application {
|
2018-08-03 18:07:12 +00:00
|
|
|
private Thread.UncaughtExceptionHandler prev = null;
|
|
|
|
|
2019-03-17 17:18:53 +00:00
|
|
|
private static final List<String> DEFAULT_CHANNEL_NAMES = Collections.unmodifiableList(Arrays.asList(
|
|
|
|
"service", "notification", "warning", "error"
|
|
|
|
));
|
|
|
|
|
2019-03-27 10:37:27 +00:00
|
|
|
@Override
|
|
|
|
protected void attachBaseContext(Context base) {
|
|
|
|
super.attachBaseContext(getLocalizedContext(base));
|
|
|
|
}
|
|
|
|
|
2018-08-03 18:07:12 +00:00
|
|
|
@Override
|
|
|
|
public void onCreate() {
|
|
|
|
super.onCreate();
|
2019-05-10 06:53:45 +00:00
|
|
|
|
2019-04-12 06:20:24 +00:00
|
|
|
logMemory("App create version=" + BuildConfig.VERSION_NAME);
|
2018-08-03 18:07:12 +00:00
|
|
|
|
|
|
|
prev = Thread.getDefaultUncaughtExceptionHandler();
|
|
|
|
|
|
|
|
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
|
|
|
|
@Override
|
|
|
|
public void uncaughtException(Thread thread, Throwable ex) {
|
2018-09-14 08:31:49 +00:00
|
|
|
if (ownFault(ex)) {
|
2018-12-24 12:27:45 +00:00
|
|
|
Log.e(ex);
|
2018-12-18 16:06:54 +00:00
|
|
|
|
2018-12-28 09:56:40 +00:00
|
|
|
if (BuildConfig.BETA_RELEASE ||
|
|
|
|
!Helper.isPlayStoreInstall(ApplicationEx.this))
|
2018-12-18 16:06:54 +00:00
|
|
|
writeCrashLog(ApplicationEx.this, ex);
|
2018-08-08 13:05:43 +00:00
|
|
|
|
2018-09-14 08:31:49 +00:00
|
|
|
if (prev != null)
|
|
|
|
prev.uncaughtException(thread, ex);
|
|
|
|
} else {
|
2018-12-24 12:27:45 +00:00
|
|
|
Log.w(ex);
|
2018-09-14 08:31:49 +00:00
|
|
|
System.exit(1);
|
2018-08-03 18:07:12 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
2018-08-15 07:40:18 +00:00
|
|
|
|
2019-05-10 19:01:17 +00:00
|
|
|
if ("eu.faircode.email".equals(BuildConfig.APPLICATION_ID))
|
|
|
|
setupBugsnag();
|
2019-05-10 13:18:53 +00:00
|
|
|
|
|
|
|
upgrade(this);
|
|
|
|
|
|
|
|
createNotificationChannels();
|
|
|
|
|
|
|
|
if (Helper.hasWebView(this))
|
|
|
|
CookieManager.getInstance().setAcceptCookie(false);
|
|
|
|
|
|
|
|
MessageHelper.setSystemProperties();
|
|
|
|
ContactInfo.init(this, new Handler());
|
|
|
|
Core.init(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onTrimMemory(int level) {
|
|
|
|
logMemory("Trim memory level=" + level);
|
|
|
|
super.onTrimMemory(level);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onLowMemory() {
|
|
|
|
logMemory("Low memory");
|
|
|
|
super.onLowMemory();
|
|
|
|
}
|
|
|
|
|
|
|
|
private void logMemory(String message) {
|
|
|
|
ActivityManager.MemoryInfo mi = new ActivityManager.MemoryInfo();
|
|
|
|
ActivityManager activityManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
|
|
|
|
activityManager.getMemoryInfo(mi);
|
|
|
|
int mb = Math.round(mi.availMem / 0x100000L);
|
|
|
|
int perc = Math.round(mi.availMem / (float) mi.totalMem * 100.0f);
|
|
|
|
Log.i(message + " " + mb + " MB" + " " + perc + " %");
|
|
|
|
}
|
|
|
|
|
|
|
|
private void setupBugsnag() {
|
2019-05-10 06:53:45 +00:00
|
|
|
// https://docs.bugsnag.com/platforms/android/sdk/
|
|
|
|
com.bugsnag.android.Configuration config =
|
|
|
|
new com.bugsnag.android.Configuration("9d2d57476a0614974449a3ec33f2604a");
|
|
|
|
|
|
|
|
if (BuildConfig.DEBUG)
|
|
|
|
config.setReleaseStage("development");
|
|
|
|
else if (BuildConfig.BETA_RELEASE)
|
|
|
|
config.setReleaseStage(BuildConfig.PLAY_STORE_RELEASE ? "beta/play" : "beta");
|
|
|
|
else
|
|
|
|
config.setReleaseStage(BuildConfig.PLAY_STORE_RELEASE ? "stable/play" : "stable");
|
|
|
|
|
2019-05-10 09:03:01 +00:00
|
|
|
config.setAutoCaptureSessions(false);
|
2019-05-10 09:46:11 +00:00
|
|
|
|
2019-05-10 13:17:30 +00:00
|
|
|
config.setDetectAnrs(false);
|
|
|
|
|
2019-05-10 09:46:11 +00:00
|
|
|
List<String> ignore = new ArrayList<>();
|
2019-05-10 13:44:36 +00:00
|
|
|
|
|
|
|
ignore.add("com.sun.mail.util.MailConnectException");
|
|
|
|
ignore.add("javax.mail.AuthenticationFailedException");
|
2019-05-10 15:02:05 +00:00
|
|
|
ignore.add("java.net.UnknownHostException");
|
2019-05-11 20:03:52 +00:00
|
|
|
ignore.add("java.net.ConnectException");
|
2019-05-10 20:33:47 +00:00
|
|
|
ignore.add("java.net.SocketTimeoutException");
|
2019-05-11 05:55:53 +00:00
|
|
|
ignore.add("java.net.SocketException");
|
2019-05-11 15:02:11 +00:00
|
|
|
// android.accounts.OperationCanceledException
|
2019-05-10 13:44:36 +00:00
|
|
|
|
|
|
|
ignore.add("javax.mail.StoreClosedException");
|
|
|
|
ignore.add("javax.mail.FolderClosedException");
|
|
|
|
ignore.add("javax.mail.ReadOnlyFolderException");
|
|
|
|
|
2019-05-10 09:46:11 +00:00
|
|
|
ignore.add("javax.mail.MessageRemovedException");
|
2019-05-10 13:44:36 +00:00
|
|
|
ignore.add("javax.mail.internet.AddressException");
|
|
|
|
|
2019-05-10 09:46:11 +00:00
|
|
|
config.setIgnoreClasses(ignore.toArray(new String[0]));
|
2019-05-10 06:53:45 +00:00
|
|
|
|
|
|
|
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
|
|
|
|
|
|
|
config.beforeSend(new BeforeSend() {
|
|
|
|
@Override
|
|
|
|
public boolean run(@NonNull Report report) {
|
2019-05-10 13:44:36 +00:00
|
|
|
Error error = report.getError();
|
|
|
|
if (error != null) {
|
|
|
|
Throwable ex = error.getException();
|
|
|
|
|
2019-05-10 20:33:47 +00:00
|
|
|
if (ex instanceof MessagingException &&
|
|
|
|
(ex.getCause() instanceof IOException ||
|
2019-05-11 13:28:55 +00:00
|
|
|
ex.getCause() instanceof ConnectionException ||
|
2019-05-11 20:03:52 +00:00
|
|
|
ex.getCause() instanceof SocketTimeoutException ||
|
|
|
|
ex.getCause() instanceof ProtocolException))
|
2019-05-10 13:44:36 +00:00
|
|
|
return false;
|
|
|
|
|
|
|
|
if (ex instanceof MessagingException &&
|
|
|
|
("connection failure".equals(ex.getMessage()) ||
|
|
|
|
"failed to create new store connection".equals(ex.getMessage())))
|
|
|
|
return false;
|
2019-05-10 15:00:50 +00:00
|
|
|
|
2019-05-10 20:33:47 +00:00
|
|
|
if (ex instanceof IllegalStateException &&
|
|
|
|
("Not connected".equals(ex.getMessage()) ||
|
|
|
|
"This operation is not allowed on a closed folder".equals(ex.getMessage())))
|
|
|
|
return false;
|
|
|
|
|
2019-05-10 15:00:50 +00:00
|
|
|
if (ex instanceof FileNotFoundException &&
|
|
|
|
ex.getMessage() != null &&
|
2019-05-11 13:28:55 +00:00
|
|
|
(ex.getMessage().startsWith("Download image failed") ||
|
|
|
|
ex.getMessage().startsWith("https://autoconfig.thunderbird.net/")))
|
2019-05-10 15:00:50 +00:00
|
|
|
return false;
|
2019-05-10 13:44:36 +00:00
|
|
|
}
|
|
|
|
|
2019-05-10 09:03:01 +00:00
|
|
|
return prefs.getBoolean("crash_reports", false); // opt-in
|
2019-05-10 06:53:45 +00:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
Bugsnag.init(this, config);
|
2019-05-10 09:03:01 +00:00
|
|
|
if (prefs.getBoolean("crash_reports", false))
|
|
|
|
Bugsnag.startSession();
|
2019-05-10 06:53:45 +00:00
|
|
|
|
2019-05-10 09:46:11 +00:00
|
|
|
final String installer = getPackageManager().getInstallerPackageName(BuildConfig.APPLICATION_ID);
|
|
|
|
final boolean fingerprint = Helper.hasValidFingerprint(this);
|
|
|
|
|
|
|
|
Bugsnag.beforeNotify(new BeforeNotify() {
|
|
|
|
@Override
|
|
|
|
public boolean run(@NonNull Error error) {
|
|
|
|
error.addToTab("extra", "installer", installer == null ? "-" : installer);
|
|
|
|
error.addToTab("extra", "fingerprint", fingerprint);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
});
|
2019-04-12 06:20:24 +00:00
|
|
|
}
|
|
|
|
|
2019-05-06 11:59:26 +00:00
|
|
|
static void upgrade(Context context) {
|
|
|
|
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
|
|
|
int version = prefs.getInt("version", 468);
|
|
|
|
if (version < BuildConfig.VERSION_CODE) {
|
|
|
|
Log.i("Upgrading from " + version + " to " + BuildConfig.VERSION_CODE);
|
|
|
|
|
|
|
|
SharedPreferences.Editor editor = prefs.edit();
|
|
|
|
|
|
|
|
editor.remove("notify_trash");
|
|
|
|
editor.remove("notify_archive");
|
|
|
|
editor.remove("notify_reply");
|
|
|
|
editor.remove("notify_flag");
|
|
|
|
editor.remove("notify_seen");
|
|
|
|
|
|
|
|
editor.putInt("version", BuildConfig.VERSION_CODE);
|
|
|
|
editor.apply();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-27 10:37:27 +00:00
|
|
|
static Context getLocalizedContext(Context context) {
|
|
|
|
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
|
|
|
boolean english = prefs.getBoolean("english", false);
|
|
|
|
|
|
|
|
if (english) {
|
|
|
|
Configuration config = new Configuration(context.getResources().getConfiguration());
|
|
|
|
config.setLocale(Locale.US);
|
|
|
|
return context.createConfigurationContext(config);
|
|
|
|
} else
|
|
|
|
return context;
|
|
|
|
}
|
|
|
|
|
2018-09-14 08:31:49 +00:00
|
|
|
private void createNotificationChannels() {
|
2018-08-15 07:40:18 +00:00
|
|
|
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
|
2018-12-09 17:49:52 +00:00
|
|
|
NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
|
2018-08-15 07:40:18 +00:00
|
|
|
|
|
|
|
NotificationChannel service = new NotificationChannel(
|
|
|
|
"service",
|
|
|
|
getString(R.string.channel_service),
|
|
|
|
NotificationManager.IMPORTANCE_MIN);
|
|
|
|
service.setSound(null, Notification.AUDIO_ATTRIBUTES_DEFAULT);
|
2018-10-06 20:58:32 +00:00
|
|
|
service.setShowBadge(false);
|
2018-11-06 10:18:46 +00:00
|
|
|
service.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
|
2018-08-15 07:40:18 +00:00
|
|
|
nm.createNotificationChannel(service);
|
|
|
|
|
|
|
|
NotificationChannel notification = new NotificationChannel(
|
|
|
|
"notification",
|
|
|
|
getString(R.string.channel_notification),
|
2018-11-05 07:48:02 +00:00
|
|
|
NotificationManager.IMPORTANCE_HIGH);
|
2018-11-06 10:18:46 +00:00
|
|
|
notification.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
|
2018-08-15 07:40:18 +00:00
|
|
|
nm.createNotificationChannel(notification);
|
|
|
|
|
2019-01-23 08:44:25 +00:00
|
|
|
NotificationChannel warning = new NotificationChannel(
|
|
|
|
"warning",
|
|
|
|
getString(R.string.channel_warning),
|
|
|
|
NotificationManager.IMPORTANCE_HIGH);
|
|
|
|
warning.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
|
|
|
|
nm.createNotificationChannel(warning);
|
|
|
|
|
2018-08-15 07:40:18 +00:00
|
|
|
NotificationChannel error = new NotificationChannel(
|
|
|
|
"error",
|
|
|
|
getString(R.string.channel_error),
|
|
|
|
NotificationManager.IMPORTANCE_HIGH);
|
2019-01-23 08:44:25 +00:00
|
|
|
error.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
|
2018-08-15 07:40:18 +00:00
|
|
|
nm.createNotificationChannel(error);
|
2019-03-17 18:06:51 +00:00
|
|
|
|
|
|
|
NotificationChannelGroup group = new NotificationChannelGroup(
|
|
|
|
"contacts",
|
|
|
|
getString(R.string.channel_group_contacts));
|
|
|
|
nm.createNotificationChannelGroup(group);
|
2018-08-15 07:40:18 +00:00
|
|
|
}
|
2018-08-03 18:07:12 +00:00
|
|
|
}
|
2018-09-14 08:31:49 +00:00
|
|
|
|
2019-03-17 17:18:53 +00:00
|
|
|
@RequiresApi(api = Build.VERSION_CODES.O)
|
2019-03-17 18:17:41 +00:00
|
|
|
static JSONArray channelsToJSON(Context context) throws JSONException {
|
2019-03-17 17:18:53 +00:00
|
|
|
JSONArray jchannels = new JSONArray();
|
|
|
|
|
2019-03-17 18:17:41 +00:00
|
|
|
NotificationManager nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
|
2019-03-17 17:18:53 +00:00
|
|
|
for (NotificationChannel channel : nm.getNotificationChannels())
|
|
|
|
if (!DEFAULT_CHANNEL_NAMES.contains(channel.getId())) {
|
|
|
|
JSONObject jchannel = new JSONObject();
|
|
|
|
|
|
|
|
jchannel.put("id", channel.getId());
|
|
|
|
jchannel.put("group", channel.getGroup());
|
|
|
|
jchannel.put("name", channel.getName());
|
|
|
|
jchannel.put("description", channel.getDescription());
|
|
|
|
|
|
|
|
jchannel.put("importance", channel.getImportance());
|
|
|
|
jchannel.put("dnd", channel.canBypassDnd());
|
|
|
|
jchannel.put("visibility", channel.getLockscreenVisibility());
|
|
|
|
jchannel.put("badge", channel.canShowBadge());
|
|
|
|
|
|
|
|
Uri sound = channel.getSound();
|
|
|
|
if (sound != null)
|
|
|
|
jchannel.put("sound", sound.toString());
|
|
|
|
// audio attributes
|
|
|
|
|
|
|
|
jchannel.put("light", channel.shouldShowLights());
|
|
|
|
// color
|
|
|
|
|
|
|
|
jchannel.put("vibrate", channel.shouldVibrate());
|
|
|
|
// pattern
|
|
|
|
|
|
|
|
jchannels.put(jchannel);
|
|
|
|
}
|
|
|
|
|
|
|
|
return jchannels;
|
|
|
|
}
|
|
|
|
|
|
|
|
@RequiresApi(api = Build.VERSION_CODES.O)
|
2019-03-17 18:17:41 +00:00
|
|
|
static void channelsFromJSON(Context context, JSONArray jchannels) throws JSONException {
|
|
|
|
NotificationManager nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
|
2019-03-17 17:18:53 +00:00
|
|
|
for (int c = 0; c < jchannels.length(); c++) {
|
|
|
|
JSONObject jchannel = (JSONObject) jchannels.get(c);
|
|
|
|
|
|
|
|
String id = jchannel.getString("id");
|
|
|
|
if (nm.getNotificationChannel(id) == null) {
|
|
|
|
NotificationChannel channel = new NotificationChannel(
|
|
|
|
id,
|
|
|
|
jchannel.getString("name"),
|
|
|
|
jchannel.getInt("importance"));
|
|
|
|
|
|
|
|
if (jchannel.has("group") && !jchannel.isNull("group"))
|
|
|
|
channel.setGroup(jchannel.getString("group"));
|
2019-03-17 18:06:51 +00:00
|
|
|
else
|
|
|
|
channel.setGroup("contacts");
|
2019-03-17 17:18:53 +00:00
|
|
|
|
|
|
|
if (jchannel.has("description") && !jchannel.isNull("description"))
|
|
|
|
channel.setDescription(jchannel.getString("description"));
|
|
|
|
|
|
|
|
channel.setBypassDnd(jchannel.getBoolean("dnd"));
|
|
|
|
channel.setLockscreenVisibility(jchannel.getInt("visibility"));
|
|
|
|
channel.setShowBadge(jchannel.getBoolean("badge"));
|
|
|
|
|
|
|
|
if (jchannel.has("sound") && !jchannel.isNull("sound")) {
|
|
|
|
Uri uri = Uri.parse(jchannel.getString("sound"));
|
2019-03-17 18:17:41 +00:00
|
|
|
Ringtone ringtone = RingtoneManager.getRingtone(context, uri);
|
2019-03-17 17:18:53 +00:00
|
|
|
if (ringtone != null)
|
|
|
|
channel.setSound(uri, Notification.AUDIO_ATTRIBUTES_DEFAULT);
|
|
|
|
}
|
|
|
|
|
|
|
|
channel.enableLights(jchannel.getBoolean("light"));
|
|
|
|
channel.enableVibration(jchannel.getBoolean("vibrate"));
|
|
|
|
|
|
|
|
Log.i("Creating channel=" + channel);
|
|
|
|
nm.createNotificationChannel(channel);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-14 08:31:49 +00:00
|
|
|
public boolean ownFault(Throwable ex) {
|
|
|
|
if (ex instanceof OutOfMemoryError)
|
|
|
|
return false;
|
2018-09-18 08:28:51 +00:00
|
|
|
|
2018-09-14 08:31:49 +00:00
|
|
|
if (ex instanceof RemoteException)
|
|
|
|
return false;
|
2018-09-18 08:28:51 +00:00
|
|
|
|
2019-05-11 07:21:48 +00:00
|
|
|
if (ex instanceof TimeoutException &&
|
|
|
|
ex.getMessage() != null &&
|
|
|
|
ex.getMessage().startsWith("com.sun.mail.imap.IMAPStore.finalize"))
|
|
|
|
return false;
|
|
|
|
|
2018-10-15 06:02:56 +00:00
|
|
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
|
|
|
|
if (ex instanceof RuntimeException && ex.getCause() instanceof DeadSystemException)
|
|
|
|
return false;
|
|
|
|
|
2018-12-30 07:55:31 +00:00
|
|
|
if (BuildConfig.BETA_RELEASE)
|
|
|
|
return true;
|
|
|
|
|
2018-09-14 08:31:49 +00:00
|
|
|
while (ex != null) {
|
|
|
|
for (StackTraceElement ste : ex.getStackTrace())
|
|
|
|
if (ste.getClassName().startsWith(getPackageName()))
|
|
|
|
return true;
|
|
|
|
ex = ex.getCause();
|
|
|
|
}
|
2018-12-10 09:53:46 +00:00
|
|
|
|
2018-09-14 08:31:49 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2018-12-10 09:53:46 +00:00
|
|
|
static void writeCrashLog(Context context, Throwable ex) {
|
|
|
|
File file = new File(context.getCacheDir(), "crash.log");
|
2018-12-24 12:27:45 +00:00
|
|
|
Log.w("Writing exception to " + file);
|
2018-09-14 08:31:49 +00:00
|
|
|
|
2019-02-22 15:59:23 +00:00
|
|
|
try (FileWriter out = new FileWriter(file, true)) {
|
2018-12-19 11:51:27 +00:00
|
|
|
out.write(BuildConfig.VERSION_NAME + " " + new Date() + "\r\n");
|
2018-12-24 12:27:45 +00:00
|
|
|
out.write(ex + "\r\n" + android.util.Log.getStackTraceString(ex) + "\r\n");
|
2018-09-14 08:31:49 +00:00
|
|
|
} catch (IOException e) {
|
2018-12-24 12:27:45 +00:00
|
|
|
Log.e(e);
|
2018-09-14 08:31:49 +00:00
|
|
|
}
|
|
|
|
}
|
2018-08-02 13:33:06 +00:00
|
|
|
}
|