现在设备的安全性越来越受到重视,随之而来的便是开发中的各种不便,比如有普通权限,运行时权限,系统权限之分。对于运行时权限的添加可以参考
对于Android中各个权限的含义可以参考android/frameworks/base/core/res/AndroidManifest.xml中的释义
转载请注明出处,本文出自
的博客
对于可以编译到源码里的apk添加系统权限很简单,就两步
一,在androidmanifest.xml文件中添加uid,即让应用跑在system进程中:android:sharduserid= “”
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.fang.zrf.networkdemo" android:sharedUserId="android.uid.system">二,在该应用的mk文件中添加签名,即让该应用使用系统签名
LOCAL_CERTIFICATE := platform
然后使用编译命令编译apk即可。
但如果没有mk的应用该怎么办呢?
其实也可以总结出来,让一个应用使用系统权限不外乎两步
第一就是uid改为system第二就是使用系统的签名,明白了这些之后我们就可以对应用使用系统权限了
第一步同上,添加Android:shareduserid属性
第二步,将打包好的apk使用系统签名重新签名打包。签名打包使用到一个Android源码中自带的一个工具叫做signapk,所在目录为Android/out/host/linux-x86/framework
使用cmd命令进行重新签名打包java -jar signapk.jar platform.x509.pem platform.pk8 old.apk new.apk
其中old.apk是打包好的apk,而new.apk是重新签名的apk。然后可以使用adb install -r new.apk将应用安装到手机上,此时即可获取系统权限。但有一个条件,既然用的是系统的签名,那首先就要保证你应用的系统签名和手机的系统签名一致,这个可能各大厂商会有所改动,所以不太能兼容。
好了,说了这么多,来个demo看一看吧。demo所实现的功能有三个,
一是开启手机移动网络
二是关闭手机移动网络
三是获取手机移动网络
其实总结起来就是对手机移动网络的set和get两个功能而已。源码上对于set和get的方法属于hide的,不供三方应用使用,所以我们可以利用反射来调用到。
首先,先来看看需要什么权限
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/> <uses-permission android:name="android.permission.MODIFY_PHONE_STATE"/>
紧接着就是设置手机移动网络的 状态
public static void setMobileDataState(Context context, boolean enable){ Class[] argsClass = new Class[1]; argsClass[0] = boolean.class;//setmobiledataenable方法中要传入一个boolean类型的参数 ConnectivityManager connMr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); try { Method method = connMr.getClass().getMethod("setMobileDataEnabled",argsClass); method.invoke(connMr,enable); } catch (Exception e) { e.printStackTrace(); Toast.makeText(context,"set failure + e = " + e.getCause(),Toast.LENGTH_LONG).show(); } }
然后是获取手机移动网络的状态
public static boolean getMobileDataState(Context context){ ConnectivityManager connMr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); Class[] argsclass = null;//get时不需要传入参数,所以直接传入一个null的数组即可 try { Method method = connMr.getClass().getDeclaredMethod("getMobileDataEnabled",argsclass); return (boolean)method.invoke(connMr); } catch (Exception e) { e.printStackTrace(); } return false; }
接下来就是界面设计的方法的调用了,
先来看看界面实现效果
public class MainActivity extends Activity implements View.OnClickListener{ private TextView mOpenNet; private TextView mCloseNet; private TextView mGetNetState; private TextView mNetState; private boolean isOpenState; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); initData(); } /** * 初始化view */ private void initView(){ mOpenNet = (TextView) findViewById(R.id.open_network); mCloseNet = (TextView) findViewById(R.id.close_network); mGetNetState = (TextView) findViewById(R.id.get_state); mNetState = (TextView) findViewById(R.id.network_state); setClickListener(mOpenNet,mCloseNet,mGetNetState); } /** * 初始化数据 */ private void initData(){ updateView(); } /** * 设置view的点击事件 * @param views */ private void setClickListener(View...views){ for (View view:views) { if (view != null){ view.setOnClickListener(this); } } } @Override public void onClick(View v) { switch (v.getId()){ case R.id.open_network: NetManager.setMobileDataState(getApplicationContext(),true); updateView(); break; case R.id.close_network: NetManager.setMobileDataState(getApplicationContext(),false); updateView(); break; case R.id.get_state: updateView(); break; default: break; } } @Override protected void onResume() { super.onResume(); updateView(); } private void updateView(){ isOpenState = NetManager.getMobileDataState(getApplicationContext()); String str = isOpenState ? "true" : "false"; if (str.equals(mNetState.getText().toString())){ return; } mNetState.setText(str); setTvEnable(!isOpenState,isOpenState); } private void setTvEnable(boolean setEnable,boolean closeEnable){ mOpenNet.setEnabled(setEnable); mCloseNet.setEnabled(closeEnable); } }
代码完成后,在outputs目录下找到apk文件使用cmd命令进行重新签名。
到此,结束
如有问题,欢迎学习交流,微信公众号---fanfan程序媛