如何在 android 中以编程方式授予系统级权限?
How to give system level permissions programatically in android?
我正在尝试读取现有的 APN,然后需要在我的 android 设备中写入自定义 APN 名称。但它不允许我 read/write 即使我将我的应用程序放在 /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): 在 com.android.internal.telephony.ITelephony$Stub$Proxy.supplyPin(ITelephony.java:1775)
01-01 15:01:17.833: W/System.err(1717): 在 com.intel.sunnypoint.headless.HeadlessService.simUnlock(HeadlessService.java:194)
01-01 15:01:17.833: W/System.err(1717): 在 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): 在 java.lang.reflect.Method.invoke(本机方法)
01-01 15:01:17.833: W/System.err(1717): 在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:749)
01-01 15:01:17.833: W/System.err(1717): 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:639)
下面是我的代码
public int InsertAPN(字符串名称){
//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;
}
请指导我如何设置它。提前致谢。
对于分类为'dangerous'的权限,您需要向用户请求权限,仅将它们放在清单中是无法实现的。
参考https://developer.android.com/training/permissions/requesting.html
如果您在设置方面需要帮助,请告诉我:)
如果您阅读文档,您会看到:
MODIFY_PHONE_STATE
Allows modification of the telephony state - power on, mmi, etc.
Does not include placing calls.
Not for use by third-party applications.
请注意最后一行。该权限只能由系统使用,不能被其他应用程序使用。
系统级应用程序预安装到系统文件夹中或使用特殊制造商证书编译。你说你把它放在 /system/app
文件夹中,但你应该明白只有 root 设备的用户才能重复你的步骤。当然,将您的应用程序发布到 Google Play.
将无法实现此目标
总的来说,您似乎在尝试使用一些隐藏的 API。您应该寻找其他方法来实现此目标。可能不允许以编程方式更改 APN,但我不确定。
1.You 需要使用与系统签名相同的密钥对您的应用程序进行签名
2.You 需要您的应用在 android 清单
中具有系统 uid
3.SELinux政策,如果强制执行需要允许那个操作,你的情况我觉得没问题
我正在尝试读取现有的 APN,然后需要在我的 android 设备中写入自定义 APN 名称。但它不允许我 read/write 即使我将我的应用程序放在 /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): 在 com.android.internal.telephony.ITelephony$Stub$Proxy.supplyPin(ITelephony.java:1775) 01-01 15:01:17.833: W/System.err(1717): 在 com.intel.sunnypoint.headless.HeadlessService.simUnlock(HeadlessService.java:194) 01-01 15:01:17.833: W/System.err(1717): 在 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): 在 java.lang.reflect.Method.invoke(本机方法) 01-01 15:01:17.833: W/System.err(1717): 在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:749) 01-01 15:01:17.833: W/System.err(1717): 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:639)
下面是我的代码
public int InsertAPN(字符串名称){
//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;
}
请指导我如何设置它。提前致谢。
对于分类为'dangerous'的权限,您需要向用户请求权限,仅将它们放在清单中是无法实现的。
参考https://developer.android.com/training/permissions/requesting.html
如果您在设置方面需要帮助,请告诉我:)
如果您阅读文档,您会看到:
MODIFY_PHONE_STATE
Allows modification of the telephony state - power on, mmi, etc. Does not include placing calls.
Not for use by third-party applications.
请注意最后一行。该权限只能由系统使用,不能被其他应用程序使用。
系统级应用程序预安装到系统文件夹中或使用特殊制造商证书编译。你说你把它放在 /system/app
文件夹中,但你应该明白只有 root 设备的用户才能重复你的步骤。当然,将您的应用程序发布到 Google Play.
总的来说,您似乎在尝试使用一些隐藏的 API。您应该寻找其他方法来实现此目标。可能不允许以编程方式更改 APN,但我不确定。
1.You 需要使用与系统签名相同的密钥对您的应用程序进行签名
2.You 需要您的应用在 android 清单
中具有系统 uid3.SELinux政策,如果强制执行需要允许那个操作,你的情况我觉得没问题