ConsumerIrManage.hasIrEmitter()始终返回false(API 19)

kal*_*nas 6 android infrared android-4.4-kitkat

我打电话ConsumerIrManager.hasIrEmitter()给我的LG G2,但它总是回来false.

根据红外发射器的文档:

在包含红外(IR)发射器的设备上运行时,您现在可以使用ConsumerIrManagerAPI 传输IR信号.要获取实例ConsumerIrManager,请将getSystemService()CONSUMER_IR_SERVICE作为参数调用.然后,您可以getCarrierFrequencies()通过传递所需的频率和信号模式来查询设备支持的IR频率并发送信号transmit().

您应该首先通过调用来检查设备是否包含IR发射器hasIrEmitter(),但如果您的应用仅与具有一个设备的设备兼容,则应<uses-feature>在清单中包含"android.hardware.consumerir"(FEATURE_CONSUMER_IR)元素.

我的代码如下:

MainActivity.java

import android.hardware.ConsumerIrManager;
....

@Override
protected void onCreate(Bundle savedInstanceState) {
    ....
    ConsumerIrManager mCIR = (ConsumerIrManager)getSystemService(CONSUMER_IR_SERVICE);
    Log.e(TAG, "mCIR.hasIrEmitter(): " + mCIR.hasIrEmitter());
    PackageManager pm = getPackageManager();
    Log.e(TAG, "pm.hasSystemFeature(PackageManager.FEATURE_CONSUMER_IR): "
        + pm.hasSystemFeature(PackageManager.FEATURE_CONSUMER_IR));
    FeatureInfo[] fi = pm.getSystemAvailableFeatures();
    for (int i = 0; i < fi.length; i++) {
        Log.e(TAG, "Feature: " + fi[i].name);
    }
    ....
}
Run Code Online (Sandbox Code Playgroud)

AndroidManifest.xml中

<uses-permission android:name="android.permission.TRANSMIT_IR" android:required="false" />
<uses-feature android:name="android.hardware.consumerir" />
Run Code Online (Sandbox Code Playgroud)

SystemAvailableFeatures列表中我看不到"android.hardware.consumerir"(FEATURE_CONSUMER_IR),但LG G2肯定有IR.

有没有人成功使用hasEmitterIr()

Ran*_*ndy 14

对于任何想要从十六进制IR代码转换为十进制"计数"模式到十进制"持续时间"模式的人:

三星电源十六进制代码(来自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
Run Code Online (Sandbox Code Playgroud)

转换使用HEX2DEC方法为十进制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
Run Code Online (Sandbox Code Playgroud)

使用第一个参数作为您的频率,并将其余参数放入计数模式的int数组中:

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};
Run Code Online (Sandbox Code Playgroud)

使用频率查找每秒脉冲数:

Frequency: 38028; 
Second: 1,000,000 Microseconds
Second/Frequency = Pulses
1000000/38028 = ~26.3 Pulses
Run Code Online (Sandbox Code Playgroud)

通过将每个值乘以脉冲将计数模式转换为持续时间模式:

169 * 26.3 = 4444
168 * 26.3 = 4418
21 * 26.3 = 552
...
Run Code Online (Sandbox Code Playgroud)

如果您想快速获取包含所有Duration值的字符串,那么只需通过hex2dec方法运行十六进制代码,然后在此方法中使用该输出:

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;
}
Run Code Online (Sandbox Code Playgroud)

这将打印十进制持续时间值的字符串到日志.然后我会复制它(不包括第一个值)并创建一个静态的最终int数组,如下所示:

    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};
Run Code Online (Sandbox Code Playgroud)

现在您已将两个模式作为静态final int数组,您可以传输:

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);
            }
        }
    }   
};
Run Code Online (Sandbox Code Playgroud)

注意:我不确定4.4.4需要哪种模式.


小智 3

我尝试使用 HTC One Google Play 版本的 ConsumerIrManager。

ConsumerIrManager.hasIrEmitter() 返回 true。我可以通过consumerIrManager.transmit()传输IR代码。

但我遇到了一个问题,transmit() 的行为与 Android API 文档不同。

API文档如下。

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.
Run Code Online (Sandbox Code Playgroud)

但参数“pattern”的单位似乎是25微秒,而不是微秒。这是因为载波的一个脉冲的长度为25微秒。(我将载波频率设置为40000Hz,因此一个脉冲的长度为25微秒。)

我不确定这是 HTC One Google Play Edition 的移植错误,还是 Android 4.4 的错误。


注意:我在尝试在 Samsung Tab2 上使用 IR 时注意到,计时周期也偏离了 25.6 倍(实际脉冲长度 / 25.6),所以这可能是 IR 发射器模块的内部功能吗?