I'm developing an Android app that intercepts the pressing hardware buttons and makes REST calls to their pressure.
The button that I have to intercept is the Push to talk (PTT) button, so not a regular button, such as power button or volume button.
When the application runs in the foreground I use the method onKeyDown (int keyCode, KeyEvent event).
The PTT button, as the identifier, has the number 27 and then inside the method I wrote the following lines of code:
if (keyCode == 27) {// I pressed the PTT button}
All this works perfectly.
But now I send the application in the background (with the function moveTaskToBack(true);) and when I press the PTT button I would intercept it.
I am aware of BroadcastReceiver, of IntentFilter and Service, however, these allow you to intercept the limited intent actions (such intent.action.SCREEN_OFF or others normal actions), among which are not able to find the pressure of the PTT button.
Is there any way to intercept the PTT button when the application is in the background?
Thank you
The solution to your question depends highly on the device you are using. If you have a phone with a dedicated PTT button, the manufacturer of the phone almost certainly has made an Intent available for app developers such as yourself to intercept PTT down and up events, but you'll need to contact the manufacturer for more information.
For instance, phones from Kyocera, Sonim, and Casio have such Intents available, and you'd simply need to put a receiver declaration in your AndroidManifest.xml, like this for a Kyocera phone:
<receiver android:exported="true" android:name="com.myapp.receiver.KeyReceiverKyocera">
<intent-filter android:priority="9999999">
<action android:name="com.kodiak.intent.action.PTT_BUTTON" />
<action android:name="com.kyocera.android.intent.action.PTT_BUTTON" />
</intent-filter>
</receiver>
Then, a simple BroadcastReceiver class that receives the up and down intents:
public class KeyReceiverKyocera extends BroadcastReceiver
{
private static boolean keyDown = false;
#Override
public void onReceive(Context context, Intent intent)
{
String action = intent.getAction();
if (keyDown)
processPTTDown();
else
processPTTUp();
keyDown = !keyDown;
}
}
Hope this helps,
Shawn
Related
I am working with a bluetooth button and Zebra TC20. I want to start zebra's scan when extra bluetooth button get clicked.
Bluetooth button is supported by their app - flic. There is an option to send Intent. So I would like to send intent to my app. This could be done by implicit intent. But I am building this app so I know exact activity when the scan should be triggered.
From what I read I should use explicit intent if I want the activity which I know the name, but everywhere explicit intent is tied within one app.
Is it possible to call specific activity of my app from another app?
This question is edited.
Look at the manual at page 52-61 everything is explained, i had to implement it with a ET55, but it seems to be the same process.
I personnaly did it using the Intent output option ith intent delivered via broadcast.
First you can make open the DataWedge App (the app should be preinstalled, it is where you configure things about the scanner)
You create a profile for your app
You click on the profile and you check the Profile enabled option
You enable barcode input and Intent ouput, disable Keystroke and ip output
You associate your app (Associated apps option)
(go to Page 75-76 of manual) You set the intent action with something like datawedge.yourapp.SCANNER_RESULT
You left category blank
You set intent delivery to Broadcast Intent
For the rest the default option should be ok
Then, in your app you have to register the broadcast receiver (in onCreate()):
//first you implement the action to be executed when it receives the broadcast
receiverZebra = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
final String scanResult = intent.getStringExtra("com.symbol.datawedge.data_string");
/*
do things with the barcode here
*/
}
};
//then make a filter for the broadcast
filterZebra = new IntentFilter();
filterZebra.addCategory(Intent.CATEGORY_DEFAULT);
//the action you set in step 5 in datawedge
filterZebra.addAction("datawedge.yourapp.SCANNER_RESULT");
Then in the onStart and onStop methods you can register/unregister your broadcast receiver
#Override
protected void onStart(){
super.onStart();
registerReceiver(receiverZebra, filterZebra);
}
#Override
protected void onStop()
{
super.onStop();
unregisterReceiver(receiverZebra);
}
There are other ways to implement it, there wouldn't be other option than Intent output if there were not but it works great for me. I don't think there is much differences between the TC20 and ET55 so it should work for you as well
After the question was edited
Taken from this tutorial
In the configuration app of your button, you should be able to link an intent action name to the bluetooth button. To receive it, you have to set an intent filter in your app manifest :
<activity
android:name="com.example.myapplication.activitytolaunch"
android:label="#string/app_name" >
<intent-filter>
<action android:name="com.example.myapplication.ACTIVITY_TO_LAUNCH" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
And your button will have to launch the intent : "com.example.myapplication.ACTIVITY_TO_LAUNCH"
If you want to launch the activity directly, you can use the second part of the answer. If you have to process the barcodes when your app is opened (i.e. adding the barcodes to a list), if you can tell the button to broadcast an intent, you can use the first part.
How can I program the Bixby button (KeyCode: 1082) on the Samsung Galaxy S8, that it will start my application instead of the Bixby launcher? The App All in one Gestures has already this function with custom keys, but how can I do this in Android programatically?
It seems Samsung doesn't approve of users doing this, and has apparently disabled this functionality in recent updates, at least in some places. Reports vary, but be warned that the example below might not work on every device, or at all in the near future. More details are available in the following article (off-site link to XDA Developers):
Samsung has Removed the Ability to Remap the Bixby Button on the Galaxy S8/S8+
All in one Gestures uses an AccessibilityService to accomplish this. Your app can do the same, but the user would have to explicitly enable your app as an Accessibility Service in the device Settings for it to work.
The Bixby button apparently emits simple KeyEvents with a keycode of 1082. Your AccessibilityService just needs to override the onKeyEvent() method, and check the keycode of the event passed in. For example:
public class BixbyInterceptService extends AccessibilityService {
private static final int KEYCODE_BIXBY = 1082;
#Override
protected boolean onKeyEvent(KeyEvent event) {
if (event.getKeyCode() == KEYCODE_BIXBY &&
event.getAction() == KeyEvent.ACTION_DOWN) {
// Do your thing here; startActivity(), Toast, Notification, etc.
Toast.makeText(this, "Bixby button pressed", 0).show();
// Return true to stop the event from propagating further.
return true;
}
return super.onKeyEvent(event);
}
#Override
public void onAccessibilityEvent(AccessibilityEvent event) {}
#Override
public void onInterrupt() {}
}
You'll need to properly register your AccessibilityService in the manifest for it to be eligible to be enabled as such by the user. For example, between the <application> tags:
<service
android:name=".BixbyInterceptService"
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/bixby_service_config" />
</service>
The resource attribute on the <meta-data> element above points to an XML file with the necessary settings for the Service. Under your project's res/ folder, create an xml/ folder if needed, and add this file there:
bixby_service_config.xml
<?xml version="1.0" encoding="utf-8"?>
<accessibility-service
xmlns:android="http://schemas.android.com/apk/res/android"
android:accessibilityFlags="flagRequestFilterKeyEvents"
android:canRequestFilterKeyEvents="true"
/>
After installation, you will need to enable your app in the Services under the Accessibility section in the device Settings.
I am developing an VoIP app.
My app registers to a SIP based back-end server using a User-ID and password.
Once the registration is successful, the user can make sip calls through this app.
If the user uses the native phone dialer to dial out a number, My app intercepts the call and places the call through SIP.
Once the call is intercepted, the native phone dialer goes to background and my app's 'call status' screen is displayed(my app comes to foreground).
My requirements are as follows:
Once the call is intercepted, instead of showing my app's UI, we need to display the native dialer(default phone dialer) 'call status' / 'call progress' screen(like Samsung's Touchwiz for Samsung phones, HTC Sense for HTC phones etc), but the call should go through my app(SIP). Our app should take control over all the functionality of the native dialer 'call status' screen.
Eg: If the user taps the 'Call End' button on the 'Call Status' screen of the native dialer, my app should end the call. Similarly all the controls on the 'Call Status' screen of the native dialer should handover control to my app to take the necessary action.
Please let me know if it is possible to accomplish this and how to implement.
*public void onReceive(final Context context, Intent intent) {
final String intentAction = intent.getAction();
if (intentAction.equals(Intent.ACTION_NEW_OUTGOING_CALL)) {
SharedPreferences getPrefs = PreferenceManager
.getDefaultSharedPreferences(context);
boolean bool_CustomFlag = getPrefs.getBoolean(
"use_custom_dialer_preference", true);
if (bool_CustomFlag == true) {
setResultData(null);
final String strPhoneNum = intent*
.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
(new Thread() {
public void run() {
try {
Intent intent = new Intent(Intent.ACTION_CALL,Uri.fromParts("my_data_scheme",
Uri.decode(strPhoneNum),null));
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
}*
I have created my own data scheme for my outgoing call activity so that brodcastreciver can listen to Action_outgoing_call and launch the my outgoing call activity when call is made through native dialer.
*<activity
android:name=".OutgoingCallActivity"
android:screenOrientation="portrait">
<intent-filter >
<action android:name="android.intent.action.CALL" />
<category android:name= "android.intent.category.DEFAULT" />
<data android:scheme = "sip" />
<data android:scheme="my_data_scheme" />
</intent-filter>
</activity>*`
Sorry, Android does not have any API to be able to do what you want to do with the builtin incall status screen.
The only documented way is to bring up your own incall status screen. A lot of SIP applications simulate the built-in android incall status screen so it looks the same anyway.
I'm writing an application that allows people in danger to call 911.
This is how it should work:
He (or she) feels danger.
He pushes the volume-down key three times.
My app calls 911.
But I'm facing the following problem: how can I receive a hardward key event in sleep mode?
I've searched Google and other search engines, but can't find anything related.
public class YourBoardcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (Intent.ACTION_CAMERA_BUTTON.equals(intent.getAction())) {
Intent main = new Intent();//
}
}
}
And in your Manifest :
<receiver android:name="YourBoardcastReceiver">
<intent-filter>
<action android:name="android.intent.action.SCREEN_ON" />
</intent-filter>
</receiver>
The only way I think you could do that is with a BroadcastReceiver, but it seems that the volume buttons do not generate an Intent when the screen is off (see here). The closest thing you might be able to do is use the camera button to do something similar.
Perhaps it is better this way, anyway, though. I imagine it would annoy users if their phone called 911 while in their pocket because of the volume buttons, or the camera button too for that matter. Also, it's not something I would expect to happen.
Is it possible to override the function of a hardware button programmically on a droid? Specifically, I'd like to be able to override the camera button on my phone programmically. Is this possible?
How to Handle Camera Button Events
As soon as camera button is pressed a broadcast message is sent to all the applications listening to it. You need to make use of Broadcast receivers and abortBroadcast() function.
1) Create a class that extends BroadcastReceiver and implement onReceive method.
The code inside onReceive method will run whenever a broadcast message is received. In this case I have written a program to start an activity called myApp.
Whenever hardware camera button is clicked the default camera application is launched by the system. This may create a conflict and block your activity. E.g If you are creating your own camera application it may fail to launch because default camera application will be using all the resources. Moreover there might be other applications which are listening to the same broadcast. To prevent this call the function "abortBroadcast()", this will tell other programs that you are responding to this broadcast.
public class HDC extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
// Prevent other apps from launching
abortBroadcast();
// Your Program
Intent startActivity = new Intent();
startActivity.setClass(context, myApp.class);
startActivity.setAction(myApp.class.getName());
startActivity.setFlags(
Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
context.startActivity(startActivity);
}
}
}
2) Add below lines to your android manifest file.
<receiver android:name=".HDC" >
<intent-filter android:priority="10000">
<action android:name="android.intent.action.CAMERA_BUTTON" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
The above lines are added to your manifest file to tell the system that your program is ready to receive broadcast messages.
This line is added to receive an intimation when hardware button is clicked.
<action android:name="android.intent.action.CAMERA_BUTTON" />
HDC is the class created in step 1(do not forget the ".")
<receiver android:name=".HDC" >
The "abortBroadcast()" function is called to prevent other applications from responding to the broadcast. What if your application is the last one to receive the message? To prevent this some priority has to be set to make sure that your app receives it prior to any other program. To set priority add this line. Current priority is 10000 which is very high, you can change it according to your requirements.
<intent-filter android:priority="10000">