Activity terminating abruptly without any exception - android

I have an Activity that sometimes terminates abruptly but without any exception being reported or logged. The Activity just ends suddenly and the app returns to the previous Activity in the stack.
I'm using ACRA (http://code.google.com/p/acra/) to capture and report errors, and it works well for all other errors in the app, but in this one case it does not detect any exception having been thrown. Nor is anything reported in Logcat.
It always happens at the same "place" in the app, when the user takes a certain action, but it is very intermittent and I've yet to make it happen while attached with the debugger.
Are there any other options (besides ACRA and Logcat) for determining what is happening to the Activity? Or is this something in the world of Android Activities that is "known?"
If it matters, this Activity is doing Bitmap manipulation and saving; I've had to take steps to avoid potential out of memory errors; but I was getting ACRA reports of OOM exceptions when they did occur, so I don't think this is due to OOME.
At the point where it seems to fail, the Activity creates an AsyncTask and executes it. Here's the code for the AsyncTask (ActivityAsyncTask is a really simple super class; EditPhotoEctivity is the one that is dying without an exception, sometime during the creation or execution of this task):
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.IOException;
import org.apache.commons.io.FileUtils;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.media.MediaScannerConnection;
import android.media.MediaScannerConnection.MediaScannerConnectionClient;
import android.net.Uri;
import android.view.View;
public class CompositeAndSavePictureTask extends ActivityAsyncTask<File, Void, Uri>
implements MediaScannerConnectionClient {
public static final String FILE_EXTENSION = ".jpg";
private static final int COMPRESSION_QUALITY = 100;
private File file;
private Uri mSavedImageUri;
private MediaScannerConnection mMediaScannerConnection;
public CompositeAndSavePictureTask(EditPhotoActivity owningActivity) {
super(owningActivity);
mMediaScannerConnection = new MediaScannerConnection(owningActivity, this);
}
#Override
protected EditPhotoActivity getOwner() {
return (EditPhotoActivity) super.getOwner();
}
#Override
protected void onPreExecute() {
getOwner().toggleControlsVisibility(false);
}
#Override
protected Uri doInBackground(File... params) {
file = params[0];
Bitmap picture = null;
View mainContentView = getMainContentView();
try {
picture = captureBitmap(mainContentView);
saveBitmap(picture);
} catch (Exception ex) {
LogUtils.logError(this, "Could not save photo", ex);
setError(ex);
return null;
} finally {
cleanUpCapture(mainContentView, picture);
}
try {
mMediaScannerConnection.connect();
synchronized (mMediaScannerConnection) {
mMediaScannerConnection.wait();
}
} catch (InterruptedException ex) {
LogUtils.logInfo(this, "MediaScannerConnection was interrupted during scan.");
setError(ex);
}
return mSavedImageUri;
}
protected Bitmap captureBitmap(View mainContentView) throws Exception {
mainContentView.setDrawingCacheEnabled(true);
return mainContentView.getDrawingCache();
}
protected void cleanUpCapture(View mainContentView, Bitmap capturedBitmap) {
mainContentView.setDrawingCacheEnabled(false);
if (capturedBitmap != null) {
capturedBitmap.recycle();
}
}
protected void saveBitmap(Bitmap bitmap) throws IOException {
BufferedOutputStream outStream = null;
try {
outStream = new BufferedOutputStream(FileUtils.openOutputStream(file));
bitmap.compress(CompressFormat.JPEG, COMPRESSION_QUALITY, outStream);
} finally {
try {
if (outStream != null) {
outStream.close();
}
} catch (IOException ex) {
LogUtils.logError(this, "Could not close output stream", ex);
}
}
}
#Override
protected void onPostExecute(Uri savedFileURI) {
getOwner().toggleControlsVisibility(true);
getOwner().onSaveResult(savedFileURI);
}
public void onMediaScannerConnected() {
mMediaScannerConnection.scanFile(file.getPath(), null /* mimeType */);
}
public void onScanCompleted(String path, Uri uri) {
mMediaScannerConnection.disconnect();
mSavedImageUri = uri;
synchronized (mMediaScannerConnection) {
mMediaScannerConnection.notify();
}
}
}
See also view.getDrawingCache() only works once, which has some relation but is a slightly different scenario.
Any and all ideas are welcomed.

I had a similar problem before. I was trying to open a file for reading, but instead of typing the complete address which was "/sdcard/something.txt", I gave it the wrong path (just "something.txt") without the sdcard part. After a lot of pain I have discovered that if you want the program to open something that is not really there, the activity just ends whitout any notice (to to console, to logcat etc. ). As it won't send back an error, it won't go on the "catch" branch.
So, I would suggest checking the file opperations.
Disclaimer: I know for sure that this causes this kind of behavior when trying to open the wrong path using the ndk and native code, but I suppose it would be the same if you do this mistake from in java code.

Please forgive the newbie comment, but if it's terminating without a Exception, you may be catching it somewhere and the program is continuing on it's merry way, but in an invalid state.

Related

SafetyNet.listHarmfulApps() does not run on emulator

While I have seen multiple posts and blogs that it doesn't work on the emulator, I've also seen blogs stating that we can do testing on emulators which are equipped with Google Play Services. We have such emulators and I've setup one such emulator ('Play Store enabled emulators)'). Is that the correct assumption? Can I test SafetyNet API integration with such an emulator?
It runs Android 8.1.
My code is as follows (ignore silly mistakes, the code compiles in my laptop. I've just edited some parts to maintain my company's confidentiality).
In this code, the following logs print into my logcat:- About to get harmful apps and Enabled app verification. But no other log statement from this class prints. Does anyone know why?
package some.kindof.package;
import android.content.Context;
import com.google.android.gms.common.api.ApiException;
import com.google.android.gms.common.api.CommonStatusCodes;
import com.google.android.gms.safetynet.SafetyNetClient;
import com.google.android.gms.safetynet.SafetyNetStatusCodes;
import com.google.android.gms.safetynet.SafetyNetApi.HarmfulAppsResponse;
import com.google.android.gms.safetynet.SafetyNetApi;
import com.google.android.gms.safetynet.HarmfulAppsData;
import com.google.android.gms.tasks.Task;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.OnFailureListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class HarmfulAppsDetector {
private static final Logger LOGGER = LoggerFactory.getLogger(HarmfulAppsDetector.class);
private HarmfulAppsResponseParser parser;
public boolean checkHarmfulApps(final SafetyNetClient safetyNetClient) throws Exception {
try {
LOGGER.info("About to get harmful apps"); //This prints
try {
safetyNetClient.enableVerifyApps();
} catch (Throwable e) {
LOGGER.error("Could not enable app verification");
System.exit(0); //Assume app will exit
}
LOGGER.info("Enabled app verification"); //This prints
//Check that verify apps is enabled
try {
safetyNetClient
.isVerifyAppsEnabled()
.addOnCompleteListener(new OnCompleteListener<SafetyNetApi.VerifyAppsUserResponse>() {
#Override
public void onComplete(Task<SafetyNetApi.VerifyAppsUserResponse> task) {
LOGGER.info("Verified that app verification is enabled or not? See right below:-");
LOGGER.info("See this:- " + task.getResult().isVerifyAppsEnabled());
}
});
} catch (Throwable e) {
LOGGER.error("Error checking whether app verification is enabled", e);
}
//List harmful apps using Google's SafetyNet APIs
safetyNetClient
.listHarmfulApps()
.addOnCompleteListener(new OnCompleteListener<HarmfulAppsResponse>() {
#Override
public void onComplete(Task<HarmfulAppsResponse> harmfulAppsResponseTask) {
LOGGER.info("Task is over.");
if (harmfulAppsResponseTask.isSuccessful()) {
LOGGER.info("Was able to hit Google and get response.");
HarmfulAppsResponse result = harmfulAppsResponseTask.getResult();
LOGGER.info("Response is:- " + result);
boolean harmfulAppsExist = parser.doHarmfulAppsExist(result);
if(harmfulAppsExist) {
//Blah do something here
}
} else {
LOGGER.error("An error occurred. " +
"Call isVerifyAppsEnabled() to ensure " +
"that the user has consented.");
}
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(Exception e) {
LOGGER.error("Task exception", e);
}
});
//Calling listHarmfulApps is now over
return true; //Just for testing, have to parse output and return that when the code actually works
} catch (Throwable e) {
LOGGER.error("Error occurred using Google for verifying harmful apps", e);
throw e;
}
}
}
Why do the async parts of the code, calls to isVerifyAppsEnabled() and listHarmfulApps(), not seem to even execute?

android studio: java.lang.RuntimeException: An error occured while executing doInBackground()

i'm trying to make an app by using calimero library for KNX. In my app, i use some buttons, switches, togglebuttons, etc to switch on/off the lights.
With 'Button', everything works well. I can switch on/off a light or open/close curtains.
private class button9OnClickListener implements View.OnClickListener {
public void onClick(View view){
try {
falseTask dt = new falseTask();
String adr = "5/1/0";
dt.execute(adr);
} catch (Exception e) {
}
}
}
But when i use 'Switch' with either OnClickListener or OnCheckedChangeListenser, it crash.
private class switch1OnCheckedChangeListener implements CompoundButton.OnCheckedChangeListener {
public void onCheckedChanged(CompoundButton compoundButton, boolean isChecked) {
if(compoundButton.isChecked()) {
try {
trueTask dt = new trueTask();
String adr = "5/4/6";
dt.execute(adr);
} catch (Exception e) {
e.printStackTrace();
}
} else {
try {
falseTask dt = new falseTask();
String adr = "5/4/6";
dt.execute(adr);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
the problem is below:
uncaughtException java.lang.RuntimeException: An error occured while executing doInBackground()
and here's my doInBackground
protected String doInBackground(String...strings){
String adr = strings[0];
try {
final InetSocketAddress localEP = new InetSocketAddress(InetAddress.getByName(hostip), 0);
final InetSocketAddress remoteEP = new InetSocketAddress(remoteip, knxServerPort);
knxLink = new KNXNetworkLinkIP(KNXNetworkLinkIP.TUNNEL, localEP, remoteEP, true, TPSettings.TP1);
pc = new ProcessCommunicatorImpl(knxLink);
pc.write(new GroupAddress(adr), true);
knxLink.close();
}
catch (final KNXException e) {
}
catch (final UnknownHostException e) {
}
return null;
}
i'm new to java and android programming. Can you help with this problem? i can't understand why this work for 'button' but not for 'switch'.
Thank you in advance
UPDATE
I copy my code and try with eclipse. Everything work fine. I can switch on/off the light i want and there is no error.
With android studio, it did not work. Someone know the reason?
I tried with ToggleButton and Switch in Eclipse. All work good. I put exactly what I used in android studio. I copy all the code without any change. Can't understand the problem.
Finally I find the problem. I use 2 Bundle in the MainActivity and I use these 2 Bundle in doInBackground for my AsyncTask in the SecondActivity. But I just pass on the first Bundle to the SecondActivity and I forget to pass on the second Bundle. So I got error while executing doInBackground() What foolish mistake I have made...

ParseFile.cancel() not working - file keeps being downloaded

I'm using parse.com Android SDK to manage some images in my app. Is cancel() the only way to stop a transaction with the parse.com server?
Minimal example:
final ParseFile file = ... ;
file.getDataInBackground(new GetDataCallback() {
//called when loading is done
#Override
public void done(byte[] bytes, ParseException e) {
Log.e(TAG, String.valueOf(bytes == null));
}
}, new ProgressCallback() {
//called to notify progress
#Override
public void done(Integer integer) {
Log.e(TAG, String.valueOf(integer));
if (integer > 50) {
file.cancel();
}
}
});
I would expect that loading stops after the 50% is reached, but it does not. My log in this situation would be:
1
2
3
....
49
50
51
....
98
99
100
true
The only difference from times you call cancel() and times you don't, is that if you canceled the byte[] result is null. But that is really secondary, the point here is that file keeps consuming bandwidth and, moreover, overlaps with future downloads, slowing things down.
Is there any way to really stop ParseFile loading? Do you see any workaround, like stopping its thread? Maybe something using the underlying bolts framework? Using my own async task?
Example: continueWhile() method might be useful, but I can't figure out how to use it.
I would like to know the reason for the downvote, maybe the common title? That is really what I am experiencing: ParseFile.cancel() is not working. And it should, according to the official docs.
Comments suggest that I should simply call break. While I don't think it would work, I might clarify that the code I posted was just a minimal, concise working example providing both context and the issue. I don't want to cancel() the transaction from inside the progress callback; I want to call parseFile.cancel() from everywhere. I put in the progress callback to show that, while it should stop, it doesn't.
Edit This is what I'm really trying to do. I have tried different ways but this is it.
ParseFile currentFile;
public void setFile(ParseFile file) {
if (currentFile != null) {
currentFile.cancel();
}
currentFile = file;
currentFile.getDataInBackground(new GetDataCallback() {
...
}, new ProgressCallback() {
... // logs
});
}
With such code and say, two big images to download, things go like:
//calling setFile(file1)
1
2
3
...
20
21
22
//calling setFile(file2), thus also calling file1.cancel()
1
2
23 //file1 going on!
3
24
4
25
... //things get slower and this screws up progress bars and such.
TL;DR;
The only conclusion I can draw at this point is that there is a difference in our implementations that is causing cancel to fail for you.
EDIT: this seems to be the case as seen in your own answer. The difference being SDK versions. https://stackoverflow.com/a/32034500/2680506
Full Answer:
The description for the cancel() method:
"Cancels the current network request and callbacks whether it's uploading or fetching data from the server."
I was curious about this so I did a little testing of my own. I took my app, made a ParseFile from the bytes of an image and attempted to save it in the background.
Test 1
Bitmap file = BitmapFactory.decodeResource(context.getResources(), R.drawable.background);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
file.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] byteArray = stream.toByteArray();
final ParseFile myTestFile = new ParseFile(byteArray);
myTestFile.saveInBackground(new SaveCallback(){
#Override
public void done(ParseException e) {
if(e == null)
{
Log.i(null, "Done saving.");
}
}
}, new ProgressCallback(){
#Override
public void done(Integer progress) {
Log.i(null, "Progress at " + progress + "%");
if(progress > 50)
{
myTestFile.cancel();
}
}});
//myTestFile.cancel();
Test 2
Bitmap file = BitmapFactory.decodeResource(context.getResources(), R.drawable.background);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
file.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] byteArray = stream.toByteArray();
ParseFile myTestFile = new ParseFile(byteArray);
myTestFile.saveInBackground(new SaveCallback(){
#Override
public void done(ParseException e) {
if(e == null)
{
Log.i(null, "Done saving.");
}
}
}, new ProgressCallback(){
#Override
public void done(Integer progress) {
Log.i(null, "Progress at " + progress + "%");
}});
myTestFile.cancel();
The results for Test 1 were similar to what you describe, because the file is very small I only got one progress callback at 100% but then it also invoked the SaveCallback.
In Test 2, however, the cancel() method appears to function as one would expect, resulting in no logs or callbacks.
It appears that cancel fails to work because you are calling it from the Callback. This is consistent with the fact that you continue to see ProgressCallbacks after you originally cancel in your own tests.
EDIT
I just uploaded an image and tested cancel for myself, in the onCreate() method of my activity I have this code:
ParseQuery<ParseObject> newQuery = ParseQuery.getQuery("TestObject");
newQuery.findInBackground(new FindCallback<ParseObject>(){
#Override
public void done(List<ParseObject> objects, ParseException e)
{
ParseFile myTestFile = objects.get(0).getParseFile("file");
myTestFile.getDataInBackground(new GetDataCallback()
{
#Override
public void done(byte[] data, ParseException e)
{
Log.i(null, "Download finished");
}
},
new ProgressCallback()
{
#Override
public void done(Integer percentDone)
{
Log.i(null, "Download at " + percentDone + "%");
}
});
//myTestFile.cancel();
}});
When cancel is commented, It will enter the GetDataCallback with a populated byte array. When cancel is not commented no call back will occur. Strangely enough the ProgressCallback is never called although it says it is guaranteed. However, it still appears that cancel is working for me.
Looks like this was a real bug, now fixed. I used to stay with the v1.9.2 release; today I updated to v1.10.0 and everything works fine.

Codenameone when I read the qrCode uzing Zxing on Android the application goes back to 'init' and 'start'

I am using Codenameone and ZXing to read a QRCode. When I call the Scanner, my mobile opens the QRCode reader application and I get to read the QRCode except that when android takes me back to my app it goes through init then start statuses. Which moves me back to the login form of my application instead of continuing filling the form that I was in.
Any help on what to do to stay in the same form? Is there something I'm doing wrong? Thanks in advance.
EverproX.addMessage("Before Scan\n");
CodeScanner.getInstance().scanQRCode(new ScanResult() {
public void scanCompleted(String contents, String formatName, byte[] rawBytes) {
EverproX.addMessage("Scan Completed "+contents);
}
public void scanCanceled() {
EverproX.addMessage("Scan Cancelled");
}
public void scanError(int errorCode, String message) {
EverproX.addMessage("Scan Error "+errorCode+" "+message);
}
});
EverproX can be seen as a log class.
By analyzing our log we can say that as soon as we call the CodeScanner.getInstance().scanQRCode() the application is called for 'Destroy'. Then after the scanning is done it goes again through the init and start. It never goes into the scanComplete scanCanceled or scanError Callbacks.
Is it normal that the App is destroyed upon call of CodeScanner? Many thanks.
Inside your codenameone project, you should find a class named (for example MyApp.java) based on your app's name, modify the code to read something like similar to this:
public class MyApp {
private Form current;
public void init(Object context) {
// Pro users - uncomment this code to get crash reports sent to you automatically
Display.getInstance().addEdtErrorHandler(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
evt.consume();
Log.p("Exception in AppName version " + Display.getInstance().getProperty("AppVersion", "Unknown"));
Log.p("OS " + Display.getInstance().getPlatformName());
Log.p("Error " + evt.getSource());
Log.p("Current Form " + Display.getInstance().getCurrent().getName());
Log.e((Throwable) evt.getSource());
Log.sendLog();
}
});
}
public void start() {
if (current != null) {
current.show();
return;
}
new StateMachine("/theme");
}
public void stop() {
current = Display.getInstance().getCurrent();
}
public void destroy() {
current = null;
}
}

Android not waiting for DB response before finishing statement

I have an interesting problem that I've never run into in programming before. I have an onClickListener that does a lot of username and password checks (makes sure the username is proper length, not taken, etc). I'm using MobDB, and I was using a conditional statement that would return a row if the username already existed. The problem is that the Listener skips the DB and goes to the final check that, if everything works, posts a new username and password to my DB. How can I make it wait for a response from the DB before skipping to the last check?
Here is the relevant code:
usernamecheck3 = true;
MobDB.getInstance().execute(APP_KEY, null, rd, null, false, new MobDBResponseListener() {
#Override public void mobDBSuccessResponse() {
usernamecheck3 = false;
Log.e("mobdbSuccess:", "success");
}
#Override public void mobDBResponse(Vector<HashMap<String, Object[]>> row) {
}
#Override public void mobDBResponse(String jsonObj) {
/*Log.e("mobdbSuccess:", "jsonObj");
Log.e("mobdbSuccess:", jsonObj);
JSONObject mainObject;
try {
mainObject = new JSONObject(jsonObj);
// need to parse the json object.
} catch (JSONException e1) {
e1.printStackTrace();
} */
}
#Override public void mobDBFileResponse(String fileName, byte[] fileData) {
//get file name with extension and file byte array
}
#Override public void mobDBErrorResponse(Integer errValue, String errMsg) {
usernamecheck3 = false;
Log.e("doesnt", "work");
}
});
if(usernamecheck3 == false){
Toast.makeText(getApplicationContext(), "Username is taken, please choose another", Toast.LENGTH_SHORT).show();
}
Basically the check always returns true, and then logcat will say mobdbSuccess: success, which should have set the Bool to false.
Thanks.
MobDBResponseListener is executing on a different thread. What happens here is that the processing is split, while a thread is doing the query, the main thread on which you added the listener, skips right ahead to the validation. Your best bet is to place the validation inside the MobDBResponseListener, on the mobDBResponse method.
Try to debug your code and calls, the Listener may be using an async task. If so, you may do anything you please from the response method, as it will be executing in the main thread again. Otherwise, you should look at solutions that handle threaded execution like Handlers

Categories

Resources