broadcastreceiver onReceive problem ACTION_MEDIA_BUTTON Android - android

I've found a lot of pages about this in the web, but none of them helped me. I've been for hours stucked in this problem. That's why i decided to make my own question.
What I want to do is an application that receives an intent of the type ACTION_MEDIA_BUTTON and the method onReceive() of the Broadcastreceiver does something.
My Activity is like this:
public class MusicControlActivity extends Activity {
private MediaButtonIntentReceiver receiver = new MediaButtonIntentReceiver();
#Override
public void onCreate(Bundle p_SavedInstanceState) {
super.onCreate(p_SavedInstanceState);
setContentView(R.layout.main);
IntentFilter filter = new IntentFilter(Intent.ACTION_MEDIA_BUTTON);
filter.setPriority(1000);
registerReceiver(receiver,filter);
}
#Override
public void onDestroy()
{
unregisterReceiver(receiver);
}
And my broadcastreceiver as follow:
public class MediaButtonIntentReceiver extends BroadcastReceiver {
public MediaButtonIntentReceiver()
{
super();
}
#Override
public void onReceive(Context context, Intent intent)
{
String v_IntentAction = intent.getAction();
if (!Intent.ACTION_MEDIA_BUTTON.equals(v_IntentAction)) {
return;
}
KeyEvent v_Event = (KeyEvent)intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
if (v_Event == null) {
return;
}
int v_Action = v_Event.getAction();
if (v_Action == KeyEvent.ACTION_DOWN) {
// do something
Toast.makeText(context, "BUTTON PRESSED!", Toast.LENGTH_SHORT).show();
}
abortBroadcast();
}
}
The problem is that it doesn't work, no matter what I do. I've tried registering it dynamically with registerReceiver as in the code above. Also I've tried statically in the AndroidManifest.xml like this:
<receiver android:name=".MediaButtonIntentReceiver" android:enabled="true">
<intent-filter android:priority="10000000">
<action android:name="android.intent.action.ACTION_MEDIA_BUTTON" />
</intent-filter>
</receiver>
And as you can see I've set the priority to a high level and even though it doesn't work.
I've been on this for the whole day and I don't know what to do. The method onReceive from the broadcastreceiver isn't called anytime.
Does anyone know what should I do?

Use android.intent.action.MEDIA_BUTTON Instead in your manifest. Check : http://developer.android.com/training/managing-audio/volume-playback.html

First, you should stop using Toast as your diagnostic test. Use the Log class to log to LogCat, or breakpoints, or something.
Next, you should get rid of your MediaButtonIntentReceiver constructor, as it is not needed.
Then, I would dump the if (!Intent.ACTION_MEDIA_BUTTON.equals(v_IntentAction)) block, since it is also not needed.
Next, I would make sure that your media button actually works. Does it control other applications, like a music player? It may be that your media button is not Android-compliant or something.

Related

WakefulBroadcastReceiver startWakefulService fails to proceed

My app will not invoke the intentservice request from the wakefulbroadcastreceiver
Manifest:
<service
android:name=".MyWearableListenerService">
<intent-filter>
<action android:name="com.google.android.gms.wearable.DATA_CHANGED" />
<action android:name="com.google.android.gms.wearable.MESSAGE_RECEIVED"/>
<data android:scheme="wear" android:host="*"/>
</intent-filter>
</service>
<service
android:name=".CounterActivity$WearableReceiverService"
android:exported="false">
</service>
<receiver
android:name=".CounterActivity$WearableReceiver"
android:enabled="true">
</receiver>
So i register all receivers and services.
inside my main activity i have these as sub-classes within the main class so i can call the method in the main class msgReqAction()
public class WearableReceiver extends WakefulBroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent service = new Intent(context, WearableReceiverService.class);
startWakefulService(context, service);
}
}
public class WearableReceiverService extends IntentService {
public WearableReceiverService(){
super("WearableReceiverService");
}
#Override
protected void onHandleIntent(Intent intent) {
msgReqAction(intent.getIntExtra(MyConstants.BROADCAST_DATA_REQ, 0));
WearableReceiver.completeWakefulIntent(intent);
}
}
I don't think having these as subclasses should hinder the situation but it may. if i must have these outside the main class for operation let me know.
finally i begin the whole process from a listener outside the main activity that listens for a message from the wearable
#Override
public void onMessageReceived(final MessageEvent messageEvent) {
nodeId = messageEvent.getSourceNodeId();
String incomingPath = messageEvent.getPath();
int incomingReq = Integer.parseInt(new String(messageEvent.getData()));
if(incomingPath.equalsIgnoreCase(MyConstants.MSG_COUNTER_REQ_PATH)) {
Intent broadcastIntent = new Intent();
broadcastIntent.setAction(MyConstants.BROADCAST_ACTION_RESP);
broadcastIntent.addCategory(Intent.CATEGORY_DEFAULT);
broadcastIntent.putExtra(MyConstants.BROADCAST_DATA_REQ, incomingReq);
sendBroadcast(broadcastIntent);
}else if(incomingPath.equalsIgnoreCase(MyConstants.MSG_DEFAULT_PATH)){
}
}
public static final String BROADCAST_ACTION_RESP = "com.example.johnbravado.zionwork.MESSAGE_PROCESSED";
my project is com.example.johnbravado.zionwork - also on a side note is there a way to change and refactor that in android studio easily so i can get rid of example or change it completely?
when i run the debugger the system gets all the way to
startWakefulService(context, service);
then it crashes without entering the intent service. is there somethig simple i am missing amongst all this which is preventing it from going into the service and doing work. best i can tell is it does not go into the service at all. i added some intro lines of the service
#Override
protected void onHandleIntent(Intent intent) {
int data;
data = 0;
data++;
msgReqAction(intent.getIntExtra(MyConstants.BROADCAST_DATA_REQ, 0));
WearableReceiver.completeWakefulIntent(intent);
}
and tried to run debug points on these lines and it didnt get there.
You cannot have a Service defined as a non-static inner class.
A non-static inner class contains a reference to its outer class. This means that in order to create a new instance of the inner class, you need to have an instance of the outer class.
When Android tries to start your Service, it tries to create a new instance of the inner class. This fails, because Android does not have an instance of the outer class to use in the creation.
The same rule applies to the BroadcastReceiver.
Solution: Move all your inner classes to full-fledged classes (in their own source files).
The solution was to eliminate the WakefulfulBroadcastReceiver and secondary IntentService. Instead, I used a BroadcastReceiever and sent a broadcast directly from the Wearable listener function and used that to process data directly within the activity.
public class WearableReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
//Intent service = new Intent(context, WearableReceiverService.class);
//startWakefulService(context, service);
PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
PowerManager.WakeLock wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
"com.example.johnbravado.zionwork");
wakeLock.acquire();
// Do Work
msgReqAction(intent.getIntExtra(MyConstants.BROADCAST_DATA_REQ, 0));
wakeLock.release();
}
}
Even though i do not do much that would necessarily require a wakelock. if i decide later to do more work i have it ready to go. i am not sure if this is best place for the wakelock either never really used them but that is another topic.
I removed reference to the extra service and receiver in the manifest file also. works good now

Remove floating button from WindowManager when power key pressed

My app has a service that add a floating button to WindowManager.
I want to remove my floating button from WindowManager When user press the power key and turn screen off. So when user turn screen on my floating button does not conceal (mask) android pattern screen lock.
I add following code to my Service but it doesn't work !
Should I add any permission or my service must run in background?!
public class Receiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF))
{
try{
// Remove Floating Button from Window Manager
MyWindowManager.removeView(floating_btn);
// Stop Service
stopSelf();
}
catch (Exception e)
{
//Log Error
}
}
}
}
Normally you would declare a receiver in your manifest. Something like this
<receiver android:name="com.whatever.client.Receiver"
<intent-filter>
<action android:name="android.intent.action.SCREEN_OFF" />
</intent-filter>
</receiver>
For some reason (not sure why), you don't seem to be able to do this for SCREEN_OFF or SCREEN_ON. So you have to register it programmatically.
As a test, I made a simple app.
public class App extends Application {
#Override
public void onCreate() {
super.onCreate();
BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
startService(new Intent(context, MyService.class));
}
}
};
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_SCREEN_OFF);
registerReceiver(receiver, filter);
}
}
With a simple service.
public class MyService extends IntentService {
public MyService() {
super("MyService");
}
#Override
protected void onHandleIntent(Intent intent) {
Log.e("MyService", "Screen was turned off!");
}
}
I've got the same problem and I'm working on it now. In your case it didn't work because 1) your "stopSelf()" have to in class extended by Service, not by BroadcastReceiver. 2) if you want to remove a view from window manager you have to somehow pass(the information of view) that view from that method where you'd declared it to method where you want to remove that view

Why BroadcastReceiver works even when app is in background ?

I am checking Internet connectivity in my app using BroadcastReceiver and I show an alert dialog if the connection is lost. It works fine. But my problem is that BroadcastReceiver works even if my app is in backgroung. So dialog pops up when internet connection is lost even if user is in some other app. This is totally ruining my app.
Has anyone got any idea how to restrict Broadcast receiver in the app only?
Here is my BroadcastReceiver :
public class ConnectivityChangedReceiver extends BroadcastReceiver{
#Override
public void onReceive( Context context, Intent intent )
{
ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService( Context.CONNECTIVITY_SERVICE );
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.isConnected()) {
} else {
try{
Intent i=new Intent(context, InternetDialogActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
} catch(Exception e){
e.printStackTrace();
}
}
}
}
And the activity is:
public class InternetDialogActivity extends Activity implements OnClickListener{
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.internet_dialog_box);
getWindow().setLayout(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
Button retryButton = (Button) findViewById(R.id.retryInternetButton);
retryButton.setOnClickListener(this);
}
public boolean checkConnectivity(){
ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
if (networkInfo!=null && networkInfo.isConnected()) {
finish();
return true;
} else {
Intent intent = getIntent();
finish();
startActivity(intent);
return false;
}
}
#Override
public void onClick(View view) {
switch(view.getId()){
case R.id.retryInternetButton:
try{
checkConnectivity();
} catch(Exception e){
e.printStackTrace();
}
break;
}
}
}
Here is how I declared receiver and activity in manifest:
<receiver android:name="com.lisnx.service.ConnectivityChangedReceiver"
android:label="NetworkConnection">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
</intent-filter>
</receiver>
<activity android:name="com.lisnx.activity.InternetDialogActivity"
android:configChanges="orientation|keyboardHidden"
android:theme="#android:style/Theme.Dialog" />
I have read that we can restrict BroadcastReceiver to work within the app by not declaring it in the manifest. But I don't know how will receiver work then? Please help me. I am stuck on it badly. Thanx in advance.
A BroadcastReceiver works when the app is in the background because the event that the receiver picks up are sent globally, and each app is registered to listen in on these, regardless of whether or not it is running.
To deal with this, in your BroadcastReceiver's onReceive code, check if your app is in the foreground.
There is one--and only one that I know of--consistently effective method to do this. You need to keep track of your pause/resume actions for your application. Ensure that you check this in every activity.
There is some sample code in this answer (solution #1). In your case, you would want to check MyApplication.isActivityVisible() == true as a validation before doing anything from your BroadcastReceiver.
Have you tried to remove the Intent filter from the manifest and register/unregister it in activity? So you can try to register Intent filter in onStart() and unregister it on onStop() methods. The code goes somethink like this:
static final String ACTION = "android.net.conn.CONNECTIVITY_CHANGE";
IntentFilter filter = new IntentFilter(ACTION);
this.registerReceiver(ConnectivityChangedReceiver, filter);
unregisterReceiver(ConnectivityChangedReceiver);
You should also learn about Activity Lifecycle, if it's not familiar yet.
You should register/unregister your BroadcastReceiver in onPause() and onResume() of each activity. Then you know that the receiver is only "listening" when your app is in the foreground. You can easily do that by creating your own BaseActivity that extends Activity and overrides onPause() and onResume() and registers/unregisters your receiver. Just have all your activities extend BaseActivity and have them call through to super.onResume() and super.onPause() as usual. Here's example code:
public class BaseActivity extends Activity {
// Create an IntentFilter to listen for connectivity change events
static IntentFilter filter = new IntentFilter("android.net.conn.CONNECTIVITY_CHANGE");
// Create an instance of our BroadcastReceiver
static ConnectivityChangedReceiver receiver = new ConnectivityChangedReceiver();
#Override
protected void onPause() {
super.onPause();
// Stop listening for connectivity change events
unregisterReceiver(receiver);
}
#Override
protected void onResume() {
super.onResume();
// Listen for connectivity change events
registerReceiver(receiver, filter);
}
}
All your activities should extend BaseActivity and if they need to do anything special in onResume() or onPause() just make sure to call through to super.onXXXXX() like this:
public MyActivity extends BaseActivity {
#Override
protected void onResume() {
super.onResume();
// Here you do whatever you need to do in onResume() of your activity
...
}
#Override
protected void onPause() {
super.onPause();
// Here you do whatever you need to do in onPause() of your activity
...
}
}
I didn't run the code through a compiler so I apologize if there's a typo or I missed something.
I think you will have to make sure that you are not using the receiver when app is in background. For that you will have to use every activities onPause() and onResume() methods.
As far as I know, if Broadcast receiver is registered inside manifest.xml then broadcast receiver exists as long as application exists. Also, Dynamically registered receivers (that means, Register your BroadcastReceiver programmatically) are called on the UI thread. This means that your receivers blocks any UI handling and thus the onReceive() method should be as fast as possible.
However, I will try to discuss information about Broadcast Receiver. But, first should know some information. Firstly, Broadcast receiver is a standalone application component which means it will continue running even when other application component are not running. That's why we unregister broadcast receiver in onPause on the activity. Also, Developer should register this in Activity.onResume() implementation.
Secondly, Developer should not unregister in Activity.onSaveInstanceState(), because this won't be called if the user moves back in the history stack. I have put that information from BroadcastReceiver documentation.
Another point is that a BroadcastReceiver object is only valid for the duration of the call to onReceive(). As soon as the onReceive() method is finished, your BroadcastReceiver terminates.
Now, how to register your receiver programmatically:
public abstract Intent registerReceiver (BroadcastReceiver receiver, IntentFilter filter)
Here, BroadcastReceiver- receiver will be call when any broadcast intent match with filter.
And IntentFilter- Intent specifies which event your receiver should listen to.
Register:
YourConnectionListener receiver;
this.reciever = new YourConnectionListener();
IntentFilter filter = new IntentFilter();
filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
registerReceiver(this.reciever, filter);
Sent your Broadcast Info:
Intent intent = new Intent();
intent.putExtra("Message", "Your connectivity info has Changed!!");
this.sendBroadcast(intent);
Receiver:
Now, need to receive the Broadcast. Android calls the onReceive() method on all registered broadcast receivers whenever the event occurs. Say you want to be notified whenever the connection is changed.
public class YourConnectionListener extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent){
// your Code
}
}
onReceive() has two arguments:
context: The Context object you can use to access additional information or to start services or activities.
intent: Intent used to register your receiver. This object contains additional information that you can use in your implementation.
Additionally, Developer should avoid any long-lasting tasks in your BroadcastReceiver. So, In statically and dynamically registered receivers, Developer should do minor tasks in the receiver itself.For any longer tasks you should start a service from within your receiver.
To make a Broadcast Receiver that fires only when you app is running follow the below code.
1. Create your Broadcast Receiver like this:
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class InternetStatusNotifier extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
//Recieve notification here
}
}
2. Make an activity or fragment where you want the Broadcast Receiver to work like this:
import android.app.Activity;
import android.content.IntentFilter;
import android.os.Bundle;
public class MainActivity extends Activity {
private InternetStatusNotifier mInternetStatusNotifier;
#Override
protected void onCreate(Bundle savedInstanceState) {
mInternetStatusNotifier = new InternetStatusNotifier();
super.onCreate(savedInstanceState);
}
#Override
protected void onResume() {
registerReceiver(mInternetStatusNotifier, new IntentFilter(
"android.net.conn.CONNECTIVITY_CHANGE"));
super.onResume();
}
#Override
protected void onPause() {
unregisterReceiver(mInternetStatusNotifier);
super.onPause();
}
Note: That is how you use broadcasts receiver in a screen specific manner. Only the screen displaying will receive broadcasts in this way. When you register broadcast using manifest file then they are even received when app is closed
That is the way broadcast receivers work in Android. If you register for a broadcast in the manifest and your app is not running, Android will start a new process to handle the broadcast. It is generally a bad idea to directly show a UI from a broadcast receiver, because this may interrupt other apps. I'm also not convinced that a universal 'connection lost' dialog is a good idea either. This should probably be handled by each activity that uses network access.
As for the original question, you need to disable your receiver when your activity goes in the background (onPause(), etc.) and enable it when you come to the foreground (onResume(), etc). Put enabled=false in your manifest and then use something like this in your code to toggle it as necessary:
public static void toggle(Context context, boolean enable) {
int flag = enable ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED
: PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
ComponentName receiver = new ComponentName(context,
ConnectivityMonitor.class);
context.getPackageManager().setComponentEnabledSetting(receiver, flag,
PackageManager.DONT_KILL_APP);
}
A simple way of finding whether the app is in foreground or not
if((mContext.getPackageName().equalsIgnoreCase(
((ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE))
.getRunningTasks(1).get(0).topActivity.getPackageName())))
{
//app is in foreground;
}
I better suggest you to check the internet setting from the application when someone opens it, here is the piece of code how i do it.
public static boolean isNetworkConnected(Context ctx) {
ConnectivityManager cm = (ConnectivityManager) ctx.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo ni = cm.getActiveNetworkInfo();
if (ni == null) {
return false; // There are no active networks.
} else
return true;
}

Discovering if Android activity is running

I'm using C2DM, my BroadcastReceivers propagate the C2DM events to a local service. the service complete the registration by sending the id to my webserver pus it's responsible for letting the device know about new messages, however if the application (one of the activities) is up we want to send an intent to that activity with the new data so it can be updated, if not than the NotificationManager is used to notify the user.
The issue is, how to know the activity is running ? the Application object is not an option since the Service is part of the application it's obviously going to be present. unregister in the onDesroy of each application is also not an option since it may occur in orientation change...
Any standard way to get it done ?
Solution 1:
You can use ActivityManager for Checking if Activity is Running or not:
public boolean isActivityRunning() {
ActivityManager activityManager = (ActivityManager)Monitor.this.getSystemService (Context.ACTIVITY_SERVICE);
List<RunningTaskInfo> activitys = activityManager.getRunningTasks(Integer.MAX_VALUE);
isActivityFound = false;
for (int i = 0; i < activitys.size(); i++) {
if (activitys.get(i).topActivity.toString().equalsIgnoreCase("ComponentInfo{com.example.testapp/com.example.testapp.Your_Activity_Name}")) {
isActivityFound = true;
}
}
return isActivityFound;
}
need to add the permission to your manifest..
<uses-permission android:name="android.permission.GET_TASKS"/>
Solution 2:
Your can use an static variable in your activity for which you want to check it's running or not and store it some where for access from your service or broadcast receiver as:
static boolean CurrentlyRunning= false;
public void onStart() {
CurrentlyRunning= true; //Store status of Activity somewhere like in shared //preference
}
public void onStop() {
CurrentlyRunning= false;//Store status of Activity somewhere like in shared //preference
}
I hope this was helpful!
The next approach would work well if you want to handle incoming Google Cloud message (C2DM) by your activity (if any is running) or issue a notification if no activities are running.
Register one BroadcastReceiver in the manifest file. This receiver will handle C2D messages whenever application not running. Register another BroadcastReceiver programmatically in your activity. This receiver will handle C2D messages whenever activity is running.
AndoroidManifest.xml
<receiver
android:name=".StaticReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="com.mypackage" />
</intent-filter>
</receiver>
MyReceiver.java
public class StaticReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// TODO Trigger a Notification
}
}
MyActivity.java
public class MyActivity extends ActionBarActivity {
#Override
protected void onResume() {
super.onResume();
final IntentFilter filter = new
IntentFilter("com.google.android.c2dm.intent.RECEIVE");
filter.addCategory("com.mypackage");
filter.setPriority(1);
registerReceiver(dynamicReceiver, filter,
"com.google.android.c2dm.permission.SEND", null);
}
#Override
protected void onPause() {
super.onPause();
unregisterReceiver(dynamicReceiver);
}
private final BroadcastReceiver dynamicReceiver
= new BroadcastReceiver()
{
#Override
public void onReceive(Context context, Intent intent) {
// TODO Handle C2DM
// blocks passing broadcast to StaticReceiver instance
abortBroadcast();
}
};
}
Note! To catch broadcasts first, the priority of dynamicReceiver IntentFilter must be higher than priority of StaticReceiver instance IntentFilter (default priority is '0').
PS. It looks like broadcasts issued by Google Cloud Messaging Service are ordered broadcasts. Original idea author: CommonsWare
Copied from here.
you can use a static variable within the activity.
class MyActivity extends Activity {
static boolean active = false;
public void onStart() {
active = true;
}
public void onStop() {
active = false;
}
}
Easiest way to check that whether an Activity is running or not is:
Context context = MyActivity.this;
if (! ((Activity) context).isFinishing()) {
// Activity is running
} else {
// Activity has been finished
}
Note: If activity is not running you should not perform any UI related operation.

How do I use a service to monitor Orientation change in Android

I'm writing a Widget that will display a countdown timer. I have the widget working the way I want it until I flip the phone from landscape to portrait. My widget does not update and goes to it's initial state at start of the widget until an onupdate is called by my recurring alarm. I would like to call an onupdate manually once the orientation changes to update my widget I've been researching this for a while now and I've found out that I need to use a Service which will monitor the orientation changes and call my onupdate for my widget.
My problem is I can't find a straight answer as to how to use a service to monitor the change. I've seen that with an activity I can add android:configChanges="orientation|keyboardHidden" to the manifest for an activity and use a onConfigurationChanged, but can I do this for a service. If so how? Is there a better way to monitor the orientation change? I've also read on the internet that a service isn't the best way to do this either.
I've seen tutorials for creating orientation listeners but they seem to use depreciated function calls.
Thanks in Advance
Service#onConfigurationChanged(Configuration newConfig) works for me. No need to register Receivers for my opinion. I also did not add any filter to AndroidManifest. Did I miss something in the discussion since nobody suggested this solution? My Service is running on foreground.
Just place inside your service:
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
//Your handling
}
Please find below an example which does what you ask for, hope this helps.
public class ScreenOrientationListener extends Activity {
private static final String TAG = "ScreenOrientationListener";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mContext = this;
setContentView(R.layout.main);
startService( new Intent(this, MyService.class) );
}
}
and here comes MyService class
public class MyService extends Service {
private static final String TAG = "MyService";
private static final String BCAST_CONFIGCHANGED = "android.intent.action.CONFIGURATION_CHANGED";
private static Context mContext;
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
Log.d(TAG, "onCreate()");
mContext = this;
IntentFilter filter = new IntentFilter();
filter.addAction(BCAST_CONFIGCHANGED);
this.registerReceiver(mBroadcastReceiver, filter);
}
#Override
public void onDestroy() {
Log.d(TAG, "onDestroy()");
//Unregister receiver to avoid memory leaks
mContext.unregisterReceiver(mBroadcastReceiver);
}
#Override
public void onStart(Intent intent, int startid) {
Log.d(TAG, "onStart()");
}
public BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent myIntent) {
if ( myIntent.getAction().equals( BCAST_CONFIGCHANGED ) ) {
Log.d(TAG, "received->" + BCAST_CONFIGCHANGED);
if(getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE){
// it's Landscape
Log.d(TAG, "LANDSCAPE");
}
else {
Log.d(TAG, "PORTRAIT");
}
}
}
};
}
and here is the part to define MyService in manifest file
<!-- Services -->
<service android:enabled="true" android:name="com.wareninja.android.external.screenorientationlistener.services.MyService">
<intent-filter>
<action android:name="android.intent.action.CONFIGURATION_CHANGED"/>
</intent-filter>
</service>
You could create a BroadcastReceiver that listens for Intent.ACTION_CONFIGURATION_CHANGED (android.intent.action.CONFIGURATION_CHANGED)
Note that it does say:
You can not receive this through
components declared in manifests, only
by explicitly registering for it with
Context.registerReceiver().
Which means you can't register your reciever in the manifest file. You would have to register it in code.
then get the configuration and check what the orientation is as Floern stated.
I would suggest you use an OrientationEventListener object. It does exactly what you are looking for and it is not deprecated. It's been around since API level 3.

Categories

Resources