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">
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.
in my app i run a service in which i keep record of incoming and out going calls on text file(saved it on internal storage) using broadcastReciever. but when i press clear data button(settings=>apps=>Myapp=>clear data) my service also stops. i used Log.d() in onDestroy() method but it is not logged in logcat when i press clear data.
i read this question having same problem but i didn't find any solution. then i went through Developer Guide. i am really confused.
The data associated the the app will no longer persist on clearing. To avoid this you need to sign your app as a system app.
Clear Data does kill the app, and always has.
"Force Stop" has gone through various iterations of meanings. It used
to mean to just kill all processes and services, and clearing data
would also do the same as a force stop. There were also older
iterations of the platform that were not as good as figuring out when
to disable the button, which is probably why you are seeing it remain
enabled in 2.2.
However in 3.2 I believe the meaning of "Force Stop" change to put the
application in a state where it would not be able to run until the
user had done something to explicitly start it (such as launching it
from launcher, selecting it as an input method, etc). When that change
was made, "Clear Data" continued to just kill the processes and stop
its services, so the app was not in the full stopped state so the
button remains enabled.
Edit:
Example of working code:
Step 1) Create one Android BroadCastReciever and register it for two action
Manifest
<service android:name="ServiceTest" >
</service>
<receiver android:name="ReceiverCall" >
<intent-filter>
<action android:name="com.android.techtrainner" />
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
com.android.techtrainner is the custom action. BroadCastReceiver Class contain code to restart service again
public class ReceiverCall extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.i("Service Stops", "Ohhhhhhh");
context.startService(new Intent(context, ServiceTest.class));;
}
}
Step 2) Create Android service class , do some task there (I have taken one Timer to print Log) and in onDestory()
public void onDestroy() {
try {
mTimer.cancel();
timerTask.cancel();
} catch (Exception e) {
e.printStackTrace();
}
Intent intent = new Intent("com.android.techtrainner");
intent.putExtra("yourvalue", "torestore");
sendBroadcast(intent);
}
Any one know,how to hide default screen of incoming call..??
I want to hide default screen of incoming call.
Any kind of help appreciated.
Thank you
You can not remove default screen but you can replace with your own custom screen, below is method.
your app should handles the ACTION_ANSWER intent, and after you can display whatever screen you like.
For your app to handle intents you have to add intent filters to the app manifest file. This is fully described in the Intent class documentation. Here is a quick sample on how you could handle the ACTION_ANSWER intent:
<activity class=".MyCustomCallActivity"
android:label="#string/mycustomcall_title">
<intent-filter>
<action android:name="android.intent.action.ANSWER" />
</intent-filter>
...
</activity>
one option is to register broadcast receiver and set sendorderdbroadcast having higher priority. By setting higher priority intent, your onReceive will be worked first and from there you can able to show your own custom activity.
I have a problem. I'm using the below code to interrupt links to my app as
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:scheme="http" android:host="twitter.com"/>
<data android:scheme="http" android:host="facebook.com"/>
</intent-filter>
But the problem is that I need to set data scheme and host at runtime i.e. I can add or delete the host at runtime. How to set the value of data scheme and host at runtime? I am using below code but it is not working
IntentFilter filter = new IntentFilter();
filter.addAction("android.intent.action.VIEW");
filter.addCategory("android.intent.category.DEFAULT");
filter.addCategory("android.intent.category.BROWSABLE");
filter.addDataScheme("http");
filter.addDataAuthority("www.facebook.com", null);
RecieveBroadcaster receiver = new RecieveBroadcaster();
registerReceiver(receiver, filter);
Strictly speaking, the string corresponding to ACTION_VIEW is an activity action by convention; the fact that you place it into the intent-filter element of an activity in your manifest, makes it an activity action! The system listens for these on your application's behalf, which is basically why you don't (can't) listen for them yourself. The Context.startActivity() method generates these Intents.
The rules of intent resolution actually determine whether a particular Intent matches any IntentFilters. For activity intents, there may be multiple matches, and that usually displays the "Chooser" interface, so the user can select a target.
There are three Intent "streams" that never cross: startActivity(), sendBroadcast() and startService(). These are all initiated via methods in Context and each has a specific target Activity, BroadcastReceiver and Service respectively.
It is a simple matter to set up a BroadcastReceiver (not ReceiveBroadcaster did you even try that code?) to get the events you are interested in, and then use Context.startActivity() with the Intent you want. You can even use a custom action, so you know it was triggered by the receiver, and not the user.
The only question is: is there a broadcast event you can arrange to receive? There may be a system event you can register for, or you may be able to generate a custom event yourself, via Context.sendBroadcast().
Remember you can inspect the incoming Intent your activity was started with, and "forward" the same or a modified Intent if it doesn't exactly match what you are looking for. As you correctly determined, you cannot dynamically alter an activity's set of IntentFilters, so you will have to inspect the host of every request.
Remember you can also register receivers in your manifest as well, and have that implementation called automatically by the system.
How can I write a Broadcast Receiver that will be invoked when user clicks on any application icon?
I tried by writing:
<receiver android:name = "myreceiver">
<intent-filter>
<action android:name = "android.intent.action.MAIN">
</intent-filter>
</receiver>
But it is not called.
I tried,
by using Packagemanager I will get ApplicationInfo. From that I can know all the application starting activity name and package names. I thought I can use them to registerReceiver
and my receiver will listen by its launching activity and package name.
But I strucked. I am unable to do that. I think I lost the way.
What can I do to solve this problem?
I don't think this is possible, there is just too much room for abuse. What are you trying to do that you would need to be notified anytime someone launched an application?
Use this technique:
//implement onClickListener on your class
Class blabla extends Activity implements onClickListener{
...
...
}
//this will force you to override the onClick method on your activity or //fragment
#override
void onClick(View V){
sendBroadcast(new Intent("clickSomewhere!"));
//Put here more actions you want to do when anything is touched/clicked
}
Basically this is it. Anytime you press a button the Broadcast will be sent. Your Broadcast receiver, could be coded in some other place, listening to incoming broadcasts. If you need more code of the broadcast sending side, or the broadcast receiving side let me know.