I have been trying to create a simple application that will let the user customize the behavior of airplane mode in Android. The motivation for this is from a relative who has a Samsung Fascinate, and during calls he will accidentally turn on airplane mode. This happens when he holds the phone, accidentally holds down the side power/lock button, which opens a dialog with a menu for “Silent Mode”, “Airplane Mode”, and “Power Off”. He accidentally triggers airplane mode by a touch of the phone to his cheek. This drops the call and is an annoyance to him.
Ultimately, I would like to create an app that prevents the cellular radio from being turned off while the user is in the middle of a call. But, for a first iteration I thought it made sense to let the user manually choose which radios would not get turned off by airplane mode.
I am not looking to modify the Android source开发者_如何学Go code or do something that would require rooting. I am looking for a solution within the standard framework
My first attempt to solve this was to create an application that would modify System.AIRPLANE_MODE_RADIOS
like so:
System.putString(getApplication().getContentResolver(), System.AIRPLANE_MODE_RADIOS, "");
According to the API docs, this constant is "A comma separated list of radios that need to be disabled when airplane mode is on". It seems that airplane mode does not actually use this constant, and it continues to work as normal after the change is made.
My next attempt was to create a BroadCastReceiver, receive the AIRPLANE_MODE action, and send out an Intent to reverse it:
Intent am = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
intent.putExtra("state", 0);
context.sendBroadcast(am);
This does turn off airplane mode after it has been activated. However, if the user was in the middle of a call, it will still be dropped (which makes sense). So, this is not quite the solution to my problem.
Does anyone know how to prevent airplane mode from disabling the cellular radio?
As far as i know you wont be able to do this since the option itself(airplane mode) would be of no use if 3rd party applications are able to access towers with airplane mode enabled on the device.
The source of PhoneApp.java
https://android.googlesource.com/platform/packages/apps/Phone/+/gingerbread-release/src/com/android/phone/PhoneApp.java
Makes it clear why this will not work.
In contrast to the wifi and bluetooth implementations which register a receiver for Intent.ACTION_AIRPLANE_MODE_CHANGED
only when on the list of airplane mode radios, PhoneApp does it all the time:
IntentFilter intentFilter =
new IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED);
And then unconditionally acts on it:
if (action.equals(Intent.ACTION_AIRPLANE_MODE_CHANGED)) {
boolean enabled = System.getInt(getContentResolver(),
System.AIRPLANE_MODE_ON, 0) == 0;
phone.setRadioPower(enabled);
}
Given the purpose of airplane mode, I'm sure this is an intentional feature and not a bug.
If the airplane mode is triggered by a physical button it is possible to override the button press action. Although to achieve this I believe it requires root access to the system.
But to trigger airplane mode from a physical button is a weird idea. IF the button is in the software and while in the call, perhaps you can create a phone application that doesn't have an airplane mode button inside the call screen.
Some applications modify the actual call-in-progress screen, and I know the CityID thing that came pre-installed on my Fascinate (Tells me the city associated with the area code of the number being dialed or incoming) was able to interrupt a call right before it dialed the number to tell me to register the software. If you can make your own (full-screen) call-in-progress view then it sounds like you have a solution. Perhaps not the most elegant, but it solves the problem.
I know this is possible to do because Opera-mini can go "full screen" and you can't drag down the task menu from the top; it is not visible to the user while in "full screen" mode.
I have an app in the market called "Airplane Mode Wi-fi Tool", it allows the user to do this using the following method:
Settings.System.putString(getContentResolver(),
Settings.System.AIRPLANE_MODE_RADIOS, "cell,bluetooth");
Default RADIOS are "cell,bluetooth,wifi" (these are the radios that turn off when enabling airplane mode.
I don't think you will be able to do this as it would make airplane mode redundant. One would think that it would be possible to disallow airplane mode from starting somehow. I think the solution you are looking for is a bad idea as it modifies an application to make it useless while still allowing it to run. The problem is a design issue that should be solved by the phone creator. I have no real experience with android (yet) but I would imagine that the kind of functionality you are looking for in the standard framework wont be there.
I'm sure there is a reasonable way around this problem but its unlikely to be in the direction you are going.
精彩评论