I want you to know I'm a newbie to Android Development.
I have developed an Android application. Before releasing the app I tested it many times on my device and several others to check if it crashes or not. The app passed all the tests.
Now the app is crashing on some of the user's device and how to know reason of crashing app of the user's device.
I'm a bit confused about how to tackle problems like this.
private static void logInitError(#NonNull String message) {
CrashLog.log(message);
CrashLog.log(locationManager == null ? "!!! NOT INITIALISED !!!" : "locationManager initialised");
DebugTestException debugException = new DebugTestException();
CrashLog.logException(debugException);
}
private static void logInitErrorNoProvider(#NonNull String message) {
CrashLog.log(message);
CrashLog.log(locationManager == null ? "!!! NOT INITIALISED !!!" : "locationManager initialised");
DebugTestException debugException = new DebugTestException();
CrashLog.logException(debugException);
}
The best way to monitor the app is to use firebase crashlytics.
You will get real-time analytics from your app, refer the official guide for implementation.
Related
I have integrated the play core in-app update it's working fine in the testing track but when a release is published in the production track it's always giving the UPDATE_NOT_AVAILABLE flag. I think the problem might be because Timed Publishing/Publishing Overview is enabled. Is there any fix or any setting which I have to change from the play console itself? or do I have to implement something in my android end?
here is the Implemented code-
AppUpdateManager appUpdateManager = AppUpdateManagerFactory.create(context);
Task<AppUpdateInfo> appUpdateInfoTask = appUpdateManager.getAppUpdateInfo();
appUpdateInfoTask.addOnCompleteListener(listener -> {
if (listener.isSuccessful()) {
Log.d(TAG, "Update Available " + (listener.getResult().updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE)); // returns false
Log.d(TAG, "Update Allowed" + listener.getResult().isUpdateTypeAllowed(AppUpdateType.IMMEDIATE)); // returns false
Log.d(TAG, "Update Availibility" + listener.getResult().updateAvailability()); // returns 1 that is UPDATE_NOT_AVAILABLE
if (listener.getResult().updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE
&& listener.getResult().isUpdateTypeAllowed(AppUpdateType.IMMEDIATE)) {
try {
appUpdateManager.startUpdateFlowForResult(
listener.getResult(),
AppUpdateType.IMMEDIATE,
activity,
1001);
} catch (IntentSender.SendIntentException e) {
Log.e(TAG, "showPopup: ", e);
dialog.show();
}
} else {
Log.d(TAG, "no update: " + listener.getResult());
dialog.show();
}
} else {
Log.e(TAG, "no update: ", listener.getException());
}
});
I had a similar problem yesterday, and in my desperation put what should of been a comment about having a similar problem as an answer... #Natty showed me the error of my ways, and I felt bad, so made sure I'd come back with a better actual answer:
I discovered that the likely culprit is google play app signing. It looks like they changed things in August 2021 so as the default is to allow google to manage the app signing, which means your app is signed by a different key with each release, and thus your releases have different signatures, and it won't find the updates. The exceptions is internal app sharing.
Sadly, there appears to be no way to opt-out
You can't disable App Signing after being activated as you can read in the image below:
see this post
It get worse... because ya know google... your can't delete you app either, the only thing you can do is to
unpublish the app.
Then create a new version on the google play store. Change the applicationId to some slight variant so it counts as a different app.
When adding you first release for the new app in any track, make sure to select the appropriate option for app signing above where you drop in the app bundle
click use different key
Either use a keystore generated from android studio or make a new one. From then on google will use that same keystore for signing all future releases of the app.
I even went back and double checked this was the case for me, by checking the older version of the app and the new version on internal testing tracks. Indeed, the new version using the same app signing keystore works for in-app updates, but the older version with google app signing did not.
Just bear in mind a whole new app has to go through the review process, which can take 1-3 days for new apps (seemed to be much quicker once the initial review is done)
I am working on android project, where NFC is used as a communication. I am facing a weird problem, when mobile device has a NFC, it is enabled, but it is not working on some devices (adapter is not enabled when debugging). I am writing logs and it prints, NFC on, adapter disabled.
For example: HTC One m9(os 7.0). Also happens with OnePlus One(os 9)! But again, it works on other devices.
Did you experience the same issue?
Here is some code:
object NfcUtil {
fun getNfcAdapter(c: Context): NfcAdapter? {
val manager = c.getSystemService(Context.NFC_SERVICE) as NfcManager
return manager.defaultAdapter
}
fun doesSupportHce(c: Context): Boolean {
return c.packageManager.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION)
}
}
val adapter = NfcUtil.getNfcAdapter(this)
if (adapter != null && NfcUtil.doesSupportHce(this)) {
if (adapter.isEnabled) {
tvNfcOff.extHide()
} else {
tvNfcOff.extShow()
}
}
I think that if NFC is supported and enabled but the adapter is disabled (https://developer.android.com/reference/android/nfc/NfcAdapter#isEnabled()) I'll follow the guidelines and redirects the user to the settings screen with the intent mentioned in the documentation.
If the user come back few times you could monitor it and show a different message instead of redirecting to settings, something like: NFC is not working properly on your device. I'd check if you have lots of users using those devices, if yes, I will try to research more on the Operating System and Device having this issue.
And later on I will just try to debug it with that Device and that specific Operating System that is having this kind of issue. I'll try to see if other apps using NFC has same issues or they work fine, and by work fine I mean that the communication happens not that other apps dont show any warning/error popup message.
And if I found out its an issue in a specific OS Version, also with other apps, I'll just try to inform the users and get an update on which version the issue have been fixed. Otherwise if other apps can make a successful NFC communication in that device/OS that is not working for me, I'll just dig deeper.
For now I can say there is nothing wrong in your implementation and looks good.
It might be an issue with the current OS or if you have any Custom ROM that might not fully support or have a functional NFC driver.
Two additional bits of info that might be useful
1) Use a Broadcaster receiver to get notified when the NFC state changes, because using the quick settings pull down does not pause your app, therefore retesting nfc status in onResume does not work (a user changing via the full settings app will pause you App, though)
Example of how to do it in Java
#Override
protected void onCreate(Bundle savedInstanceState) {
// All normal onCreate Stuff
// Listen to NFC setting changes
this.registerReceiver(mReceiver, filter);
}
// Listen for NFC being turned on while in the App
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (action.equals(NfcAdapter.ACTION_ADAPTER_STATE_CHANGED)) {
final int state = intent.getIntExtra(NfcAdapter.EXTRA_ADAPTER_STATE,
NfcAdapter.STATE_OFF);
switch (state) {
case NfcAdapter.STATE_OFF:
// Tell the user to turn NFC on if App requires it
break;
case NfcAdapter.STATE_TURNING_OFF:
break;
case NfcAdapter.STATE_ON:
// Do something with this to enable NFC listening
break;
case NfcAdapter.STATE_TURNING_ON:
break;
}
}
}
};
2) Don't assume that the device has a NFC settings page, if your app works with and without NFC, if the adapter is null don't assume you can start an Intent to the NFC settings page as suggested by #denis_lor as this will cause a crash if the OS does not have a NFC adapter to turn on.
I am trying to clear a data from within the app and my app is device owner, hence I am getting and error
java.lang.SecurityExeception :Clearing DeviceOwner data is forbidden.
Code I am using is
public void onClearData(View view) {
try {
boolean isCleared = ((ActivityManager) getSystemService(ACTIVITY_SERVICE)).clearApplicationUserData();
if (!isCleared) {
Toast.makeText(this, "Not able to clear the data", Toast.LENGTH_SHORT).show();
}
} catch (Exception e) {
e.printStackTrace();
}
}
Now, my question is that how it will be possible to clear a data of device owner app from within the app? Would appreciate a help.
The way you're doing it is how it's done, according to the docs.
But since you're getting that security exception, your app is probably set as a device owner app, and you're not allowed to deactivate it, remove its data nor uninstall it while it is on this state.
If that's really the case I'd suggest you to unset it as a Device Owner App. Try to use dpm remove-active-admin for that.
Take a look at those questions for more info:
How to make my app a device owner?
How to remove set-device-owner in Android DPM?
Disable a device owner app from android terminal
I'm trying to develop an app that can get the Network stats from specific packages, but I'm getting these problems:
When I try to use the NetworkStats Library of Android 6.0(Marshmallow), I get this Exception:
NetworkStats: Neither user 10412 nor current process has
android.permission.READ_NETWORK_USAGE_HISTORY.
Here is the code:
try {
TelephonyManager tm;String subscriberID;
NetworkStatsManager networkStatsManager;
NetworkStats networkStats;NetworkStats.Bucket bucket;
tm = (TelephonyManager) mContext.getSystemService(mContext.TELEPHONY_SERVICE);
subscriberID = tm.getSubscriberId();
networkStatsManager = mContext.getSystemService(NetworkStatsManager.class);
networkStats = networkStatsManager.queryDetailsForUid
(typeMobile, subscriberID, dtBegin, dtEnd, uidPackage);
if(networkStats !=null){
while (networkStats.hasNextBucket()) {
bucket = new NetworkStats.Bucket();
networkStats.getNextBucket(bucket);
Log.d("Bucket RX:",bucket.getUid()+" -" +String.valueOf(bucket.getRxBytes()));
Log.d("Bucket TX:",bucket.getUid()+" -" +String.valueOf(bucket.getTxBytes()));
}
}
}
catch (Exception ex){
Logger.e(ex.getMessage());
}
How can I get the functionality of NetworkStats in previous versions of Android (5.0 & 4.0)? Is there any library?
READ_NETWORK_USAGE_HISTORY permission is only granted for system applications. So, unless you are using a rooted phone, you won't be able to use it. The only way out is to use TrafficStats which is available since API level 8.
Mmm ... After a little bit research over internet I give up on using this Android Native Library. I have managed to make it work, but its necessary that the user enables it through "User Data Access" option (Located under Settings App). Then I try to launch this app to the user so the user can enable by himself, but this doesnt not work on many devices. See this link:
Devices without "Apps using Usage Data" or android.settings.USAGE_ACCESS_SETTINGS intent
enter image description here
I released my Android app two days ago, using admob advertising. I used my personal phone as the test phone, but took out the test mode code before releasing it. My admob status is active and I get requests and impressions on the report, but whenever I try to use the app on my personal phone i only get "test ads". I don't know why. I looked through the code of my app and can't find anything amiss. And i did delete the test version of the app and then download the released version from the market.
I'm not sure why the test ads are appearing in your app, but one way to shut them off is to go to your Admob App Settings, and choose the option "Disable test mode for all requests" as your Test Mode setting.
You customers would not have been seeing the debug ads. You probably have a line like:
AdManager.setTestDevices( new String[] {
AdManager.TEST_EMULATOR, // Android emulator
"E83D20734F72FB3108F104ABC0FFC738", // My T-Mobile G1 Test Phone
}
Assuming E83D20734F72FB3108F104ABC0FFC738 is you're personal phone, any time that phone makes a request it will get a test ad. All other phones will not be eligible for test ads, unless they are also individually added to that method.
Nick's answer works. (But is missing the final parenthesis.)
But what if I want to give my (not yet released) Android app out to 10 friends?
Is there any java code that says "treat ALL phones as test devices"?
Here is code for treat all devices as test devices:
String aid = Settings.Secure.getString(context.getContentResolver(), "android_id");
try {
Object obj;
((MessageDigest) (obj = MessageDigest.getInstance("MD5"))).update(aid.getBytes(), 0, aid.length());
aid = String.format("%032X", new Object[] { new BigInteger(1, ((MessageDigest) obj).digest()) });
} catch (NoSuchAlgorithmException localNoSuchAlgorithmException) {
aid = aid.substring(0, 32);
}
adRequest.addTestDevice(aid);