2G / 3G / 4G网络强制切换

3
我正在忙于编写代码以获取信号强度等信息,但是希望能通过编程方式“强制”我的网络连接到2G / 3G / 4G,以便进行更具有说服力的测量。我知道有很多应用程序可以实现以下功能:
1. 强制连接到2G / 3G / 4G网络 2. 强制连接到特定频段的信道 3. 甚至强制测量特定基站的单元ID(CID)
但到目前为止在谷歌上没有取得太多进展。如果有人能指点我方向,那就太好了!

嗨@Paul,你找到了不需要构建自定义SDK的解决方案吗? - jotade
嗨@jotade,很遗憾我没有找到解决这个问题的方法。在我能够为这个主题花费额外时间之前,我必须继续进行替代性工作。 - Paul
2个回答

2
我相信你的要求需要一部已经root过的手机。然而,如果你想强制网络保持在LTE/GSM/CDMA模式下,你可以通过以下意图来触发这些设置:
    try{
        Intent intent = new Intent("android.intent.action.MAIN");
        intent.setClassName("com.android.settings", "com.android.settings.RadioInfo");
        startActivity(intent);
    } catch(Exception e){
        Toast.makeText(getApplicationContext(), " Device not supported" , Toast.LENGTH_LONG).show();
    } 

很久以前的事了,但还是谢谢你的回答。我会在有机会的时候试一试。 - Paul

1

PermissionUtils.java类用于请求权限,适用于SDK版本>=23

public class PermissionUtils {
Context context;
Activity current_activity;

PermissionResultCallback permissionResultCallback;
ArrayList<String> permission_list=new ArrayList<>();
ArrayList<String> listPermissionsNeeded=new ArrayList<>();

String dialog_content="";
int req_code;

public PermissionUtils(Context context)
{
    this.context=context;
    this.current_activity= (Activity) context;
    permissionResultCallback= (PermissionResultCallback) context;
}

public PermissionUtils(Context context, PermissionResultCallback callback)
{
    this.context=context;
    this.current_activity= (Activity) context;
    permissionResultCallback= callback;
}


public void check_permission(ArrayList<String> permissions, String dialog_content, int request_code)
{
    this.permission_list=permissions;
    this.dialog_content=dialog_content;
    this.req_code=request_code;

    if(Build.VERSION.SDK_INT >= 23)
    {
        if (checkAndRequestPermissions(permissions, request_code))
        {
            permissionResultCallback.PermissionGranted(request_code);
        }
    }
    else
    {
        permissionResultCallback.PermissionGranted(request_code);
    }

}


/**
 * Check and request the Permissions
 *
 * @param permissions
 * @param request_code
 * @return
 */

private  boolean checkAndRequestPermissions(ArrayList<String> permissions,int request_code) {

    if(permissions.size()>0)
    {
        listPermissionsNeeded = new ArrayList<>();

        for(int i=0;i<permissions.size();i++)
        {
            int hasPermission = ContextCompat.checkSelfPermission(current_activity,permissions.get(i));

            if (hasPermission != PackageManager.PERMISSION_GRANTED) {
                listPermissionsNeeded.add(permissions.get(i));
            }

        }

        if (!listPermissionsNeeded.isEmpty())
        {
            ActivityCompat.requestPermissions(current_activity, listPermissionsNeeded.toArray(new String[listPermissionsNeeded.size()]),request_code);
            return false;
        }
    }

    return true;
}

/**
 *
 *
 * @param requestCode
 * @param permissions
 * @param grantResults
 */
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults)
{
    switch (requestCode)
    {
        case 1:
            if(grantResults.length>0)
            {
                Map<String, Integer> perms = new HashMap<>();

                for (int i = 0; i < permissions.length; i++)
                {
                    perms.put(permissions[i], grantResults[i]);
                }

                final ArrayList<String> pending_permissions=new ArrayList<>();

                for (int i = 0; i < listPermissionsNeeded.size(); i++)
                {
                    if (perms.get(listPermissionsNeeded.get(i)) != PackageManager.PERMISSION_GRANTED)
                    {
                        if(ActivityCompat.shouldShowRequestPermissionRationale(current_activity,listPermissionsNeeded.get(i)))
                            pending_permissions.add(listPermissionsNeeded.get(i));
                        else
                        {
                            Log.i("Go to settings","and enable permissions");
                            permissionResultCallback.NeverAskAgain(req_code);
                           return;
                        }
                    }

                }

                if(pending_permissions.size()>0)
                {
                    showMessageOKCancel(dialog_content,
                            new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialog, int which) {

                                    switch (which) {
                                        case DialogInterface.BUTTON_POSITIVE:
                                            Log.d("LOG","ON OK BTN CLICK CALLING CHECK PERMISSION METHOD");
                                            check_permission(permission_list,dialog_content,req_code);
                                            break;
                                        case DialogInterface.BUTTON_NEGATIVE:
                                            Log.i("permisson","not fully given");
                                            if(permission_list.size()==pending_permissions.size()){
                                                Log.d("LOG","ON NO BTN CLICK CALLING Permission Denided METHOD");
                                                //permissionResultCallback.PermissionDenied(req_code);
                                                check_permission(permission_list,dialog_content,req_code);
                                            }
                                            else{
                                                Log.d("LOG","ON NO BTN CLICK CALLING PartialPermissionGranted METHOD");
                                                permissionResultCallback.PartialPermissionGranted(req_code,pending_permissions);
                                            }

                                            break;
                                    }


                                }
                            });

                }
                else
                {
                    permissionResultCallback.PermissionGranted(req_code);
                }
            }
            break;
    }
}


/**
 * Explain why the app needs permissions
 *
 * @param message
 * @param okListener
 */
public void showMessageOKCancel(String message, DialogInterface.OnClickListener okListener) {
    new AlertDialog.Builder(current_activity)
            .setMessage(message)
            .setPositiveButton("Ok", okListener)
            .setNegativeButton("Cancel", okListener)
            .setCancelable(false)
            .create()
            .show();
}

public interface PermissionResultCallback
{
    void PermissionGranted(int request_code);
    void PartialPermissionGranted(int request_code, ArrayList<String> granted_permissions);
    void PermissionDenied(int request_code);
    void NeverAskAgain(int request_code);
}
}

将此权限添加到您的AndroidManifest.xml中。
 <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
 <uses-permission android:name="android.permission.READ_PHONE_STATE" />

TelephonyManagerHelper.java的信息
public class TelephonyManagerHelper implements PermissionUtils.PermissionResultCallback {

private Context context;
private Activity current_activity;
private boolean isPermissionGranted;
TelephonyManager telephonyManager;
String Information;


private ArrayList<String> permissions=new ArrayList<>();
private PermissionUtils permissionUtils;
private final static int REQUEST_CHECK_SETTINGS = 2000;


public TelephonyManagerHelper(Context context) {
    this.context=context;
    this.current_activity= (Activity) context;
    permissionUtils=new PermissionUtils(context,this);
    permissions.add(Manifest.permission.READ_PHONE_STATE);
    permissions.add(Manifest.permission.ACCESS_COARSE_LOCATION);
}

/**
 * Method to check the availability of location permissions
 * */

public void checkpermission()
{
    permissionUtils.check_permission(permissions,"Need permission for getting Phone information",1);
}

private boolean isPermissionGranted() {
    return isPermissionGranted;
}

/**
 * Handles the permission results
 */
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults)
{
    permissionUtils.onRequestPermissionsResult(requestCode,permissions,grantResults);
}


/**
 * Handles the activity results
 */
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    switch (requestCode) {
        case REQUEST_CHECK_SETTINGS:
            switch (resultCode) {
                case Activity.RESULT_OK:
                    // All required changes were successfully made
                    Information=getInformation();
                    break;
                case Activity.RESULT_CANCELED:
                    // The user was asked to change settings, but chose not to
                    break;
                default:
                    break;
            }
            break;
    }
}

public String getInformation() {
    try{
        telephonyManager= (TelephonyManager) context.getSystemService(context.TELEPHONY_SERVICE);

        int phoneType=telephonyManager.getPhoneType();
        String PhoneType="";
        if (phoneType==telephonyManager.PHONE_TYPE_NONE){  //0
            PhoneType="NONE";
        }else if(phoneType==telephonyManager.PHONE_TYPE_GSM){  //1
            PhoneType="GSM";
        }else if(phoneType==telephonyManager.PHONE_TYPE_CDMA){ //2
            PhoneType="CDMA";
        }else if(phoneType==telephonyManager.PHONE_TYPE_SIP){ //3
            PhoneType="SIP";
        }else{
            PhoneType="Not Found";
        }

        int networkType=telephonyManager.getNetworkType();
        String NetworkType="";

        if (networkType==telephonyManager.NETWORK_TYPE_UNKNOWN){   //0
            NetworkType="UNKNOWN";
        }else if(networkType==telephonyManager.NETWORK_TYPE_GPRS){ //1
            NetworkType="GPRS";
        }
        else if(networkType==telephonyManager.NETWORK_TYPE_EDGE){ //2
            NetworkType="EDGE";
        }
        else if(networkType==telephonyManager.NETWORK_TYPE_UMTS){ //3
            NetworkType="UMTS";
        }
        else if(networkType==telephonyManager.NETWORK_TYPE_CDMA){ //4
            NetworkType="CDMA";
        }
        else if(networkType==telephonyManager.NETWORK_TYPE_EVDO_0){ //5
            NetworkType="EVDO 0";
        }
        else if(networkType==telephonyManager.NETWORK_TYPE_EVDO_A){ //6
            NetworkType="EVDO A";
        }
        else if(networkType==telephonyManager.NETWORK_TYPE_1xRTT){ //7
            NetworkType="1xRTT";
        }
        else if(networkType==telephonyManager.NETWORK_TYPE_HSDPA){ //8
            NetworkType="HSDPA";
        }
        else if(networkType==telephonyManager.NETWORK_TYPE_HSUPA){ //9
            NetworkType="HSUPA";
        }else if(networkType==telephonyManager.NETWORK_TYPE_HSPA){ //10
            NetworkType="HSPA";
        }else if (networkType==telephonyManager.NETWORK_TYPE_IDEN){ //11
            NetworkType="IDEN";
        }else if(networkType==telephonyManager.NETWORK_TYPE_EVDO_B){ //12
            NetworkType="EVDO B";
        }else if(networkType==telephonyManager.NETWORK_TYPE_LTE){ //13
            NetworkType="LTE";
        }else if(networkType==telephonyManager.NETWORK_TYPE_EHRPD){ //14
            NetworkType="EHRPD";
        }else if(networkType==telephonyManager.NETWORK_TYPE_HSPAP){ //15
            NetworkType="HSPAP";
        }else if(networkType==telephonyManager.NETWORK_TYPE_GSM){ //16
            NetworkType="GSM";
        }else if(networkType==telephonyManager.NETWORK_TYPE_TD_SCDMA){ //17
            NetworkType="SCDMA";
        }else {                                                       // 18
            NetworkType="IWLAN";
        }


        @SuppressLint("MissingPermission")
        String DeviceId = telephonyManager.getDeviceId();
        @SuppressLint("MissingPermission")
        String PhoneNumber = telephonyManager.getLine1Number();

        @SuppressLint("MissingPermission")
        String SubscribeIdIMSI=telephonyManager.getSubscriberId();

        @SuppressLint("MissingPermission")
        String NetworkCountryISO= telephonyManager.getNetworkCountryIso();
        String NetworkOperator=telephonyManager.getNetworkOperator();
        int MCC = Integer.parseInt(NetworkOperator.substring(0, 3)); // mobile country code
        int MNC = Integer.parseInt(NetworkOperator.substring(3));    // mobile network code

        String NetworkOperatorName=telephonyManager.getNetworkOperatorName();
        String SimCountryIso=telephonyManager.getSimCountryIso();
        String SimOperator=telephonyManager.getSimOperator();
        String SimOperatorName=telephonyManager.getSimOperatorName();
        @SuppressLint("MissingPermission")
        String SimSerialNumber=telephonyManager.getSimSerialNumber();
        int simState=telephonyManager.getSimState();

        String SimState="";
        if (simState==telephonyManager.SIM_STATE_UNKNOWN){ //0
            SimState="UNKNOWN";
        }else if (simState==telephonyManager.SIM_STATE_ABSENT){ //1
            SimState="ABSENT";
        }else if (simState==telephonyManager.SIM_STATE_PIN_REQUIRED){ //2
            SimState="PIN REQUIRED";
        }else if (simState==telephonyManager.SIM_STATE_PUK_REQUIRED){ //3
            SimState="PUK REQUIRED";
        } else if (simState==telephonyManager.SIM_STATE_NETWORK_LOCKED){ //4
            SimState="NETWORK LOCKED";
        }else if (simState==telephonyManager.SIM_STATE_READY){ //5
            SimState="READY";
        }else if (simState==telephonyManager.SIM_STATE_NOT_READY)//6
        {
            SimState="NOT READY";
        }else if(simState==telephonyManager.SIM_STATE_PERM_DISABLED){ //7
            SimState="PERM DISABLED";
        }else if(simState==telephonyManager.SIM_STATE_CARD_IO_ERROR){ //8
            SimState="CARD IO ERROR";
        }else { //9
            SimState="CARD RESTRICTED";
        }


        @SuppressLint("MissingPermission")
        GsmCellLocation gsmCellLocation = (GsmCellLocation) telephonyManager.getCellLocation();
        int CID = gsmCellLocation.getCid(); // CellID
        int LAC = gsmCellLocation.getLac(); // Location Area Code

        Information="Phone Type : "+PhoneType+"\n\n"+
                "Network Type: "+NetworkType+"\n\n"+
                "DeviceId:  "+DeviceId+"\n\n"+
                "PhoneNumber: "+PhoneNumber+"\n\n"+
                "SubscribeIdIMSI :  "+SubscribeIdIMSI+"\n\n"+
                "NetworkCountryISO :  "+NetworkCountryISO+"\n\n"+
                "NetworkOperator :  "+NetworkOperator+"\n\n"+
                "MCC Mobile Country Code:"+MCC+"\n\n"+
                "MNC Mobile Network Code:"+MNC+"\n\n"+
                "NetworkOperatorName :"+NetworkOperatorName+"\n\n"+
                "SimCountryIso :"+SimCountryIso+"\n\n"+
                "SimOperator :"+SimOperator+"\n\n"+
                "SimOperatorName  :"+SimOperatorName+"\n\n"+
                "SimSerialNumber  :"+SimSerialNumber+"\n\n"+
                "Sim State :"+SimState+"\n\n"+
                "cellID :"+CID+"\n\n"+
                "LAC Location Area Code:"+LAC+"\n\n";
    }catch (Exception e){e.printStackTrace();}
    return Information;

}

@Override
public void PermissionGranted(int request_code) {
    Log.i("PERMISSION","GRANTED");
    isPermissionGranted=true;
}

@Override
public void PartialPermissionGranted(int request_code, ArrayList<String> granted_permissions) {
    Log.i("PERMISSION PARTIALLY","GRANTED");
}

@Override
public void PermissionDenied(int request_code) {
    Log.i("PERMISSION","DENIED");
}

@Override
public void NeverAskAgain(int request_code) {
    Log.i("PERMISSION","NEVER ASK AGAIN");
    permissionUtils.showMessageOKCancel("App Required To Get Phone State \nPlease Grant Permission from AppInfo > Permissions > Phone , Location",
            new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {

                    switch (which) {
                        case DialogInterface.BUTTON_POSITIVE:
                            Intent intent = new Intent();
                            intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                            Uri uri = Uri.fromParts("package", BuildConfig.APPLICATION_ID, null);
                            intent.setData(uri);
                            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                            context.startActivity(intent);
                            break;
                        case DialogInterface.BUTTON_NEGATIVE:

                            break;
                    }


                }
            });
}

}

SimCardInformationActivity.java 显示信息

public class SimCardInformationActivity extends AppCompatActivity {
 TextView txtSimInformation;
 TelephonyManagerHelper telephonyHelper;
   String Info;
    @Override
     protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_sim_card_information);
    txtSimInformation=findViewById(R.id.txtSimInformation);
    telephonyHelper=new TelephonyManagerHelper(SimCardInformationActivity.this);
    telephonyHelper.checkpermission();

    getTelephonyInformaiton();


}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    Log.d("LOG:On Activity Result","Request Code "+requestCode+"  Result Code"+requestCode);
    telephonyHelper.onActivityResult(requestCode,resultCode,data);
}

// Permission check functions
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    // redirects to utils
    Log.d("LOG:onRequestPermResult","Request Code "+requestCode+"  Grant Result"+grantResults);
    telephonyHelper.onRequestPermissionsResult(requestCode,permissions,grantResults);
}


private void getTelephonyInformaiton() {
      Info=telephonyHelper.getInformation();
      txtSimInformation.setText(Info);
}

@Override
protected void onResume() {
    super.onResume();
    getTelephonyInformaiton();
}

}

activity_sim_card_information.xml用于布局

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.app.SimCardInformationActivity">

    <ScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/txtSimInformation"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
    </ScrollView>

</RelativeLayout>

嗨,Saurabh,非常感谢您提供这个详尽的代码,其中的helper类特别有助于显示一些额外的SIM、网络和运营商相关数据,可以通过扫描代码来读取和显示。但是我现在对强制特定网络连接很感兴趣,例如强制连接到LTE或GSM网络(也许与ConnectivityManager有关?)。同样地,强制连接到1800MHz频段而不是900Mhz频段(作为测量的一种蜂窝选择形式)等等... - Paul
在定义 public String getInformation() 函数之前添加 throws SecurityException 以消除烦人的错误。 :) - IOviSpot
请阅读[答案]并[编辑]您的答案,以包含解释为什么这段代码实际上可以解决手头的问题。请记住,您不仅要解决问题,还要教育提问者和未来的读者。 - Adriaan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接