Simulate Taking Picture In Default System Camera App
Solution 1:
Yes, Its possible After 2 days investigation I find the solution.
Requirement : Open system camera app and click pic.
Step 1:
Add Camera permission in manifest file:
<uses-permission android:name="android.permission.CAMERA"/>
<uses-feature
android:name="android.hardware.camera"
android:required="false" />
<uses-feature
android:name="android.hardware.camera.front"
android:required="false" />
Step 2: Create one service which extends AccessibilityService
<service
android:name=".AccessTest"
android:enabled="true"
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"
android:exported="true">
<intent-filter>
<action android:name="android.accessibilityservice.AccessibilityService" />
</intent-filter>
<meta-data
android:name="android.accessibilityservice"
android:resource="@xml/accessibility_service_config"/>
</service>
Step 3: Start service when you required
Intent mailAccessabilityIntent = new Intent(getApplicationContext(), AccessTest.class);
startService(mailAccessabilityIntent);
Step 4: Add accessibility file.
<?xml version="1.0" encoding="utf-8"?>
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
android:accessibilityEventTypes="typeAllMask"
android:accessibilityFeedbackType="feedbackAllMask"
android:accessibilityFlags="flagEnableAccessibilityVolume"
android:canRetrieveWindowContent="true"
android:notificationTimeout="100"
android:packageNames="com.google.android.GoogleCamera"
android:settingsActivity="com.mobiliya.cameraautoclick.MainActivity" />
Step 5: Write service class where you want to handle camera related listener.
public class AccessTest extends AccessibilityService {
private final static String TAG = "Yogesh";
@Override
public void onCreate() {
super.onCreate();
Log.d("Yogesh","I am started");
}
@Override
protected void onServiceConnected() {
super.onServiceConnected();
Log.d(TAG, "onServiceConnected");
}
@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
Log.d(TAG, "ACC::onAccessibilityEvent: " + event.getEventType());
//TYPE_WINDOW_STATE_CHANGED == 32
if (AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED == event
.getEventType()) {
AccessibilityNodeInfo nodeInfo = event.getSource();
if (nodeInfo == null) {
return;
}
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
String x = takePictureIntent.resolveActivity(getPackageManager()).getPackageName();
Log.d("Yogesh","Package name " + x);
List<AccessibilityNodeInfo> list1 = nodeInfo.findAccessibilityNodeInfosByText("Switch to front camera");
for (AccessibilityNodeInfo node : list1) {
Log.i(TAG, "ACC::onAccessibilityEvent: click " + node);
node.performAction(AccessibilityNodeInfo.ACTION_CLICK);
}
final List<AccessibilityNodeInfo> list = nodeInfo.findAccessibilityNodeInfosByText("Take photo");
final android.os.Handler handler = new android.os.Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
for (AccessibilityNodeInfo node : list) {
Log.i(TAG, "ACC::onAccessibilityEvent: click " + node);
node.performAction(AccessibilityNodeInfo.ACTION_CLICK);
}
handler.postDelayed(this,5000);
}
},10000);
for (AccessibilityNodeInfo node : list) {
Log.i(TAG, "ACC::onAccessibilityEvent: click " + node);
node.performAction(AccessibilityNodeInfo.ACTION_CLICK);
}
Log.d(TAG,"Access " + getAllChildNodeText(nodeInfo).toString());
}
}
private List<CharSequence> getAllChildNodeText(AccessibilityNodeInfo infoCompat) {
List<CharSequence> contents = new ArrayList<>();
if (infoCompat == null)
return contents;
if (infoCompat.getContentDescription() != null) {
contents.add(infoCompat.getContentDescription().toString().isEmpty() ? "unlabelled" : infoCompat.getContentDescription());
} else if (infoCompat.getText() != null) {
contents.add(infoCompat.getText().toString().isEmpty() ? "unlabelled" : infoCompat.getText());
} else {
getTextInChildren(infoCompat, contents);
}
if (infoCompat.isClickable()) {
if (infoCompat.getClassName().toString().contains(Button.class.getSimpleName())) {
if (contents.size() == 0) {
contents.add("Unlabelled button");
} else {
contents.add("button");
}
}
contents.add("Double tap to activate");
}
return contents;
}
private void getTextInChildren(AccessibilityNodeInfo nodeInfoCompat, List<CharSequence> contents) {
if (nodeInfoCompat == null)
return;
if (!nodeInfoCompat.isScrollable()) {
if (nodeInfoCompat.getContentDescription() != null) {
contents.add(nodeInfoCompat.getContentDescription());
} else if (nodeInfoCompat.getText() != null) {
contents.add(nodeInfoCompat.getText());
}
if (nodeInfoCompat.getChildCount() > 0) {
for (int i = 0; i < nodeInfoCompat.getChildCount(); i++) {
if (nodeInfoCompat.getChild(i) != null) {
getTextInChildren(nodeInfoCompat.getChild(i), contents);
}
}
}
}
}
@Override
public void onInterrupt() {
}
}
Here getAllChildNodeText() return all text button which is clickable, Google default application have Take Photo
text so for this view you can perform action.
Added handler for capture pic every 10 seconds for more clarification.
If you want to track multiple camera app then remove below line and use Java code for set package more details See -Accessibility Service
android:packageNames="com.google.android.GoogleCamera"
I uploaded working example -> https://github.com/ycrathi/cameraautoclick
Note: In above GitHub repo have multiple unwanted code, which I tried.
This solution is not global for all app. You can find some famous app like google camera and find text and then perform click action package wise.
Solution 2:
you can use 3rd-party "fake camera" apps such as:
Image2Camera Fake Camera by New Horizon Apps Fake Camera - donate version by Vaclav Balak
alternatively you can use:
ICS emulator - that supports camera
alternatively you can use:
In your AVD advanced settings, you should be able to set front and back cameras to Webcam() or Emulated
Post a Comment for "Simulate Taking Picture In Default System Camera App"