How to get the crash info from ApplicationErrorReport class? - android

Android ICS (api 14) introduced the ApplicationErrorReport class with the following info:
CrashInfo BatteryInfo and ANRInfo. From the class overview it seems that this class refers to all application installed on the device and not for debugging your own personal application.
I cannot seem to reach that information (simulated crashes and anr's)
I tried this code:
ApplicationErrorReport appp = new ApplicationErrorReport();
CrashInfo test = appp.crashInfo;
Log.i(test.stackTrace);
but i get that test is null
How to get the crash information?

In the ApplicationErrorReport API it says:
ApplicationErrorReport()
Create an uninitialized instance of ApplicationErrorReport.
This means that the "type" of error is undefined, so it's not a crash report and therefore the crashinfo is null.
EDIT:
I took a look at the source code. You can instantiate the CrashInfo part via the method readFromParcel(in) where the first int in the parcel is the int corresponding to ApplicationErrorReport.TYPE_CRASH. Alternatively you can create a CrashInfo object yourself and assign it to the ApplicationErrorReport, but this again requires a parcel if you want to CrashInfo data to be filled.
I tried looking for code where it is used, but the only thing I could find is the ApplicationManagerNative (also using parcels).
case HANDLE_APPLICATION_CRASH_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor);
IBinder app = data.readStrongBinder();
ApplicationErrorReport.CrashInfo ci = new ApplicationErrorReport.CrashInfo(data);
handleApplicationCrash(app, ci);
reply.writeNoException();
return true;
})

Related

How to create TelephonyDisplayInfo object in android R device

I want to get getOverrideNetworkType() in android Like as Android CA 5G NSA NR but Enable to Create TelephonyDisplayInfo object to get this. I am using this code but get
TelephonyDisplayInfo mTelephonyDisplayInfo;
mTelephonyDisplayInfo = new TelephonyDisplayInfo(TelephonyManager.NETWORK_TYPE_UNKNOWN,
TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE);
but get error:-
TelephonyDisplayInfo() is not public in android.telephony.TelephonyDisplayInfo. Cannot be accessed from outside package this error.
Comment from Google support:
Although the constructor is public, it's #hide and not a part of the
API surface, so it shouldn't be accessible to developers. To get the
TelephonyDisplayInfo, please use
PhoneStateListener#onDisplayInfoChanged instead. Closing this as
working as intended.

Android printing with Brother SDK via WiFi throws ERROR_WRONG_LABEL despite selecting correct labelNameIndex

I've been trying to print with Brother Print SDK 3.5.1 on Android 8.1.0. I keep getting ERROR_WRONG_LABEL.
This is the code I use
void printPdf() {
// Specify printer
final Printer printer = new Printer();
PrinterInfo settings = printer.getPrinterInfo();
settings.printerModel = PrinterInfo.Model.QL_810W;
settings.port = PrinterInfo.Port.NET;
settings.ipAddress = "192.168.1.73";
settings.workPath = "storage/emulated/0/Download/";
// Print Settings
settings.labelNameIndex = LabelInfo.QL700.W62RB.ordinal();
settings.printMode = PrinterInfo.PrintMode.FIT_TO_PAGE;
settings.orientation = PrinterInfo.Orientation.PORTRAIT;
settings.isAutoCut = true;
printer.setPrinterInfo(settings);
// Connect, then print
new Thread(new Runnable() {
#Override
public void run() {
if (printer.startCommunication()) {
PrinterStatus result = printer.printPdfFile("/storage/emulated/0/Download/hello world red.pdf", 1);
if (result.errorCode != PrinterInfo.ErrorCode.ERROR_NONE) {
Log.d("TAG", "ERROR - " + result.errorCode);
}
printer.endCommunication();
}
}
}).start();
}
My printer model is QL-810W and I use the black and red W62 roll.
I've tried the Sample Application, where setting W62RB in labelNameIndex prints fine.
Changing the roll for different one with different width didn't help.
I've also tried iterating over numbers 0 to 50 and using them as labelNameIndex.
Based on this thread, I thought that the issue may be in specifying the workPath attribute. Setting workPath to getContext().getCacheDir().getPath() results in ERROR_OUT_OF_MEMORY instead of ERROR_WRONG_LABEL. Not specifying workPath and adding <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> to AndroidManifest.xml results in ERROR_WRONG_LABEL
EDIT
I've modified the Brother Sample app and uploaded it to GitHub. The app now launches Activity_PrintPdf.java by default where I inserted my printing code with hardcoded values at the beginning of onCreate method - this works fine and prints the PDF file as expected.
Then I created a new Empty Activity project in Android Studio, copy pasted the library, added the imports to build.gradle and copy pasted the permissions into AndroidManifest.xml. Then I copy pasted the printing code at the beginning of onCreate method in MainActivity.java. Running the app results in ERROR_WRONG_LABEL.
This is the modified working example app and this is the one that results in the error. I want to use the code as native module that I call from my React Native app, so it's important that I manage to set up the printing code from scratch rather than modifying the existing example app.
EDIT 2
I've inspected the library with a debugger: when executing printer.setPrinterInfo(mPrinterInfo) the library internally calls private boolean createWorkPath(String dirPath) of Printer object. On return from this method, the debugger shows Source code doesn't match the bytecode and seems to forget the created directory. This also internally sets mResult.errorCode = ErrorCode.ERROR_WORKPATH_NOT_SET. However, instead of rising any error here the code just silently proceeds, which later results in ERROR_WRONG_LABEL when trying to print. Running the same code snipper in the modified Sample app works fine.
I'd be grateful if you could help or suggest what to try next.
Thank you!
I've now fixed the issue, which was that the Brother library silently failed to create a temporarily folder and instead of reporting an error, it continued and failed later to read the label information. Based on this thread, it is now required to specify runtime file read and write permissions as opposed to the compile-time ones in AndroidManifest.xml.
Adding
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},1);
at the beginning of onCreate before the printing code fixed the issue.

Android 7.0/API24: How to check for notification access (Settings.Secure.enabled_notification_listeners)

In Android 6.0/API23 and earlier, the following used to work:
String settingEnabled = android.provider.Settings.Secure.getString(this.getContentResolver(), "enabled_notification_listeners");
In Android 7.0 Nougat/API24 this seems to be no longer supported, because the code above returns null.
It actually was never mentioned here: https://developer.android.com/reference/android/provider/Settings.Secure.html
How do we check if our app has notification access in Android 7.0 Nougat API24?
Edit: It seems that actually that after you first gained the access in the settings, the code above returns the correct state. But not on the initial request after installation.
Use this:
Set<String> packageNames = NotificationManagerCompat.getEnabledListenerPackages (context);

invoking createDisplay on android.view.SurfaceControl using reflection returns null

I am trying to call createDisplay method on android.view.SurfaceControl using reflection but it is returning null on Marshmallow device. I Don't know why.
The reason to do is to create virtualdisplay without using MediaProjection API.
Following is the code.
Class surfaceControlClass = Class.forName("android.view.SurfaceControl");
Class cls = surfaceControlClass;
IBinder token = (IBinder) cls.getDeclaredMethod("createDisplay", new Class[]{String.class, Boolean.TYPE}).invoke(null, new Object[]{name, Boolean.valueOf(false)});
You need System Permission(android.permission.ACCESS_SURFACE_FLINGER) to do that, check your LogCat and you will find permission warning.
Actually you can't make it work unless you have the Platform Signature of your device.
But you can test it on emulator using the default AOSP signature.

Using BatteryStatsImpl internal class via Reflection in android

I am trying to get a list of running applications and the amount of battery used by each of them. I have google for a long time but didnt come up with a solution. However there have been a few references on the PowerProfile, PowerUsageSummary internal classes.
I used them through Reflection technique but didnt get what i was looking for. PowerUsageSummary shows the same details as you can see by going to Device Settings->Applications->Battery Use(This is how it can be seen in a Samsund device).
Then i used PowerProfile class but i got only the mA of current utilized by WIFI, AUDIO, VIDEO,GPS, BLUETOOTH etc(The mA values dont change so often. I am not sure if the values are correct). Another reference was the BatteryStatsImpl class. I tested this class but the values are 0 always. Still i am looking for the list of running applications and the amount of battery used by each of them. Any help is appreciated.
Thanks,
Here is the sample code that i tried for BatteryStatsImpl class.
String BATTERY_PROFILE_CLASS = "com.android.internal.os.BatteryStatsImpl";
Object mBatteryProfile = Class.forName(BATTERY_PROFILE_CLASS).getConstructor().newInstance();
Method batteryMeth = Class.forName(BATTERY_PROFILE_CLASS).getMethod("getBatteryUptime", long.class);
Object arglist1[] = new Object[1];
arglist1[0] = System.currentTimeMillis();
// This is to calculate the batteryUpTime since the current time.
Long batteryUptime = (Long) batteryMeth.invoke(mBatteryProfile, arglist1);
Method dischargeMeth = Class.forName(BATTERY_PROFILE_CLASS).getMethod("getDischargeStartLevel");
// This is to calculate the dischargeTime of the device battery
Integer dischargeTime = (Integer) dischargeMeth.invoke(mBatteryProfile);
First please note that you can't make use of this API unless you are installed on the system image and so can hold the BATTERY_STATS permission. This is not available to third part apps installed separately from the system.
To use this, you don't directly instantiate BatteryStatsImpl. You request an instance of it from the current stats being collected by BatteryStatsService. You can look for the source code of the settings app for how to do this: https://code.google.com/p/android-source-browsing/source/browse/src/com/android/settings/fuelgauge/PowerUsageSummary.java?repo=platform--packages--apps--settings
In particular:
import android.os.BatteryStats;
import com.android.internal.app.IBatteryStats;
import com.android.internal.os.BatteryStatsImpl;
IBatteryStats mBatteryInfo;
UserManager mUm;
BatteryStatsImpl mStats;
mBatteryInfo = IBatteryStats.Stub.asInterface(
ServiceManager.getService("batteryinfo"));
private void load() {
try {
byte[] data = mBatteryInfo.getStatistics();
Parcel parcel = Parcel.obtain();
parcel.unmarshall(data, 0, data.length);
parcel.setDataPosition(0);
mStats = com.android.internal.os.BatteryStatsImpl.CREATOR
.createFromParcel(parcel);
mStats.distributeWorkLocked(BatteryStats.STATS_SINCE_CHARGED);
} catch (RemoteException e) {
Log.e(TAG, "RemoteException:", e);
}
}
the BatteryStatsService maintains the stats. Have a look in there how BatteryStatsImpl is used to do that (those note*() methods are called by the system when e.g. screen turns on)
Maybe you can get the current stats from there

Categories

Resources