APN 开关实现原理

来源:互联网 发布:淘宝买家一直没有评价 编辑:程序博客网 时间:2024/04/30 05:55

关闭APN的原理是在APN信息表(content://telephony/carriers/current)的apn, type字段添加自定义的后缀(参考自APNDroid)

 

 

package com.android.settings.widget;
 
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.provider.BaseColumns;
 
/**
 * Utility class for changing APN state
 
*/
public class ApnUtils {
    
private static final String SUFFIX_APN = "_suffix_apn"// type 1
 
    
private static final String MMS = "mms";
 
    
private static final String COLUMN_ID = BaseColumns._ID;
    
private static final String COLUMN_APN = "apn";
    
private static final String COLUMN_TYPE = "type";
    
private static final String COLUMN_APN_ID = "apn_id"// for preferred APN
 
    
private static final String[] PROJECTION = new String[] { COLUMN_ID,
            COLUMN_APN, COLUMN_TYPE };
    
private static final Uri CURRENT_APNS = Uri
            .parse(
"content://telephony/carriers/current");
    
private static final Uri PREFERRED_APN = Uri
            .parse(
"content://telephony/carriers/preferapn");
    
    
/**
     * Gets the state of APN
     * 
     * 
@param context
     * 
@return true if enabled
     
*/
    
public static boolean getApnState(Context context) {
        
        ContentResolver resolver 
= context.getContentResolver();
        
int counter = 0;
        Cursor cursor 
= null;
        
try {
            cursor 
= resolver.query(CURRENT_APNS, PROJECTION, nullnullnull);
            
int typeIndex = cursor.getColumnIndex(COLUMN_TYPE);
            cursor.moveToNext();
            
while (!cursor.isAfterLast()) {
                String type 
= cursor.getString(typeIndex);
 
                
if (isDisabled(type)) {
                    
return false// no need to continue
                }
 
                
if (!isMms(type) || /* this is MMM and we */shouldDisableMms()) {
                    counter
++;
                }
 
                cursor.moveToNext();
            }
        } 
finally {
            
if (cursor != null) {
                cursor.close();
            }
        }
        
return counter != 0;
    }
    
    
private static boolean isMms(String type) {
        
return type != null && type.toLowerCase().endsWith(MMS);
    }
 
    
private static boolean shouldDisableMms() {
        
// TODO Auto-generated method stub
        return false;
    }
    
    
private static boolean isDisabled(String value) {
        
return value != null && value.endsWith(SUFFIX_APN);
    }
    
    
/**
     * Set APN State
     * 
     * 
@param context
     * 
@param enabled
     
*/
    
public static void setApnState(Context context, boolean enabled) {
        
boolean shouldDisableMms = shouldDisableMms();
        
        ContentResolver resolver 
= context.getContentResolver();
        ContentValues values 
= new ContentValues();
        Cursor cursor 
= null;
 
        String[] args 
= new String[1];
        
try {
            
// COLUMN_ID{0}, COLUMN_APN{1}, COLUMN_TYPE{2}
            cursor = resolver.query(CURRENT_APNS, PROJECTION, nullnullnull);
            
int idIndex = cursor.getColumnIndex(COLUMN_ID);
            
int apnIndex = cursor.getColumnIndex(COLUMN_APN);
            
int typeIndex = cursor.getColumnIndex(COLUMN_TYPE);
            cursor.moveToFirst();
            
while (!cursor.isAfterLast()) {
 
                String typeValue 
= cursor.getString(typeIndex);
                
if (!enabled // we should disable
                        && isMms(typeValue) // and this is MMS
                        && !shouldDisableMms) { // but users disallow us to
                                                
// disable MMS
                    
// ignore
                    cursor.moveToNext();
                    
continue;
                }
 
                args[
0= String.valueOf(cursor.getInt(idIndex)); // id
                values.put(COLUMN_APN, getAdaptedValue(cursor.getString(apnIndex), enabled));
                values.put(COLUMN_TYPE, getAdaptedValue(typeValue, enabled));
 
                resolver.update(CURRENT_APNS, values, COLUMN_ID 
+ "=?", args);
 
                
// move to next
                cursor.moveToNext();
            }
 
        } 
catch (Exception e) {
            
throw new RuntimeException(e);
        } 
finally {
            
if (cursor != null) {
                cursor.close();
            }
        }        
    }
    
    
private static String getAdaptedValue(String value, boolean enable) {
        
        
final String modifier = SUFFIX_APN;
        
        
// handle null-value
        if (value == nullreturn enable ? value : modifier;
        
        
// remove any modifier so that value becomes enabled in any case
        value = removeModifiers(value); 
        
        
if (!enable) { // add required modifier
            value = addModifier(value);
        }
        
        
return value;
    }
    
    
private static String removeModifiers(String value) {
        
if (value.endsWith(SUFFIX_APN)) 
            
return value.substring(0, value.length() - SUFFIX_APN.length());
        
else 
            
return value;
    }
    
    
private static String addModifier(String value) {
        
return value + SUFFIX_APN;
    }
}