I know. Don't do this. I don't care. It's for a root app.
The app is installed to /system/app/ with 0777 permission
I was previously using:
ContentResolver cr = context.getContentResolver();
Settings.Secure.setLocationProviderEnabled(cr, LocationManager.GPS_PROVIDER, !isGpsOn);
This is how I'm trying it on 4.4 since that was deprecated:
int value;
if (isGpsOn)value = Settings.Secure.LOCATION_MODE_OFF;
else value = Settings.Secure.LOCATION_MODE_HIGH_ACCURACY;
Settings.Secure.putInt(cr, Settings.Secure.LOCATION_MODE, value);
And it is silently failing (according to some user reports). How can I properly toggle GPS with Android 4.4 from an app in System folder?
Don't do this. :)
Check the code for GPS TOGGLER
GPS toggle widget for Android rooted devices. It wrks well even for
those ROMs and kernels, other software failed.
With your code, just checking:
Hope you declared the following permissions in your manifest:
<uses-permission android:name="android.permission.WRITE_SETTINGS"/>
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS"/>
I had used this on rooted LG Optimus, android 4.0/4.1.
Reportedly this may no longer work but i am not sure about it for all devices and o.s.:
Switch it ON/OFF with a flag check and this code:
try {
Settings.Secure.putString (context.getContentResolver(),
Settings.Secure.LOCATION_PROVIDERS_ALLOWED, String.format ("%s,%s",
Settings.Secure.getString (context.getContentResolver(),
Settings.Secure.LOCATION_PROVIDERS_ALLOWED), LocationManager.GPS_PROVIDER));
} catch(Exception e) {}
Related
I'm using Qt (6.4.1) for android. I used to ask "ACCESS_FINE_LOCATION" permission to get GPS position using code like:
auto permissionGPS = QtAndroidPrivate::requestPermission("android.permission.ACCESS_FINE_LOCATION").result();
if(permissionGPS == QtAndroidPrivate::Authorized){
source = QGeoPositionInfoSource::createDefaultSource(0);
if (source) {
auto last = source->lastKnownPosition(false);
if(last.isValid()){
receivePosition(last);
}else{
connect(source, &QGeoPositionInfoSource::positionUpdated, this, &Locator::receivePosition);
source->startUpdates();
}
}
}else{
emit GPSRefusal(false);
}
Unfortunately if the user perfers to allow "ACCESS_COARSE_LOCATION", this code doesn't work anymore.
If I replace requested permission with "ACCESS_COARSE_LOCATION" (which is reasonable for my app), I get the following error:
W qt.positioning.android: : Position data not available due to missing permission 4
Does any one know how to get ACCESS_COARSE_LOCATION positioning working with Qt ?
For an Android 13 device you first have to request COARSE location permission.
And only after you obtained permission request gps FINE permission.
Two steps.
I would like to enable bluetooth with my app without user interaction, the prompt does not appear on my devices - Android 7, 8 & 9, and my friend's Android 10. But it appears in my work colleague's devices (Android 10).
I used the following permissions
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
And used the following Bluetooth Adaptor methods.
bluetoothAdapter.enable();
bluetoothAdapter.disable();
I have no intent ACTION_REQUEST_ENABLE or ACTION_REQUEST_DISABLE in my source code.
Am I missing some permissions or methods?
Or is this an environment problem?
Any advise on how should I handle this would be much appreciated.
Thank you.
bluetoothAdapter.enable() will directly run com.android.settings/.bluetooth.RequestPermissionHelperActivity, and you should listen for ACTION_STATE_CHANGED yourself.
I think use the BluetoothAdapter.ACTION_REQUEST_ENABLE is a better way, which will first run com.android.settings.bluetooth.RequestPermissionActivity and then RequestPermissionHelperActivity. RequestPermissionActivity will listen for ACTION_STATE_CHANGED, while your app only need the result code of Activity.RESULT_OK.
private boolean ensureBluetoothEnabled() {
if(((BluetoothManager) Objects.requireNonNull(getSystemService(Context.BLUETOOTH_SERVICE)))
.getAdapter().isEnabled()) {
return true;
} else {
Intent btIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
btIntent.putExtra(Intent.EXTRA_PACKAGE_NAME, Constants.PACKAGE);
startActivityForResult(btIntent, REQUEST_CODE_BL_OPEN);
return false;
}
}
After reading through a bunch of stale guides and stackoverflows, I was able to usb adb to install an apk as a system app in /system/priv-app that successfully toggles AirplaneMode in Android oreo:
// method in Activity, called via click listener on a Button
private void setMobileRadioEnabled_Option1(boolean enabled) {
android.content.Context context = this;
int value = enabled ? 0 : 1;
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.JELLY_BEAN_MR1) {
Settings.System.putInt(
context.getContentResolver(),
Settings.System.AIRPLANE_MODE_ON, value);
} else {
Settings.Global.putInt(
context.getContentResolver(),
Settings.Global.AIRPLANE_MODE_ON, value);
}
}
Permissions in AndroidManifest.xml:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS"/>
Standard release build in AndroidStudio with custom signing keys, installed via:
adb root
adb remount
adb push app-release.apk /system/priv-app
adb shell chmod 644 /system/priv-app/app-release.apk
adb reboot
On reboot, the app is installed and I can run it without issue.
I check in the notifications drawer / status bar what things are like to start with:
I then click my Button in the app, and check what happens:
As you can see, airplane mode seems to be successfully enabled based on the status of the airplane mode icon. But wifi and cellular data continue to be connected, and the status bar doesn't replace the text "Android" with "Airplane mode". In this state, if I hop over to chrome, I can clearly load websites I've never visited before. So airplane mode doesn't in fact seem to be actually on.
What am I doing wrong? I expect turning on airplane mode via System.putInt() to have the same effect as tapping the airplane mode tile in the status bar. No exceptions or useful error information spitting to logcat when I execute the code.
Checking this answer it seems that you need to send a broadcast to notify that you changed the airplane mode.
The broadcast should be:
Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
intent.putExtra("state", < current value of the airplane mode >);
sendBroadcast(intent);
Alternatively to jonathanrz's additional code above, which I believe is closer to canonical, I found that the following worked in place of the Settings.System.putInt() code and did not require sending the intent (or adding the permission(s) necessary to send it), at least on Oreo. I created it by merging a few answers and offhand comments from other posts, particularly an answer sketch hidden in a comment by "Navas pk" on Toggle airplane mode in Android:
private void setMobileRadioEnabled_Option2(boolean enabled) {
try {
final ConnectivityManager mConnectivityManager = (ConnectivityManager) getSystemService(android.content.Context.CONNECTIVITY_SERVICE);
final Class mClass = Class.forName(mConnectivityManager.getClass().getName());
final Method setAirplaneMode = mClass.getDeclaredMethod("setAirplaneMode", Boolean.TYPE);
setAirplaneMode.setAccessible(true);
setAirplaneMode.invoke(mConnectivityManager, !enabled);
} catch (Exception e) {
e.printStackTrace();
}
}
I've read a really lot of posts yet, but the problem still occurs...
My app needs calendar permission, and this wil work fine till Android 5.
In my trap.xml in the permissions ar set as followed:
<android xmlns:android="http://schemas.android.com/apk/res/android">
<manifest>
<uses-sdk android:minSdkVersion="14" android:targetSdkVersion="23"/>
<uses-permission android:name="android.permission.READ_CALENDAR"/>
<uses-permission android:name="android.permission.WRITE_CALENDAR"/>
</manifest>
</android>
When I try to set the permission like I found on Jira:
function calenderTask() {
if (Ti.Calendar.hasCalendarPermissions()) {
showCalendars(Ti.Calendar.selectableCalendars);
} else {
Ti.Calendar.requestCalendarPermissions(function(e) {
if (e.success) {
showCalendars(Ti.Calendar.selectableCalendars);
} else {
Ti.API.error(e.error);
alert('Access to calendar is not allowed');
}
});
}
}
function showCalendars(calendars) {
for (var i = 0; i < calendars.length; i++) {
Ti.API.info("Calender: "+calendars[i].name);
}
}
calenderTask();
only after a fresh install on the device (Samgung S7, Android 6) there is some action when I place an alert in the code.
The next run it looks like the code is ignored.
And... most important of all, there is no permissions set.
When I manually set the permission in the settings of my device, the app works fine.
Please is there somebody with a solution for me?
I'm also trying to find a better way of checking Calendar permissions on Android 6.
Meanwhile, I'm using this code to send the user right to the app settings on a dialog:
var dialog = Ti.UI.createAlertDialog();
dialog.message = 'Please check your calendar permissions';
dialog.cancel = 1;
dialog.buttonNames = ['Settings', 'Cancel'];
dialog.addEventListener('click', function(e){
var intentData = {action: "android.settings.APPLICATION_DETAILS_SETTINGS", data: "package:" + Ti.App.getId()};
var flags = [ Ti.Android.FLAG_ACTIVITY_NEW_TASK, Ti.Android.FLAG_ACTIVITY_NO_HISTORY, Ti.Android.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS];
if (e.index === 0){
win.openIntent(intentData, flags);
}
});
dialog.show();
I hope it helps a bit...
I found a solution/workaround for my problem that the calendar permission was not asked for.
In the settings section of the device I removed the permissions by hand by the specific app. Now I did a reset on all settings of the installed app's and then the question is asked on the device when I start the particular part of the app.
Thus just remove the permissions and delete the app from the device is not enough!
I've used the part of code that I listed before, that from Jira.
So, for the moment my problem is solved (I think) and the app is asking for the needed permissions after first install.
Carlos, thanks for your comment, and I hope you can do something with my investigations too.
I am developing an application with NFC and wifi direct. I get the MAC address using NFC and the Wifi Direct to transfer data. I call discoverpeers() and could get success. But there is no callback WIFI_P2P_PEERS_CHANGED_ACTION, the callback comes only when I go to settings and the select wifidirect.
This was discussed in the other question
Can I turn on WiFi-Direct from code? on Android API-14 (ICS)
"I'd like to add that WiFi direct on JB and above (at least on AOSP) is not active all the time - it only appears to be. If you look at listeners for WiFi direct, it turns itself off after some time. It turns itself back on if you open the wifi direct menu, however. You might have to have the host do a peer search or initialize itself in order to be able to be found. Likely a battery saving trick. I have also found that it's blocking, since as it accepts a connection, the entire system will lock up and fail to connect sometimes. (The system invitation) – Mgamerz "
Can anyone suggest the solution for the problem WIFI_P2P_PEERS_CHANGED_ACTION callback is not got and can get only when manually go to settings->wifi->tap on wifidirect
I used two devices Samsung galaxy nexus and nexus 7 both running on 4.2.2
There is no available API to enable wifiP2P but you can invoke method "enableP2p" from android settings 4.0.1
WifiP2pManager manager = (WifiP2pManager) getActivity().getSystemService(Context.WIFI_P2P_SERVICE);
Channel channel = manager.initialize(getActivity(), getActivity().getMainLooper(), null);
try {
Method method1 = manager.getClass().getMethod("enableP2p", Channel.class);
method1.invoke(manager, channel);
//Toast.makeText(getActivity(), "method found",
// Toast.LENGTH_SHORT).show();
} catch (Exception e) {
//Toast.makeText(getActivity(), "method did not found",
// Toast.LENGTH_SHORT).show();
}
To disable wifiP2P use this method
Method method1 = manager.getClass().getMethod("disableP2p", Channel.class);
Not from code. The user has to. That's why the demo has the link to wifi settings in the action bar.
When you call manager.discoverPeers(channel, new WifiP2pManager.ActionListener()
define onFailure and look at the reasonCode. If it's 0, then either the Wifi or WiFi direct is off.
If you look at the WiFi Direct demo app, the WifiDirectBroadcast Reciever, this piece of code looks at whether p2p is enabled specifically
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION.equals(action)) {
// UI update to indicate wifi p2p status.
int state = intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE, -1);
if (state == WifiP2pManager.WIFI_P2P_STATE_ENABLED) {
// Wifi Direct mode is enabled
activity.setIsWifiP2pEnabled(true);
} else {
activity.setIsWifiP2pEnabled(false);
activity.resetData();
}
Then when discover peers is called it looks at the variable set by setIsWifiP2pEnabled
thanks user3093354. to continue with your solution, in order to disable the p2p you have to invoke:
Method method1 = manager.getClass().getMethod("disableP2p", Channel.class);
//Try this it may be help you
WifiManager wifiManager = (WifiManager)this.getSystemService(this.WIFI_SERVICE);
wifiManager.setWifiEnabled(true); //True - to enable WIFI connectivity .
//False -disable WIFI connectivity.
//add this permissions in Manifest file :
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
You can load the wifi driver from a command prompt with the desired concurrency level if you are rooted:
/system/bin/insmod /system/lib/modules/wlan.ko con_mode=3
These are the values:
typedef enum
{
VOS_STA_MODE=0,
VOS_STA_SAP_MODE=1,
VOS_P2P_CLIENT_MODE,
VOS_P2P_GO_MODE,
VOS_MONITOR_MODE,
VOS_FTM_MODE = 5,
VOS_IBSS_MODE,
VOS_P2P_DEVICE_MODE,
VOS_MAX_NO_OF_MODE
} tVOS_CON_MODE;
This is for an Atheros card.