ConsumerIrManage.hasIrEmitter() always returns false (API 19)

僤鯓⒐⒋嵵緔 提交于 2019-11-28 17:41:03

For anyone else who wants to go from a hex IR code to a decimal 'count' pattern to a decimal 'duration' pattern:

Samsung Power hex code (From remotecentral.com):

0000 006d 0022 0003 00a9 00a8 0015 003f 0015 003f 0015 003f 0015 0015 0015 0015 0015 0015 0015 0015 0015 0015 0015 003f 0015 003f 0015 003f 0015 0015 0015 0015 0015 0015 0015 0015 0015 0015 0015 0015 0015 003f 0015 0015 0015 0015 0015 0015 0015 0015 0015 0015 0015 0015 0015 0040 0015 0015 0015 003f 0015 003f 0015 003f 0015 003f 0015 003f 0015 003f 0015 0702 00a9 00a8 0015 0015 0015 0e6e

Convert to decimal using the hex2dec method in irdude:

38028,169,168,21,63,21,63,21,63,21,21,21,21,21,21,21,21,21,21,21,63,21,63,21,63,21,21,21,21,21,21,21,21,21,21,21,21,21,63,21,21,21,21,21,21,21,21,21,21,21,21,21,64,21,21,21,63,21,63,21,63,21,63,21,63,21,63,21,1794,169,168,21,21,21,3694

Use the first argument as your frequency and put the rest in an int array for your Count Pattern:

private static final int SAMSUNG_FREQ = 38028;
private static final int[] SAMSUNG_POWER_TOGGLE_COUNT = {169,168,21,63,21,63,21,63,21,21,21,21,21,21,21,21,21,21,21,63,21,63,21,63,21,21,21,21,21,21,21,21,21,21,21,21,21,63,21,21,21,21,21,21,21,21,21,21,21,21,21,64,21,21,21,63,21,63,21,63,21,63,21,63,21,63,21,1794,169,168,21,21,21,3694};

Use the frequency to find the pulses per second:

Frequency: 38028; 
Second: 1,000,000 Microseconds
Second/Frequency = Pulses
1000000/38028 = ~26.3 Pulses

Convert the Count Pattern to Duration Pattern by multiplying each value by the pulses:

169 * 26.3 = 4444
168 * 26.3 = 4418
21 * 26.3 = 552
...

If you want a quick way to get a string with all of the Duration values, then just run your hex code through the hex2dec method and then use that output in this method:

protected String count2duration(String countPattern) {
    List<String> list = new ArrayList<String>(Arrays.asList(countPattern.split(",")));
          int frequency = Integer.parseInt(list.get(0));
          int pulses = 1000000/frequency;
          int count;
          int duration;

          list.remove(0);

          for (int i = 0; i < list.size(); i++) {
           count = Integer.parseInt(list.get(i));
           duration = count * pulses;
           list.set(i, Integer.toString(duration));
          }

          String durationPattern = "";
          for (String s : list) {
           durationPattern += s + ",";
          }

          Log.d(TAG, "Frequency: " + frequency);
          Log.d(TAG, "Duration Pattern: " + durationPattern);

    return durationPattern;
}

That will print the string of decimal duration values to the log. I would then just copy that (not including the first value) and make a static final int array like this:

    private static final int[] SAMSUNG_POWER_TOGGLE_DURATION = {4495,4368,546,1638,546,1638,546,1638,546,546,546,546,546,546,546,546,546,546,546,1638,546,1638,546,1638,546,546,546,546,546,546,546,546,546,546,546,546,546,1638,546,546,546,546,546,546,546,546,546,546,546,546,546,1664,546,546,546,1638,546,1638,546,1638,546,1638,546,1638,546,1638,546,46644,4394,4368,546,546,546,96044};

So now that you have your two patterns as static final int arrays, you can transmit:

ConsumerIrManager mCIR;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // Get a reference to the ConsumerIrManager
    mCIR = (ConsumerIrManager) this.getSystemService(Context.CONSUMER_IR_SERVICE);

    setContentView(R.layout.consumer_ir);

    // Set the OnClickListener for the button so we see when it's pressed.
    findViewById(R.id.send_button).setOnClickListener(mSendClickListener);
}


View.OnClickListener mSendClickListener = new View.OnClickListener() {
    public void onClick(View v) {
        if (!mCIR.hasIrEmitter()) {
            Log.e(TAG, "No IR Emitter found\n");
            return;
        }

        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
            mCIR.transmit(SAMSUNG_FREQ, SAMSUNG_POWER_TOGGLE_COUNT);
            } else { 
             // Later version of Android 4.4.3
             mCIR.transmit(SAMSUNG_FREQ, SAMSUNG_POWER_TOGGLE_DURATION);
            }
        }
    }   
};

Note: I'm not sure which pattern 4.4.4 needs.

kita yuki

I tried ConsumerIrManager using HTC One Google Play Edition.

consumerIrManager.hasIrEmitter() returned true. And I could transmit IR codes by consumerIrManager.transmit().

But I had a problem that the behavior of transmit() was different from the Android API document.

The API document is as follows.

public void transmit (int carrierFrequency, int[] pattern)
  Tansmit and infrared pattern 
  This method is synchronous; when it returns the pattern has been transmitted. 
  Only patterns shorter than 2 seconds will be transmitted.

  Parameters
    carrierFrequency    The IR carrier frequency in Hertz.
    pattern                 The alternating on/off pattern in microseconds to transmit.

But it seemed that the unit of parameter "pattern" was 25microseconds, not microseconds. This is because the length of one pulse of the carrier was 25microseconds. (I set carrierFrequency to 40000Hz, so the length of one pulse was 25microseconds.)

I am not sure whether this a porting bug of HTC One Google Play Edition, or a bug of Android 4.4.


Note: Just something I noticed while trying to use the IR on a Samsung Tab2 was the timing periods were also off by a factor of 25.6 (actual pulse length / 25.6) so could this be a internal function of the IR transmitter module?

I have this working fine on HTC One using CM 11. The pattern array contains the number of pulse, not the timings. This is an error in Google documentation.

I suspect it won't work on LG and Sony as they use an IR chip with built in databse of codes. I hope I'm wrong about this.

Touchsquid apps will have this driver shortly.

I made a small app to test IR Balster on my LG G2 using

https://android.googlesource.com/platform/development/+/master/samples/ApiDemos/src/com/example/android/apis/hardware/ConsumerIr.java

https://android.googlesource.com/platform/development/+/master/samples/ApiDemos/res/layout/consumer_ir.xml

It gave me a message: "No IR Emitter found!"

The function hasIrEmitter() returns false. The ConsumerIrManager API does not seems to be implemented.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!