Is there a way for my to program my app to automatically restart itself whenever it crashes? My app is just a simple media rendering App, however it occasionally crashes ( it's supposed to ). Is this at all possible? Thanks. My code looks like this
public void Play(){ if(mp != null) {
mp.reset();
mp.release();
mp = null;
}
AudioRenderer mr = new AudioRenderer();
mp = mr.AudioRenderer(filePath);
}
private class AudioRenderer extends Activity {
private MediaPlayer AudioRenderer(String filePath) {
File location = new File(filePath);
Uri path = Uri.fromFile(location);
mp= MediaPlayer.create(this, path);
}
return mp
}
this will do the job for you.
How to start the automatically stopped android service?
still i don't understand why it is supposed to crash.
UPDATE
you create an handler for uncaught exception
private Thread.UncaughtExceptionHandler onRuntimeError= new Thread.UncaughtExceptionHandler() {
public void uncaughtException(Thread thread, Throwable ex) {
//Try starting the Activity again
};
in your on create, you register an handler for uncaught exception
#Override
protected void onCreate() {
super.onCreate();
Thread.setDefaultUncaughtExceptionHandler(onRuntimeError);
}
I might be late a lot, but I found 2 in 1 solution for your problem.
public void doRestart() {
Intent mStartActivity = new Intent(context, LoginActivity.class);
int mPendingIntentId = 123456;
PendingIntent mPendingIntent = PendingIntent.getActivity(context, mPendingIntentId, mStartActivity, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager mgr = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 100, mPendingIntent);
System.exit(0);
}
private void appInitialization() {
defaultUEH = Thread.getDefaultUncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(_unCaughtExceptionHandler);
}
//make crash report on ex.stackreport
private Thread.UncaughtExceptionHandler defaultUEH;
// handler listener
private Thread.UncaughtExceptionHandler _unCaughtExceptionHandler = new Thread.UncaughtExceptionHandler() {
#Override
public void uncaughtException(Thread thread, Throwable ex) {
ex.printStackTrace();
doRestart();
}
};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_index);
appInitialization();
Related
I want to restart my application after crash. So I created a crash handler on Application class:
public final class MyApp extends Application {
private static Thread.UncaughtExceptionHandler mDefaultUEH;
private Thread.UncaughtExceptionHandler mCaughtExceptionHandler = new Thread.UncaughtExceptionHandler() {
#Override
public void uncaughtException(Thread thread, Throwable ex) {
Intent splashIntent = new Intent(getInstance().getActivity(), A1SplashScreen.class);
//splashIntent.addCategory(Intent.CATEGORY_LAUNCHER);
//splashIntent.setAction(Intent.ACTION_MAIN);
splashIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
splashIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
splashIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
int requestID = (int) System.currentTimeMillis();
PendingIntent pending = PendingIntent.getActivity(getInstance().getActivity(), requestID, splashIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_ONE_SHOT);
AlarmManager alarmManager = (AlarmManager) getInstance().getActivity().getSystemService(ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC, System.currentTimeMillis(), pending);
mDefaultUEH.uncaughtException(thread, ex);
}
};
#Override
public void onCreate() {
super.onCreate();
Fabric.with(this, new Crashlytics());
mDefaultUEH = Thread.getDefaultUncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(mCaughtExceptionHandler);
}
}
A1SplashScreen is main activity of the application, so I want to start that activity after crash. There is no problem on API 21 and above. But problem is on API level lower than 21. After application crashes, A1SplashScreen launches but onCreate() method of it does not called. So the screen freezes and nothing shown (only white screen). It does not response and does not crash. Here is screenshot:
RESOLVED
When I call System.exit(2) method, application restarted. But I could not see crash on crashlytics. On the other hand, if I do not call System.exit(), I can see crash on crashlytic but application does not restart. That's why I ran System.exit(2) method and mDefaultUEH.uncaughtException(thread, throwable) parallel via ExecutorService. Here is the working code :
private Thread.UncaughtExceptionHandler mCaughtExceptionHandler = new Thread.UncaughtExceptionHandler() {
#Override
public void uncaughtException(Thread thread, Throwable ex) {
Intent intent = new Intent(getApplicationContext(), A1SplashScreen.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
getInstance().getActivity().startActivity(intent);
activity.finish();
ExecutorService executorService = Executors.newCachedThreadPool();
CallCrashlytics callCrashlytics = new CallCrashlytics(thread, ex);
CallSystemExit callSystemExit = new CallSystemExit();
try {
executorService.invokeAll(Arrays.asList(callCrashlytics, callSystemExit));
}catch (InterruptedException e){
e.printStackTrace();
}
}
};
class CallCrashlytics implements Callable<Void>{
Thread thread;
Throwable throwable;
CallCrashlytics(Thread thread, Throwable throwable){
this.thread = thread;
this.throwable = throwable;
}
#Override
public Void call() throws Exception {
mDefaultUEH.uncaughtException(thread, throwable);
return null;
}
}
class CallSystemExit implements Callable<Void>{
#Override
public Void call() throws Exception {
System.exit(2);
return null;
}
}
How to set beep sound when mobile out of the range without button onclick event?using Mediaplayer.when mobile out of the range it continous send beep sound and in range it not beep.Please help me.I am new in android.
You Have More than One Option For Example Handlers , Broadcastreceiver and a service.
For Handler
Handler mediaHandler = new Handler();
if(something)
mediaHandler.postDelayed(MediaTimeTask, 5000);
private Runnable MediaTimeTask = new Runnable() {
public void run() {
mPlay = MediaPlayer
.create(FutureJobReminder.this, R.raw.breakalert);
mPlay.setLooping(false);
mPlay.start();
mediaHandler.postDelayed(this, 5000);
if (somecondition to stop the alert ) {
stopme();
}
}
};
private void stopme() {
try {
mPlay.stop();
mediaHandler.removeCallbacks(MediaTimeTask);
} catch (Exception e) {
e.printStackTrace();
}
}
SO here is BroadcastReceiver
private final BroadcastReceiver abcd = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
//dosomething
Startalert();
}
};
public void Startalert( ) {
MediaPlayer mplay;
mplay = MediaPlayer.create(NewMessage.this, R.raw.alert);
//R.raw.alert is a sound which is in raw folder
mplay.start();
mPlay.setLooping(true);//this will hepl you you to call you sound again and again
mPlay.stop();//stop alert sound
}
don't forget to unregister the BroadcastReceiver and release media.
unregisterReceiver(abcd);
Happy Coding.
Hi I am dealing with a 3rd party library that is buggy at times and causes the activity restart. Is there a way to tell when an activity is restarted from a crash? I tried using an uncaught exception handler like this but it wasn't being triggered.
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
#Override
public void uncaughtException(Thread thread, Throwable throwable) {
Log.d("un", "caught");
}
});
write like this
Thread.setDefaultUncaughtExceptionHandler(new MyExceptionHandler(this,YOURCURRENTCLASSNAME.class));
And use this class dear. i also used this
public class MyExceptionHandler implements
java.lang.Thread.UncaughtExceptionHandler {
private final Context myContext;
private final Class<?> myActivityClass;
public MyExceptionHandler(Context context, Class<?> c) {
myContext = context;
myActivityClass = c;
}
public void uncaughtException(Thread thread, Throwable exception) {
StringWriter stackTrace = new StringWriter();
exception.printStackTrace(new PrintWriter(stackTrace));
System.err.println(stackTrace);// You can use LogCat too
Intent intent = new Intent(myContext, myActivityClass);
String s = stackTrace.toString();
// you can use this String to know what caused the exception and in
// which Activity
intent.putExtra("uncaughtException",
"Exception is: " + stackTrace.toString());
intent.putExtra("stacktrace", s);
myContext.startActivity(intent);
// for restarting the Activity
// Process.killProcess(Process.myPid());
System.out.println("comingggggggggggggggggg in crashhhhhhhhhhhhhhhhhhhh and restrttttttttttttt autometically ");
Intent i = myContext.getPackageManager().getLaunchIntentForPackage(myContext.getPackageName() );
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
i.addCategory(Intent.CATEGORY_HOME);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
myContext.startActivity(i);
System.exit(0);
}
}
Or, if you are looking for a working-out-of-the-box solution, you can use a bug tracker service, such as Crashlytics or Crittercism. They both offer a way of knowing if the current run occurred just after a crash.
Crashlytics
Crashlytics.getInstance().setListener(new CrashlyticsListener() {
#Override
public void crashlyticsDidDetectCrashDuringPreviousExecution() {
// if this method is called, it means that a crash occurred
// in the previous run
didCrashOnLastLoad = true;
}
});
Crittercism (source)
CritterCallback cb = new CritterCallback() {
#Override public void onCritterDataReceived(CritterUserData userData) {
boolean crashedOnLastLoad = userData.crashedOnLastLoad();
// ...do something with crashedOnLastLoad
}
};
CritterUserDataRequest request = new CritterUserDataRequest(cb)
.requestDidCrashOnLastLoad();
// Fire off the request.
request.makeRequest();
I need to call the Google activity recognition service through a service (not activity) and run it in the background, of course when the user starts the app, which has an activity (But the service does not called directly from activity).
Therefore I have created a service class (ActivitySensor) and another class (ActivityRecognitionScan).
When I install the app on my Galaxy Nexus S device, the service starts calling onCreate and onDestroy automatically. Even without doing anything in the GUI
It is very strange behaviour. Does anybody has the same experience or solution for it?
I mean I get something as follows in the debug console:
Activity-Logging --- onCreate
Activity-Logging --- onDestroy
Activity-Logging --- onCreate
Activity-Logging --- onDestroy
Activity-Logging --- onCreate
Activity-Logging --- onDestroy
...
Here are my two classes:
public class ActivitySensor extends IntentService {
private ActivityRecognitionScan myascan;
private Intent inIntent;
private static long ACTIVITY_LOG_INTERVAL = 30000L;
private static JsonEncodeDecode jsonencoder = new JsonEncodeDecode();
public ActivitySensor() {
super("ActivitySensor");
}
#Override
public void onCreate(){
super.onCreate();
Log.d("Activity-Logging", "--- onCreate");
try {
myascan = new ActivityRecognitionScan(getApplicationContext());
myascan.startActivityRecognitionScan();
} catch (Exception e) {
Log.e("[Activity-Logging]","----------Error:"+e.getLocalizedMessage());
e.printStackTrace();
}
}
#Override
public void readSensor() {
// Log.e("Activity-Logging", "ActivityRecognitionResult.hasResult: "+String.valueOf(ActivityRecognitionResult.hasResult(inIntent)));
if (ActivityRecognitionResult.hasResult(inIntent)) {
ActivityRecognitionResult result = ActivityRecognitionResult.extractResult(inIntent);
DetectedActivity activity = result.getMostProbableActivity();
final int type = activity.getType();
String strType = new String();
switch(type){
case DetectedActivity.IN_VEHICLE:
strType = "invehicle";
break;
case DetectedActivity.ON_BICYCLE:
strType ="onbicycle";
break;
case DetectedActivity.ON_FOOT:
strType = "onfoot";
break;
case DetectedActivity.STILL:
strType = "still";
break;
case DetectedActivity.TILTING:
strType ="tilting";
break;
case DetectedActivity.UNKNOWN:
strType ="unknown";
break;
}
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
Editor edt = prefs.edit();
String previousActv = prefs.getString("PREVIOUS_ACTIVIY","");
long previousDate = prefs.getLong("PREVIOUS_DATE", 0);
if (previousActv.length()==0){ // nothing was in the string and it is the first time just initialize
previousActv = strType;
previousDate = new Date().getTime();
// Log.e("-----FIRST TIME: type:", previousActv+" date:"+String.valueOf(previousDate));
edt.putString("PREVIOUS_ACTIVIY", strType);
edt.putLong("PREVIOUS_DATE", previousDate);
edt.commit();
}else {
if (!strType.equalsIgnoreCase(previousActv)){
Date readablePrevDate = new Date(previousDate);
Date nowDate = new Date();
String jsonstr = jsonencoder.EncodeActivity("Activity", readablePrevDate, nowDate, strType, activity.getConfidence());
// Log.e("[Activity-Logging] ----->",jsonstr);
edt.putString("PREVIOUS_ACTIVIY", strType);
edt.putLong("PREVIOUS_DATE", nowDate.getTime());
edt.commit();
DataAcquisitor.dataBuff.add(jsonstr);
}
}
}
}
#Override
protected void onHandleIntent(Intent intent) {
Log.d("Activity-Logging", "--- onHandleIntent"+ "---"+intent.getAction());
intent.putExtra("LOG_INTERVAL",ACTIVITY_LOG_INTERVAL );
intent.putExtra("STOP",false);
inIntent = intent;
readSensor();
}
#Override
public void onDestroy(){
Log.d("Activity-Logging", "--- onDestroy");
myascan.stopActivityRecognitionScan();
myascan=null;
//super.onDestroy();
}
}
This is the class that calls the Google Activity Recognition Service:
ActivityRecognitionScan implements GooglePlayServicesClient.ConnectionCallbacks, GooglePlayServicesClient.OnConnectionFailedListener {
private Context ctx;
private static final String TAG = "ActivityRecognition";
private static ActivityRecognitionClient actrecClient;
private static PendingIntent callbackIntent;
private long ACTIVITY_LOG_INTERVAL=30000;
public ActivityRecognitionScan(Context context) {
ctx=context;
}
public void startActivityRecognitionScan(){
int resp = GooglePlayServicesUtil.isGooglePlayServicesAvailable(ctx);
if(resp == ConnectionResult.SUCCESS){
actrecClient = new ActivityRecognitionClient(ctx, this, this);
if (!actrecClient.isConnected()){
actrecClient.connect();
} else{
Log.e("ActivityRecognitionScan"," ---Activity recognition client is already connected");
}
}else{
Log.e("[Activity-Logging]", "Google Play Service hasn't installed");
}
}
public void stopActivityRecognitionScan(){
try{
if (actrecClient.isConnected() || actrecClient.isConnecting() ){
actrecClient.removeActivityUpdates(callbackIntent);
actrecClient.disconnect();
}
} catch (Exception e){
e.printStackTrace();
}
}
#Override
public void onConnectionFailed(ConnectionResult result) {
Log.e("[ActivityRecognitionScan]", "Connection Failed");
}
#Override
public void onConnected(Bundle connectionHint) {
try{
Intent intent = new Intent(ctx, ActivitySensor.class);
Bundle bundle = intent.getExtras();
callbackIntent = PendingIntent.getService(ctx, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
long interval = 5000;
if ( null!= bundle && bundle.containsKey("LOG_INTERVAL") ){
interval = bundle.getLong("LOG_INTERVAL");
}
actrecClient.requestActivityUpdates(interval, callbackIntent);
actrecClient.disconnect();
}catch(Exception ex){
Log.e("[Activity-Logging]","Error in requesting Activity update "+ex.getMessage());
ex.printStackTrace();
}
}
#Override
public void onDisconnected() {
callbackIntent.cancel();
actrecClient = null;
Log.e("[ActivityRecognitionScan]","---onDisconnected");
}
}
IntentService automatically stops itself on completion of onHandleIntent as per the source code (see ServiceHandler.handleMessage()) as per the description of an IntentService:
Clients send requests through startService(Intent) calls; the service is started as needed, handles each Intent in turn using a worker thread, and stops itself when it runs out of work.
Use a Service if you want it to run continuously in the background.
You have 2 issues with your code that is causing the problem you are experiencing.
When activity is detected, the pending intent that is called calls (and creates, since it is an IntentService) ActivitySensor. The onCreate will connect another ActivityRecognitionClient, which is unnecessary. This causes another activity to be detected which causes your logging loop.
You should separate the creation of the ActivityRecognitionClient from the handling of the detected activity. You don't need to keep recreating it as subsequent detections will use the same PendingIntent. This will prevent the logging loop.
I am getting the NPE while starting the service. I have just gone through the service tutorial on android developer site.
Logs are showing unable to resume activity...
#Override
protected void onResume() {
super.onResume();
CustomIntentService cis = new CustomIntentService();
Intent intent1 = new Intent(this, CustomIntentService.class);
intent1.putExtra("NUM", 1);
cis.startService(intent1);
}
My service is :
public class CustomIntentService extends IntentService {
private final static String TAG = "CustomIntentService";
public CustomIntentService() {
super("CustomIntentService");
Log.d(TAG,"out CustomIntentService");
}
#Override
protected void onHandleIntent(Intent intent) {
Log.d(TAG, "onHandleIntent");
Log.d(TAG, "service num = " + intent.getIntExtra("NUM", 0));
if (Looper.getMainLooper() == Looper.myLooper()) {
Log.d(TAG, "In main ui thread");
} else {
Log.d(TAG, "In worker thread");
}
}
}
Change your code for onResume to the following:
#Override
protected void onResume() {
super.onResume();
//CustomIntentService cis = new CustomIntentService();
Intent intent1 = new Intent(this, CustomIntentService.class);
intent1.putExtra("NUM", 1);
startService(intent1);
}
This should fix the issue, remember intent knows which service to start and startService() is called on context. So here activity's instance will be the context.
Also,
Since Service is a component, so you should be declaring it in the AndroidManifestFile
<service
android:name=".CustomIntentService">
</service>
*Note: CustomIntentService should be under current directory, or you can supply absolute path also.
You can refer this