Android 4.2.1 - Actualización de una columna en la base de datos de configuración APN programáticamente
Pregunta
Estoy intentando actualizar la columna 'Nombre' de la tabla de base de datos APN preferida que se encuentra en la ubicación: contenido: // Telefonía / Carriers / PrefSapn. Sin embargo, el Contenido de mi aplicaciónResolver.Update () siempre devuelve 0, lo que significa que no se han actualizado las filas. Ya tengo acceso de root para la aplicación y lo confirmé programáticamente antes de ejecutar la actualización ().
Los detalles sobre las columnas de la tabla se pueden encontrar aquí y Aquí . También me aseguré de hacer referencia a la Documentación sobre cómo se llama la función de actualización .
El método de actualización:
public boolean setAPN(String newAPN, TextView t){
//get URI objects for the tables
final Uri APN_TABLE_URI = Uri.parse("content://telephony/carriers");
final Uri PREFERRED_APN_URI = Uri.parse("content://telephony/carriers/preferapn");
//Confirm permissions
PackageManager pm = getPackageManager();
if (pm.checkPermission(permission.WRITE_APN_SETTINGS, getPackageName()) == PackageManager.PERMISSION_GRANTED) {
//Update name field
ContentResolver resolver = this.getContentResolver();
ContentValues values = new ContentValues();
values.put("name", newAPN);
long rc = resolver.update(PREFERRED_APN_URI, values, null, null);
//Display the row contents (always has the original fields, doesn't update)
Cursor c = getContentResolver().query(PREFERRED_APN_URI, null, null, null, null);
c.moveToFirst();
int index = c.getColumnIndex("_id"); //getting index of required column
Short id = c.getShort(index); //getting APN's id from
index = c.getColumnIndex("name");
String name = c.getString(index);
index = c.getColumnIndex("mcc");
String mcc = c.getString(index);
index = c.getColumnIndex("mnc");
String mnc = c.getString(index);
index = c.getColumnIndex("numeric");
String numeric = c.getString(index);
t.setText(" ID:" + id + "\n" +
" APN Name: " + name + "\n" +
" MCC: " + mcc + "\n" +
" MNC: " + mnc + "\n" +
" Numeric: " + numeric + "\n"
);
} else {
t.setText(" You don't have permission to do this. ");
}
return true;
}
Como se mencionó anteriormente, también tengo el permiso: "android.permission.write_apn_settings" en el archivo manifiesto:
¿He llamado a la función de actualización incorrectamente para mi propósito particular? ¿O está utilizando la actualización () la forma incorrecta de ir sobre esto?
Solución
Esta pregunta ha estado muerta durante casi un mes, pero hice una solución para este problema y quería compartirlo.La solución consiste en copiar la entrada de APN preferida existente, excluyendo el campo Nombre, insertando el nuevo APN en la lista de soporte, luego configurando la nueva APN como se prefiere utilizando la ID recién generada.
public int InsertAPN(String name){
//Set the URIs and variables
int id = -1;
boolean existing = false;
final Uri APN_TABLE_URI = Uri.parse("content://telephony/carriers");
final Uri PREFERRED_APN_URI = Uri.parse("content://telephony/carriers/preferapn");
//Check if the specified APN is already in the APN table, if so skip the insertion
Cursor parser = getContentResolver().query(APN_TABLE_URI, null, null, null, null);
parser.moveToLast();
while (parser.isBeforeFirst() == false){
int index = parser.getColumnIndex("name");
String n = parser.getString(index);
if (n.equals(name)){
existing = true;
Toast.makeText(getApplicationContext(), "APN already configured.",Toast.LENGTH_SHORT).show();
break;
}
parser.moveToPrevious();
}
//if the entry doesn't already exist, insert it into the APN table
if (!existing){
//Initialize the Content Resolver and Content Provider
ContentResolver resolver = this.getContentResolver();
ContentValues values = new ContentValues();
//Capture all the existing field values excluding name
Cursor apu = getContentResolver().query(PREFERRED_APN_URI, null, null, null, null);
apu.moveToFirst();
int index;
index = apu.getColumnIndex("apn");
String apn = apu.getString(index);
index = apu.getColumnIndex("type");
String type = apu.getString(index);
index = apu.getColumnIndex("proxy");
String proxy = apu.getString(index);
index = apu.getColumnIndex("port");
String port = apu.getString(index);
index = apu.getColumnIndex("user");
String user = apu.getString(index);
index = apu.getColumnIndex("password");
String password = apu.getString(index);
index = apu.getColumnIndex("server");
String server = apu.getString(index);
index = apu.getColumnIndex("mmsc");
String mmsc = apu.getString(index);
index = apu.getColumnIndex("mmsproxy");
String mmsproxy = apu.getString(index);
index = apu.getColumnIndex("mmsport");
String mmsport = apu.getString(index);
index = apu.getColumnIndex("mcc");
String mcc = apu.getString(index);
index = apu.getColumnIndex("mnc");
String mnc = apu.getString(index);
index = apu.getColumnIndex("numeric");
String numeric = apu.getString(index);
//Assign them to the ContentValue object
values.put("name", name); //the method parameter
values.put("apn", apn);
values.put("type", type);
values.put("proxy", proxy);
values.put("port", port);
values.put("user", user);
values.put("password", password);
values.put("server", server);
values.put("mmsc", mmsc);
values.put("mmsproxy", mmsproxy);
values.put("mmsport", mmsport);
values.put("mcc", mcc);
values.put("mnc", mnc);
values.put("numeric", numeric);
//Actual insertion into table
Cursor c = null;
try{
Uri newRow = resolver.insert(APN_TABLE_URI, values);
if(newRow != null){
c = resolver.query(newRow, null, null, null, null);
int idindex = c.getColumnIndex("_id");
c.moveToFirst();
id = c.getShort(idindex);
}
}
catch(SQLException e){}
if(c !=null ) c.close();
}
return id;
}
//Takes the ID of the new record generated in InsertAPN and sets that particular record the default preferred APN configuration
public boolean SetPreferredAPN(int id){
//If the id is -1, that means the record was found in the APN table before insertion, thus, no action required
if (id == -1){
return false;
}
Uri.parse("content://telephony/carriers");
final Uri PREFERRED_APN_URI = Uri.parse("content://telephony/carriers/preferapn");
boolean res = false;
ContentResolver resolver = this.getContentResolver();
ContentValues values = new ContentValues();
values.put("apn_id", id);
try{
resolver.update(PREFERRED_APN_URI, values, null, null);
Cursor c = resolver.query(PREFERRED_APN_URI, new String[]{"name", "apn"}, "_id="+id, null, null);
if(c != null){
res = true;
c.close();
}
}
catch (SQLException e){}
return res;
}
A continuación, puede llamar al método así:
int identity = InsertAPN(NEW_APN_NAME);
SetPreferredAPN(identity);