android: how to restrict data access to 2g by code? - android

i want to set the system preference (by code) for just using 2g networks instead of using 3g. so far i haven't found anything that could have helped me. i suppose i need to set it via the ConnectionManager? can anyone point me in the right direction here?

Unfortunately, you can't do this. The best you can do is take the user to the relevant settings screen (Mobile Network Settings), where they can choose for themselves. There's no API to actually change the setting.
Some ROMs (e.g. CyanogenMod) build this into the system, and there may be options if you are rooted/installed as a system app, but if you want something standard/mass applicable then I'm afraid you're out of luck.

use the following code
public class CheckNetworkType extends Activity
{
private static final String tag = "CheckNetworkType";
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TelephonyManager tm = (TelephonyManager) this.getSystemService(Context.TELEPHONY_SERVICE);
if(tm.getNetworkType() == TelephonyManager.NETWORK_TYPE_EDGE )
{
// Network type is 2G
Log.v(tag, "2G or GSM");
}
else
if(tm.getNetworkType() == TelephonyManager.NETWORK_TYPE_CDMA)
{
// Network type is 2G
Log.v(tag, "2G or CDMA");
}
else
if(tm.getNetworkType() == TelephonyManager.NETWORK_TYPE_UMTS)
{
// Network type is 3G
Log.v(tag, "3G Network available.");
}
}
}

Related

Dual SIM: auto-switch data to other SIM (system-app)

I'm working on a system app(signed with os signature),
I need to programmatically switch data between 2 SIMs. After spend a lot of time reading Settings app source code of AOSP (here)
I found that when you manually click on switch data in Settings app, this code executes:
(you can find it here)
public static void setMobileDataEnabled(Context context, int subId, boolean enabled,
boolean disableOtherSubscriptions) {
final TelephonyManager telephonyManager = context.getSystemService(TelephonyManager.class)
.createForSubscriptionId(subId);
final SubscriptionManager subscriptionManager = context.getSystemService(
SubscriptionManager.class);
telephonyManager.setDataEnabled(enabled);
if (disableOtherSubscriptions) {
final List<SubscriptionInfo> subInfoList =
subscriptionManager.getActiveSubscriptionInfoList();
if (subInfoList != null) {
for (SubscriptionInfo subInfo : subInfoList) {
// We never disable mobile data for opportunistic subscriptions.
if (subInfo.getSubscriptionId() != subId && !subInfo.isOpportunistic()) {
context.getSystemService(TelephonyManager.class).createForSubscriptionId(
subInfo.getSubscriptionId()).setDataEnabled(false);
}
}
}
}
}
But when I tried this code, it just turned off the current data without turning on data on other SIM! I can also see in phone Settings app that data had been changed to the other SIM, and it's UI switch is on, but actually there is no network data(It seems like just UI had been changed, but still the default data remain on previous SIM card)
It seems I've missed something. Looking forward for your helps. Thanks!

Detect Android device is foldable?

I'm working on a project that needs to distinguish a device type at startup, so whether it's a phone, tablet or foldable. I can distinguish between phone and tablet but is there a way to detect whether an android device is a foldable?
Check the link --> https://developer.android.com/
It seems that these is no particular API or configuration for detecting fordable device.
Some of my own idea is to check the screen resolution size? As that would differ somehow from other phones !
is simple:
I use this code im my apps, I share it with you
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TelephonyManager manager = (TelephonyManager)getApplicationContext().getSystemService(Context.TELEPHONY_SERVICE);
if (Objects.requireNonNull(manager).getPhoneType() == TelephonyManager.PHONE_TYPE_NONE) {
Toast.makeText(MainActivity.this, "Detected... You're using a Tablet", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(MainActivity.this, "Detected... You're using a Mobile Phone", Toast.LENGTH_SHORT).show();
}
}
}

How to WifiP2pDevice.deviceName for current device?

I know similar questions are asked but the answers didn't work for me. I tried this answer but it throws null pointer exception. I also saw this answer but WifiP2pManager does not have any property or method that returns device name.
Can anyone please help?
I basically want to show user their device name and let them change it if they want to set custom name.
Thanks.
If you're still looking for the answer, here's how:
Identify own device name
This becomes available upon receiving the WIFI_P2P_THIS_DEVICE_CHANGED_ACTION intent in your broadcast receiver. Simply use the deviceName member variable like so:
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION.equals(action)) {
WifiP2pDevice self = (WifiP2pDevice) intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_DEVICE);
// Now self.deviceName gives you own device name
} else if(WifiP2pManager.WIFI_P2P...) {
...
2. Change own device name
There's no method to change the device name using the WifiP2pManager as per the develper docs, and although a public setDeviceName() method exists in the source code, you can't call it on your object (probably to keep devs from calling it on an object representing a nearby peer device). What worked for me was to obtain a Method object representing said method and invoking it on my WifiP2pManager instance:
private WifiP2pManager manager;
private WifiP2pManager.Channel channel;
...
public void changeDeviceName(String deviceNewName) {
try {
Method method = manager.getClass().getMethod("setDeviceName", WifiP2pManager.Channel.class, String.class, WifiP2pManager.ActionListener.class);
method.invoke(manager, channel, deviceNewName, new WifiP2pManager.ActionListener() {
#Override
public void onSuccess() {
Toast.makeText(MainActivity.this, "Name successfully changed", Toast.LENGTH_LONG).show();
}
#Override
public void onFailure(int reason) {
Toast.makeText(MainActivity.this, "Request failed: " + reason, Toast.LENGTH_SHORT).show();
Log.d(TAG, "Name change failed: " + reason);
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
Alternatively, users can rename their device manually from the advanced WiFi settings (Preferences > Advanced > WiFi Direct > Configure Device),
EDIT: Starting with Pie, use of non-SDK interfaces (essentially classes, variables or methods marked with #hide, which you access using reflection) is being restricted and will eventually be disallowed. The above method is currently greylisted (which means support for reflecting it might be removed in the future). Read up more here: https://developer.android.com/distribute/best-practices/develop/restrictions-non-sdk-interfaces

For Android Wi-Fi, is it possible to monitor in / out (e.g. up / down) data transfer information?

I want to re-present the data transfer arrows for Wi-Fi (as seen in the Quick Settings panel) in my app. I have been looking at the source code for Quick Settings and have been roadblocked by a couple of non-public APIs (AsyncChannel & WiFiManager.getWifiServiceMessenger) - does anyone know if there is any conceivable way around this?
For example, NetworkController...
// wifi
mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
Handler handler = new WifiHandler();
mWifiChannel = new AsyncChannel(); //Private
Messenger wifiMessenger = mWifiManager.getWifiServiceMessenger(); // Private
if (wifiMessenger != null) {
mWifiChannel.connect(mContext, handler, wifiMessenger);
}
...is handled in...
// ===== Wifi ===================================================================
class WifiHandler extends Handler {
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
...
case WifiManager.DATA_ACTIVITY_NOTIFICATION:
if (msg.arg1 != mWifiActivity) {
mWifiActivity = msg.arg1;
refreshViews();
}
break;
...
}
}
}
...where mWifiConnectivity is communicated to the Quick Setting panel.
I am thinking this is not possible, but thanks for your consideration and confirmation of this hunch :-\
check out this other question here in SO, looks like he's done the monitoring part.

How to check if an Android device has voice capabilities

Does anyone know a good way of programmaticaly checking if an Android device, phone or tablet, has voice capabilities?
By voice capabilities I mean capability to make phone calls. I know there are devices, like Galaxy tab in North America, that don't have this capability.
I haven't tried this myself, but it looks like the details you need would be in the TelephonyManager:
private boolean hasPhoneAbility()
{
TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
if(telephonyManager.getPhoneType() == TelephonyManager.PHONE_TYPE_NONE)
return false;
return true;
}
I know this question was posted a long time ago, but I still thought I would post the solution I came up with that works for me so far, just so anyone with the same problem can benefit. (Because it seems like lots of people are having trouble finding a solution).
I just checked for the device's voicemail number, and obviously if it doesn't have one, then it is not a phone. In my code, to check this, it is tm.getVoiceMailNumber();
Here's what I did:
callButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
TelephonyManager tm = (TelephonyManager)getSystemService(TELEPHONY_SERVICE);
String ableToMakePhoneCalls = tm.getVoiceMailNumber(); //check device for voicemail number (null means no voicemail number).
if(ableToMakePhoneCalls == null){ //If the device does not have voicemail, then it must not be a phone. So it can't call.
//I displayed an alert dialog box here
}
else{
String phoneNum = "tel:8885554444";
Intent intentPhone = new Intent(android.content.Intent.ACTION_CALL);
intentPhone.setData(Uri.parse(phoneNum));
startActivity(intentPhone);
}
}
});
In theory, you should be able to use Intent.resolveActivity to do this. There's a problem (described here) with Galaxy tabs in particular. They evidently report that they have calling capability. You can even resolve an intent successfully. Unfortunately, it resolves to a no-op activity.
I would assume that prepare() would fail if there is not mic available:
mRecorder = new MediaRecorder();
mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mRecorder.setOutputFile(audio_file);
mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
try {
mRecorder.prepare();
mRecorder.start();
} catch (Exception e) {}

Categories

Resources