如何通过安卓手机传输红外信号实现电视开机、增减音量?

6

我使用了这段代码来控制三星电视的开机、音量增加和减少,但是它对我没有起作用。所以我想知道我有没有漏掉什么或者做错了什么,请给我建议。

 power.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                irSend(v);
            }
        });

        volup.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                irSend(v);
            }
        });

        voldown.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                irSend(v);
            }
        });
        irData = new SparseArray<String>();
            irData.put(R.id.voldown,
                    hex2dec("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"));
            irData.put(R.id.volup,
                    hex2dec("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 003f 0015 003f 0015 003f 0015 0015 0015 0015 0015 0015 0015 0015 0015 0015 0015 0015 0015 0015 0015 0015 0015 003f 0015 003f 0015 003f 0015 003f 0015 003f 0015 0702 00a9 00a8 0015 0015 0015 0e6e"));
            irData.put(R.id.power,
                    hex2dec("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 003f 0015 003f 0015 0015 0015 003f 0015 0015 0015 0015 0015 0015 0015 0015 0015 0015 0015 0015 0015 003f 0015 0015 0015 003f 0015 003f 0015 003f 0015 003f 0015 0702 00a9 00a8 0015 0015 0015 0e6e"));



        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {

            irInit4KitKat();

        }
    }

@TargetApi(Build.VERSION_CODES.KITKAT)
public void irInit4KitKat() {

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

}


public void irSend(View view) {

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT){

        irSend4Kitkat(view);
    }
}

    @TargetApi(Build.VERSION_CODES.KITKAT)
    private void irSend4Kitkat(View view) {

if(mCIR.hasIrEmitter() == true){
    String data = irData.get(view.getId());
    if (data != null) {
    String values[] = data.split(",");
    int[] pattern = new int[values.length-1];

    for (int i=0; i<pattern.length; i++){
        pattern[i] = Integer.parseInt(values[i+1]);
    }
    Log.e("LOG", mCIR.getCarrierFrequencies()+ "@" + Integer.parseInt(values[0]) + "@" + pattern);

    mCIR.transmit(Integer.parseInt(values[0]), pattern);
    }
}else{
        Log.e("LOG", "not supported options");
        Toast.makeText(MainActivity.this , "This device is not Support infrared." , Toast.LENGTH_LONG).show();
        }
    }



    protected String hex2dec(String irData) {
    List<String> list = new ArrayList<String>(Arrays.asList(irData
        .split(" ")));
    list.remove(0); // dummy
    int frequency = Integer.parseInt(list.remove(0), 16); // frequency
    list.remove(0); // seq1
    list.remove(0); // seq2

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

    frequency = (int) (1000000 / (frequency * 0.241246));
        list.add(0, Integer.toString(frequency));

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

我还在menifest文件中设置了权限。
 <uses-permission android:name="android.permission.TRANSMIT_IR"
    android:required="false" />
<uses-feature android:name="android.hardware.consumerir" />

我只使用19及以上版本。当我们点击文本电源时,红外线灯会亮起来。


我从未做过这种类型的应用程序,请给我建议。谢谢。 - user6615010
1个回答

1

虽然我不熟悉Android红外API,但我可以分享一些我以前构建玩具项目时收集到的知识。

背景

本质上,我想制作一个控制我家周围红外设备的应用程序。我的问题是,我的先前(和当前)的Android设备没有任何红外功能。

解决方案

为了解决这个问题,我编写了几个Arduino示例,利用红外LED向这些设备发送信号,并让我的Android设备使用蓝牙与Arduinos通信。当Arduino通过蓝牙接收到特定消息时,就会发出精确的红外信号,指定某个设备的命令。

而且它起作用了!

实际代码和答案之前的小总结

对我来说,这不是一项容易的任务,需要做些研究。在所提供的样本代码中,我无法知道你对这个主题的了解程度,因此我认为我会倾泻我解决问题时所知道的一切。

它是如何工作的?

嗯,你们可能已经知道了,红外线是使用红外光作为传输的另一种串行通信方式。通俗地说,这意味着有某些东西模拟了1和0(灯亮与灯灭),并且两个设备都需要发送和读取位以理解消息。

旁注:它对光干扰非常敏感,但在室内工作得很好。 旁注2:一些供应商(如Sony)会发送短暂的消息突发而不是一次性发送消息。 Sony在较长的暂停之前会发送3个信号的短有效载荷。

彩蛋:我还注意到一些供应商会发送静态前缀,以便他们的设备可以过滤掉命令中的干扰。

例如:以0xFEFEXXXX开头的以正确频率发送的消息是Vendor-X的有效前缀。

我如何知道我需要使用哪个消息和频率才能让我的电视/空调发出哔哔声?

嗯,你有点麻烦。通常,红外通信协议是专有的而不是开源的。这意味着有两件主要的事情可以解决这个问题:

  1. 你可以自己尝试破解协议(建议)
  2. 你可以进行调查,看看是否有在线社区已经针对你所针对的供应商破解了协议

1-自己破解协议

如果你已经拥有一个供应商设备,这听起来可能是一项艰巨的任务,但如果你已经拥有一个供应商设备,那么这并不难。问题在于,一旦供应商对通信协议感到舒适,他们就会将其塞入每个其他设备中,直到发现重大缺陷。因此,一旦你破解了Vendor-X电视的代码,它也很可能适用于其他Vendor-X电视。

我该怎么做?

我为我的数码相框(NIX X08G)、Sony Bravia电视和廉价LED灯带使用了一个简单的Arduino草图,配合红外接收器获取信号并将其打印出来。

你可以在这里找到所有的代码

您要找的是ir_code_dump文件夹下的.ino草图。 请确保传感器与README.md文件中描述的规格相匹配。 所以只需组装硬件(非常简单和便宜),将ir_code_dump草图烧录到Arduino中,然后使用红外线遥控器指向红外线传感器并开始将输出拉入串行控制台。 您可能只需从Arduino IDE复制输出到一个.txt 文件中,稍后在Android/Arduino项目中使用该文件。
正如您在存储库的其他文件夹中看到的,我已经编写了非常小的Arduino草图,用于切换帧、Sony电视和LED灯条。

嘿,但是你上面提到了空调。为什么没有空调的草图?

很好。关于AC发生的事情是,它们所吐出的消息太长了,我无法使用ir_code_dump arduino sketch来提取消息,因为存在内存限制和实现细节。 尽管如此,有一些开源的努力试图提取这些消息并使它们可供社区使用。 这是我使用过的repo

2-进行研究

看到我上面描述的所有内容?很可能已经有其他人为您完成了这项工作,并在github或类似网站上发布了它。您可以搜索并查看是否已经破解了您供应商的代码。

在Android上发送消息

在这里,我只能提供指南,告诉您如果我必须自己实现它,我会怎么做,因为我从未有机会使用给定的API。

开源库

我敢打赌,肯定有人已经解决了这个问题,并且很可能创建了一个开源库,你可以直接使用。这种方法是最快的,也是最不麻烦的,因为其他人已经使用过它并测试过它是否有效地解决了手头的问题。你还可以偷偷看一下代码,看看如何自己实现同样的功能。这个看起来很合适

自己实现

假设你已经破解了想要发送的负载和你愿意发送的频率:你缺少的是使用Android API对其进行编码。

查看Arduino IR库,了解他们如何实际切换红外LED的实现细节,看看你是否可以自己完成或者是否有包装器API可以简化这个过程。

最后注意:

我知道我没有提供解决你特定问题的Android示例代码,但我希望我能为你提供一些启示,让你更容易找到正确的路径或自己解决问题。

祝节日快乐!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接