Search code examples
androidandroid-sourceapn

How to give system level permissions programatically in android?


I am trying to read existing APN and then need to write custum APN name in my android device. But it is not allowing me to read/write even I put my app in /system/app and declare below permissions in my manifest.

throws below error

15:01:17.831: W/System.err(1717): java.lang.SecurityException: Neither user 10060 nor current process has android.permission.MODIFY_PHONE_STATE. 01-01 15:01:17.832: W/System.err(1717): at android.os.Parcel.readException(Parcel.java:1620) 01-01 15:01:17.832: W/System.err(1717): at android.os.Parcel.readException(Parcel.java:1573) 01-01 15:01:17.832: W/System.err(1717): at com.android.internal.telephony.ITelephony$Stub$Proxy.supplyPin(ITelephony.java:1775) 01-01 15:01:17.833: W/System.err(1717): at com.intel.sunnypoint.headless.HeadlessService.simUnlock(HeadlessService.java:194) 01-01 15:01:17.833: W/System.err(1717): at com.intel.sunnypoint.headless.HeadlessService.onStartCommand(HeadlessService.java:166) 01-01 15:01:17.833: W/System.err(1717): at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3032) 01-01 15:01:17.833: W/System.err(1717): at android.app.ActivityThread.access$2300(ActivityThread.java:150) 01-01 15:01:17.833: W/System.err(1717): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1455) 01-01 15:01:17.833: W/System.err(1717): at android.os.Handler.dispatchMessage(Handler.java:102) 01-01 15:01:17.833: W/System.err(1717): at android.os.Looper.loop(Looper.java:148) 01-01 15:01:17.833: W/System.err(1717): at android.app.ActivityThread.main(ActivityThread.java:5446) 01-01 15:01:17.833: W/System.err(1717): at java.lang.reflect.Method.invoke(Native Method) 01-01 15:01:17.833: W/System.err(1717): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:749) 01-01 15:01:17.833: W/System.err(1717): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:639)

Below is my code

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;
            Log.d(TAG, "APN already configured.");
            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();


        //Assign them to the ContentValue object
        values.put("name", name); //the method parameter
        values.put("apn", "Simple CMW APN");
        values.put("type", "default");
        values.put("proxy", "");
        values.put("port", "");
        values.put("user", "");
        values.put("password", "");
        values.put("server", "");
        values.put("mmsc", "");
        values.put("mmsproxy", "");
        values.put("mmsport", "");
        values.put("mcc", "001");
        values.put("mnc", "01");
        values.put("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(Exception 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 (Exception e){}
    return res;
}

Please guide me how to set it. Thanks in advance.


Solution

  • 1.You need to sign your application in the same key the system is signed

    2.You need your app to have the system uid in android manifest

    3.SELinux policy, if enforced need to allow that operation, in your case I think it will have no problem