如何在android中以编程方式提供系统级权限?

时间:2016-12-09 03:33:02

标签: android android-source apn

我正在尝试阅读现有的APN,然后需要在我的Android设备中编写custum APN名称。但即使我将我的应用程序放在/ system / app中并在我的清单中声明以下权限,它也不允许我读/写。

抛出错误

15:01:17.831:W / System.err(1717):java.lang.SecurityException:用户10060和当前进程都没有android.permission.MODIFY_PHONE_STATE。 01-01 15:01:17.832:W / System.err(1717):在android.os.Parcel.readException(Parcel.java:1620) 01-01 15:01:17.832:W / System.err(1717):在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):在android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3032) 01-01 15:01:17.833:W / System.err(1717):在android.app.ActivityThread.access $ 2300(ActivityThread.java:150) 01-01 15:01:17.833:W / System.err(1717):在android.app.ActivityThread $ H.handleMessage(ActivityThread.java:1455) 01-01 15:01:17.833:W / System.err(1717):在android.os.Handler.dispatchMessage(Handler.java:102) 01-01 15:01:17.833:W / System.err(1717):在android.os.Looper.loop(Looper.java:148) 01-01 15:01:17.833:W / System.err(1717):在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)

以下是我的代码

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;
}

请指导我如何设置它。提前致谢。

3 个答案:

答案 0 :(得分:0)

对于归类为“危险”的权限,您需要向用户请求权限,将它们放入清单中将无法实现此目的。

请参阅https://developer.android.com/training/permissions/requesting.html

如果您需要帮助设置,请告诉我:)

答案 1 :(得分:0)

如果您将阅读文档,您可以看到:

  

MODIFY_PHONE_STATE

     

允许修改电话状态 - 开机,mmi等      不包括拨打电话。

     

不适用于第三方应用程序。

请注意最后一行。只有系统可以使用而不被其他应用程序使用的许可。

系统级应用程序已预先安装到系统文件夹中,或使用特殊制造商的证书进行编译。你说你把它放在/system/app文件夹中但你应该明白只有root用户的用户才能重复你的步骤。当然,您无法实现将您的应用发布到Google Play中的目标。

总的来说,看起来您正在尝试使用一些隐藏的API。您应该了解实现此目标的其他方法。可能不允许以编程方式更改APN,但我不确定。

答案 2 :(得分:0)

1.您需要使用系统签名的相同密钥签署您的申请

2.你需要你的应用程序在android清单中使用系统uid

3.SELinux政策,如果强制执行需要允许该操作,在您的情况下我认为它将没有问题