I recently switched to using Android ndk-r9 and am having some difficulty with my app that seems to be related to compiler optimization. I have the following function:
int GetTouchPos(GTouchEvents * pEvents, GPointF * pPos, int * pButton = 0)
{
int count = 0;
GTouchEvent * pEvent;
if (pEvents->GetCount(&count) == GResult_Ok)
{
GDebugLog((GS("GetTouchPos: count = %d"), count));
if (pEvents->GetEvent(0, &pEvent) == GResult_Ok)
{
pEvent->GetTapPos(pPos);
if (pButton)
{
pEvent->GetButton(pButton);
}
pEvent->Release();
}
}
return(count);
}
If I build my project and run it, the call to GDebugLog formats and logs the value of the variable 'count'. When I do this, 'count' is 1 and my app works correctly. However if I comment out the GDebugLog line (and make NO other changes), when I run my app, it no longer works. In the function GTouchEvents::GetCount, I also am logging what it is returning and the value is always correctly '1'. Also, I log the return from the call to the function above (i.e. GetTouchPos). When the GDebugLog line is present, the logged return value is the correct value '1'. However when I comment out the GDebugLog call, the logged return value is a seemingly random number, which looks suspiciously like an uninitialized variable.
Note that this all works with our without the GDebugLog line when I was using r8b. Also note that if I turn optimization off, this code works perfectly using r9 whether the debugging line is present or not. Also note that this behavior only presents itself when compiling for the ARM processor. The version I build for x86 works without problem.
Am I doing something questionable here that is causing the optimizer to generate incorrect code?
Can anyone shed some light on what might be happening?
Thanks.
Related
When using the OnReceiveContentListener I followed along with the guide here. I also looked at the example project they reference. From my understanding the way it works is that if I enter the code
val editTextOnReceiveContentListener =
androidx.core.view.OnReceiveContentListener { editText, contentInfoCompat ->
val split = contentInfoCompat.partition { it.uri != null }
val uriContent = split.first
val remaining = split.second
/** Process uriContent here... **/
//return remaining
remaining
}
ViewCompat.setOnReceiveContentListener(
myEditText,
arrayOf("image/gif", "image/png"),
editTextOnReceiveContentListener
)
Then when 'remaining' is null the app will NOT show the user "AppName doesn't support image insertion here". And most of the time it seems to be work just as I expect.
However if I use the 'Cold Boot Now' option for starting the emulator (and other times occasionally) then the first gif that is entered will still display that image insertion is not supported here. Everything else seems to work fine except it shows the error. This happens even though the log shows that 'remaining' is null. I tested it on emulator devices Nexus 5 and Pixel 2 for API 29 and 31.
My question is, is this something that I should be concerned about and/or can fix in some way?
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.
for awhile now, I am working on a media playing app. In this app, I also programmed a little 5 Band EQ using mainly this code:
try
{
AppPreferencesClass ap = new AppPreferencesClass(ctx);
if (Activity_Player.eq != null)
{
Activity_Player.eq.Dispose();
}
Activity_Player.eq = new Android.Media.Audiofx.Equalizer(0, Activity_Player.mediaPlayerSessionId);
Activity_Player.eq.SetEnabled(true);
await Task.Run(() =>
{
if (Activity_Player.EqActive)
{
if (ap.getAwesomeSound())
{
Activity_Player.eq.SetBandLevel(0, Convert.ToInt16(Activity_Equalizer.awesomesound0));
Activity_Player.eq.SetBandLevel(1, Convert.ToInt16(Activity_Equalizer.awesomesound1));
Activity_Player.eq.SetBandLevel(2, Convert.ToInt16(Activity_Equalizer.awesomesound2));
Activity_Player.eq.SetBandLevel(3, Convert.ToInt16(Activity_Equalizer.awesomesound3));
Activity_Player.eq.SetBandLevel(4, Convert.ToInt16(Activity_Equalizer.awesomesound4));
}
else
{
Activity_Player.eq.SetBandLevel(0, Convert.ToInt16(ap.getEQ0()));
Activity_Player.eq.SetBandLevel(1, Convert.ToInt16(ap.getEQ1()));
Activity_Player.eq.SetBandLevel(2, Convert.ToInt16(ap.getEQ2()));
Activity_Player.eq.SetBandLevel(3, Convert.ToInt16(ap.getEQ3()));
Activity_Player.eq.SetBandLevel(4, Convert.ToInt16(ap.getEQ4()));
}
}
});
}
catch
{
}
For many days, this worked just fine but out of NO WHERE, the catch block sometimes gets activated. But only occasionally.On other times, try works fine but there are just no more changes to the audio being played. This is odd enough, since I never changed anything on this code after it starting working.
I then tried another phone (Samsung S4) on my code and the eq worked just perfectly.
So this got me googleing and I think I might have heard that there can only be as many audiosession IDs after you just would run out. I tested and the audio session ID used here is somewhere at 74,000.
So this could be an issue I thought but this would easialy be tested because I already had this very app running in the google play store just an older version of it. I am 100 percent positive, that in this version the EQ worked on my phone. Otherwise I would have not uploaded that version.
Anyway, I downloaded my old app from the play store and here we go:
It doesnt work anymore. The EQ in the old version also has simply NO effect on the audio. While ofcourse on my other phones this old version works perfectly.
Before I am going to reset my own personal phone I wanted to ask you guys if this could be infact the case.
Another thing is, that I am using many static variables in order to get the EQ to work right. Actually, the variable EQ itself is static. Do maybe static variables sort of leave a "trace" behind and maybe I have set the eq up just "too" many times? Although I am disposing of the object before intialising it again (see in my code).
Summing up:
1.) Can there maybe be a maxmium number of EQ or AudioSessionIDs and I have passed those?
2.) Can creating static variables over and over again in my code cause a memory leak so big, even deinstalling the app doesnt do anything?
Thank you!
This is the error log:
11-20 12:16:43.736 E/AudioEffect(16990): set(): AudioFlinger could not create effect, status: -38
11-20 12:16:43.736 E/AudioEffects-JNI(16990): Error setting AudioEffect
11-20 12:16:43.737 E/AudioEffect-JAVA(16990): Error code -19 when initializing AudioEffect.
Thread started: #311-20 12:16:43.745 V/MediaPlayerNative(16990): unrecognized message: (6, 0, 0)
After 2 days of googeling and trying evetything out, here is the issue:
NOT CALLING RELEASE() will have you eventually have to REBOOT your phone. It wont allow too many instances of an EQ to be set.
Solution:
if (eq != null)
{
eq.Release();
}
I'm using android Log.isLoggable api in order to determine whether my custom log tag is on and should I log. (I'm setting property using setprop log.tag. on the device).
As far as Docs says, and as I'm familiar with older version, it should return true if the log level in the property is equal or high than the one I'm checking in my code.
This works fine for Lollipop and below (api 22) it's seems that something was changed in Marshmallow, as I encounter inconsistency and buggy behavior, playing with the values of the tag will result sometimes with the wrong value returned from isLogabble(), for instance a concrete scenario I did a check in code :
boolean shouldLog = Log.isLoggable("mytag", Log.DEBUG);
Log.d("debug", "shouldLog = " + shouldLog);
I set log.tag.mytag value to some arbitrary string
launch my app, and see the isLoggable = false, that's OK
then I change log.tag.mytag to VERBOSE
launch my app, isLoggable still false , that's not OK! should be true now
same scenario is not reproducible at Lollipop and didn't encounter any other misbehaviors.
Any suggestions, do I miss something here?
Hello there? There is one question.
nexus5 lollipop5.1's issue.
surfaceflinger there is a code that comes in response to the device screen information in ScreenshotClient update by using.
The code looks like the following.
unsigned int sw, sh, xsize, gsize, stride;
... ...
ScreenshotClient sc;
sp<IBinder> display = SurfaceComposerClient::getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain);
if( sc.update(display,Rect(), sw,sh, false) != NO_ERROR) {
... ...
sc.release();
return 0;
}
stride = sc.getStride();
mapbase = sc.getPixels();
... ...
The above code, in other lollipop version is operating normally. Of course, nexus7 the same version also operate normally.
However, the change in nexus5. My code to reference, but continue to code loop is. And because you try to get to continue the screen. First I code in nexus5 is operating normally. However, when a certain count is, update is not came under the other screen to return the error. More ...! After complete finished my code, re-run, after it is another well, the same phenomenon occurs when it comes to a certain number. If you are ability who know about this?
I'm sorry it is not so good in English.
I had solve. ScreenshotClient sc and sp < IBinder > display should be declared as a global variable. If the class is declared error occurs several times. (example. It declared in the function to be repeated.)