I always admired the way Android Studio operates in some aspects, like the ability to find out every thing that is not ok, like arrays that get declared and written, but never read, or functions that get never called.
The problem now is that I have an async function using along with the Parse SDK (Facebook Login) that seems just not understood by the IDE.
Button mFbParseLoginButton = (Button) findViewById(R.id.fbloginbutton);
final java.util.List<String> permissions = Arrays.asList("user_friends", "user_birthday", "user_hometown", "public_profile");
mFbParseLoginButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ParseFacebookUtils.logInWithReadPermissionsInBackground(LoginActivity.this, permissions, new LogInCallback() {
#Override
public void done(ParseUser user, ParseException err) {
if (user == null) {
Log.d("MyApp", "Uh oh. The user cancelled the Facebook login.");
} else if (user.isNew()) {
Log.d("MyApp", "User signed up and logged in through Facebook!");
// Create the user
regFacebookUser(user);
//registerFacebookUser(user);
} else {
Log.d("MyApp", "User logged in through Facebook!");
loginFacebookUser(user);
}
}
});
}
});
It just seems not to understand that this code potentially can call regFacebookUser and loginFacebookUser functions.
These buttons have been working for days of this app's development, and still do and receive the logs
06-03 15:30:54.460 1543-1543/xxxxxxxxxxxxx D/MyApp﹕ User logged in through Facebook!
But this is how actually Android Studio displays the code of regFacebookUser
If you know how Android Studio works, you'll know that when a method or a variable is grey, it means it's never used. Indeed it's the thing it says when I go hover every grey variable of this code.
At the right, in the scrollbar there are yellow squares everywhere around all the code for this. What can I do to resolve this bug?
I got Android Studio 0.9.9 and always been working fine. I wouldn't upgrade to the newer 1.2 to avoid incompatibility issues to the projects I'm working on. (When I had Eclipse the only upgrading of SDK messed up everything to me)
Related
I have a Unity Scene built with Cardboard SDK and exported as a library for Android. The library is used to play videos in cardboard mode on the android app. it's not the whole app, but a part in it. The rest of the android app is built with Kotlin and Java.
I have implemented that and all the functions work as expected, but, exiting the scene crashes the android.
We tried various ways to clear player prefs and even clear memory before closing the scene. But on android it always crashes. I have two android phones with android 9 and 10 for testing.
In the android app, I have made it such that as soon as the app crashes, I try to recover. My crash is that some lateinit var variables are destroyed. Their value becomes null and recovering the previous activity crashes it. So right after I exit the unity scene, I load the dereferenced variables back into memory and everything works again.
Note: I have tried using Application.Quit(); in unity, but it just closes the whole app. On the other hand, I only want to close the running scene
In unity [I call a function goBack in android part to close the app]:
public void GoToHome()
{
Pause();
Stop();
Resources.UnloadUnusedAssets();
PlayerPrefs.DeleteAll();
AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity");
jo.Call("goBack");
}
In App:
public void goBack()
{
UnityPlayer.currentActivity.finish();
finish();
loadDerereferencedVars();
}
This goes perfectly on android 9. On the other phone with android 10, after I close the scene, the app continues to function, but, there comes a message
When I click close app, the app continues to work.
I have checked the logs and there is a null pointer dereference cause for the crash in Unity Main >...
If you'd like to see the Unity Crash Log from LogCat in Android Studio
So, since the app is still running, I thought, it would be better to just hide the crash report and just let the user not know about this crash, but still report it.
I tried enclosing my app in Application and added a method to catch uncaughtException.
here is my application class:
public class MyApp extends Application {
private static final String TAG = "MyAPP";
#Override
public void onCreate() {
super.onCreate();
Thread.setDefaultUncaughtExceptionHandler(
new Thread.UncaughtExceptionHandler() {
#Override
public void uncaughtException (Thread thread, Throwable e) {
handleUncaughtException (thread, e);
}
});
}
/**
* Handles Uncaught Exceptions
*/
private void handleUncaughtException (Thread thread, Throwable e) {
// The following shows what I'd like, though it won't work like this.
Toast.makeText(getApplicationContext(), "Looks like I am having a bad day!", Toast.LENGTH_LONG).show();
Log.e("UncaughtException", "I found an exception!");
// Add some code logic if needed based on your requirement
}
}
Again, this works perfectly in Android 9 and I also got the error reported. However in the phone with android 10, I just get the crash report like the image above and no error is reported.
I want to know why the crash handling is not working and how can I fix it?
I would not finish the Activity you came from, instead just open a new intent (on UnityActivity). When you end this intent the app will come back to the last active Activity.
I will give you my script as an example:
public void sendJobToUnity(String fileName, boolean isNewJob){
//creates a new job. It exists inside the JobSelector Activity
isUnityLoaded = true;
//this is what you are looking for part1
Intent i = new Intent(JobSelector.this, MainUnityActivity.class); //same as (CurrentActivity.this, UnityActivity.this)
//those are how I send some data across the app. just ignore it
//i.putExtra("jobName", fileName);
//i.putExtra("isNewJob",isNewJob);
//i.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
startActivityForResult(i, 1); //this is what you are looking for part2
}
For closing it, in the MainUnityActivity Activity I have an override that Unity sends to Android in order to Unload the activity (not quit it completely cause you cannot load it again if you do it) like this:
#Override
protected void receiveJobAndUnloadUnity(String data){
saveCurrentJob(data); //saves the job it receives from Unity
mUnityPlayer.unload(); //this is what you are looking for part3
}
If you want to unload Unity from android you can put "mUnityPlayer.unload();" wherever you want, provided you have started the Activity the way I've shown you.
Note that "mUnityPlayer" is a default Unity variable and cannot be renamed
This question already has answers here:
Branch.io (Android SDK): 'only initialize Branch in the Launcher activity' and GDPR
(2 answers)
Closed 4 years ago.
I want my app to be GDPR compliant. It means that I want to avoid to launch any tool like Branch.io as long as the user did not give its consent.
My problem is that the Branch.io documentation https://docs.branch.io/pages/apps/android/ mentions that I have to put the following code in my launcher activity :
#Override
public void onStart() {
super.onStart();
// Branch init
Branch.getInstance().initSession(new Branch.BranchReferralInitListener() {
#Override
public void onInitFinished(JSONObject referringParams, BranchError error) {
if (error == null) {
Log.i("BRANCH SDK", referringParams.toString());
} else {
Log.i("BRANCH SDK", error.getMessage());
}
}
}, this.getIntent().getData(), this);
}
#Override
public void onNewIntent(Intent intent) {
this.setIntent(intent);
}
It is also mentioned in the doc :
Only initialize Branch in the Launcher activity
The app will open through the Launcher activity, where Branch will initialize and retrieve the deep link data from the link click.
So, I don't see how to make something GDPR compliant. Indeed, if this code really needs to be executed in the onStart of the launcher activity, I don't have time to execute it before the user gave its consent.
Is there any workaround?
In the same documentation, there is an explanation about how to disable tracking by Branch SDK, so your application is GDPR compliant, but still keep all the SDK features.
Here's the anchor to that section.
All you need to do is implement the following code right before calling the initSession():
Branch.getInstance().disableTracking(true);
You will need to build out the handling of this line based on whether the user gave a consent for tracking or not.
I unsuccessfully try to solve my Google Awareness Api Exception Problem for days now.
I do have implemented a Awareness Snapshot Client to resolve the current POI nearby for my context collection application. But unfortunately I always get the exception "com.google.android.gms.common.api.ApiException: 7508" without any results. I've also implemented a SnapshotClient for receiving current weather conditions and it works with good results. It's nearly the same code , but the one for Weather works fine and the one for Places don't.
I'm browsing the net for days now to solve this problem, but there is no information about that specific exception code and it's also not handled in the official android documentation.
Please help me out!!
My code is:
public String measure() {
if(checkPermission() && resultWasFetched){
resultWasFetched = false;
Awareness.getSnapshotClient(this.context).getPlaces()
.addOnSuccessListener(new OnSuccessListener<PlacesResponse>() {
#Override
public void onSuccess(PlacesResponse placesResponse) {
placeLikelihoods = placesResponse.getPlaceLikelihoods();
resultWasFetched = true;
Log.i(TAG, "detected: "+ placeLikelihoods);
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.e(TAG, "Could not detect places: " + e);
}
});
}
I'm new to stackoverflow, so sorry if there is something missing or a problem with anything else!
Check to make sure you have an API key for Google Maps.
You can get the api key and enable through the Google API Manager. Without it, you will not be authenticated to access maps. Places, you might imagine, runs off the back of Google Maps.
Cordova, Version 3.5.0-0.2.6
<body><script>
alert("documentready");
document.addEventListener("deviceready", function() {
alert("deviceready");
}, false);
</script></body>
I enter the app after deploying, I get 'documentready' and 'deviceready' alerted.
I leave the app with the back button.
I get 'documentready' only.
When I force-close the app with the taskmanager or re-deploy it, I get both alerts.
I want this behaviour to occur also after normal re-entering the app.
I would prefer a solution where there is no evidence left that the app has been opened before, after I leave it. Nothing restored from garbage collection etc. Ideally executing the same log as the force-close method from the task manager.
OK: I want, when I close my app via back button, that exactly the same happens, as when I open the task manager and force my app to close. Is this at least theoretically possible?
Alternatively, I would like the app, when left via back-button, to be in a 'hibernate-like' state, that if I re-enter it it behaves absolutely like it has never been left (call same logic as when the menu/home button is pressed).
QUESTION STILL OPEN - 50RS BOUNTY TO EARN
Add this to your mainActivity.java (whatever it is called in your project):
#Override
public void onBackPressed() {
finish();
}
I'm not sure why you'd want such behavior, but you can kill the app on back press (or on finish).
Calling android.os.Process.killProcess(android.os.Process.myPid()) is just like a forcing a stop from the task manager.
Add this to your CordovaActivity and it should kill everything without any remains:
#Override
public void onBackPressed() {
android.os.Process.killProcess(android.os.Process.myPid());
System.exit(0);
}
I've implemented the same thing, I used the backbutton event from cordova. You can find more about the backbutton event here: link. I can't find documentation about the app.exitApp() function but I do know it is only available for android and amazon-fireos.
See code snippet below, you only need to know when you want to exit, but you might know that from the document.location object or something. Hope it helps.
document.addEventListener("backbutton", function (evt) {
// replace this with some logic (maybe document.location) to now if you are on the main page or not
if (true) {
// Check if methods exists
if (typeof navigator.app !== "undefined" && typeof navigator.app.exitApp !== "undefined") {
evt.preventDefault();
navigator.app.exitApp();
}
} else {
history.back();
}
}, false);
This should work:
In my_app_dir->config.xml add
<preference name="KeepRunning" value="false" />
And below
document.addEventListener("deviceready", function() {...
add
document.addEventListener('backbutton', function() {
navigator.app.exitApp();
}, false);
Afterwards open cmd, go to your project folder and run cordova build android; cordova run --device android;
What works for me, the problem might be that the DOM is not ready when you add the event listener. And may be caused by a faster load due to the app being cached. Use a self executing function to add the event listener and you will be sure the DOM is loaded.
function domIsReady() {
alert('DOM is ready')
}
function deviceIsReady() {
alert('Device is Ready')
}
( function() {
if (document.readyState === "complete") {
domIsReady();
} else {
if (window.addEventListener) {
window.addEventListener('DOMContentLoaded', domIsReady, false);
} else {
window.attachEvent('onload', domIsReady);
}
};
document.addEventListener("deviceready", deviceIsReady, true);
}());
If my app crashes, it hangs for a couple of seconds before I'm told by Android that the app crashed and needs to close. So I was thinking of catching all exceptions in my app with a general:
try {
// ...
} catch(Exception e) {
// ...
}
And make a new Activity that explains that the application crashed instantly (and also giving users an opportunity to send a mail with the error details), instead of having that delay thanks to Android. Are there better methods of accomplishing this or is this discouraged?
Update: I am using a Nexus 5 with ART enabled and I am not noticing the delay I used to experience with apps crashing (the "hanging" I was talking about originally). I think since everything is native code now, the crash happens instantly along with getting all the crash information. Perhaps the Nexus 5 is just quick :) regardless, this may not be a worry in future releases of Android (given that ART is going to be the default runtime in Android L).
Here, check for the link for reference.
In here you create a class say ExceptionHandler that implements java.lang.Thread.UncaughtExceptionHandler..
Inside this class you will do your life saving stuff like creating stacktrace and gettin ready to upload error report etc....
Now comes the important part i.e. How to catch that exception.
Though it is very simple. Copy following line of code in your each Activity just after the call of super method in your overriden onCreate method.
Thread.setDefaultUncaughtExceptionHandler(new ExceptionHandler(this));
Your Activity may look something like this…
public class ForceClose extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Thread.setDefaultUncaughtExceptionHandler(new ExceptionHandler(this));
setContentView(R.layout.main);
}
}
You could just use a generic alert dialog to quickly display error messages.
For example...
//******************************************
//some generic method
//******************************************
private void doStuff()
{
try
{
//do some stuff here
}
catch(Exception e)
{
messageBox("doStuff", e.getMessage());
}
}
//*********************************************************
//generic dialog, takes in the method name and error message
//*********************************************************
private void messageBox(String method, String message)
{
Log.d("EXCEPTION: " + method, message);
AlertDialog.Builder messageBox = new AlertDialog.Builder(this);
messageBox.setTitle(method);
messageBox.setMessage(message);
messageBox.setCancelable(false);
messageBox.setNeutralButton("OK", null);
messageBox.show();
}
You could also add other error handling options into this method, such as print stacktrace
i found the "wtf" (what a terrible failure) method in the Log class. From the description:
Depending on system configuration, a report may be added to the
DropBoxManager and/or the process may be terminated immediately with
an error dialog.
http://developer.android.com/reference/android/util/Log.html