I need to use the infrared transmitter on an HTC One device. Before the lolipop update I could do this no problem, but now my code does not work.
Consume
*Edit: UPDATED version of this fix can be found here: https://stackoverflow.com/a/28934938/1042362
Give this a shot:
/*
* preforms some calculations on the codesets we have in order to make them work with certain models of phone.
*
* HTC devices need formula 1
* Samsungs want formula 2
*
* Samsung Pre-4.4.3 want nothing, so just return the input data
*
*/
private static int[] string2dec(int[] irData, int frequency) {
int formula = shouldEquationRun();
//Should we run any computations on the irData?
if (formula != 0) {
for (int i = 0; i < irData.length; i++) {
if (formula == 1) {
irData[i] = irData[i] * 1000000 / frequency;
} else if (formula == 2) {
irData[i] = (int) Math.ceil(irData[i] * 26.27272727272727); //this is the samsung formula as per http://developer.samsung.com/android/technical-docs/Workaround-to-solve-issues-with-the-ConsumerIrManager-in-Android-version-lower-than-4-4-3-KitKat
}
}
}
return irData;
}
/*
* This method figures out if we should be running the equation in string2dec,
* which is based on the type of device. Some need it to run in order to function, some need it NOT to run
*
* HTC needs it on (HTC One M8)
* Samsung needs occasionally a special formula, depending on the version
* Android 5.0+ need it on.
* Other devices DO NOT need anything special.
*/
private static int shouldEquationRun() {
//Some notes on what Build.X will return
//System.out.println(Build.MODEL); //One M8
//System.out.println(Build.MANUFACTURER); //htc
//System.out.println(Build.VERSION.SDK_INT); //19
//Samsung's way of finding out if their OS is too new to work without a formula:
//int lastIdx = Build.VERSION.RELEASE.lastIndexOf(".");
//System.out.println(Build.VERSION.RELEASE.substring(lastIdx+1)); //4
//handle HTC
if (Build.MANUFACTURER.equalsIgnoreCase("HTC")) {
return 1;
}
//handle Lollipop (Android 5.0.1 == SDK 21) / beyond
if (Build.VERSION.SDK_INT >= 21) {
return 1;
}
//handle Samsung PRE-Android 5
if (Build.MANUFACTURER.equalsIgnoreCase("SAMSUNG")) {
if (Build.VERSION.SDK_INT >= 19) {
int lastIdx = Build.VERSION.RELEASE.lastIndexOf(".");
int VERSION_MR = Integer.valueOf(Build.VERSION.RELEASE.substring(lastIdx + 1));
if (VERSION_MR < 3) {
// Before version of Android 4.4.2
//Note: NO formula here, not even the other one
return 0;
} else {
// Later version of Android 4.4.3
//run the special samsung formula here
return 2;
}
}
}
//if something else...
return 0;
}
The stock remote has been stopped since end of April. Download the Peel app which is branded version used on M9.
I've just fixed this problem, for Samsung devices:
Before Android 4.4.3 each element of the pattern is the number of cycles for the on/off pulse.
For Android 4.4.3 and above each element of the pattern if the number of micro seconds for the on/off pulse.
Example:
To transmit a wave 0.5s on, 0.5 off, 0.5 on, at 38000Hz
Before Android 4.4.3 your pattern would be [19000, 190000, 19000] - The 19000 comes from 0.5s*38000Hz
For Android 4.4.3+ your pattern would be [500000, 500000, 500000] - that is you convert each time to microseconds(us).
I'm going to blame Google on this one: Before 4.4.3 was released their API said to use the number of cycles, after 4.4.3 the changed it to say to use microseconds(us), Samsung simply followed the API thus breaking our apps.
Yes, this issue seems to have been reported on the official bug tracker for Android.
I am developing an App which uses the official Consumer IR API introduced in Android 4.4 KitKat. Since the Lollipop rollouts for popular devices like the HTC One M8 or Samsung Galaxy S5 I am getting many reports from users of said devices that my App is not working on Lollipop. I do not own a Lollipop device myself, but I borrowed an M8 and did some tests.
It seems like the method ConsumerIrManager.transmit() is a no-op on Lollipop. No matter was pattern is given, it returns instantly.
Before discovering that Galaxy S5 users have the same problem, I contacted the HTC support on that matter and was told to contact the Google support.
It would seem S5 devices are getting the same issue as well, although it's hard to tell because developers are getting contradictory reports from S5 owners.
Here is an HTC-only fix that someone found for his M7 after it stopped working because of a Lollipop update. He basically reverted to an earlier version of the IR HTC API before they had switched to the official Google's api.
Otherwise, you should star the issue on the bug tracker, and perhaps point your own users to do the same. The more people star this issue, the higher priority it will be given.
My experience on HTC One M7: 1) KitKat 4.4.3 the ConsumerIRManager code worked fine, passing an array of microseconds.
2) Updated to Lolipop 5.0.2 and there was no transmission at all from the IR Led, the no-op problem. I refactored my code to use the HTC API, which requires the waveform in "clock ticks" instead of direct microseconds. All is working now.
It seems we cannot use the ConsumerIRManager on HTC One except for very specific versions, i.e. 4.4.3.