├── .gitignore ├── LICENSE ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── zoser │ │ └── app │ │ └── powermote │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── zoser │ │ │ └── app │ │ │ └── powermote │ │ │ ├── IRController.java │ │ │ ├── IRMessage.java │ │ │ ├── IRMessageRequest.java │ │ │ ├── IRMessages.java │ │ │ ├── IRNecFactory.java │ │ │ ├── IRSonyFactory.java │ │ │ └── MainActivity.java │ └── res │ │ ├── drawable │ │ ├── app_icon.png │ │ ├── button_selector.xml │ │ ├── button_selector_red.xml │ │ ├── icon_01.png │ │ ├── icon_02.png │ │ ├── icon_03.png │ │ ├── icon_04.png │ │ ├── icon_05.png │ │ ├── icon_06.png │ │ ├── icon_07.png │ │ ├── icon_08.png │ │ ├── icon_09.png │ │ └── icon_10.png │ │ ├── layout │ │ ├── main_activity.xml │ │ └── widget_button.xml │ │ ├── mipmap-hdpi │ │ └── ic_launcher.png │ │ ├── mipmap-mdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxxhdpi │ │ └── ic_launcher.png │ │ └── values │ │ ├── attrs.xml │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── zoser │ └── app │ └── powermote │ └── ExampleUnitTest.java ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── images └── image.png └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | # Built application files 2 | *.apk 3 | *.ap_ 4 | 5 | # Files for the ART/Dalvik VM 6 | *.dex 7 | 8 | # Java class files 9 | *.class 10 | 11 | # Generated files 12 | bin/ 13 | gen/ 14 | out/ 15 | 16 | # Gradle files 17 | .gradle/ 18 | build/ 19 | 20 | # Local configuration file (sdk path, etc) 21 | local.properties 22 | 23 | # Proguard folder generated by Eclipse 24 | proguard/ 25 | 26 | # Log Files 27 | *.log 28 | 29 | # Android Studio Navigation editor temp files 30 | .navigation/ 31 | 32 | # Android Studio captures folder 33 | captures/ 34 | 35 | # Intellij 36 | *.iml 37 | .idea/workspace.xml 38 | .idea/tasks.xml 39 | .idea/gradle.xml 40 | .idea/dictionaries 41 | .idea/libraries 42 | .idea/ 43 | 44 | # Keystore files 45 | *.jks 46 | 47 | # External native build folder generated in Android Studio 2.2 and later 48 | .externalNativeBuild 49 | 50 | # Google Services (e.g. APIs or Firebase) 51 | google-services.json 52 | 53 | # Freeline 54 | freeline.py 55 | freeline/ 56 | freeline_project_description.json 57 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Pablo Riedemann 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Android IR Remote Control Application 2 | A simple Android App showing the implementation of the Consumer IR Manager in Android to use the IR Blaster in the phone to control IR Devices. 3 | 4 | I use this to control all the IR devices in my living room. 5 | 6 | ## Features 7 | * Functions to create SIRC Protocol messages. 8 | * 12, 15 and 20 bit variations. 9 | * Functions to create NEC Protocol messages. 10 | 11 | # About the code. 12 | 13 | ## To Create a SIRC Protocol Message 14 | ```cs 15 | // IRSonyFactory.Create(type,command, address, repeats) 16 | IRSonyFactory.create(IRSonyFactory.TYPE_15_BITS,84,10,4); 17 | ``` 18 | 19 | ## To Create a NEC Protocol Message 20 | ```cs 21 | // IRNecFactory.create(command,address,repeats); 22 | IRNecFactory.create(16,32,3);; 23 | ``` 24 | 25 | ## To Send a message using the IR 26 | ```cs 27 | IRMessage msg = IRSonyFactory.create(IRSonyFactory.TYPE_15_BITS,84,10,4); 28 | IRController irController = new IRController(getApplicationContext()); 29 | irController.sendMessage(msg); 30 | ``` 31 | 32 | # Screenshots 33 | ![Example](https://raw.githubusercontent.com/ZoserLock/android-ir-remote/master/images/image.png) 34 | 35 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 24 5 | buildToolsVersion '26.0.2' 6 | defaultConfig { 7 | applicationId "com.zoser.app.powermote" 8 | minSdkVersion 23 9 | targetSdkVersion 24 10 | versionCode 1 11 | versionName "1.0" 12 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | } 21 | 22 | dependencies { 23 | compile fileTree(dir: 'libs', include: ['*.jar']) 24 | androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { 25 | exclude group: 'com.android.support', module: 'support-annotations' 26 | }) 27 | compile 'com.android.support:appcompat-v7:24.2.1' 28 | compile 'com.android.support:support-v4:24.2.1' 29 | testCompile 'junit:junit:4.12' 30 | } 31 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in E:\Compilers\Androidsdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | 19 | # Uncomment this to preserve the line number information for 20 | # debugging stack traces. 21 | #-keepattributes SourceFile,LineNumberTable 22 | 23 | # If you keep the line number information, uncomment this to 24 | # hide the original source file name. 25 | #-renamesourcefileattribute SourceFile 26 | -------------------------------------------------------------------------------- /app/src/androidTest/java/com/zoser/app/powermote/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.zoser.app.powermote; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumentation test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() throws Exception { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("com.zoser.app.powermote", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 12 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /app/src/main/java/com/zoser/app/powermote/IRController.java: -------------------------------------------------------------------------------- 1 | package com.zoser.app.powermote; 2 | 3 | import android.content.Context; 4 | import android.hardware.ConsumerIrManager; 5 | import android.util.Log; 6 | 7 | import java.util.ArrayList; 8 | import java.util.LinkedList; 9 | import java.util.Queue; 10 | 11 | public class IRController extends Thread 12 | { 13 | private static int MAX_QUEUED_COUNT = 2; 14 | private static int MAX_WAIT_PER_PULSE_MS = 40; 15 | private static int MAX_WAIT_PER_MESSAGE_MS = 40; 16 | 17 | private ConsumerIrManager _irManager; 18 | 19 | private Context _context = null; 20 | 21 | private boolean _enabled = false; 22 | 23 | private Object _messageLock = new Object(); 24 | private Queue _messageQueue = new LinkedList(); 25 | 26 | public IRController(Context context) 27 | { 28 | _context = context; 29 | _irManager = (ConsumerIrManager)context.getSystemService(Context.CONSUMER_IR_SERVICE); 30 | 31 | if(_irManager != null) 32 | { 33 | if(_irManager.hasIrEmitter()) 34 | { 35 | _enabled = true; 36 | } 37 | } 38 | } 39 | 40 | private void executeMessage(IRMessageRequest request) 41 | { 42 | if(_enabled) 43 | { 44 | ArrayList messages = request.getMessages(); 45 | for(int a = 0;a < messages.size();++a) 46 | { 47 | IRMessage message = messages.get(a); 48 | 49 | int frequency = message.getFrequency(); 50 | int [] codes = message.getMessage(); 51 | 52 | _irManager.transmit(frequency, codes); 53 | WaitPerMessage(); 54 | } 55 | } 56 | } 57 | 58 | public long sendMessage(IRMessageRequest request) 59 | { 60 | synchronized(_messageLock) 61 | { 62 | if(_messageQueue.size() < MAX_QUEUED_COUNT) 63 | { 64 | _messageQueue.add(request); 65 | _messageLock.notify(); 66 | } 67 | } 68 | 69 | if(request != null) 70 | { 71 | long time = request.getRequestTime(); 72 | return time; 73 | } 74 | else 75 | { 76 | return 0; 77 | } 78 | } 79 | 80 | 81 | public void startWork() 82 | { 83 | this.start(); 84 | } 85 | 86 | public void stopWork() 87 | { 88 | sendMessage(null); 89 | try 90 | { 91 | join(); 92 | } 93 | catch(InterruptedException e) 94 | { 95 | Log.d("Zoser","Interupted"); 96 | } 97 | } 98 | 99 | @Override 100 | public void run() 101 | { 102 | Log.d("Zoser","Worker Starts!"); 103 | while(true) 104 | { 105 | 106 | IRMessageRequest message = null; 107 | synchronized(_messageLock) 108 | { 109 | if(_messageQueue.size() > 0) 110 | { 111 | message = _messageQueue.poll(); 112 | 113 | if(message == null) 114 | { 115 | Log.d("Zoser", "Closing Worker!"); 116 | break; 117 | } 118 | } 119 | else 120 | { 121 | try 122 | { 123 | _messageLock.wait(); 124 | } 125 | catch(InterruptedException e) 126 | { 127 | Log.d("Zoser","Interupted"); 128 | } 129 | } 130 | } 131 | 132 | if(message != null) 133 | { 134 | executeMessage(message); 135 | } 136 | 137 | WaitPerPulse(); 138 | 139 | } 140 | Log.d("Zoser","Worker Stops!"); 141 | } 142 | 143 | private void WaitPerPulse() 144 | { 145 | try 146 | { 147 | Thread.sleep(MAX_WAIT_PER_PULSE_MS); 148 | } 149 | catch(InterruptedException e) 150 | { 151 | e.printStackTrace(); 152 | } 153 | } 154 | 155 | 156 | private void WaitPerMessage() 157 | { 158 | try 159 | { 160 | Thread.sleep(MAX_WAIT_PER_MESSAGE_MS); 161 | } 162 | catch(InterruptedException e) 163 | { 164 | e.printStackTrace(); 165 | } 166 | } 167 | } 168 | -------------------------------------------------------------------------------- /app/src/main/java/com/zoser/app/powermote/IRMessage.java: -------------------------------------------------------------------------------- 1 | package com.zoser.app.powermote; 2 | 3 | public class IRMessage 4 | { 5 | public static int FREQ_37_KHZ = 37000; 6 | public static int FREQ_38_KHZ = 38000; 7 | public static int FREQ_40_KHZ = 40000; 8 | 9 | private int _frequency; 10 | private int _messageTime; 11 | private int [] _message; 12 | 13 | public IRMessage(int frequency, int [] message) 14 | { 15 | _frequency = frequency; 16 | _message = message; 17 | 18 | calculateMessageTime(); 19 | } 20 | 21 | public int getFrequency() 22 | { 23 | return _frequency; 24 | } 25 | 26 | public int[] getMessage() 27 | { 28 | return _message; 29 | } 30 | 31 | public int getMessageTime() 32 | { 33 | return _messageTime; 34 | } 35 | 36 | private void calculateMessageTime() 37 | { 38 | int time = 0; 39 | for(int a=0;a < _message.length;++a) 40 | { 41 | time += _message[a]; 42 | } 43 | _messageTime = time; 44 | } 45 | } 46 | 47 | -------------------------------------------------------------------------------- /app/src/main/java/com/zoser/app/powermote/IRMessageRequest.java: -------------------------------------------------------------------------------- 1 | package com.zoser.app.powermote; 2 | 3 | import java.util.ArrayList; 4 | 5 | public class IRMessageRequest 6 | { 7 | private ArrayList _messages = new ArrayList(); 8 | 9 | public IRMessageRequest(IRMessage... args) 10 | { 11 | for(int a=0;a getMessages() 18 | { 19 | return _messages; 20 | } 21 | 22 | public long getRequestTime() 23 | { 24 | long time = 0; 25 | for(int a=0;a<_messages.size();++a) 26 | { 27 | time += _messages.get(a).getMessageTime(); 28 | } 29 | return time; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /app/src/main/java/com/zoser/app/powermote/IRMessages.java: -------------------------------------------------------------------------------- 1 | package com.zoser.app.powermote; 2 | 3 | public class IRMessages 4 | { 5 | // MISC 6 | public static IRMessage NEC_REPEAT; 7 | // Sony Speaker 8 | public static IRMessage HOME_SONY_SPEAKER_ON; 9 | 10 | // Sony HT 11 | public static IRMessage HOME_SONY_HT_ON; 12 | public static IRMessage HOME_SONY_HT_VOLUME_UP; 13 | public static IRMessage HOME_SONY_HT_VOLUME_DOWN; 14 | // HDMI SPLITTER 15 | public static IRMessage HDMI_SPLITTER_ON; 16 | public static IRMessage HDMI_SPLITTER_SET_1; 17 | public static IRMessage HDMI_SPLITTER_SET_2; 18 | public static IRMessage HDMI_SPLITTER_SET_3; 19 | public static IRMessage HDMI_SPLITTER_SET_4; 20 | public static IRMessage HDMI_SPLITTER_SET_5; 21 | 22 | // LG TV 23 | public static IRMessage HOME_LG_TV_ON; 24 | public static IRMessage HOME_LG_TV_VOLUME_UP; 25 | public static IRMessage HOME_LG_TV_VOLUME_DOWN; 26 | 27 | public static void initialize() 28 | { 29 | // MISC 30 | NEC_REPEAT = IRNecFactory.createRepeat(); 31 | 32 | // Sony Speaker 33 | HOME_SONY_SPEAKER_ON = IRSonyFactory.create(IRSonyFactory.TYPE_12_BITS,84,1,3); 34 | 35 | // Sony HT 36 | HOME_SONY_HT_ON = IRSonyFactory.create(IRSonyFactory.TYPE_15_BITS,84,10,3); 37 | HOME_SONY_HT_VOLUME_UP = IRSonyFactory.create(IRSonyFactory.TYPE_15_BITS,36,10,3); 38 | HOME_SONY_HT_VOLUME_DOWN = IRSonyFactory.create(IRSonyFactory.TYPE_15_BITS,100,10,3); 39 | 40 | // LG TV 41 | HOME_LG_TV_ON = IRNecFactory.create(16,32,2); 42 | HOME_LG_TV_VOLUME_UP = IRNecFactory.create(64,32,2); 43 | HOME_LG_TV_VOLUME_DOWN = IRNecFactory.create(192,32,2); 44 | 45 | //HDMI SPLITTER 46 | HDMI_SPLITTER_ON = IRNecFactory.create(98,0,0); 47 | HDMI_SPLITTER_SET_1 = IRNecFactory.create(2,0,0); 48 | HDMI_SPLITTER_SET_2 = IRNecFactory.create(224,0,0); 49 | HDMI_SPLITTER_SET_3 = IRNecFactory.create(168,0,0); 50 | HDMI_SPLITTER_SET_4 = IRNecFactory.create(144,0,0); 51 | HDMI_SPLITTER_SET_5 = IRNecFactory.create(152,0,0); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /app/src/main/java/com/zoser/app/powermote/IRNecFactory.java: -------------------------------------------------------------------------------- 1 | package com.zoser.app.powermote; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class IRNecFactory 7 | { 8 | public static final int HDR_MARK = 9000; 9 | 10 | public static final int HDR_SPACE = 4500; 11 | 12 | public static final int ONE_MARK = 1687; 13 | public static final int ZERO_MARK = 562; 14 | public static final int SPACE = 562; 15 | 16 | public static final int REPEAT_TIME = 110000; 17 | public static final int REPEAT_SPACE = 2250; 18 | 19 | public static IRMessage create(int command, int addr, int repeats) 20 | { 21 | List message = new ArrayList<>(); 22 | 23 | message.add(HDR_MARK); 24 | message.add(HDR_SPACE); 25 | 26 | List header1 = decodeInt(addr,8); 27 | List header2 = decodeInt(~addr,8); 28 | 29 | List data1 = decodeInt(command,8); 30 | List data2 = decodeInt(~command,8); 31 | 32 | message.addAll(header1); 33 | message.addAll(header2); 34 | message.addAll(data1); 35 | message.addAll(data2); 36 | message.add(SPACE); 37 | 38 | int messageTime=0; 39 | for(int a=0;a message = new ArrayList<>(); 68 | 69 | message.add(HDR_MARK); 70 | message.add(REPEAT_SPACE); 71 | message.add(SPACE); 72 | message.add(REPEAT_TIME - (HDR_MARK + REPEAT_SPACE +SPACE)); 73 | 74 | int [] finalCode = new int[message.size()]; 75 | 76 | for(int a=0;a decodeInt(int num, int bits) 85 | { 86 | List values = new ArrayList<>(); 87 | for (int i = bits - 1; i >= 0; i--) 88 | { 89 | values.add(SPACE); 90 | values.add(((num & (1 << i)) == 0)?ZERO_MARK:ONE_MARK); 91 | } 92 | return values; 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /app/src/main/java/com/zoser/app/powermote/IRSonyFactory.java: -------------------------------------------------------------------------------- 1 | package com.zoser.app.powermote; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class IRSonyFactory 7 | { 8 | public static final int TYPE_12_BITS = 1; 9 | public static final int TYPE_15_BITS = 2; 10 | public static final int TYPE_20_BITS = 3; 11 | 12 | public static final int HDR_MARK = 2400; 13 | public static final int HDR_SPACE = 600; 14 | 15 | public static final int ONE_MARK = 1200; 16 | public static final int ZERO_MARK = 600; 17 | public static final int SPACE = 600; 18 | 19 | public static final int REPEAT_TIME = 45000; 20 | 21 | public static IRMessage create(int mode, int command, int addr, int repeats) 22 | { 23 | List tempMessage = new ArrayList<>(); 24 | List outMessage = new ArrayList<>(); 25 | 26 | tempMessage.add(HDR_MARK); 27 | tempMessage.add(HDR_SPACE); 28 | 29 | List cmdPulses = decodeInt(command,7); 30 | List addrPulses = null; 31 | 32 | switch(mode) 33 | { 34 | case TYPE_12_BITS: 35 | addrPulses = decodeInt(addr,5); 36 | break; 37 | case TYPE_15_BITS: 38 | addrPulses = decodeInt(addr,8); 39 | break; 40 | case TYPE_20_BITS: 41 | addrPulses = decodeInt(addr,13); 42 | break; 43 | default: 44 | break; 45 | } 46 | 47 | tempMessage.addAll(cmdPulses); 48 | tempMessage.addAll(addrPulses); 49 | 50 | int messageTime=0; 51 | for(int a=0;a 1) 57 | { 58 | for(int i = 0; i < repeats; i++) 59 | { 60 | for(int a = 0; a < tempMessage.size() - 1; ++a) 61 | { 62 | outMessage.add(tempMessage.get(a).intValue()); 63 | } 64 | 65 | outMessage.add(REPEAT_TIME - messageTime); 66 | } 67 | } 68 | else 69 | { 70 | for(int a = 0; a < tempMessage.size(); ++a) 71 | { 72 | outMessage.add(tempMessage.get(a).intValue()); 73 | } 74 | } 75 | 76 | int [] finalCode = new int[outMessage.size()]; 77 | 78 | for(int a=0;a decodeInt(int num, int bits) 88 | { 89 | List values = new ArrayList<>(); 90 | for (int i = bits - 1; i >= 0; i--) 91 | { 92 | values.add(((num & (1 << i)) == 0)?ZERO_MARK:ONE_MARK); 93 | values.add(SPACE); 94 | } 95 | return values; 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /app/src/main/java/com/zoser/app/powermote/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.zoser.app.powermote; 2 | 3 | import android.content.Context; 4 | import android.os.Bundle; 5 | import android.os.Vibrator; 6 | import android.support.v7.app.AppCompatActivity; 7 | import android.util.Log; 8 | import android.view.MotionEvent; 9 | import android.view.View; 10 | import android.widget.ImageButton; 11 | import android.widget.ImageView; 12 | import android.widget.LinearLayout; 13 | import android.widget.RelativeLayout; 14 | import android.widget.TextView; 15 | 16 | public class MainActivity extends AppCompatActivity implements View.OnTouchListener 17 | { 18 | private IRController _irController; 19 | 20 | private ImageButton _buttonPowerAll; 21 | 22 | private LinearLayout [] _button = new LinearLayout[12]; 23 | private IRMessageRequest [] _buttonRequest = new IRMessageRequest[12]; 24 | 25 | private LinearLayout [] _rows = new LinearLayout[4]; 26 | 27 | private View _currentClickedView = null; 28 | 29 | private Vibrator _vibrator = null; 30 | 31 | private long _lastBurstTime = 0; // Microsecconds 32 | private long _waitTime = 315000; // Microsecconds 33 | private long _waitTimeMax = 1000000; // Microsecconds 34 | private long _waitTimeMin = 300000; // Microsecconds 35 | 36 | @Override 37 | protected void onCreate(Bundle savedInstanceState) 38 | { 39 | super.onCreate(savedInstanceState); 40 | 41 | IRMessages.initialize(); 42 | 43 | setContentView(R.layout.main_activity); 44 | 45 | getSupportActionBar().hide(); 46 | 47 | _vibrator = (Vibrator) getApplicationContext().getSystemService(Context.VIBRATOR_SERVICE); 48 | 49 | _irController = new IRController(getApplicationContext()); 50 | _irController.startWork(); 51 | 52 | getRowReferences(); 53 | 54 | _buttonPowerAll = (ImageButton) findViewById(R.id.id_Button_ALL); 55 | 56 | _button[0] = createIRButton("HDMI HUB",R.drawable.icon_04,_rows[0], new IRMessageRequest(IRMessages.HDMI_SPLITTER_ON)); 57 | _button[1] = createIRButton("LG TV",R.drawable.icon_01,_rows[0],new IRMessageRequest(IRMessages.HOME_LG_TV_ON)); 58 | _button[2] = createIRButton("HOME THEATER",R.drawable.icon_03,_rows[0],new IRMessageRequest(IRMessages.HOME_SONY_HT_ON)); 59 | 60 | _button[3] = createIRButton("HDMI 1",R.drawable.icon_09,_rows[1],new IRMessageRequest(IRMessages.HDMI_SPLITTER_SET_1)); 61 | _button[4] = createIRButton("HDMI 2",R.drawable.icon_09,_rows[1],new IRMessageRequest(IRMessages.HDMI_SPLITTER_SET_2)); 62 | _button[5] = createIRButton("HTPC",R.drawable.icon_10,_rows[1],new IRMessageRequest(IRMessages.HDMI_SPLITTER_SET_3)); 63 | 64 | _button[6] = createIRButton("VOLUME UP",R.drawable.icon_02,_rows[2],new IRMessageRequest(IRMessages.HOME_LG_TV_VOLUME_UP)); 65 | _button[7] = createIRButton("CHROMECAST",R.drawable.icon_06,_rows[2],new IRMessageRequest(IRMessages.HDMI_SPLITTER_SET_5)); 66 | _button[8] = createIRButton("VOLUME UP",R.drawable.icon_02,_rows[2],new IRMessageRequest(IRMessages.HOME_SONY_HT_VOLUME_UP)); 67 | 68 | _button[9] = createIRButton("VOLUME DOWN",R.drawable.icon_08,_rows[3],new IRMessageRequest(IRMessages.HOME_LG_TV_VOLUME_DOWN)); 69 | _button[10] = createIRButton("SWITCH",R.drawable.icon_07,_rows[3],new IRMessageRequest(IRMessages.HDMI_SPLITTER_SET_4)); 70 | _button[11] = createIRButton("VOLUME DOWN",R.drawable.icon_08,_rows[3],new IRMessageRequest(IRMessages.HOME_SONY_HT_VOLUME_DOWN)); 71 | 72 | _lastBurstTime = System.nanoTime(); 73 | 74 | for(int a=0;a<12;a++) 75 | { 76 | _button[a].setOnTouchListener(this); 77 | } 78 | 79 | _buttonPowerAll.setOnTouchListener(this); 80 | 81 | } 82 | 83 | @Override 84 | protected void onPause() 85 | { 86 | super.onPause(); 87 | Log.d("Zoser","onPause"); 88 | } 89 | 90 | @Override 91 | protected void onRestart() 92 | { 93 | super.onRestart(); 94 | 95 | Log.d("Zoser","onRestart"); 96 | } 97 | 98 | @Override 99 | protected void onDestroy() 100 | { 101 | Log.d("Zoser","onDestroy"); 102 | _irController.stopWork(); 103 | super.onDestroy(); 104 | } 105 | 106 | private void getRowReferences() 107 | { 108 | _rows[0] = (LinearLayout)findViewById(R.id.id_Layout_Row_01); 109 | _rows[1] = (LinearLayout)findViewById(R.id.id_Layout_Row_02); 110 | _rows[2] = (LinearLayout)findViewById(R.id.id_Layout_Row_03); 111 | _rows[3] = (LinearLayout)findViewById(R.id.id_Layout_Row_04); 112 | 113 | } 114 | 115 | 116 | private LinearLayout createIRButton(String title, int imageResource, LinearLayout row,IRMessageRequest request) 117 | { 118 | View child = getLayoutInflater().inflate(R.layout.widget_button, null); 119 | 120 | RelativeLayout mainLayout = (RelativeLayout)child.findViewById(R.id.layout_main); 121 | LinearLayout buttonLayout = (LinearLayout)child.findViewById(R.id.layout_button); 122 | 123 | LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.MATCH_PARENT); 124 | lp.weight = 1; 125 | mainLayout.setLayoutParams(lp); 126 | 127 | ImageView imageView = (ImageView)child.findViewById(R.id.image_main); 128 | TextView titleView = (TextView)child.findViewById(R.id.text_title); 129 | 130 | imageView.setImageResource(imageResource); 131 | titleView.setText(title); 132 | 133 | row.addView(child); 134 | 135 | buttonLayout.setTag(request); 136 | 137 | return buttonLayout; 138 | } 139 | 140 | public boolean onTouch(View v, MotionEvent event) 141 | { 142 | _waitTime = Math.max(_waitTime,_waitTimeMin); 143 | _waitTime = Math.min(_waitTime,_waitTimeMax); 144 | 145 | if((System.nanoTime() - _lastBurstTime) > (_waitTime * 1000)) 146 | { 147 | int ev = event.getActionMasked(); 148 | 149 | if(ev == MotionEvent.ACTION_MOVE) 150 | { 151 | _lastBurstTime = System.nanoTime(); 152 | 153 | if(v == _buttonPowerAll) 154 | { 155 | _waitTime = sendIRMessage(new IRMessageRequest(IRMessages.HDMI_SPLITTER_ON, IRMessages.HOME_LG_TV_ON, IRMessages.HOME_SONY_HT_ON)); 156 | } 157 | else 158 | { 159 | _waitTime = sendIRMessage(((IRMessageRequest) v.getTag())); 160 | } 161 | return true; 162 | } 163 | } 164 | return false; 165 | } 166 | 167 | 168 | public long sendIRMessage(IRMessageRequest request) 169 | { 170 | _vibrator.vibrate(60); 171 | return _irController.sendMessage(request); 172 | } 173 | } 174 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/app_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZoserLock/android-ir-remote/facd1bd6794fb5a3788870da2604cea3a53f9fa1/app/src/main/res/drawable/app_icon.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/button_selector.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/button_selector_red.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/icon_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZoserLock/android-ir-remote/facd1bd6794fb5a3788870da2604cea3a53f9fa1/app/src/main/res/drawable/icon_01.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/icon_02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZoserLock/android-ir-remote/facd1bd6794fb5a3788870da2604cea3a53f9fa1/app/src/main/res/drawable/icon_02.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/icon_03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZoserLock/android-ir-remote/facd1bd6794fb5a3788870da2604cea3a53f9fa1/app/src/main/res/drawable/icon_03.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/icon_04.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZoserLock/android-ir-remote/facd1bd6794fb5a3788870da2604cea3a53f9fa1/app/src/main/res/drawable/icon_04.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/icon_05.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZoserLock/android-ir-remote/facd1bd6794fb5a3788870da2604cea3a53f9fa1/app/src/main/res/drawable/icon_05.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/icon_06.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZoserLock/android-ir-remote/facd1bd6794fb5a3788870da2604cea3a53f9fa1/app/src/main/res/drawable/icon_06.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/icon_07.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZoserLock/android-ir-remote/facd1bd6794fb5a3788870da2604cea3a53f9fa1/app/src/main/res/drawable/icon_07.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/icon_08.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZoserLock/android-ir-remote/facd1bd6794fb5a3788870da2604cea3a53f9fa1/app/src/main/res/drawable/icon_08.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/icon_09.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZoserLock/android-ir-remote/facd1bd6794fb5a3788870da2604cea3a53f9fa1/app/src/main/res/drawable/icon_09.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/icon_10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZoserLock/android-ir-remote/facd1bd6794fb5a3788870da2604cea3a53f9fa1/app/src/main/res/drawable/icon_10.png -------------------------------------------------------------------------------- /app/src/main/res/layout/main_activity.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 17 | 24 | 25 | 39 | 40 | 41 | 49 | 50 | 51 | 59 | 60 | 61 | 69 | 70 | 71 | 72 | 80 | 81 | 82 | 83 | 84 |