Force stop app using accessibility service Android? - android

I am using accessibility service for reading top package. But now I need to stop app and stop it's all running services through accessibility.
I have been searching on same found clean master doing same.
Please suggest how can I do same?

Using accessibility service you can force stop application.Ref below code
public class MyAccessibilityService extends AccessibilityService {
#Override
public void onAccessibilityEvent(AccessibilityEvent event) {
//TYPE_WINDOW_STATE_CHANGED == 32
if (AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED == event
.getEventType()) {
AccessibilityNodeInfo nodeInfo = event.getSource();
if (nodeInfo == null) {
return;
}
List<AccessibilityNodeInfo> list = nodeInfo
.findAccessibilityNodeInfosByViewId("com.android.settings:id/left_button");
//We can find button using button name or button id
for (AccessibilityNodeInfo node : list) {
node.performAction(AccessibilityNodeInfo.ACTION_CLICK);
}
list = nodeInfo
.findAccessibilityNodeInfosByViewId("android:id/button1");
for (AccessibilityNodeInfo node : list) {
node.performAction(AccessibilityNodeInfo.ACTION_CLICK);
}
}
}
#Override
public void onInterrupt() {
// TODO Auto-generated method stub
}
}
Open Setting screen click application which u want to force stop from installed application.
https://developer.android.com/guide/topics/ui/accessibility/services.html#event-details

Related

Prevent onAccessibilityEvent(AccessibilityEvent event) goes in an infinite loop

I've got an AccessibilityEvent which can stop app automatically. But when starting app info intent, it goes to infinite loop of turn on/off alert dialog.
How can I prevent it ? Here's the code:
#Override
public void onAccessibilityEvent(AccessibilityEvent event) {
if (AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED == event
.getEventType()) {
AccessibilityNodeInfo nodeInfo = event.getSource();
if (nodeInfo == null) {
return;
}
List<AccessibilityNodeInfo> list = nodeInfo
.findAccessibilityNodeInfosByViewId("com.android.settings:id/force_stop_button");
for (AccessibilityNodeInfo node : list) {
Log.i(TAG, "check1 = " + check);
node.performAction(AccessibilityNodeInfo.ACTION_CLICK);
check = true;
}
list = nodeInfo
.findAccessibilityNodeInfosByText("CANCEL");
for (AccessibilityNodeInfo node : list) {
node.performAction(AccessibilityNodeInfo.ACTION_CLICK);
}
}
}
And by the way, any idea to get the force_stop_button clicked immediately after the app info intent started ?
EDIT: I think the problem is in AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED. If I bypass that check, it works, but really hard to control.
In your code, whenever the AccessibilityService detects the Force Stop button in Settings activity, it is clicked.
Now, a dialog will be shown with two buttons : Ok & Cancel.
You are then performing click action on cancel button.
So, App Info -> Dialog -> Cancel -> App Info -> Dialog -> Cancel ...
is the loop you will get.
Change list = nodeInfo.findAccessibilityNodeInfosByText("CANCEL");
to list = nodeInfo.findAccessibilityNodeInfosByText("OK");
In order to click a node, you have to add some delay :
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
node.performAction(AccessibilityNodeInfo.ACTION_CLICK);
}
}, 300);

Android AccessibilityService: How to record and replay view clicks?

I am trying to implement an AccessibilityService that records the user's actions (only click events at this point) and stores them, such that they can be replayed at a later point in time.
For this I register for AccessibilityEvent.TYPE_VIEW_CLICKED events and check if I could somehow recover them later on (when all I have is a reference to the window / root node of the activity) by using two strategies:
Get the clicked view's id and look for this id in the root node's tree
Get the clicked view's text and look for this text in the root node's tree
I have tested this in various applications and different parts of the Android system and the results have been very confusing. About half of the views were not recoverable by any of the two strategies, and some views were sometimes reported as being recoverable and sometimes not. I found out that the latter was due to a race condition, since the accessibility service runs in a different process than the application to which the clicked views belong.
My question now is whether there is a better way to get a handle to a view in an accessibility and find this view again in a later execution of the application.
Below you find the code of my AccessiblityService class:
public class RecorderService extends AccessibilityService {
private static final String TAG = "RecorderService";
#Override
public void onAccessibilityEvent(AccessibilityEvent event) {
switch (event.getEventType()) {
case AccessibilityEvent.TYPE_VIEW_CLICKED:
AccessibilityNodeInfo node = event.getSource();
if (node == null) {
Log.i(TAG, "node is null");
return;
}
AccessibilityNodeInfo root = getRootInActiveWindow();
if (root == null) {
Log.i(TAG, "root is null");
return;
}
// Strategy #1: locate node via its id
String id = node.getViewIdResourceName();
if (id == null) {
Log.i(TAG, "id is null");
} else {
List<AccessibilityNodeInfo> rootNodes = root.findAccessibilityNodeInfosByViewId(id);
if (rootNodes.size() == 1) {
Log.i(TAG, "success (via id)");
return;
} else {
Log.i(TAG, "multiple nodes with that id");
}
}
// Strategy #2: locate node via its text
CharSequence text = node.getText();
if (text == null) {
Log.i(TAG, "text is null");
} else {
List<AccessibilityNodeInfo> rootNodes = root.findAccessibilityNodeInfosByText(text.toString());
if (rootNodes.size() == 1) {
Log.i(TAG, "success (via text)");
return;
}
}
Log.i(TAG, "failed, node was not recoverable");
}
}
#Override
protected boolean onKeyEvent(KeyEvent event) {
Log.i("Key", event.getKeyCode() + "");
return true;
// return super.onKeyEvent(event);
}
#Override
public void onInterrupt() {
}
}
I am developing this on SDK Version 21 (Lollipop) and testing it on a HTC Nexus M8 and a Samsung Galaxy Note2, both showing similar results.

Is it possible to shutdown a phone with android Accessibility Services

Accessibility Services provide us a way to take actions for users,Is it possible to shutdown a phone with this feature?As shown in the code :
public class MyAccessibilityService extends AccessibilityService {
#Override
public void onAccessibilityEvent(AccessibilityEvent event) {
// get the source node of the event
AccessibilityNodeInfo nodeInfo = event.getSource();
// Use the event and node information to determine
// what action to take
// take action on behalf of the user
nodeInfo.performAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD);
// recycle the nodeInfo object
nodeInfo.recycle();
}
...
}
Can we implement 'shutdown' in "//what action to take" section? You can check this service in https://developer.android.com/guide/topics/ui/accessibility/services.html#act-for-users

Android iBeacon Receiving Single Specified Signal

I am receiving a range of signals from onReceive using BroadcastReceiver in my iBeaconProject. What I would like to do is to only keep track of one of the beacons (which I specify) and it's distance from my phone to the beacon. Any ideas, guys? Please help me! I'm using http://www.radiusnetworks.com. I am getting a range of signals using the following onReceive function. How do I go about doing it? Thanks all in advance!
BroadcastReceiver bReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
int countBea = 0;
if (intent.getAction().equals(intentname) && intent.getExtras() != null && intent.getExtras().containsKey(intentname)) {
Collection<IBeacon> beaconsCol = (Collection<IBeacon>)intent.getExtras().getSerializable(intentname);
for (IBeacon bea : beaconsCol) {
Log.d("beac receive!","receive! "+bea.getProximityUuid()+" "+bea.getMajor()+" "+bea.getMinor()+" "+bea.getAccuracy()+" "+bea.getProximity()+" "+bea.getRssi()+" "+bea.getTxPower());
countBea++;
if(((mainActivity)getActivity()).UUIDValue.equalsIgnoreCase(bea.getProximityUuid())
&& ((mainActivity)getActivity()).MajorValue == bea.getMajor()
&& ((mainActivity)getActivity()).MinorValue == bea.getMinor()) {
update(bea.getProximityUuid(), +bea.getMajor(), bea.getMinor(), bea.getAccuracy());
} else if (((mainActivity)getActivity()).UUIDValue.equalsIgnoreCase(bea.getProximityUuid())
&& (((mainActivity)getActivity()).MajorValue == 0 ||
((mainActivity)getActivity()).MinorValue == 0)) {
updateNILMajorMinor();
} else {
updateMultipleBeaconsDetected();
}
}
System.out.println("COUNTBEAC " + countBea);
}
}
};
Good to see the for-each loop.
Inside it, you can identify the beacon that you want to keep track of,
for (IBeacon bea : beaconsCol) {
//in the following if, identify the specified beacon
// this will remain the same for every refresh
if(bea.getProximityUuid().equals("match it here") && bea.getMajor()==major
&& bea.getMinor()==minor){
//now display that beacon's proximity and accuracy
//the same code will update a textview or notification every time
// here you will have 1 beacon at a time, can add that to a global list
}
}
Can you give a precise idea for the implementation?
does your code enter onReceive periodically?
I have never seen anything mention using the Radius Networks SDK by listening for broadcasts. Instead they ask that you implement certain interfaces and register them with an IBeaconManager.
You may find their code samples useful. That page contains the following snippet, which you may recognize as equivalent to the code in your question.
public class RangingActivity extends Activity implements IBeaconConsumer, RangeNotifier {
private static final String TAG = RangingActivity.class.getName();
private IBeaconManager iBeaconManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
iBeaconManager = IBeaconManager.getInstanceForApplication(this);
iBeaconManager.bind(this);
}
#Override
protected void onDestroy() {
super.onDestroy();
iBeaconManager.unBind(this);
}
#Override
public void onIBeaconServiceConnect() {
iBeaconManager.setRangeNotifier(this);
try {
// edit this to match the UUID of your beacon
// or leave null to detect everything
String uuid = null;
Region region = new Region("myRangingUniqueId", uuid, null, null);
iBeaconManager.startRangingBeaconsInRegion(region);
} catch (RemoteException e) {
Log.e(TAG, "problem while starting ranging", e);
}
}
#Override
public void didRangeBeaconsInRegion(Collection<IBeacon> iBeacons, Region region) {
if (!iBeacons.isEmpty()) {
double accuracy = iBeacons.iterator().next().getAccuracy();
Log.i(TAG, "The first iBeacon I see is about " + accuracy + " meters away.");
}
}
}

Back Button Issue in Android Webview

THe problem is little difficult to convey, The Actual scenario will be help you guys to understand the real problem.
In the Android Application.
I have a lot of the Jquery Mobile Page append to the android Webview.
When i select one Page (E.g) Profile , the page opens properly and if i press the back button, the application moves to the main page, if i again select profile and press back the application goes to the login page.
if i select some other page and select the profile this is not happening. this issue is not only with the single page. in all the page i have the same issue. Can some one guide me what should i have do?
The Source code of the Key Press event,
enter code here
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK && webview.isEnabled()
&& !this.onLogin) {
webview.loadUrl("javascript:handleDeviceBack()");
return true;
} else if (keyCode == KeyEvent.KEYCODE_BACK && this.onLogin) {
moveTaskToBack(true);
}
if (keyCode == KeyEvent.KEYCODE_HOME) {
webview.loadUrl("javascript:handleDeviceHome()");
return true;
}
return false;
}
In my web view,
enter code here
handleDeviceBack = function(status) {
mHealth.util.logMessage('On device Back');
var historyBack = {
"home" : "page",
"loginPage" : "page",
"welcomeMsg" : "page"
};
var moduleIndex = {
"assessNotFound" : "../../home/view/home.html",
"showActivity" : "../../home/view/home.html",
"showMessage" : "../../home/view/home.html",
"show_tracker" : "../../home/view/home.html",
"settingsPage" : "../../home/view/home.html"
};
var graphPages = {
"singlehealthdatapage" : "page",
"multiplehealthdatapage" : "page"
};
var otherShortcuts = {
"show_tracker_view" : "../../trackers/view/showtracker.html",
"detailMessage" : "../../messages/view/showmessage.html",
"alfrescoDIV" : "../../messages/view/showmessage.html"
};
// var exitAppCriteria={ "home" : "page","loginPage" : "page","welcomeMsg" :
// "page"};
if($('.ui-page-active').attr('id')=="condition_index")
{
$.mobile.changePage("../../home/view/history.html");
}
else if (historyBack[$('.ui-page-active').attr('id')]
|| $('body').children().is('#tandcPage')) {
Android.finishActivity();
} else if (moduleIndex[$('.ui-page-active').attr('id')]) {
Android.highlightHome();
$('.ui-alert-wallpaper').detach();
$.mobile.changePage(moduleIndex[$('.ui-page-active').attr('id')]);
} else if (graphPages[$('.ui-page-active').attr('id')]) {
Android.showTab();
Android.pageHistory();
} else if (otherShortcuts[$('.ui-page-active').attr('id')]) {
$.mobile.changePage(otherShortcuts[$('.ui-page-active').attr('id')]);
} else {
$('.dw').detach();
$('.dwo').detach();
$('.dw').detach();
$('.ui-alert-wallpaper').detach();
Android.showTab();
Android.pageHistory();
}
};
I found the problem is with the Android.pageHistory();
enter code here
public void pageHistory() {
this.activity.runOnUiThread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
WebContainerActivity.webview.goBack();
}
});
}
Where First time its running properly but if the function called repeatly the web view.go back to the first page.
In your activity override backpressed method like this
#Override
public void onBackPressed() {
webview.loadUrl(sameurl);
}
Hard coded the URL by their ID and solved the issue temporarily.

Categories

Resources