I just want to know how to launch an Activity in a try/catch bloc, i made this
public void onReceive(Context context, Intent intent) {
SipAudioCall incomingCall = null;
try {
Intent monIntent = new Intent(this,dialog.class);
startActivity(monIntent);
SipAudioCall.Listener listener = new SipAudioCall.Listener() {
#Override
public void onRinging(SipAudioCall call, SipProfile caller) {
But i have errors:
constructor Intent(IncomingCallReceiver, Class<dialog>) is not defined
Method startActivity(Intent) is undefined for the type IncomingCallReceiver
I want to show an alertdialog when having a call.
How can i solve this problem?
Thank you very much.
Whole class:
public class IncomingCallReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
SipAudioCall incomingCall = null;
try {
SipAudioCall.Listener listener = new SipAudioCall.Listener() {
#Override
public void onRinging(SipAudioCall call, SipProfile caller) {
try {
call.answerCall(30);
} catch (Exception e) {
e.printStackTrace();
}
}
};
SIPCommunicator wtActivity = (SIPCommunicator) context;
incomingCall = wtActivity.manager.takeAudioCall(intent, listener);
incomingCall.answerCall(30);
incomingCall.startAudio();
incomingCall.setSpeakerMode(true);
if(incomingCall.isMuted()) {
incomingCall.toggleMute();
}
wtActivity.call = incomingCall;
wtActivity.updateStatus(incomingCall);
} catch (Exception e) {
if (incomingCall != null) {
incomingCall.close();
}
}
}
}
The problem you are facing is not the try catch block, it's the fact that you are starting activity in a listener implementation. Substitute
Intent monIntent = new Intent(this,dialog.class);
with
Intent monIntent = new Intent(<Name of this class>.this,dialog.class);
and
startActivity(monIntent);
with
<Name of this class>.this.startActivity(monIntent);
By <Name of this class> I mean the head class where you are writing your code.
By the looks of it, you are launching a new thread from within a try/catch block. This is bad practice as the thread can fail should an exception be being thrown.
Instead, declare a variable before the value, and assign to it on the line preceding the catch statement.
Also assign to it if the exception is raised, but a different value.
Then launch the thread outside the try/catch block, based on the successful evaluation of the variable.
Use callbacks to trap failed threads, not exceptions.
int x = 0;
try
{
/* Do some logic here */
x = 1; // we have success
}
catch(Exception e)
{
x = -1; // failure
}
if (x > 0)
{
Intent monIntent = new Intent(this,dialog.class);
startActivity(monIntent);
...
}
As a newbie I would like to state my view:-
Try putting some error messages to find out where the error is occurring. Also check the log file.
Example of try catch:-
try
{
//some code
//Toast message on success
Toast.makeText(this, R.string.msgStatusUpdatedSuccefully, Toast.LENGTH_LONG).show();
}
catch (TwitterException e)
{
//Toast message on failure
Toast.makeText(this, R.string.msgStatusUpdateFailed, Toast.LENGTH_LONG).show();
e.printStackTrace();
}
I would check if my imports are all fine for all the api's that I am using.
Also does your main public class looks like the following to resolve the undefined error:-
public class StatusActivity extends Activity implements OnClickListener{}
Related
In some cases I need to get data from misc intents and try to use sendOrderedBroadcast. But this call is async, and I don't know how to wait for it. I try:
onCreate(...)
{
// ...
sendOrderedBroadcast(...);
if (someResult!=null)
{
// Never executed
}
// ...
}
onButtonPressed(...)
{
if (someResult!=null)
{
// Often fires
}
}
I think I need to call something like Windows message loop
while (::PeekMessage(...))
{
GetMessage(...);
}
after sendOrderedBroadcast and before using someResult.
How I can do it? Or, is there more convenient and right way?
UPD More details
public class DetailsChecker extends BroadcastReceiver{
public void onReceive(Context context, Intent intent)
// ...
}
// ...
sendOrderedBroadcast(detailsIntent, null, new DetailsChecker(), null,
Activity.RESULT_OK, null, null);
Actually, it is possible. You can specify a handler that will receive the response in sendOrderedbroadcast, so you can receive it on another thread and block the UI thread while the broadcast is being processed. Something like that:
final Object monitor = new Object();
HandlerThread thread = new HandlerThread("blabla");
thread.start();
synchronized (monitor) {
Intent intent = new Intent("nanana");
context.sendOrderedBroadcast(intent,
null,
new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// mystuff
someResult = tagada;
synchronized(monitor) {
monitor.notify();
}
}
},
new Handler(thread.getLooper()),
Activity.RESULT_OK,
null,
null
);
try {
monitor.wait(2000); // timeout for receiving the result
} catch (InterruptedException e) {
}
}
thread.quit();
if (someResult != null) {
// gets executed
}
Of course, "blocking the UI thread is bad, m'kaaaaay". But I guess you know what you're doing.
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();
Is there any way to directly communicate with a WallpaperService from an Activity? It doesn't look like I can use the normal service communication classes because the onBind method is declared final in the WallpaperService class I'm extending. Worth noting that I'm referring to my WallpaperService not any.
Any workarounds if this isn't possible?
My solution was to use local sockets. I created an instance of a LocalServerSocket in the constructor of my wallpaper's Engine. Here's a quick implementation. Server runs on a separate thread and is directly tied to the lifecycle of MyEngine. The thread will stop when continueSocket is set to false. This happens onDestroy. Problem is that LocalServerSocket.accept() blocks until there's something to do. The workaround is to send a message to our own server so it will run through the loop again and check continueSocket (which is now false), closing the server. Check the closeSocketServer method. I have it running in onDestroy in the example but you might want to use it elsewhere like onSurfaceDestroyed and add your own sanity checks.
public class MyWallpaperService extends WallpaperService {
#Override
public Engine onCreateEngine() {
return new MyEngine();
}
private class MyEngine extends Engine {
private boolean continueSocket = true;
MyEngine() {
new Thread() {
#Override
public void run() {
try {
LocalServerSocket server = new LocalServerSocket("MyAddress");
Log.d("SERVER READY", "Server is ready.");
while(continueSocket) {
LocalSocket receiver = server.accept();
if(receiver != null) {
InputStream input = receiver.getInputStream();
byte[] data = IOUtils.toByteArray(input);
Log.d("GOT DATA", new String(data));
}
}
server.close();
} catch (IOException ex) {
Log.wtf("IOEXCEPTION", ex);
}
}
}.start();
}
#Override
public void onDestroy() {
closeSocketServer();
super.onDestroy();
}
private void closeSocketServer() {
continueSocket = false;
try {
LocalSocket socket = new LocalSocket();
socket.connect(new LocalSocketAddress("MyAddress"));
socket.getOutputStream().write(new byte[0]);
socket.getOutputStream().close();
socket.close();
} catch (IOException ex) {
//
}
}
}
}
And in my Activity it can be as simple as this...
try {
LocalSocket sender = new LocalSocket();
sender.connect(new LocalSocketAddress("MyAddress"));
String data = "Hello world!";
Log.d("SENT DATA", data);
sender.getOutputStream().write(data.getBytes());
sender.getOutputStream().close();
sender.close();
} catch (IOException ex) {
Log.wtf("IOEXCEPTION", ex);
}
Logcat ends up looking like this:
D/SERVER READY﹕ Server is ready. (when the wallpaper starts up)
D/SENT DATA﹕ Hello world! (when the activity sends data)
D/GOT DATA﹕ Hello world! (when the wallpaper gets the data)
In your WallpaperService onCreateEngine:
IntentFilter intentFilter = new IntentFilter("your.package.your.action");
MyBroadcastReceiver mReceiver = new MyBroadcastReceiver(mRenderer);
LocalBroadcastManager.getInstance(getApplicationContext())
.registerReceiver(mReceiver, intentFilter);
In mRenderer's class:
public void receiveCommand(int i) {
Log.d("got", String.valueOf(i));
}
Receiver class:
public class MyBroadcastReceiver extends BroadcastReceiver {
private final MyRenderer _mRenderer;
public MyBroadcastReceiver(MyRenderer mRenderer) {
_mRenderer = mRenderer;
}
#Override
public void onReceive(Context context, Intent intent) {
_mRenderer.receiveCommand(intent.getExtra("msg", -1));
}
}
Now call from activity:
Intent in = new Intent();
in.setAction("your.package.your.action");
in.setExtra("msg", 42);
LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(in);
I refactoring my threads in order to avoid memory leaks, and I got 2 errors regarding handler and startActivityForResult being called from within the thread ( dealing with GoogleDrive)
I have in my DownloadActivity :
public class DownloadActivity extends Activity {
....
private void getFolderId(){
getFolderIdThread = new GetFolderIdThread();
getFolderIdThread.start();
}
private static class GetFolderIdThread extends Thread {
private Boolean mRunning = false;
#Override
public void run() {
mRunning = true;
fResultList = new ArrayList<File>();
Files f1 = mService.files();
Files.List request = null;
aFolderId = null;
do {
try {
request = f1.list();
String aQuery = "'root' in parents and mimeType='application/vnd.google-apps.folder' and title='"+ aFolderName + "'";
request.setQ(aQuery);
FileList fileList = request.execute();
fResultList.addAll(fileList.getItems());
request.setPageToken(fileList.getNextPageToken());
} catch (UserRecoverableAuthIOException e) {
startActivityForResult(e.getIntent(), REQUEST_AUTHORIZATION); <= THIS RAISES THE ERROR
} catch (IOException e) {
e.printStackTrace();
if (request != null){
request.setPageToken(null);
}
}
} while (request.getPageToken() !=null && request.getPageToken().length() > 0);
if (fResultList.size() == 0) {
Log.d(TAG, "cannot find the training folder at root level");
Message msg = handler.obtainMessage(); <= THIS RAISES THE ERROR
Bundle bundle = new Bundle();
bundle.putInt("msgKey", DownloadActivity.NO_TRAININGS_FOLDER);
msg.setData(bundle);
handler.sendMessage(msg); <= THIS RAISES THE ERROR
} else {
File folder = fResultList.get(0);
aFolderId = folder.getId();
getFolderContents(); <= THIS RAISES THE ERROR
}
}
public void close() {
mRunning = false;
}
}
I have the handler defined in my activity
Handler handler = new Handler() {
#Override
public void handleMessage(Message msg) {
...
}
}
and the onActivityResult
protected void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
switch (requestCode) {
case REQUEST_ACCOUNT_PICKER:
....
break;
}
}
what are my options to bypass this error ?
Your GetFolderIdThread class is static and a static nested class cannot reference non-static methods and fields in the instance of the outer class that created it. Such a nested class can only access static methods and fields in your Activity. Remove static from the class definition and I think your problem will resolve.
You also need to post your call to startActivityForResult on the UI thread. Of course you should be able to use your handler for that, something like:
handler.post(new Runnable()
{
public void run()
{
startActivityForResult(e.getIntent(), REQUEST_AUTHORIZATION);
}
});
Make sure your thread can gracefully complete as well when you do that because it will continue to run.
I am trying to start an activity after n seconds with a handler. The application was crashing on the startActivity call, so I put the handler code in my application's onCreate, and it is still crashing (which makes me think that the error comes from me not using startActivity well) :
#Override
public void onCreate(){
String roomName = this.getSettingValue(R.string.PREFERENCES_ROOM_NAME, "");
Room room;
try {
room = this.getRoomWithName(roomName);
} catch (ReservatorException ex) {
Toast err = Toast.makeText(this, ex.getMessage(),
Toast.LENGTH_LONG);
err.show();
return;
}
Intent i = new Intent(this, RoomActivity.class);
i.putExtra("room", room);
this.startActivity(i);
}
Strange thing is that this work when called from a view, by using exactly the same code, but different context :
Intent i = new Intent(getContext(), RoomActivity.class);
// ...
I am pretty new to Android ... so there may be information missing in that question, or I might even be trying to do something completely stupid who knows ?
EDIT
Link to the stacktrace : http://pastebin.com/vh2QC3xz
EDIT2
Here is the handler version of my code (so what I am trying to do in the end) :
public class ReservatorApplication extends Application {
private GoToFavouriteRoom goToFavouriteRoomRunable;
class GoToFavouriteRoom implements Runnable {
ReservatorApplication app;
public GoToFavouriteRoom(ReservatorApplication anApp){
app = anApp;
}
#Override
public void run() {
String roomName = app.getSettingValue(R.string.PREFERENCES_ROOM_NAME, "");
Room room;
try {
room = app.getDataProxy().getRoomWithName(roomName);
} catch (ReservatorException ex) {
Toast err = Toast.makeText(app, ex.getMessage(),
Toast.LENGTH_LONG);
err.show();
return;
}
RoomActivity.startWith(app, room);
}
}
private final ReservatorAppHandler handler = new ReservatorAppHandler();
class ReservatorAppHandler extends Handler{
#Override
public void handleMessage(Message msg){
return;
}
}
#Override
public void onCreate(){
String serverAddress = getSettingValue(R.string.PREFERENCES_SERVER_ADDRESS, "mail.futurice.com");// TODO: change to mail.futurice.com before delivery
proxy = new SoapDataProxy(serverAddress);
// proxy = new DummyDataProxy();
proxy = new CachedDataProxy(proxy);
addressBook = new FumAddressBook();
try {
addressBook.prefetchEntries();
} catch (ReservatorException e) {
// TODO: DIE!
}
goToFavouriteRoomRunable = new GoToFavouriteRoom(this);
handler.postDelayed(goToFavouriteRoomRunable, 20000);
}
Ok ... I finally solved my problem, mainly thanks to #Drax
Apparently, you just can't start an activity from an application ... you need an instance of an activity. So :
public class ReservatorApplication extends Application {
#Override
public void onCreate(){
Intent i = new Intent(this, RoomActivity.class);
this.startActivity(i);
}
}
Is just not valid, and causes a RunTimeException ...
As far as crashing is concern when you start activity in handler with "this". it will take handler's context. and when you do getContext() it will take activity context.
Intent i = new Intent(YourActivityName.this, RoomActivity.class);
or
Intent i = new Intent(getBaseContext(), RoomActivity.class);
It`s hard to answer without seeing the stack trace from logcat, but I found that sometimes you need to pass the application context to the a new Intent before starting an Activity.
Try this line:
Intent i = new Intent(getApplicationContext(), RoomActivity.class);