Android跨进程通信的四种方式 && 常用服务(运行包名/网络状态/音频服务/马达服务)&& 快捷开关源码

来源:互联网 发布:移动网络短信 编辑:程序博客网 时间:2024/06/10 02:49

由于Android系统中应用程序之间不能共享内存。因此,在不同应用程序之间交互数据(跨进程通讯)就稍微麻烦一些。在android SDK中提供了4种用于跨进程通讯的方式。这4种方式正好对应于android系统中4种应用程序组件:Activity、Content Provider、Broadcast和Service。其中Activity可以跨进程调用其他应用程序的Activity;Content Provider可以跨进程访问其他应用程序中的数据(以Cursor对象形式返回),当然,也可以对其他应用程序的数据进行增、删、改操 作;Broadcast可以向android系统中所有应用程序发送广播,而需要跨进程通讯的应用程序可以监听这些广播;Service和Content Provider类似,也可以访问其他应用程序中的数据,但不同的是,Content Provider返回的是Cursor对象,而Service的这种可以跨进程通讯的服务叫AIDL服务。
               其中Broadcast和AIDL的较为常见,着重说下Activity和Content Provider的跨进程通信
(1)Activity的跨进程访问与进程内访问略有不同。虽然它们都需要Intent对象,但跨进程访问并不需要指定Context对象和Activity的 Class对象,而需要指定的是要访问的Activity所对应的Action(一个字符串)。例如,下面的代码可以直接调用拨打电话的Activity。

Intent callIntent = new  Intent(Intent.ACTION_CALL, Uri.parse("tel:12345678" );  startActivity(callIntent);  
ACTION_CALL这个常量是一个字符串常量,也是我们在这节要介绍的跨进程调用Activity的关键。如果在应用程序中要共享某个Activity,需要为这个 Activity指定一个字符串ID,也就是Action。也可以将这个Action看做这个Activity的key。在其他的应用程序中只要通过这个 Action就可以找到与Action对应的Activity,并通过startActivity方法来启动这个Activity。详细的使用方法见下文的链接
(2)Content Provider提供了一种在多个应用程序之间数据共享的方式(跨进程共享数据)。应用程序可以利用Content Provider完成下面的工作:1. 查询数据;2. 修改数据;3. 添加数据;4. 删除数据。我们可以通过这些Content Provider获得相关信息的列表。这些列表数据将以Cursor对象返回。
对于访问Content Provider的程序,需要使用ContentResolver对象。该对象需要使用getContentResolver方法获得,与Activity一样,Content Provider也需要与一个URI对应。每一个Content Provider可以控制多个数据集,在这种情况下,每一个数据集会对应一个单独的URI。所有的URI必须以“content://”开头。
详细的使用方法见下文的链接:http://blog.csdn.net/toyuexinshangwan/article/details/8640709

================================================================================================================================

          利用android.app.Activity.getSystemService这个方法,可以获得系统常用的服务及一些列方法。举例如下:

(1) 获得当前正在运行的应用包名

        创建一个activity,首先在XML中要添加获取系统运行任务的权限:

<uses-permission  android:name="android.permission.GET_TASKS" />

否则运行时会报异常:java.lang.SecurityException: Permission Denial:。。。。。。requires android.permission.GET_TASKS
        响应核心源码如下:

import android.app.ActivityManager;public class MainActivity extends Activity {    @Override    public void onCreate(Bundle savedInstanceState) {    Log.i("zhangcheng","run here");        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        TextView strText = (TextView)findViewById(R.id.callinfo);        ActivityManager activityManager = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE); //获得页面管理服务        String currentPackageName = "";        currentPackageName = activityManager.getRunningTasks(1)        .get(0).topActivity.getPackageName();//获得当前运行任务顶层页面的包名        strText.setText(currentPackageName);    }}

我的java src路径是:CallPhone\src\com\example\callphone\,所以最终显示的包名是:com.example.callphone。

=========================================================================================
       有时需要判断当前app是否联网,是用的WIFI还是其他网络连接方式等。核心代码如下:

(1)当前联网网络类型,是否联网了

ConnectivityManager manager = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);  if(manager == null)return;        NetworkInfo activeNetworkInfo = manager.getActiveNetworkInfo();          if(activeNetworkInfo == null)        return;        TextView display = (TextView)findViewById(R.id.testview1);                if((activeNetworkInfo.getType() == ConnectivityManager.TYPE_WIFI)        && activeNetworkInfo.isConnected()){        display.setText("WIFI NET");                                   }else if(activeNetworkInfo.getType() == ConnectivityManager.TYPE_MOBILE        && activeNetworkInfo.isConnected()){          display.setText("MOBILE NET");        }
需要的权限

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> 

(2)开关WIFI:

用到的权限

<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> 
开关按钮
WifiManager wifiManager;wifiManager = (WifiManager)getSystemService(Context.WIFI_SERVICE);public void onClick(View v){    if(wifiManager.isWifiEnabled()){    wifiManager.setWifiEnabled(false);    }else{    wifiManager.setWifiEnabled(true);    }}

(3)开关移动网络。这个比较复杂,由于ConnectivityManager的setMobileDataEnabled函数是隐藏的,所以必须采用JAVA函数反射来调用到(JAVA反射相关内容可以参见他人的博文http://write.blog.csdn.net/postedit/8501773,目前会用但是理解不透)。

       定义全局变量

Context context = this;ConnectivityManager manager;TextView display;
       页面的onCreate函数初始化

manager = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);  if(manager == null)return;display = (TextView)findViewById(R.id.testview1);   //提示当前移动网络状态
        反射函数

public boolean invokeMethod(String methodName,Object[]  arg) throws Exception {Class ownerClass = manager.getClass();        Class[]  argsClass = null;        if (arg != null) {            argsClass = new Class[1];            argsClass[0] = arg.getClass();        }        Method method = ownerClass.getMethod(methodName, argsClass);                Boolean isOpen = (Boolean) method.invoke(manager, arg);        return isOpen;}public Object invokeBooleanArgMethod(String methodName,boolean value) throws Exception {        Class ownerClass = manager.getClass();        Class[]  argsClass = new Class[1];        argsClass[0] = boolean.class;        Method method = ownerClass.getMethod(methodName,argsClass);        return method.invoke(manager, value);}
     反复单击一个按钮,可以看到移动网络在开关切换,从状态栏图标可以看出,从页面的textview文本也可以看出是对应的。
public void onClick(View v){//Log.i("zhangcheng","click");Object[] arg = null;  try {  boolean isMobileDataEnable = invokeMethod("getMobileDataEnabled", arg);  if(!isMobileDataEnable){  invokeBooleanArgMethod("setMobileDataEnabled", true);  display.setText("MOBILE NET ON");  }  else{  invokeBooleanArgMethod("setMobileDataEnabled", false);  display.setText("MOBILE NET OFF");  }  } catch (Exception e) {   // TODO Auto-generated catch block  e.printStackTrace();  }}

需要的权限

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /><uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
============================================================================================

       通过程序获取android系统手机的铃声和音量。同样,设置铃声和音量的方法也很简单!

AudioManager mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
(1)通话音量

int max = mAudioManager.getStreamMaxVolume( AudioManager.STREAM_VOICE_CALL ); int current = mAudioManager.getStreamVolume( AudioManager.STREAM_VOICE_CALL ); Log.d(”VIOCE_CALL”, “max : ” + max + ” current : ” + current);  

(2)系统音量

max = mAudioManager.getStreamMaxVolume( AudioManager.STREAM_SYSTEM ); current = mAudioManager.getStreamVolume( AudioManager.STREAM_SYSTEM ); Log.d(”SYSTEM”, “max : ” + max + ” current : ” + current); 

(3)铃声音量

max = mAudioManager.getStreamMaxVolume( AudioManager.STREAM_RING ); current = mAudioManager.getStreamVolume( AudioManager.STREAM_RING ); Log.d(”RING”, “max : ” + max + ” current : ” + current); 

(4)音乐音量 

max = mAudioManager.getStreamMaxVolume( AudioManager.STREAM_MUSIC ); current = mAudioManager.getStreamVolume( AudioManager.STREAM_MUSIC ); Log.d(”MUSIC”, “max : ” + max + ” current : ” + current); 

(5)提示声音音量

max = mAudioManager.getStreamMaxVolume( AudioManager.STREAM_ALARM ); current = mAudioManager.getStreamVolume( AudioManager.STREAM_ALARM ); Log.d(”ALARM”, “max : ” + max + ” current : ” + current);  

         设置音量的方法也很简单:public void setStreamVolume(int streamType, int index, int flags)  ,其中streamType为铃声类型,例如:AudioManager.STREAM_VOICE_CALL、AudioManager.STREAM_SYSTEM等,index为音量大小,falgs为标志位。

         以下是修改音频设置:

(6)通话时设置静音

System.out.println("isMicrophoneMute =" + audioManager.isMicrophoneMute());audioManager.setMicrophoneMute(!audioManager.isMicrophoneMute());

(7)通话时设置免提

System.out.println("isSpeakerphoneOn =" + audioManager.isSpeakerphoneOn());audioManager.setSpeakerphoneOn(!audioManager.isSpeakerphoneOn());

别忘了修改的权限 <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
===========================================================================================
        设置振动:

mVibrator = (Vibrator) mContext.getSystemService(Service.VIBRATOR_SERVICE);   long[] pattern = {150, 100}; // OFF/ON/OFF/ON...  mVibrator.vibrate(pattern, -1);

除了以上常用服务,常用的快捷开关代码,我们也必须留存已被不时之需。有Wifi、蓝牙、GPS、同步、亮度设置、飞行模式、移动数据流量(实现开启和关闭移动网络)、静音模式、重启、关机、锁屏、屏幕旋转等。需要注意的是:实现这些开关控制时都需要在AndroidManifest.xml文件中添加相应的权限。参见原文:http://blog.csdn.net/stevenhu_223/article/details/9052083。


参考原文:http://www.cnblogs.com/wgw8299/articles/2128202.html

参考原文:http://blog.csdn.net/comkingfly/article/details/7359950

参考原文:http://blog.csdn.net/ponderforever/article/details/7167591

参考原文:http://blog.csdn.net/gf771115/article/details/6996577


原创粉丝点击