How to keep activity on Force Close? - android

I have this piece of code that's really prone to errors so I wrapped it with try{}catch statement. I don't want to go back to the previous activity, I just want it to stay on the current activity so that the user can edit whatever is wrong with them.
How do I implement this?
try{
orgi.insertOrThrow(tableName, null, values);
Toast.makeText(this, "You have successfully created a new profile!", 2).show();
gotoProfileList();
Log.e(getClass().getSimpleName(),"Successfully added to database");
}catch(SQLiteException se){
Log.e(getClass().getSimpleName(), "Database connection failed!" + se);
//Stay in this activity...
}finally{
if (orgi != null){
orgi.close();
}
}
Forget it, I was able to solve my own problem by showing up an alertDialog that tells the user about the error. Thanks anyways. :)
try{
orgi.insertOrThrow(tableName, null, values);
Toast.makeText(this, "You have successfully created a new profile!", 2).show();
gotoProfileList();
Log.e(getClass().getSimpleName(),"Successfully added to database");
}catch(SQLiteException se){
Log.e(getClass().getSimpleName(), "Database connection failed!" + se);
displayError();
//stayInThisActivity();
}finally{
if (orgi != null){
}
public void displayError(){
AlertDialog.Builder error = new AlertDialog.Builder(this);
error.setMessage("That profile name already exists, try another one.").setCancelable(false).setPositiveButton("Yes",new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
AlertDialog alert = error.create();
alert.setTitle("Error");
alert.show();
}

Force closes are caused by uncaught exceptions. You only catche the SQLiteException in your example. You need to catch other Exceptions and handle them gracefully.
Now a classical cause for FCs are use of null objects and resulting NullPointerExceptions. You shouldn't catch these. Your application will be too messed up to continue correctly in many cases. You can read more here: Catch_NullPointerException
In any case, you should run the app in the emulator or on a connected phone, cause the crash and then log into the device log with DDMS or "adb logcat". See the backtrace, find the error, fix it. If your app is in the market, the market will list backtraces send by your users devices for you. If you do not (yet?) user Android Market, you can have your app remotely log stacktraces through a PHP script running on a web server with android-remote-stacktrace
BTW it is better to pass the Exception as third parameter to the Log methods instead of concatenating the second parameter to the exception (thereby implicitly calling toString()). In your example that would be:
Log.e(getClass().getSimpleName(), "Database connection failed!", se);

Related

How to call an Android app's method remotely?

I'm working on a project that improves Automation Test for Android's App. What I want to do is very "easy": I have this very simple SIP Client with a basic UI and developed just reading the API guides on the android developer website (https://developer.android.com/guide/topics/connectivity/sip.html) that receives and makes SIP calls.
I need to control remotely this app from my PC, connected at the same local network or the same wifi, by sending commands or similar (without interact with the phone) to the app itslef running normally on my phone.For a specific example I posted the method initiateCall() that calls sipAddress(in the app, sipAddress is taken from a Text Box), what I want to do is:
Starting the app on my phone
calling the method initiateCall() from my pc giving a sipAddress as a parameter (I must not use the UI from the app running, that's why I need to give the sipAddress)
check if an outgoing call starts from the app running on my phone
I thought that the solution must be something about web-services,but I don't have any better ideas and i don't know how to start and where to start solving this problem,that's why i need you help.
public void initiateCall() {
try {
SipAudioCall.Listener listener = new SipAudioCall.Listener() {
// set up the listener for outgoing calls
#Override
public void onCallEstablished(SipAudioCall call) {
call.startAudio();
call.setSpeakerMode(true);
updateStatus(call, 2);
}
#Override
public void onCallEnded(SipAudioCall call) {
updateStatus("Call End");
}
};
call = manager.makeAudioCall(me.getUriString(), sipAddress,
listener, 30);
} catch (Exception e) {
Log.i("WalkieTalkieActivity/InitiateCall",
"Error when trying to close manager.", e);
if (me != null) {
try {
manager.close(me.getUriString());
} catch (Exception ee) {
Log.i("WalkieTalkieActivity/InitiateCall",
"Error when trying to close manager.", ee);
ee.printStackTrace();
}
}
if (call != null) {
call.close();
}
}
}
You could do it REST API style. You would need to set up a minimalistic webserver.
If you access for example the url phoneip/ctrl/makecall?number=yournumber a serverside method us called if set up correctly. Then you can call you method and use the GET or POST variables as arguments.
You would have to look into Java Webserver Libraries/Frameworks. You can pick a lightweight one for that purpose. For example this one.
You could then also add security features (authentification to protect it) quite easily.
Example with sparkjava
import static spark.Spark.*;
....
get("/ctrl/makecall", (request, response) -> {
String phonenum = request.queryParams("number"); //may not be accurate; you have to determine the GET variable called "number" in that case; you can rename it; see docs!!!
//call your method with proper arguments
});

How to join an active session running on a Chromcast device

I have to Users (User A and B) and one Chromecast device (C1).
User B starts a stream on C1.
User A connects to C1
Now User A should be able to control the stream running on C1. But every time I want to start a session the running stream on C1 is shut down and the receiver app is restarting.
Is there a way to join an active session? Or is that a job which has to be done by the web app running on the Chromecast device?
EDIT:
my sender app is a native Android app
Thanks!
You should have a look to the TicTacToe application. I think it does exactly that where 2 players can join the same game :
https://github.com/googlecast/cast-android-tictactoe
Hope this helps.
JN
What sort of sender are you using? Is it a native app (i.e. using Android or iOs SDK on a mobile device) or the sender is a chrome app?
On the receiver, you create a Receiver object and a ChannelHandler. You use the receiver to generate a ChannelFactory which you then pass to the ChannelHandler. The ChannelHandler now handles the creation of channels on the receiver. You will want to add an EventListener to the handler to listen to messages. Based on those messages you can do various things.
receiver = new cast.receiver.Receiver(YOUR_APP_ID, [YOUR_PROTOCOL], "", 5);
var dashHandler = new cast.receiver.ChannelHandler(YOUR_PROTOCOL);
dashHandler.addChannelFactory(receiver.createChannelFactory(YOUR_PROTOCOL));
dashHandler.addEventListener(cast.receiver.Channel.EventType.MESSAGE, onMessage.bind(this));
receiver.start();
...
onMessage = function (e) {
var message = e.message;
switch (message.type) {
...
}
}
On the sender, after a session is created you will want to send a check status message to the receiver to see if there are already channels attached. You can do this via your MessageStream and your receiver needs to respond in such a way that the MessageStream gets its status updated. You check that status to see if there are channels. If there are you can start listening to updates for your receiver. If not you can send a load event to the receiver to start your activity.
MediaProtocolCommand cmd = mMessageStream.requestStatus();
cmd.setListener(new MediaProtocolCommand.Listener() {
#Override
public void onCompleted(MediaProtocolCommand mPCommand) {
if (mMessageStream.getState() == 'channelsExist') {
//Start New Activity
} else {
//Join Existing Activity
}
#Override
public void onCancelled(MediaProtocolCommand mPCommand) {
}
});
This is kind of a vague response, but it could be more specific if I knew what you were trying to do. My app is using Google's RAMP protocol to play videos so my MessageStream and all it's messages are already defined. If you're doing something different, you need to create your own MessageStream.
Sorry for the late answer, but I figured it out by myself: It wasn't such complicated at all
I started the an Application like this
try {
mSession.startSession(applicationName,applicationArgs);
} catch (IllegalStateException e) {
Log.e(getClass().getSimpleName(), e.getMessage(), e);
} catch (IOException e) {
Log.e(getClass().getSimpleName(), e.getMessage(), e);
}
But it seems, that the MimeData applicationArgs is not needed at all. By removing the arguments and starting the session like below it works really fine!
try {
mSession.startSession(applicationName);
} catch (IllegalStateException e) {
Log.e(getClass().getSimpleName(), e.getMessage(), e);
} catch (IOException e) {
Log.e(getClass().getSimpleName(), e.getMessage(), e);
}
I hope this works for you too!

Toast in an AlertDialog in a try/catch

I am trying to have an error message when the use enters a number for an item that cannot be deleted in the database. I have gotten it so the user can delete an item from the database and I think used the try catch to avoid a run time error if the number does not exist. What I am trying to do is have a toast pop up when the user enter an invalid number. I have already looked at other similar postings on stack and have not have any luck. Here is my code. If you need me to post more code let me know.
public void onClick(DialogInterface dialog, int which) {
try {
String id=idNum.getText().toString();
long primaryId=Long.parseLong(id);
info.open();
info.deleteInspection(primaryId);
info.close();
dbInfo();
} catch(Exception e) {
Toast.makeText(getApplicationContext(), "Number not found", Toast.LENGTH_SHORT).show();
}
}
You could make your deleteInspection() method return a boolean value, telling wether or not a given id was deleted. Then check for it in your onClick method:
boolean result = info.deleteInspection(primaryId);
if(!result) {
Toast.makeText(getApplicationContext(), "Number not found", Toast.LENGTH_SHORT).show();
}
It's not about try/catch here, that you want to post "number not found"
the thing you need is the return the result from your Database that it found this id to delete or not
As Soren.Qvist said.
you need to return some value from your Database to your code (maybe -1, false, etc.) and check at it

Facebook with Android: unexpected NullPointerException

I have some code that connects my app to Facebook. When you log in you proceed to the next activity. If you are already logged in when you start the app you miss out the log in section. On the following page I want to be able to log out, every time I press logout I get a null pointer. Can anyone help?
My code for log out is:
private void logout() {
try {
facebookConnector.getFacebook().logout(getApplicationContext());
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
The code that is run when the app is started to check if the person has logged on is:
if (facebookConnector.getFacebook().isSessionValid()) {
Intent i = new Intent(facebook.this, facebook2.class);
startActivity(i);
finish();
}
A print screen of my error can be seen here:
Any help would be great. If you need more info please comment and I will provide asap.
facebookConnector.getFacebook() seems to return null

Should I remove e.printStackTrace() from my code before publishing

I was reading the the Android Publishing docs and they said to remove all Log calls from my code. I have some calls to e.printStackTrace() in my code that can be printed as part of the normal running of my program (ie. if a file does not exist yet).
Should I also remove these calls?
You shouldn't be using e.printStackTrace() directly anyway — doing so will send the info to the Android log without displaying which application (log tag) it came from.
As others have mentioned, continue to catch the Exception in question, but use one of the android.util.Log methods to do the logging. You could log only the message, but not the stack trace, or use verbose logging for the stack trace:
try {
Object foo = null;
foo.toString();
} catch (NullPointerException ex) {
Log.w(LOG_TAG, "Foo didn't work: "+ ex.getMessage());
Log.d(LOG_TAG, Util.stackTraceWriter(ex));
}
You should strip DEBUG or VERBOSE log messages from your production builds. The easiest way is to use ProGuard to remove Log.[dv] calls from your code.
If you allow an Exception to propagate up to the OS then the OS will log it and also pop up a Force Close window, killing your application. If you catch it, then you can prevent your application from being force closed.
If you want your users to have the ability to send you errors that they are getting, then I would log the stack trace. They can then send you the log via an app like Log Collector.
If you want to avoid the possibility of exposing your stack trace information to your users, then catch the exception and don't log it.
I would use Log class for message out put. For logs that you think are important to stay in the app - use Log.i
for errors warning - Log.e Log.w
For you debug Log.d - and that you can turnoff on base on if your application is in debug mode.
http://developer.android.com/reference/android/util/DebugUtils.html
Well printStackTrace() will log it into the OS, causing your andorid (or computer) app to terminate (force close), instead, do something like this:
public void nullPointerExceptionCauser()
{
try
{
Object example = null;
example.toString();
}
catch (Exception e)
{
Logger.log(Level.SEVERE, "Caught Exception: {0}", e.getStackTrace());
}
}
in my modest opinion (I'm not an Android developer)
It should be nice. I don't know the logging options for Android but I'm sure you have some configurable thing to output (or not) your traces.
And if you don't do printStackTrace() Android will not be doing the dirty work of ignoring it.
:)
It's only a good-feeling (style) thing.
If you want to be secure i.e. not allow anyone snooping to read exception logs you can do something like
private void hideExceptionsInReleaseMode()
{
final Thread.UncaughtExceptionHandler defaultHandler = Thread.getDefaultUncaughtExceptionHandler();
if(!BuildConfig.DEBUG)
{
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler()
{
#Override
public void uncaughtException(Thread thread, Throwable ex)
{
defaultHandler.uncaughtException(thread, new RuntimeException("Something went wrong :p"));
}
});
}
}
In order to use printStackTrace in a safer way I would use StringWrite and PrintWriter:
...
catch (final Exception e)
{
final StringWriter sw = new StringWriter();
final PrintWriter pw = new PrintWriter(sw);
e.printStackTrace(pw);
Log.e("TAG", sw.toString());
}
Or alternatively:
catch (final Exception e)
{
Log.e(TAG, Log.getStackTraceString(e));
}
Use this to remove the logs from release apk
if (BuildConfig.DEBUG) Log.d(TAG, "your meseage");

Categories

Resources