Is there any way to see country data for a Crash in Crashlytics? - crashlytics

Previously we used to rely on Firebase Console for crash reports. It was working pretty good but then Google also announced the official support for Crash reporting through Crashlytics and we went ahead with Crashlytics integration. The only problem being, we can't see the country code for a Crash anymore.
So, is there any way, we can have the country information for a Crash in Crashlytics?

Mike from Fabric here. By default, we don't capture country information for crashes. However, you can set this via a custom key.
On Android, use:
Crashlytics.setString("Country_Code", "Canada");
On iOS, use:
# Objective-C
[CrashlyticsKit setObjectValue:#"Canada" forKey:(#"Country_Code")];
# Swift
Crashlytics.sharedInstance().setObjectValue("Canada", forKey: "Country_Code")

To add on to what Mike have posted, you can get the Locale of the machine as a "guess" of the country.
It is not exactly accurate, but should suffice as an approximation of the app's distribution. (if you do not want to use the Location permission)
some thing like the following:
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Fabric.with(this, new Crashlytics());
logCountry();
setContentView(R.layout.activity_main);
}
private void logCountry() {
Crashlytics.setString("Locale", Locale.getDefault().toString());
}
}
you will get to see the locale/country under the "KEYS" tab in the firebase console.
Would have been a lot cleaner if that information is in the "DATA" tab, but guess we have to make do with what's provided.

Related

After getting the permission soft keyboard does not show up for the first time

I read all the similar questions but nothing useful in my case..
I have an activity which shows soft keyboard automatically when it is started.
It's working fluently with no error. But the issue is I need to use permissions for this activity so when the first time activity is executed and permission is asked (then granted), softkeyboard does not show up no matter what (I even need to press edittext 2-3 times for it to load)
I can fix it with recreate() method obviously because it will be necessary only for one time but you know screen refreshing lag makes the application quality lower. Do you have any suggestion please? Thanks
I figured out a way, and though it might not be helpful in your particular scenario, might help someone else. You can set windowSoftInputMode as stateAlwaysVisible for the activity in which you wish to see the keyboard after accpeting/denying permissions, and it will pop up automatically.
I encountered this problem when I was using the Dexter library, and I assume you are using it too.
Solution for those who use the Dexter library: you must call token.continue Permission Request(); in the onPermissionRationaleShouldBeShown event of your PermissionListener.
Dexter.withContext(activity)
.withPermissions(
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION
)
.withListener(new MultiplePermissionsListener() {
#SuppressLint("MissingPermission")
#Override
public void onPermissionsChecked(MultiplePermissionsReport report) {
}
#Override
public void onPermissionRationaleShouldBeShown(List<PermissionRequest> permissions, PermissionToken token) {
token.continuePermissionRequest();
}
})
.check();

UWP - Get Slidervalue from another Page

I've got 2 Pages: My Main-Page and my Settings-Page - both in XAML and xaml.cpp as code behind. I've also got a class where I want to work with the values of the Settings-Class. (As I already asked in another post) I can save the values from the Settings-Page in the cache using the XAML-tag NavigationCacheMode="Enabled". Using this my SliderValue stays the same even when I switch to my Main-Page and back again to Settings-Page.
What I want to do now: Save the value of the slider as soon as it is changed and store this value to a variable to which I have access from a third Class.
What I've got so far (not working, always showing initialvalue '70'):
Settings.xaml.cpp:
UWPApp::Settings::Settings()
{
InitializeComponent();
quality = sldQuality->Value;
}
int Settings::getQuality() {
return quality;
}
void DirectX12XamlApp::Settings::sldQuality_ValueChanged(Platform::Object^ sender, Windows::UI::Xaml::Controls::Primitives::RangeBaseValueChangedEventArgs^ e)
{
quality = sldQuality->Value;
}
In Settings.xaml.h:
public:
Settings();
int getQuality();
private:
int quality;
In Settings.xaml:
<Slider x:Name="sldQuality" ValueChanged="sldQuality_ValueChanged" HorizontalAlignment="Left" Margin="38,325,0,0" VerticalAlignment="Top" Width="168" Value="70"/>
//initial-Value = 70, which is ALWAYS showing when using getQuality() in an other Class
In my logicclass I want to use it like this:
int quality = Settings::getQuality();
Quick answer: save the value of the slider in a public static property, ideally in the separate class.
Recommended answer:
You should use MVVM structure in your app, so you would have a separate layer for storing your settings data. You can save the value of the slider in the singleton service, ideally injected through the IoC container. You may also want to save it in the local storage so the settings are saved when the user closes the app.
MVVM is really a standard of XAML-based apps, and the concept is not difficult to learn and implement.
Sounds like you're looking for a way to store and retrieve settings data for your app. Features for that have been built into the UWP. Please refer to this article from the Windows Dev Center. Examples on that page are for C#, but all the links to UWP API references contain code snippets for C++ as well.

Remove version control from Eclipose RCP project

I have an Eclipse RCP application that uses EGit and JGit to implement the version control of projects.
In some cases, I want to make it so that a project is no longer under version control. This implies both deleting the project's .git directory on the file system, and making my application aware that the project is not under version control.
I tried looking through the JGit API for solutions to this, but could not find anything useful. Simply deleting the .git directory using a file manipulation API is not sufficient, as some files in it seem to be locked (very likely by JGit).
Sorry, I'm not 100% sure because your scenario is not clear enough to me, however you said that your application is based also on EGit, so I assume that you are using the standard eclipse APIs to manage the projects. If this is the case, what you are looking for is: org.eclipse.team.core.RepositoryProvider
This is an example:
public class UntrackProject extends AbstractHandler implements IHandler {
#Override
public Object execute(ExecutionEvent event) throws ExecutionException {
IProject project = getProject(); // get the project, for example using the selection service
try {
RepositoryProvider.unmap(project);
//TODO Refresh your viewer to show changes
} catch (TeamException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
For reference, you can check the handler of the context menu "Disconnect", that does exactly what you are looking for: org.eclipse.egit.ui.internal.actions.DisconnectActionHandler
https://git.eclipse.org/c/egit/egit.git/tree/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/DisconnectActionHandler.java
It uses a lot of internal classes of egit, but in the end it uses the RepositoryProvider's API.
Note that the method RepositoryProvider.unmap(project) does NOT delete the repository, it just disconnects the project.
I hope this helps!

Play Store Alert - Unsafe Implementation of onReceivedSSLError

One of my app in the play store has received this alert recently and I am completely lost as to what should be done to stop this alert. Please refer this.
Scenarios in my app:
There's a payment gateway involved in the app but the payment takes place through a webview and I am almost sure that this alert might be a result of those webviews.
Insights from Google :
As far as I've searched, I've come across the OnReceivedSslError more often and even the alert clearly states me to handle that method properly. But I am totally lost cause I haven't implemented that method in the first place.
Deeper surfing lead me to links like this,this and this too. The common thing that I found in all the links is that they were all referring to an older version of android. But I am using my minSDK as 14 which is Android 4.0 and above. So I got lost again. And I presume that this alert comes when we use a https in our webview.
So my questions are
How did I get this issue suddenly ?
This app has been in the play store for more than 6 months and this alert comes out of the blue !!! Absolutely no idea what happened !!
How do I reproduce the issue ?
I have tried many methods to reproduce this issue and I have implemented the SSL method as given in here:But nothing seems to be working.
Will this issue affect my payment or my app in any ways ?
How can I reproduce this issue to know more and how can i stop this alert ?
What have I tried ? :
As I had my doubts in older android versions, I designed an emulator with my minSDK but even in that my flow did not enter the method.
My doubt :
Could there be a not-so-genuine SSL which could've triggered this issue ?
Any ideas and insights on this issue will be much helpful. Thanks in advance. I just need to disable that alert, as simple as that.
It seems that Google has upgraded their security checks when you use WebViewClients. In many cases - no pun intended - developers fix an SSL problem like this:
#Override
public void onReceivedSslError(WebView view, final SslErrorHandler handler, SslError error) {
handler.proceed();
}
I had this issue too, and it seems that Lint doesn't implement this check yet. So it'll be quite difficult to reproduce. If you would like to see what happens, create a self-signed certificate, set-up a webserver using this certificate and connect a webviewclient to this "untrusted" webserver. If you don't handle the onReceivedSSLError, you'll either get an error, or nothing will happen in the webview (by default).
Will it affect your payment? I guess it would, IF the SSL certificate is untrusted, as the request to the url/api will be cancelled.
The above snippet would just ignore the SSL error, and provide the possibility for a MITM-attack. Have you tried intercepting the request, alerting the user, and allowing them to make the choice to continue?
e.g.
#Override
public void onReceivedSslError(WebView view, final SslErrorHandler handler, SslError error) {
//super.onReceivedSslError(view, handler, error);
AlertDialog.Builder builder = new AlertDialog.Builder(GroupsActivity.this);
builder.setTitle("Invalid/Untrusted certificate");
builder.setMessage("You're accessing a page with an untrusted or invalid certificate. Do you want to continue?");
builder.setNegativeButton("Cancel", new OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
handler.cancel();
Toast.makeText(GroupsActivity.this, "Request cancelled", Toast.LENGTH_LONG).show();
}
});
builder.setPositiveButton("Continue", new OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
handler.proceed();
}
});
}
To properly handle SSL certificate validation, change your code to invoke handler.proceed() whenever the certificate presented by the server meets your expectations, and invoke handler.cancel() otherwise.
onReceivedSslError() should notify user about error by Alert Dialog.
If you remove onReceivedSslError() then it will call by default handler.cancel() in case of SSL error.This also will work.

In JProfiler, why does my object not show in the All Objects view?

I'm new to JProfiler. I've created a very simple test application. Here's a Main.java with a main method:
package com.example;
import java.io.IOException;
public class Main {
public static void main(String[] args) throws IOException {
Example e = new Example(); //Gets gc'ed?
System.out.println(e.getMessage());
System.in.read();
System.exit(0);
}
}
Note that I pause until key-press. This way I'm sure the main scope does not end until I press a key, so I expect e to exist and not be garbage collected (please correct me if this assumption is incorrect). The Example class:
package com.example;
public class Example {
public String getMessage() {
String testString = "This is the test string. Press a key to exit.";
return testString;
}
}
I start the above application using the JProfiler Eclipse plugin. I've created a session that's based on the Full Instrumentation profile; I've removed the Java EE and JDBC specific probes and left the rest at defaults.
Now when the profiler starts, I go to the all objects view and I'd expect to find com.example.* classes, but I find none; why is that happening?
Ok, so maybe I can only find these objects when I use another view, like the Allocation call tree, so I enable Allocation Recording using the button in the view (it's disabled by default). It asks me to click on calculate allocation after that, which pops up a dialog. I accept the defaults and I'm presented with an empty view that auto-updates in eternal emptiness.
So then I try Heap Walker. It asks me to make a dump first. I get a dialog that provides me the option to "select recorded objects" which is default unselected. I leave it at defaults and am presented with an instance count view. However, my object is not findable in this Classes view I'm presented with.
So I suppose I'm doing something fundamentally wrong; What should I do to see my objects, and specifically the precise instance count of my objects?
UPDATE 1:
I've found a part of the problem. When the profiler window comes up, it presents you with the Session Startup dialog, where you can choose the profile and set various settings. There is a little section on the first tab called "Startup" which has a setting called "Initial recording profile", which by default is set to [no recordings]. When I leave this at its default, I cannot find the Example object. When I set it to "CPU recording" I can find my Example object in the All Objects view.
UPDATE 2:
I cannot find the object in Heap Walker. When I select com.example.Example in the All Objects view, I can right-click the object and choose (show object in Heap Walker). When I do so, Heap Walker tells me there's no such object on the heap! What gives?
UPDATE 3:
The com.example.Example object seems to show up sometimes, sometimes not. I cannot figure out why. Additionally, when it shows up, it will disappear from the All objects view, even though the main loop has not exited yet, even though the com.example.Example object should still be alive...
UPDATE 4:
It turns out e is garbage collected, regardless of scope ending on IBM's J9 JVM. See my answer to this which modifies main to invoke a second method after the key-press wait, which forces the object to remain alive.
I finally truly solved this mystery. It turns out I'm running IBM's J9 VM. Apparently, J9 garbage collection is quite a bit more aggressive: It will clean up e within the main scope if e is not going to be used within that scope anymore. I have verified that this specific behaviour does not happen with Oracle's JVM.
So long story short: on IBM J9, you cannot assume that objects stay alive within the scope of a block. On Oracle's JVM, at least by default, e is not garbage collected until after the block ends, regardless of further usage of e.
On IBM J9, when you want to force the object to stay in existence, there has to be a future usage of it. To prove this I modified Example.java to contain the following:
package com.example;
public class Example {
public String getFirstMessage() {
String firstTestString = "This is the first message: Hello!";
return firstTestString;
}
public String getSecondMessage() {
String secondTestString = "This is the second message: Goodbye!";
return secondTestString;
}
}
Then, in main I made sure to have an invocation of getSecondMessage() AFTER the wait-on-key-press (System.in.read()). This way, we know for sure that the GC cannot cleanup the object before main's scope ends because there's an invocation waiting in the future, happening right after the user presses a key. So Main.java looks like:
package com.example;
import java.io.IOException;
public class Main {
public static void main(String[] args) throws IOException {
Example e = new Example();
System.out.println(e.getFirstMessage());
System.in.read();
System.out.println(e.getSecondMessage());
System.exit(0);
}
}
Profiling the above code regardless of CPU recording settings previously thought to be a factor in this will work as expected: the object stays alive because it cannot be garbage collected before the key is pressed.
This way I'm sure the main scope does not end until I press a key, so I >expect e to exist and not be garbage collected (please correct me if this >assumption is incorrect).
That is correct. The "Example" object will be held by a stack reference at that point and cannot be garbage collected. Both the "All objects" view and the heap walker will show this object.
I just tested your example and it works for me with both JProfiler 8.1.4 and JProfiler 9.0.2.
Use the "View->Find" action to search for "Example".