11

I am developing an app for commercial use with a background service that is getting transponder numbers (of animals) from an RFID reader via bluetooth.

After processing the received number I would like to send it to the clipboard and paste it in the focused text field of whatever application is currently in front which in my case is a browser app.

I already found a similar question from 2013 but with no accepted answer by now. All answers to the question just explained how to use ClipboardManager to copy and paste code within the developed application but that has not been meant by the problem as he clarified in a comment.

The simplest scenario that I could imagine is to just simulate a paste action on the android device. I would prefer not to need to install a third party app.

Community
  • 1
  • 1
markus s
  • 1,024
  • 1
  • 11
  • 20

2 Answers2

11

Just to add to Kirill's answer and assuming the app has Accessibility permission,

Create a class extending AccessibilityService and override onAccessibilityEvent method.

public class SampleAccessibilityService extends AccessibilityService {

    @Override
    public void onAccessibilityEvent(AccessibilityEvent accessibilityEvent) {
        AccessibilityNodeInfo source = accessibilityEvent.getSource();
        if (source != null) {
            AccessibilityNodeInfo rowNode = getRootInActiveWindow();
            if (rowNode != null) {
                for (int i = 0; i < rowNode.getChildCount(); i++) {
                    AccessibilityNodeInfo accessibilityNodeInfo = rowNode.getChild(i);
                    if (accessibilityNodeInfo.isEditable() && accessibilityNodeInfo.isFocused()) {
                        accessibilityNodeInfo.performAction(AccessibilityNodeInfoCompat.ACTION_PASTE);
                        return;
                    }
                }
            }
        }
    }

    @Override
    public void onInterrupt() {

    }
}

accessibilityNodeInfo.performAction(AccessibilityNodeInfoCompat.ACTION_PASTE) will paste the text that is copied to clipboard.

Also make sure you have right accessibility configuration.

config.xml

<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
    android:accessibilityFlags="flagDefault"
    android:accessibilityEventTypes="typeViewClicked|typeViewFocused"
    android:accessibilityFeedbackType="feedbackGeneric"
    android:notificationTimeout="0"
    android:canRetrieveWindowContent="true"
    android:description="@string/testing" />

Here android:accessibilityEventTypes="typeViewClicked|typeViewFocused" will filter the events to view click or view focus.

You can also the events based on the packages using "android:packageNames" (so that your service won't get called often)

Finally declare the service in manifest,

<service android:name=".SampleAccessibilityService"
            android:label="@string/app_name"
            android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
            <intent-filter>
                <action android:name="android.accessibilityservice.AccessibilityService"/>
            </intent-filter>
            <meta-data
                android:name="android.accessibilityservice"
                android:resource="@xml/config" />
</service>
Govind
  • 2,482
  • 1
  • 28
  • 40
  • I think that is a very comprehensive answer and so I will Mark it as Answer. It seems to do exactly what we need although I cannot test it at the moment because of other priorities. In addition we found [BluePiano: Bluetooth Keyboard-Wedge for Android from TEC-IT][http://www.tec-it.com/en/software/android/bluepiano/keyboard-wedge/Default.aspx] which will do for now. – markus s Jan 20 '17 at 06:41
6

If you want your app to interact with an app that isn't yours (the browser) you will have to give this app accessibility permissions. those are special kind of permission that allow apps to interact with something that is a bit more senstive.

there are accessibility actions, the one that you are looking for is the AccessibilityNodeInfoCompat.ACTION_PASTE it allows you to preform a paste into a focused field.

Note that I'd recommend you to replace the browser with a inapp WebView, and inject the values with javascript this will be much more robust solution for your automation. you can find more info on how to run JS on a webview here: How to get return value from javascript in webview of android?

Community
  • 1
  • 1
Kirill Kulakov
  • 10,035
  • 9
  • 50
  • 67
  • Although your answer hits the nail right on the head I opted for Govind's answer because it gives further details. – markus s Jan 20 '17 at 06:51