I am working on application in which i want to provide facility to user to do specific thing when you long press up or down volume button no matter my app is background or foreground.
I also want to implement this functionality when phone screen off but in stack-overflow posts says you cant do that.
i have used android.media.VOLUME_CHANGED_ACTION broadcast listener for volume button press detection and it work fine no matter your app is background but thing is that i want to detect Long press of these buttons.
how can i include this code into my broadcast so i can detect up or down button press for long time.
#Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_VOLUME_UP) {
// Do something here...
// Needed to track long presses
Log.e("Main activity", "KEYCODE_VOLUME_UP");
return true;
}
return super.onKeyDown(keyCode, event);
}
This is my broadcast receiver
intentfliter = new IntentFilter("android.media.VOLUME_CHANGED_ACTION");
mReceiver = new BroadcastReceiver()
{
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
Log.e("Main activity", "Volume button press");
}
};
getApplicationContext().registerReceiver(mReceiver, intentfliter);
manager.registerMediaButtonEventReceiver(getCallingActivity());
}
package com.example.androidsample;
import java.util.Timer;
import java.util.TimerTask;
import java.util.logging.Logger;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class VolumeButtonPressedBroadcast extends BroadcastReceiver{
public static boolean sIsReceived; // this is made true and false after each timer clock
public static Timer sTimer=null;
public static int i;
final int MAX_ITERATION=15;
public static boolean sIsAppWorkFinished=true;
#Override
public void onReceive(final Context context, Intent intent)
{
sIsReceived=true; // Make this true whenever isReceived called
if(sTimer==null && sIsAppWorkFinished){
sTimer=new Timer();
sTimer.schedule(new TimerTask() {
#Override
public void run() {
if(sIsReceived){ // if its true it means user is still pressing the button
i++;
}else{ //in this case user must has released the button so we have to reset the timer
cancel();
sTimer.cancel();
sTimer.purge();
sTimer=null;
i=0;
}
if(i>=MAX_ITERATION){ // In this case we had successfully detected the long press event
cancel();
sTimer.cancel();
sTimer.purge();
sTimer=null;
i=0;
//it is called after 3 seconds
}
sIsReceived=false; //Make this false every time a timer iterates
}
}, 0, 200);
}
}
}
Related
I create an Android app for a device without screen (not a phone). At startup my apps is launched and works correctly.
I try to catch the physical buttons event (down/up). It works but only one time when my apps starts. Then the events are not fire.
I have an idea : the apps is in the background and doesn't receive the events.
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.activity_main);
Context context = getApplicationContext();
//Start a service
Intent intent = new Intent(context,MainService.class);
context.startService(intent);
//finish();
}
#Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
//Send event to server
return true;
}
#Override
public boolean onKeyLongPress(int keyCode, KeyEvent event) {
//Send event to server
return true;
}
#Override
public boolean dispatchKeyEvent(KeyEvent event) {
//Send event to server
return true;
}
}
Do you have an idea ? I suppose I am not the first person with this problem ...
Regards,
Found the solution: a second app was catching and blocking? the events. I have removed the apps and it's ok now.
I am working on a Android Application project in which I am doing continuous task and when user click anywhere on home screen of phone I have to stop this work. Please anyone guide me how I can get touch event in my app so I can do some task. Any Broadcast for touch or any thing I can use. So that I can get in my application. Guide me.
I Do not want this thing
https://developer.android.com/reference/android/view/View.OnTouchListener.html
Thanks .
try this in your activity class,
public class TouchActivity extends Activity
{
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public boolean onTouchEvent(MotionEvent event)
{
if (event.getAction() == MotionEvent.ACTION_DOWN)
{
Log.d("Touch", "Touch");
sendBroadcast(new Intent("touch_event_has_occured"));
}
return super.onTouchEvent(event);
}
}
now in your global broadcast receiver you will get the brodcast
public class TouchReveiver extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
if (intent.getAction().equals("touch_event_has_occured"))
{
Log.d("Touch", "Touch");
}
}
}
don't forget to register the receiver with the action
I have an application which has background music in it. When I am pressing the home button, the background music is still playing. After that when I am clicking the recent apps button, to the right of the home button, and closing the app by swiping or pressing X, it is restarting as if the application is started again instead of closing the currently playing music. How do I solve this problem?
Where do I add the onTaskRemoved() method?
package com.example.dmacs.myapplication;
/**
* Created by dmacs on 4/8/16.
*/
import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.IBinder;
import java.util.Random;
/**
* Created by digen on 3/8/16.
*/
public class BackgroundAudioService extends Service implements MediaPlayer.OnCompletionListener {
MediaPlayer mediaPlayer;
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
int mfile[] = new int[5];
mfile[0]= R.raw.bgm1;
mfile[1]= R.raw.bgm2;
mfile[2]= R.raw.bgm3;
mfile[3]= R.raw.bgm4;
mfile[4]= R.raw.bgm5;
Random random = new Random();
int Low = 0;
int High = mfile.length;
int randomInt = random.nextInt(High-Low) + Low;
mediaPlayer = MediaPlayer.create(this, mfile[randomInt]);// raw/s.mp3
mediaPlayer.setOnCompletionListener(this);
}
#Override
public int onStartCommand (Intent intent,int flags, int startId){
if (!mediaPlayer.isPlaying()) {
mediaPlayer.start();
}
return START_STICKY;
}
public void onDestroy() {
if (mediaPlayer.isPlaying()) {
mediaPlayer.stop();
}
mediaPlayer.release();
}
public void onCompletion(MediaPlayer _mediaPlayer) {
stopSelf();
}
}
Clicking the Home button obviously won't stop a Service running in the background and swiping the app out of Recents won't work either, the OS will restart the Service because of START_STICKY returned from onStartCommand().
You just have to stop the Service when appropriate (in onPause(), for example) by calling stopService().
To stop your Service when your app is getting swiped out of Recents, you could just override onTaskRemoved() and call stopSelf() from there:
#Override
public void onTaskRemoved(Intent rootIntent) {
stopSelf();
}
I want to use an extra physical button in my app. It is connected to the ear phones plug. I searched the web and didn't find specific answers. Maybe i didnt use the correct search terms?
Are there any tutorials available?
What events are triggered when such a button is pressed?
Is there any difference (in coding) between the original pressy and the cheap china things?
Is it possible to emulate this thing in the adk emulator?
I really want to use this thing in my app, but i dont have a clue how.
I need some help to get started
Any ideas?
Youre answer's helped me to get startet.
Now im am facing new problems, as the toasts i'll try to make to check the responses dont appear. Button press will just play and pause music with the samsung music player on the phone.
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.view.KeyEvent;
import android.widget.Toast;
public class MediaButtonIntentReceiver extends BroadcastReceiver {
public MediaButtonIntentReceiver() {
super();
}
#Override
public void onReceive(Context context, Intent intent) {
String intentAction = intent.getAction();
Toast.makeText(context, "onRecieve triggered", Toast.LENGTH_SHORT).show();
if (!Intent.ACTION_MEDIA_BUTTON.equals(intentAction)) {
return;
}
KeyEvent event = (KeyEvent)intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
if (event == null) {
return;
}
int action = event.getAction();
Toast.makeText(context, "Action lauchched", Toast.LENGTH_SHORT).show();
if (action == KeyEvent.ACTION_DOWN) {
// do something
Toast.makeText(context, "BUTTON PRESSED!", Toast.LENGTH_SHORT).show();
}
if (action == KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE) {
// do something
Toast.makeText(context, "Play Pause pressed!", Toast.LENGTH_SHORT).show();
}
abortBroadcast();
}
}
so it seems that the reciever code isnt reached.
in my activity there are following lines:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ZaehlenActivity.this);
setContentView(R.layout.zaehlen);
IntentFilter filter = new IntentFilter(Intent.ACTION_MEDIA_BUTTON);
MediaButtonIntentReceiver r = new MediaButtonIntentReceiver();
registerReceiver(r, filter);
am i forgettig something? do i have to disable the standard earphone recognition somehow?
I think that earphone buttons are considered as MEDIA_BUTTONS so , you have to create a BroadcastReceiver which listen to android.intent.action.MEDIA_BUTTON and make a test statment to test if the action is an ACTION_DOWN , here's a suite of code it may helps :
This is the BroadcastReceiverwhich you have to declare it in AndroidManifest.xml , and make as Intent-filter : android.intent.action.MEDIA_BUTTON
public class MediaButtonIntentReceiver extends BroadcastReceiver {
public MediaButtonIntentReceiver() {
super();
}
#Override
public void onReceive(Context context, Intent intent) {
String intentAction = intent.getAction();
if (!Intent.ACTION_MEDIA_BUTTON.equals(intentAction)) {
return;
}
KeyEvent event = (KeyEvent)intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
if (event == null) {
return;
}
int action = event.getAction();
if (action == KeyEvent.ACTION_DOWN) {
// do something
Toast.makeText(context, "BUTTON PRESSED!", Toast.LENGTH_SHORT).show();
}
abortBroadcast();
}
}
And this is an Activity which listen to the BroadcastReceiverand then make a Toastif one of the buttons was clicked :
public class mainActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
IntentFilter filter = new IntentFilter(Intent.ACTION_MEDIA_BUTTON);
MediaButtonIntentReceiver r = new MediaButtonIntentReceiver();
registerReceiver(r, filter);
}
}
Hope it helps !
Seeing as Pressy is an external controller (so to speak), you'll need to use a BroadcastReceiver with an intent-filter for: android.intent.action.MEDIA_BUTTON So, for example:
Inside your AndroidManifest:
<receiver android:name="RemoteControlReceiver">
<intent-filter>
<action android:name="android.intent.action.MEDIA_BUTTON" />
</intent-filter>
</receiver>
And your new receiver class:
public class RemoteControlReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (Intent.ACTION_MEDIA_BUTTON.equals(intent.getAction())) {
// handle media button here
KeyEvent key = (KeyEvent)intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
// handle keydown etc
}
}
}
If you want to check single buttons (maybe on a cabled device, such as headphones, or wireless like Bluetooth), you could also use the onKeyDown and check for KeyEvent.KEYCODE_MEDIA_SOMEKEYIDENTIFIER Like so:
#Override
public boolean onKeyDown(int keyCode, KeyEvent event){
switch(keyCode){
case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD:
return true;
case KeyEvent.KEYCODE_MEDIA_NEXT:
return true;
case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
return true;
case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
return true;
case KeyEvent.KEYCODE_MEDIA_REWIND:
return true;
case KeyEvent.KEYCODE_MEDIA_STOP:
return true;
// etc etc...
}
return false;
}
Hope this at least gets you started. Cheers.
I am working on the application,I am having the requirement:if user long press the power button at any time and press again to start device,the activity should start from where the device was shut down.I dont know either this is a valid question or not.
I tried working with:
public class PowerMangerTestActivity extends Activity {
private static PowerManager objpowermanager;
private static PowerManager.WakeLock wl;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
callTOWakeLock();
setContentView(R.layout.main);
}//end of onCreate
public void callTOWakeLock() {
// TODO Auto-generated method stub
objpowermanager=(PowerManager)getSystemService(Context.POWER_SERVICE);
wl=objpowermanager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "******MyTag****");
//You should acquire it when your app starts,
if(wl.isHeld())
{
wl.release();
}
wl.acquire();
}
#Override
public void onDestroy() {
wl.release();
}
#Override
protected void onStop() {
// TODO Auto-generated method stub
super.onStop();
}
#Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
callTOWakeLock();
}
/*#Override
public boolean dispatchKeyEvent(KeyEvent event) {
if (event.getKeyCode() == KeyEvent.KEYCODE_POWER) {
Intent i = new Intent(this, PowerMangerTestActivity.class);
startActivity(i);
return true;
TextView tv=(TextView) findViewById(R.id.textview);
tv.setText("You press power button");
}
return super.dispatchKeyEvent(event);
}*/
}
but not getting expected behaviour.
I have tried to catch KeyEvent.KEYCODE_POWER,but not getting how to use for this scenario.
any suggestions?
thanks
This may be unacceptable to you, but you should NOT DO THIS.
It is going against a usability idea called "expected behavior".
You are doing something that a user is not expecting, and there is a good chance they are going to be pissed if you do this.
Just my two cents!
I would try and find another solution to this problem, such as caching useful data in phone storage, and recalling it when the application is resumed/started.
onPause still should be called when the power button is long pressed. The only case (as far as I know) where it won't be called is on a battery pull
It is reasonable for an emergency manager app to catch the power button event, so here's one solution, taken from Samsungs support database:
package com.samsung.lockscreenreceiver;
public class LockScreenReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if(Intent.ACTION_USER_PRESENT.equals(action)) {
// bring app to foreground
} else if(Intent.ACTION_SCREEN_OFF.equals(action) ) {
Toast.makeText(context, "screen on",Toast.LENGTH_LONG).show();
} else if (Intent.ACTION_SCREEN_ON.equals(action)) {
Toast.makeText(context, "screen off",Toast.LENGTH_LONG).show();
}
}
}
And the activity:
public class MyActivity extends Activity {
private BroadcastReceiver mReceiver;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mReceiver = new LockScreenReceiver();
IntentFilter intentFilter = new IntentFilter();
intentFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
intentFilter.addAction(Intent.ACTION_USER_PRESENT);
intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
intentFilter.addAction(Intent.ACTION_SCREEN_ON);
//intentFilter.addAction(Intent.ACTION_SHUTDOWN); // won't work unless you're the device vendor
registerReceiver(mReceiver, intentFilter);
}
#Override
protected void onDestroy()
{
super.onDestroy();
unregisterReceiver(mReceiver);
}
}
You catch power on/off and bring the activity to foreground. The activity then denies all focus changes using:
#Override
public void onWindowFocusChanged(boolean hasFocus) {
//super.onWindowFocusChanged(hasFocus);
if(!hasFocus) {
Intent closeDialog = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
sendBroadcast(closeDialog);
}
}
And you'll have to switch off screen lock, for example using:
https://play.google.com/store/apps/details?id=org.jraf.android.nolock&hl=en
The above app is not protected, so you can decompile it as usual. :)