【问题标题】:ConsumerIrManage.hasIrEmitter() always returns false (API 19)ConsumerIrManage.hasIrEmitter() 总是返回 false (API 19)
【发布时间】:2013-11-27 13:54:04
【问题描述】:

我在我的 LG G2 上调用 ConsumerIrManager.hasIrEmitter(),但它总是返回 false

根据Infrared transmitters上的文档:

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

您应始终首先通过调用hasIrEmitter() 检查设备是否包含红外发射器,但如果您的应用仅与具有红外发射器的设备兼容,则应在清单中为"android.hardware.consumerir" 添加<uses-feature> 元素(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);
    }
    ....
}

AndroidManifest.xml

<uses-permission android:name="android.permission.TRANSMIT_IR" android:required="false" />
<uses-feature android:name="android.hardware.consumerir" />

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

有人成功使用hasEmitterIr()吗?

【问题讨论】:

  • 您找到解决方案了吗?我对 G2 有同样的问题

标签: android android-4.4-kitkat infrared


【解决方案1】:

对于任何想要从十六进制 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

使用irdude中的hex2dec方法转换为十进制:

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

使用第一个参数作为您的频率,并将其余参数放入您的计数模式的 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};

使用频率找出每秒的脉冲数:

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

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

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

如果您想快速获取包含所有 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;
}

这会将十进制持续时间值的字符串打印到日志中。然后我会复制它(不包括第一个值)并制作一个静态的最终 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};

现在您已经将两个模式作为静态最终 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);
            }
        }
    }   
};

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

【讨论】:

  • 这对我有用,但仅适用于三星。你认为你可以为 HTC 工作吗?
  • 这是我相信的 HTC 手机。您使用的是哪个版本的 Android?
  • 我使用的是 Android 5.0 HTC m8。是的,我在 API 更改之前为 htc 编写了代码,以前可以在 HTC 上工作,但现在不能在三星上工作,现在反过来了,不能让它在 HTC 上工作
  • 我在第二个数组 (SAMSUNG_POWER_TOGGLE_DURATION) 上发现了一个缺失值。似乎没有转换 169 的值。如果这是您将要使用的数组,请在 4368 之前添加 4495。在我发现数组长度不匹配之前,代码无法正常工作。现在可以了。
  • @0014,谢谢...编辑答案以添加缺失值。
【解决方案2】:

我使用 HTC One Google Play Edition 尝试了 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.

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

我不确定这是否是 HTC One Google Play 版的移植错误,或者 Android 4.4 的一个错误。


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

【讨论】:

  • 三星 Galaxy Note 3 也是如此。API 文档似乎不正确...
  • 该死的 Android 文档。我昨天晚上浪费了整个晚上,想知道为什么我的代码不起作用。读完这篇文章后,我只是将长度除以 25.6,它就起作用了。 Android 文档清楚地说明了“以微秒为单位传输的交替开/关模式”。
【解决方案3】:

我在 HTC One 上使用 CM 11 可以正常工作。模式数组包含脉冲数,而不是时间。这是 Google 文档中的错误。

我怀疑它不适用于 LG 和 Sony,因为它们使用带有内置代码数据库的 IR 芯片。我希望我错了。

Touchsquid 应用很快就会有这个驱动程序。

【讨论】:

  • 您知道如何将 Pronto 十六进制代码转换为正确的 ConsumerIr 模式 (int[]) 吗?如果来自此处的 hex2dec 方法,我正在使用一个变体:github.com/rngtng/IrDude/blob/master/src/com/rngtng/irdude/… 但不是返回一个字符串,而是返回一个带有 dec 值的 int[] 表。似乎不起作用..转换有问题??
  • 好的,我知道我的错误了。问题是频率是在表的开头添加的,并且不需要,因为您将其作为 ConsumerIrManager.transmit(int carrierFrequency, int[] pattern) 的第一个参数提供!!
【解决方案4】:

我制作了一个小应用来在我的 LG G2 上测试 IR Balster,使用

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

它给了我一条消息:“没有找到红外发射器!”

函数 hasIrEmitter() 返回 false。 ConsumerIrManager API 似乎没有实现。

【讨论】:

  • 在索尼 Xperia ZL 上相同。我不明白为什么 ConsumerIrManager 不能在所有带有红外线发射器的 KitKat 设备上工作。我认为这就是将 ConsumerIrManager 集成到 KitKat 的原因。注意:在 LG G2 上,您可以使用 LG 的 QRemoteSDK。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-20
  • 2021-11-05
  • 2018-11-05
  • 2019-05-06
相关资源
最近更新 更多