MCU volup/voldown - MTCD Android Head Units Q&A

Hi,
What I have
car radio from Isudar called h53 with intel x86 chip (Intel SC9853i)
car with buttonless steering wheel
bluetooth button with buttons next, previous, volume up, volume down
Problem
BT button volume up does control system volume up. But when I press volume up on radio panel, different graphic is shown and different volume is being boosted (i guess amp directly on board)
Solution
So I've decompiled some of apps that come with the systems and found this piece of code:
Code:
} else if (intent.getAction().equals("com.unisound.unicar.broadcast.action")) {
try {
....
} else if (stringExtra.equals("volumeup")) {
this.eK.aT.write(513, 1, 1);
this.eK.aT.write(513, 1, 1);
this.eK.aT.write(513, 1, 1);
} else if (stringExtra.equals("volumedown")) {
this.eK.aT.write(513, 1, 2);
this.eK.aT.write(513, 1, 2);
this.eK.aT.write(513, 1, 2);
} ....
So I've made shell command (something like)
Code:
am broadcast -a com.unisound.unicar.broadcast.action --es type volumeup
Then I used Tasker to run this code and with bxMapper I mapped volume up button to this shell command
MY QUESTION
It's working perfectly, BUT as you can see the code
Code:
if (stringExtra.equals("volumeup")) {
this.eK.aT.write(513, 1, 1);
this.eK.aT.write(513, 1, 1);
this.eK.aT.write(513, 1, 1);
}
There are three of these writes, so volume jumps +3 units...
How to make it only +1 unit?
I'm programming webapps, java/android is out of my scope. Can anyone push me a little how to simply send write command to MCU? THX!

Related

Console commands in app?

How do i use console commands in apps, i have searched google with and did not find anything. And if possible, could someone upload an app with a button that runs a console commands. I am making an app that will start obexserver.
A portion of my Hello World for Android which doubles as a command line evaluator.
Code:
String txt = ((EditText) findViewById(R.id.txtCmd)).getText().toString(); // cmd line
boolean su = ((CheckBox) findViewById(R.id.asRoot)).isChecked(); // run as root
Process p;
try {
if (su) {
p = Runtime.getRuntime().exec("su");
(new DataOutputStream(p.getOutputStream())).writeBytes(txt + "; exit\n"); // you want the shell to terminate itself so you know the command has finished
} else
p = Runtime.getRuntime().exec(txt);
} catch (Exception e) {
e.printStackTrace();
return;
}
try {
StringBuilder sb = new StringBuilder();
InputStreamReader isr = new InputStreamReader(p.getInputStream());
int r;
while ((r = isr.read()) > 0)
sb.append((char) r); // you may want to use a buffer
msg = sb.toString();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
thanks, but i really dont have any idea about how to put this in the app
Basically you use Runtime.getRuntime().exec() to start a shell and Process object to interact with the it. I assume you have to be root to manipulate bluetooth, so you have to execute su first (which launches the default shell as root) and use the input and output streams to simulate user typing. The input stream is just standard. You'll have to use InputStreamReader if you want to read characters, and wrap a BufferedReader around that to read lines. For the output side, we use DataOutputStream to write bytes to the shell (this is cheap, but it works well for ASCII.).

Double Click Event

Hello everybody!
I do not know is this right place to ask this kind of question. If not, please move my topic to another forum.
I will be appreciate for explanation how to implement the double-click event for any object (eg. Button) from TextView class.
Thanks for any advice!
Your question doesn't really make much sense. Which control are you trying to catch the double-click event from? Button, or TextView? The control that is lowest in the view hierarchy that implements the method will catch it. Is the Button placed in an extended TextView? Or is the TextView in an extended Button?
Maybe my question wasn't precise. I would like to know how to implement the double-click listener for Button or TextView or EditText.
since you arent asking for a specific way to do it this is super rough and will not work; Just give you and idea. This is how I would do it atleast
Code:
private int numberOfClicks = 0;
....yada yada yada
//onClickListener {
numberOfClicks++;
if(numberOfClicks >= 2) {
// Call the method you want to call when the user double clicks
numberOfClicks = 0;
}
}
... yada yada yada
Burlyskink said:
since you arent asking for a specific way to do it this is super rough and will not work; Just give you and idea. This is how I would do it atleast
Code:
private int numberOfClicks = 0;
....yada yada yada
//onClickListener {
numberOfClicks++;
if(numberOfClicks >= 2) {
// Call the method you want to call when the user double clicks
numberOfClicks = 0;
}
}
... yada yada yada
Click to expand...
Click to collapse
This is a bad way to do it, since there is no timeout. If a user presses once and then waits 30 minutes and pesses again it will count as a double click. A better way would be log the millisecond timestamp when they click and then check it with the previous timestamp. If new_stamp-old_stamp < x milliseconds then it's a double tap, else it is a single tap.
That's assuming you can't just add a listener for a double tap even dispatch. I don't know if there is one because I've never needed it, but I will take a look.
Edit:
There is no double click event you can attach to, so you'd be wanting to do one of two things:
First is similar to previously posted code, but would be better to do this:
Code:
private double _millis = 0;
private static final int DOUBLE_TAP_TIMEOUT = 500; //half a second to wait for double tap
...etc...
//onClickListener {
if(0==_millis)
{
_millis = getTimeMillis();
setTimeout(DOUBLE_TAP_TIMEOUT,onTimeout);
}
else
{
cancelTimeout(); //This is second tap so cancel timeout until single tap is accepted
if(getTimeMillis()-_millis<=DOUBLE_TAP_TIMEOUT)
{
onDoubleTap(); //do double tap func
_millis=0; //reset millis
}
else
{
//millis is > 0 but this is first tap. Either millis wasn't reset or timeout func was not called
//Throw exception, handle error or do some default action
_millis = 0; //reset millis so next click is first
}
}
}
//onTimeout {
//User tapped, then didn't tap again before the timeout was over
_millis = 0; // reset millis
onClick(); // do single tap func
}
}
Problem with this method is that your millis, timeout and other double-tap centric functions are going to be in the parent class, therefore defeating the whole point of OOP. A far better way would be to create an inherrited class that is based on button/textview/whatever and override the code for detecting clicks. Then do pretty much the same thing as above but instead of calling your onClick/onDoubleclick internals, you'd call the callback that was passed in during setOnClickListener/setOnDoubleClickListener (you'd have to create the setOnDoubleClickListener yourself but if you look at setOnClickListener it'd be pretty much c&p)
Oh and note that the above is pseudocode - you can't run it.
Looking in Google, analysing, I found the best solution - I think. It's short and easy... It use not OnClickListener, but OnTouchListener, but is very similar to TomasTrek proposition. I will past it, maybe next time it will help somebody...
Code:
public class TestProject extends Activity {
private long lastTouchTime = -1;
protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);
Button button = (Button)findViewById(R.id.Button01);
button.setOnTouchListener(new OnTouchListener() {
public boolean onTouch(View arg0, MotionEvent mev) {
if(mev.getAction() == MotionEvent.ACTION_DOWN) {
long thisTime = System.currentTimeMillis();
if (thisTime - lastTouchTime < 250) {
lastTouchTime = -1;
//code to perform
} else {
lastTouchTime = thisTime;
}
}
return false;
}
});
}
}
What do you think?
gmadajczak said:
Looking in Google, analysing, I found the best solution - I think. It's short and easy... It use not OnClickListener, but OnTouchListener, but is very similar to TomasTrek proposition. I will past it, maybe next time it will help somebody...
Code:
public class TestProject extends Activity {
private long lastTouchTime = -1;
protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);
Button button = (Button)findViewById(R.id.Button01);
button.setOnTouchListener(new OnTouchListener() {
public boolean onTouch(View arg0, MotionEvent mev) {
if(mev.getAction() == MotionEvent.ACTION_DOWN) {
long thisTime = System.currentTimeMillis();
if (thisTime - lastTouchTime < 250) {
lastTouchTime = -1;
//code to perform
} else {
lastTouchTime = thisTime;
}
}
return false;
}
});
}
}
What do you think?
Click to expand...
Click to collapse
That looks like a winner, but I would suggest changing the code to look for the up event. Google engineers have changed the way some things work internally, and most of the new functions check on the up event. The reason this changed was to better work with soft buttons on the screen (such as the capacitive touch buttons on the face of the new Droid).
So, let me suggest changing:
Code:
if (mev.getAction() == MotionEvent.ACTION_DOWN)
to
Code:
if (mev.getAction() == MotionEvent.ACTION_UP)
rpcameron said:
That looks like a winner, but I would suggest changing the code to look for the up event. Google engineers have changed the way some things work internally, and most of the new functions check on the up event. The reason this changed was to better work with soft buttons on the screen (such as the capacitive touch buttons on the face of the new Droid).
So, let me suggest changing:
Code:
if (mev.getAction() == MotionEvent.ACTION_DOWN)
to
Code:
if (mev.getAction() == MotionEvent.ACTION_UP)
Click to expand...
Click to collapse
Thanks!
Another question. How to convert this code to custom Listener OnDoubleClickListener?
TomasTrek said:
This is a bad way to do it, since there is no timeout. If a user presses once and then waits 30 minutes and pesses again it will count as a double click. A better way would be log the millisecond timestamp when they click and then check it with the previous timestamp. If new_stamp-old_stamp < x milliseconds then it's a double tap, else it is a single tap.
That's assuming you can't just add a listener for a double tap even dispatch. I don't know if there is one because I've never needed it, but I will take a look.
Edit:
There is no double click event you can attach to, so you'd be wanting to do one of two things:
First is similar to previously posted code, but would be better to do this:
Code:
private double _millis = 0;
private static final int DOUBLE_TAP_TIMEOUT = 500; //half a second to wait for double tap
...etc...
//onClickListener {
if(0==_millis)
{
_millis = getTimeMillis();
setTimeout(DOUBLE_TAP_TIMEOUT,onTimeout);
}
else
{
cancelTimeout(); //This is second tap so cancel timeout until single tap is accepted
if(getTimeMillis()-_millis<=DOUBLE_TAP_TIMEOUT)
{
onDoubleTap(); //do double tap func
_millis=0; //reset millis
}
else
{
//millis is > 0 but this is first tap. Either millis wasn't reset or timeout func was not called
//Throw exception, handle error or do some default action
_millis = 0; //reset millis so next click is first
}
}
}
//onTimeout {
//User tapped, then didn't tap again before the timeout was over
_millis = 0; // reset millis
onClick(); // do single tap func
}
}
Problem with this method is that your millis, timeout and other double-tap centric functions are going to be in the parent class, therefore defeating the whole point of OOP. A far better way would be to create an inherrited class that is based on button/textview/whatever and override the code for detecting clicks. Then do pretty much the same thing as above but instead of calling your onClick/onDoubleclick internals, you'd call the callback that was passed in during setOnClickListener/setOnDoubleClickListener (you'd have to create the setOnDoubleClickListener yourself but if you look at setOnClickListener it'd be pretty much c&p)
Oh and note that the above is pseudocode - you can't run it.
Click to expand...
Click to collapse
Oh my, your right! I didn't even think about that lawl. Good catch, atleast it may have given him a path to start with xD
gmadajczak said:
Another question. How to convert this code to custom Listener OnDoubleClickListener?
Click to expand...
Click to collapse
The code I posted the change to had the OnTouchListener() method that was created. After the Button is created, it then has the OnTouchListener() method defined inline when setOnTouchListener() is called. This is the same method you use to handle any touch event event on that particular control.
How does it need to be converted to listen for double-taps, when that is what the example code is looking for?

[Q] Android Dev - Handling Enter...

Since I don't have access to the android software forum yet, and searching hasn't come up with any results (maybe I'm missing something) I'm going to post here...
I'm developing an app and I'm in a testing phase with about 6 testers all using different devices. I've run into an issue with one tester where the code that handles the use of the Enter key in an EditText box doesn't work. I've gone about this three different ways but with no luck. All three methods work fine on my device:
Method 1:
Code:
TextView.OnEditorActionListener keyListener = new TextView.OnEditorActionListener(){
public boolean onEditorAction(TextView view, int actionId, KeyEvent event) {
if(actionId == EditorInfo.IME_NULL){
if(((EditText)findViewById(view.getId())) == ((EditText)findViewById(R.id.etUser))){
((EditText) findViewById(R.id.etPass)).requestFocus();
}
if(((EditText)findViewById(view.getId())) == ((EditText)findViewById(R.id.etPass))){
logon();
}
}
return true;
}
};
Method 2:
Code:
EditText etUserName = (EditText) findViewById(R.id.etUser);
etUserName.setOnKeyListener(new OnKeyListener() {
public boolean onKey(View view, int keyCode, KeyEvent event){
if (event.getAction() == KeyEvent.ACTION_DOWN){
switch (keyCode)
{
case KeyEvent.KEYCODE_DPAD_CENTER:
case KeyEvent.KEYCODE_ENTER:
if(((EditText)findViewById(view.getId())) == ((EditText)findViewById(R.id.etUser))){
((EditText) findViewById(R.id.etPass)).requestFocus();
}
return true;
default:
break;
}
}
return false;
}
});
Method 3:
Code:
TextView.OnEditorActionListener keyListener = new TextView.OnEditorActionListener(){
public boolean onEditorAction(TextView view, int actionId, KeyEvent event) {
if(actionId == EditorInfo.IME_ACTION_NEXT) {
((EditText) findViewById(R.id.etPass)).requestFocus();
}
if (actionId == EditorInfo.IME_ACTION_DONE) {
logon();
}
return true;
}
};
Since I don't have physical access to the device, after the last method I wrote some code into the app to notify the tester if the event's actually being triggered. Nothing. So what the hell is going on here? The tester's handset is an Xperia Arc with stock 2.3.2 and she doesn't have an issue with the enter key in other apps. Is there another method that is more fool proof then relying on inconsistent IME action ids or key codes?

[Q] Control cursor PC by WP7

I want to control the PC cursor by WP7, so I try to use the ManipulationDelta in WP7 that can help me to calculate the difference between he star tap and the end tap
Code:
public MainPage()
{
InitializeComponent();
this.ManipulationDelta += new EventHandler<ManipulationDeltaEventArgs>(MainPage_ManipulationDelta);
transformG = new TransformGroup();
translation = new TranslateTransform();
transformG.Children.Add(translation);
RenderTransform = transformG; // you see I don't use any transform here because I don't know where I put. If I use the image.RenderTransform of it will move also for the screen of WP if I put this.RenderTransform, So anyone have a solution
SenderSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
}
void MainPage_ManipulationDelta(object sender, ManipulationDeltaEventArgs e)
{
startX = e.ManipulationOrigin.X;
startY = e.ManipulationOrigin.Y;
DeltaX = e.DeltaManipulation.Translation.X;
DeltaY = e.DeltaManipulation.Translation.Y;
translation.X += e.DeltaManipulation.Translation.X;
translation.Y += e.DeltaManipulation.Translation.Y;
EndX = Convert.ToDouble(translation.X);
EndY = Convert.ToDouble(translation.Y);
}
I am juste want to send DeltaX and DeltaY to the server to calculate them to the mouse position in the screen, So I write this code
Code:
void StartSending()
{
while (!stop)
try
{
SocketAsyncEventArgs socketEventArg = new SocketAsyncEventArgs();
byte[] buffer = Encoding.UTF8.GetBytes(DeltaX.ToString() + "/" + DeltaY.ToString());
socketEventArg.SetBuffer(buffer, 0, buffer.Length);
SenderSocket.SendToAsync(socketEventArg);
}
catch (Exception) { }
}
I concatenate them in 1 buffer with separate by "/" and in server I use this code to separate
Code:
void Receive(byte[] buffer)
{
string chaine = "";
if (SenderSocket != null)
{
SocketAsyncEventArgs socketEventArg = new SocketAsyncEventArgs();
socketEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(delegate(object s, SocketAsyncEventArgs e)
{
if (e.SocketError == SocketError.Success)
{
chaine = Encoding.UTF8.GetString(e.Buffer, e.Offset, e.BytesTransferred);
chaine.Trim('\0');
string[] pos = chaine.Split('/');
for (int i = 0; i < pos.Length; i++)
{
pX = Convert.ToInt32(pos[0]);
pY = Convert.ToInt32(pos[1]);
this.Cursor = new Cursor(Cursor.Current.Handle);
Cursor.Position = new Point(Cursor.Position.X + pX, Cursor.Position.Y + pY);
}
}
else
{
}
});
SenderSocket.ReceiveFromAsync(socketEventArg);
}
Just I want to control the cursor, if you have any other methods so plz help me and I am really grateful
Didn't you already have a thread about this? Please re-use existing threads instead of starting new ones. Even if it wasn't you, *somebody* was working on this problem already, and very recently. Always use the Search button before starting a thread.
So... what are you looking for from us? Does your current code work? If not, in what way does it fail? Without knowing what your question is, we can't provide answers.
If you want some advice, though...
Sending as strings is very inefficient on both ends; it would be better to use arrays (which you could convert directly to byte arrays and back again).
You're sending as TCP, which is OK but probably not optimal. For this kind of data, UDP is quite possibly better. If nothing else, it provides clearly delineated packets indicating each update.

[PATCH]Various Swipe Gestures to Wake

Disclaimer
First off all, thanks to showp1984 for his original sweep2wake, based on which, this has been made.
I am a newbie in linux kernel programming, I did spend considerable amount of time, working with others to know about how touch input works. In many places, code will be useless, or there may be better way of implementation. Based on my understanding, I coded this.
This was originally made for a specific device, so I will try to explain wherever possible, so that it becomes easier for someone to implement in case they are interested.
This post does not show how to add hooks in touch panel driver and display driver.
Gestures Available
Swipe Left
Swipe Right
Swipe Up
Swipe Down
Swipe Forward Diagonally
Swipe Backward Diagonally
Draw 'L'
Draw 'V'
Commits
Initial Commit - https://github.com/corphish/android_kernel_sony_msm8930_lp/commit/dae03796da1f8ce97ed41c1b150b18741ac75f24 (Please read the extended description, as I have explained there what I have done)
Fixes - https://github.com/corphish/android_kernel_sony_msm8930_lp/commit/73562680a73956af105bffc0f2d1e7815a375677
Walkthrough
First off all I modified detect_sweep2wake function.
Code:
static bool detect_sweep2wake(int x, int y, int id)
{
key = KEY_POWER;
if (id == 255 && s2w_touch_count > 10) {
int x = s2w_coord_nature();
if(x) {
if(x == 1) {
if(s2w_right) {
s2w_coord_reset();
doubletap2wake_reset();
return true;
}
}
if(x == 2) {
if(s2w_left){
s2w_coord_reset();
doubletap2wake_reset();
return true;
}
}
if(x == 3) {
if(s2w_up){
s2w_coord_reset();
doubletap2wake_reset();
return true;
}
}
if(x == 4) {
if(s2w_down){
s2w_coord_reset();
doubletap2wake_reset();
return true;
}
}
if(x == 5) {
if(s2w_fwd_diag){
s2w_coord_reset();
doubletap2wake_reset();
return true;
}
}
if(x == 6) {
if(s2w_bck_diag){
s2w_coord_reset();
doubletap2wake_reset();
return true;
}
}
if(x == 7) {
if(s2w_l){
s2w_coord_reset();
doubletap2wake_reset();
return true;
}
}
if(x == 8) {
if(s2w_v){
s2w_coord_reset();
doubletap2wake_reset();
return true;
}
}
//pr_info("%s returned true\n",__func__);
}
} else {
//doubletap2wake_reset();
s2w_coord_dump(x, y);
direction_vector_calc();
new_touch(x, y);
}
if (ktime_to_ms(ktime_get())-tap_time_pre > D2W_TIME){
s2w_coord_reset();
doubletap2wake_reset();
}
//pr_info("%s returned false\n",__func__);
return false;
}
It now takes id as parameters as well.
id here is the touch id which is returned when we lift off contact from touch.
Do note that for this device, the id returned when we lift off contact from touch is 255, it will be different for different devices.
What this new detect_sweep2wake fn does is, it tests whether the id returned is that id (touch id which is returned when we lift off contact from touch) and the touch count is greater than a specific number or not.
The specific touch count is used to detect continuous touches (swipes).
If true, it calls for gesture detection function, if true, returns true, if false returns false.
If false, it dumps co-ordinates. Co-ordinates are dumped to 2 variables (x,y) and previous data is stored in (x_prev,y_prev). The first values of touch (the touch co-ordinates on first touch) is stored separately as well.
Then direction_vector_calc is called, which tests the nature of co-ordinates with respect to the previous one.
Code:
void direction_vector_calc(void) {
int tot = 0;
if(s2w_coord_count > 1) {
if(x > x_pre) {
dir[0]++; //right
tot++;
} else if (x < x_pre) {
dir[1]++; //left
tot++;
}
if(y < y_pre) {
dir[2]++; //up
tot++;
} else if (y > y_pre) {
dir[3]++; //down
tot++;
}
//To determine whether both x and y co-ordinates have changed from previous input or not and act accordingly.
if(tot > 1)
multiple_dir++;
//To determine max deviation in x coord.
if(x > max_x)
max_x = x;
//To determine min deviation in x coord.
if(x < min_x)
min_x = x;
//To determine max deviation in y coord.
if(y > max_y)
max_y = y;
//To determine min deviation in y coord.
if(y < min_y)
min_y = y;
} else {
min_y = y;
min_x = x;
max_x = x;
max_y = y;
}
}
At times, there maybe cases that a co-ordinate differs from its previous co-ordinate by 2 directions. This functions take care of that too.
The readings are stored in an array an then tested by gesture detection logic.
The working of gesture_detection is explained in the extended description of this commit.
Code:
int s2w_coord_nature(void)
{
int i = 0;
pr_info("%s:Recieved count - %d\n",__func__,s2w_touch_count);
pr_info("%s:max_x-%d\n",__func__,max_x);
pr_info("%s:max_y-%d\n",__func__,max_y);
pr_info("%s:min_x-%d\n",__func__,min_x);
pr_info("%s:min_y-%d\n",__func__,min_y);
/*This function detects the nature of sweep input, and on the basis of following, it returns -
1 - sweep right
2 - sweep left
3 - sweep up
4 - sweep down*/
pr_info("%s:multiple_dir - %d\n",__func__,multiple_dir);
for(i = 0; i < 4; i++ )
pr_info("%s:dir[%d] - %d\n",__func__,i,dir[i]);
if (abs(x - x_first) > 150 && abs(y - y_first) < 50 && abs(max_y - y) < 50) {
if(dir[0] > s2w_touch_count/2) {
pr_info("%s:Sweep right\n",__func__);
return 1;
}
else if(dir[1] > s2w_touch_count/2) {
pr_info("%s:Sweep left\n",__func__);
return 2;
}
}
if (abs(y - y_first) > 150 && abs(x - x_first) < 50 && abs(max_x - x) < 50) {
if(dir[2] > s2w_touch_count/2) {
pr_info("%s:Sweep up\n",__func__);
return 3;
}
else if(dir[3] > s2w_touch_count/2) {
pr_info("%s:Sweep down\n",__func__);
return 4;
}
}
if(abs(x - x_first) > 100 && abs(y - y_first) > 100 && (multiple_dir == s2w_touch_count - 1)) {
if(x > x_first) {
pr_info("%s:Forward diagonal swipe!!\n",__func__);
return 5;
}//forward diagonal swipe!!
else if(x < x_first) {
pr_info("%s:Backward diagonal swipe!!\n",__func__);
return 6;
}//backward diagonal swipe!!
}
if(abs(x - x_first) > 100 && abs(y - y_first) > 100 && (multiple_dir < s2w_touch_count - 1) && dir[0] > s2w_touch_count/3 && dir[3] > s2w_touch_count/3) {
pr_info("%s:Draw 'L'\n",__func__);
return 7;
}
if(abs(x - x_first) > 80 && abs(y - y_first) < 50 && dir[2] > s2w_touch_count/3 && dir[3] > s2w_touch_count/3 && (multiple_dir < s2w_touch_count - 1)) {
pr_info("%s:Draw 'V'\n",__func__);
return 8;
}
s2w_coord_reset();
return 0;
}
If swipe matches any gesture, it returns corresponding value, else returns 0.
About toggling, I created separate files for each gesture. Also, to simplify things, I had added a master switch for these gestures.
I also made an app for this to control these toggles - Gesture Control 1.4
Credits
showp1984 - Without his works, this is just nothing.
thewisenerd - It is for this guy, I know what I know about touch panels.

Categories

Resources