I have a class A which extends Application.In A i am handling uncaughtexceptions. Now the issue is whenever app encounters any issue app freezes and black screen appears before crashing
public class A extends Application {
#Override
public void onCreate() {
super.onCreate();
final AppContext context = AppContext.getInstance();
context.setContext(this);
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
#Override
public void uncaughtException(Thread thread, Throwable e) {
mContext = context.getContext();
e.getCause().getMessage();
AppPreference.getInstance().setCrashReason(e.getMessage());
Intent intent = new Intent ();
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity (intent);
System.exit(1);
}
});
}
I have searched a lot but all went in vain.Thanks in advance.
You can use the following way :
public class MyApplication extends Application
{
public void onCreate ()
{
// Setup handler for uncaught exceptions.
Thread.setDefaultUncaughtExceptionHandler (new Thread.UncaughtExceptionHandler()
{
#Override
public void uncaughtException (Thread thread, Throwable e)
{
handleUncaughtException (thread, e);
}
});
}
public void handleUncaughtException (Thread thread, Throwable e)
{
e.printStackTrace(); // not all Android versions will print the stack trace automatically
Intent intent = new Intent ();
intent.setAction ("com.mydomain.SEND_LOG");
intent.setFlags (Intent.FLAG_ACTIVITY_NEW_TASK); // required when starting from Application
startActivity (intent);
}
}
according to this answer
Related
I already tried a JobService as well, but I get the same result, as with the JobIntentService, namely my Notification gets called after x seconds when the app is running in the foreground, but not after swiping the app in the recent task area.
Here is how I start the JobIntentService from my Fragment:
Intent serviceIntent = new Intent(getActivity(), AlertJob.class);
serviceIntent.putExtra("inputExtra", timeForAlarm);
AlertJob.enqueueWork(getContext(), serviceIntent);
And this is my JobIntentService Class:
public class AlertJob extends JobIntentService {
public static void enqueueWork(Context context, Intent work) {
enqueueWork(context, AlertJob.class, 123, work);
}
#Override
public void onCreate() {
super.onCreate();
}
#Override
protected void onHandleWork(#NonNull Intent intent)
{
try
{
Thread.sleep(5000);
startService(new Intent(getApplicationContext(), Service_Notification.class));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
#Override
public void onDestroy() {
super.onDestroy();
}
#Override
public boolean onStopCurrentWork() {
return super.onStopCurrentWork();
}
}
I have already tried the AlarmManager and so on as well, but the problem remains the same. The JobIntentService gets destroyed when the app is only running in the background.
Thank you very much for your help!
In my application I have a (background) Service which runs in its own process. To communicate with other components I defined some AIDL interfaces:
interface MyService {
void addOnChangeListener(ServiceChangedListener listener);
void removeOnChangeListener(ServiceChangedListener listener);
}
interface ServiceChangedListener {
void onUserChanged(in User newUser);
}
Here is my service with the MyService implementation.
public class UserService extends Service {
private RemoteCallbackList<ServiceChangedListener> listeners;
public class ServiceBinder extends MyService.Stub {
public void addOnChangeListener(ServiceChangedListener listener) {
listeners.register(listener);
}
public void removeOnChangeListener(ServiceChangedListener listener) {
listeners.unregister(listener);
}
}
// all the other implementation...
}
My Activity connects to this Service in onStart and disconnects from it in onStop where it also release the listener which is registered in onServiceConnected.
public class MainAcitivity extends AppCompatActivity {
private ServiceListener listener;
private MyService service;
protected void onStart() {
super.onStart();
Intent intent = new Intent(this, UserService.class);
bindService(intent, this, Context.BIND_AUTO_CREATE);
}
protected void onStop() {
super.onStop();
try { service.removeOnChangeListener(listener); }
catch (RemoteException e) { e.printStackTrace(); }
unbindService(this);
}
public void onServiceConnected(ComponentName className, IBinder service) {
service = MyService.Stub.asInterface(service);
try {
listener = new ServiceListener();
service.addOnChangeListener(listener);
} catch (RemoteException e) {
e.printStackTrace();
}
}
private class ServiceListener extends ServiceChangedListener.Stub {
public void onUserChanged(User u) throws RemoteException {
runOnUiThread(() -> { ... });
}
}
}
The add and remove methods for the listener simply operate on an ArrayList as you would expect so there is no long ongoing work.
LeakCanary as well as the Android studio memory analysis tool tell me that this causes a memory leak. If I comment out the lines affecting the listener no memory leak is detected. Do you have any ideas why?
I finally found the answer! You have to make the inner class static and use a WeakReference within it. Here is an official answer of a Google engineer and here a simplified one. Good luck anyone with the same problem!
What I want to do is, close all the open activities when there is any unhandled exception.
I have a BaseActivity which is base for all the activities in my application and every activity derived from this class.
I have called setDefaultUncaughtExceptionHandler in onCreate of BaseActivity.
I have a BaseActivity as below:
public abstract class BaseActivity extends Activity
{
#Override
public void onCreate(Bundle savedInstanceState)
{
// Exceptions that are not handled are received in GlobalExceptionHandler class
Thread.setDefaultUncaughtExceptionHandler(new MyExceptionHandler());
}
public class MyExceptionHandler implements UncaughtExceptionHandler
{
#Override
public void uncaughtException(Thread thread, Throwable e)
{
String report = "";
// Code to generate report string
......
// Code to generate report string
// Start error screen
Intent intent = new Intent(mContext, ErrorScreen.class);
intent.putExtra("error", report);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
// Exit
System.exit(0);
}
}
}
Here is my ErrorScreen Activity:
public class ErrorScreen extends Activity implements OnClickListener
{
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.error_screen_layout);
// Display error report from intent
}
#Override
public void onClick(View view)
{
switch(view.getId())
{
case R.id.btn_exit_app:
{
// All this is not working
// and few activities are still there
finish();
android.os.Process.killProcess(android.os.Process.myPid());
System.exit(1);
}
break;
}
}
}
On any unhandeled exception, my uncaughtException function is getting called which is as expected, then i start new activity for displaying error details and a button to exit in ErrroScreen activity.
But problem is that, after selecting exit app button, not all the activities in the application are closing, there are still few activities that are open, how to close all the open activities?
private Thread.UncaughtExceptionHandler androidDefaultUEH;
private Thread.UncaughtExceptionHandler handler = new Thread.UncaughtExceptionHandler() {
public void uncaughtException(Thread thread, Throwable ex) {
//mInstance.startActivity(new Intent(mInstance, HomeActivity.class));
Log.e("TestApplication", "Uncaught exception is: ", ex);
// here I do logging of exception to a db
Toast.makeText(getApplicationContext(), "Something went wrong..... TimesNow App is restarting...", Toast.LENGTH_SHORT).show();
PendingIntent myActivity = PendingIntent.getActivity(getApplicationContext(),
192837, new Intent(getApplicationContext(), ToBeOpenedActivity.class),
PendingIntent.FLAG_ONE_SHOT);
AlarmManager alarmManager;
alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
15000, myActivity);
System.exit(0);
androidDefaultUEH.uncaughtException(thread, ex);
}
};
Write this method in your application class..
I want custom calling screen I have achieved that but problem is that my screen is not going back when call cuts.i(..) want to terminate screen when call cuts. My code is:
public class receiver_Call extends BroadcastReceiver {
public void onReceive(final Context context, Intent intent) {
Thread pageTimer = new Thread(){
public void run(){
try{
sleep(1000);
} catch (InterruptedException e){
e.printStackTrace();
} finally {
//Toast.makeText(context," text", 5).show();
Intent i = new Intent();
i.setClass(context, My_call_receiver.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
}
}
};
pageTimer.start();
}
}
Have you tried a listener for when the call ends:
EndCallListener callListener = new EndCallListener();
TelephonyManager mTM = (TelephonyManager)this.getSystemService(Context.TELEPHONY_SERVICE);
mTM.listen(callListener, PhoneStateListener.LISTEN_CALL_STATE);
And in your Listener:
private class EndCallListener extends PhoneStateListener {
#Override
public void onCallStateChanged(int state, String incomingNumber) {
if(TelephonyManager.CALL_STATE_RINGING == state) {}
if(TelephonyManager.CALL_STATE_OFFHOOK == state) {}
if(TelephonyManager.CALL_STATE_IDLE == state) {}
}
}
EndCallListener is your class which extends PhoneStateListener (which is defined above)
I am re-launching my application after my it crashes using Thread.setDefaultUncauhtExceptionHandler(). I would like to pass an intent extra telling it that it just came back from the dead, however its not sticking. Here is the onCreate of LockedUpActivity.
public class LockedUpActivity extends Activity {
/** Called when the activity is first created. */
UncaughtExceptionHandler defaultHandler;
private static final String RECOVERED = "recovered";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
setDefaultHandler();
if (getIntent().getBooleanExtra(RECOVERED, false)) {
Log.i("LockedUp", "Back from the dead!");
((TextView) findViewById(R.id.textview)).setText("Back from the dead!");
}
else {
Log.i("LockedUp", "Machiavelli in this..");
}
}
public void goDownInFlames(View v) {
startActivity(new Intent(this, GoingDownActivity.class));
}
private void setDefaultHandler() {
defaultHandler = Thread.getDefaultUncaughtExceptionHandler();
Thread.currentThread().setUncaughtExceptionHandler(new UncaughtExceptionHandler() {
#Override
public void uncaughtException(Thread thread, Throwable ex) {
Intent i = new Intent(getApplicationContext(), LockedUpActivity.class);
i.putExtra(RECOVERED, true);
startActivity(i);
defaultHandler.uncaughtException(thread, ex);
}
});
}
}
As you can see, I am setting the extra, however it is never "Back from the dead!"
When an Application crashes or is 'forced stop', automatic garbage collection is done, variables are cleared, and so is the activity stack of the app. The extras won't remain there if the app crashes.