• Android Activity/Service/Broadcaster三大组件之间互相调用


    原文地址:http://www.cnblogs.com/linjiqin/p/3147789.html

    我们研究两个问题, 1、Service如何通过Broadcaster更改activity的一个TextView。 (研究这个问题,考虑到Service从服务器端获得消息之后,将msg返回给activity)

    2、Activity如何通过Binder调用Service的一个方法。 (研究这个问题,考虑到与服务器端交互的动作,打包至Service,Activity只呈现界面,调用Service的方法) 结构图见如下: 效果图如下: 点击“start service”按钮,启动Service,然后更改Activity的UI。 点击“send msg to server”按钮调用Service的方法,显示NotificationBar

    代码: 1、新建一个MyService类,继承Service

    复制代码
    package com.ljq.activity;
     
     
    import android.app.Notification;
    import android.app.NotificationManager;
    import android.app.PendingIntent;
    import android.app.Service;
    import android.content.Context;
    import android.content.Intent;
    import android.graphics.Color;
    import android.os.Binder;
    import android.os.IBinder;
     
    public class MyService extends Service {
     private NotificationManager notificationManager = null;
     private final IBinder binder = new LocalBinder();
     
     @Override
     public void onCreate() {
      sendMsgtoActivty("Service is oncreating.
    ");
     }
     
     @Override
     public IBinder onBind(Intent intent) {
      String msg = "Activity is sendding message to service,
     Service send msg to server!
    ";
      sendMsgtoActivty(msg);
      return binder;
     }
     
     /**
      * 把信息传递给activity
      * 
      * @param msg
      */
     private void sendMsgtoActivty(String msg) {
      Intent intent = new Intent("com.android.Yao.msg");
      intent.putExtra("msg", msg);
      this.sendBroadcast(intent);
     }
      
     @Override
     public void onDestroy() {
      super.onDestroy();
      if(notificationManager!=null){
       notificationManager.cancel(0);
       notificationManager=null;
      }
     }
     
     /**
      * 在状态栏显示通知
      * 
      * @param msg
      */
     private void showNotification(String msg) {
      notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
      // 定义Notification的各种属性   
      Notification notification =new Notification(R.drawable.icon,   
              "A Message Coming!", System.currentTimeMillis()); 
      //FLAG_AUTO_CANCEL   该通知能被状态栏的清除按钮给清除掉
      //FLAG_NO_CLEAR      该通知不能被状态栏的清除按钮给清除掉
      //FLAG_ONGOING_EVENT 通知放置在正在运行
      //FLAG_INSISTENT     是否一直进行,比如音乐一直播放,知道用户响应
      notification.flags |= Notification.FLAG_ONGOING_EVENT; // 将此通知放到通知栏的"Ongoing"即"正在运行"组中   
      notification.flags |= Notification.FLAG_NO_CLEAR; // 表明在点击了通知栏中的"清除通知"后,此通知不清除,经常与FLAG_ONGOING_EVENT一起使用   
      notification.flags |= Notification.FLAG_SHOW_LIGHTS;   
      //DEFAULT_ALL     使用所有默认值,比如声音,震动,闪屏等等
      //DEFAULT_LIGHTS  使用默认闪光提示
      //DEFAULT_SOUNDS  使用默认提示声音
      //DEFAULT_VIBRATE 使用默认手机震动,需加上<uses-permission android:name="android.permission.VIBRATE" />权限
      notification.defaults = Notification.DEFAULT_LIGHTS; 
      //叠加效果常量
      //notification.defaults=Notification.DEFAULT_LIGHTS|Notification.DEFAULT_SOUND;
      notification.ledARGB = Color.BLUE;   
      notification.ledOnMS =5000; //闪光时间,毫秒
       
      // 设置通知的事件消息   
      //Intent notificationIntent =new Intent(MainActivity.this, MainActivity.class); // 点击该通知后要跳转的Activity   
      Intent notificationIntent = new Intent(getApplicationContext(), MainActivity.class); // 加载类,如果直接通过类名,会在点击时重新加载页面,无法恢复最后页面状态。
      notificationIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
      PendingIntent contentItent = PendingIntent.getActivity(this, 0, notificationIntent, 0);   
      notification.setLatestEventInfo(this, "Message", "Message:" + msg, contentItent);
       
      // 把Notification传递给NotificationManager   
      notificationManager.notify(0, notification);
         
     }
      
     /**
      * 从activity获取信息
      * 
      * @param msg
      */
     public void receiverMsgtoActivity(String msg){
      sendMsgtoActivty("
     receiverMsgtoActivity:"+msg);
     }
     
     public void sendMsgtoServer(String msg) {
      showNotification(msg);
     }
     
     public class LocalBinder extends Binder {
      public MyService getService() {
       return MyService.this;
      }
     }
     
    }
    复制代码

    2、新建MyBroadcastreceiver类,继承BroadcastReceiver,用来发送Intent启动服务

    复制代码
    package com.ljq.activity;
     
    import android.content.BroadcastReceiver;
    import android.content.Context;
    import android.content.Intent;
     
    /**
     * 发送Intent启动服务
     * 
     * @author jiqinlin
     *
     */
    public class MyBroadcastreceiver extends BroadcastReceiver {
     @Override
     public void onReceive(Context context, Intent intent) {
      Intent service = new Intent(context, MyService.class);
      context.startService(service);
     }
     
    }
    复制代码

    3、新建MainActivity类,其实是一个activity,用来呈现界面

    复制代码
    package com.ljq.activity;
     
    import java.util.List;
     
    import android.app.Activity;
    import android.app.ActivityManager;
    import android.content.BroadcastReceiver;
    import android.content.ComponentName;
    import android.content.Context;
    import android.content.Intent;
    import android.content.IntentFilter;
    import android.content.ServiceConnection;
    import android.os.Bundle;
    import android.os.IBinder;
    import android.util.Log;
    import android.view.View;
    import android.widget.TextView;
     
    public class MainActivity extends Activity implements View.OnClickListener {
     private String msg = "";
     private TextView txtMsg;
     private UpdateReceiver receiver;
     private MyService myService;
     private final static String TAG=MainActivity.class.getSimpleName();
     
     @Override
     public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.main);
       
      txtMsg = (TextView) this.findViewById(R.id.txtMsg);
      this.findViewById(R.id.btnStart).setOnClickListener(this);
      this.findViewById(R.id.btnSend).setOnClickListener(this);
       
      //订阅广播Intent
      receiver = new UpdateReceiver();
      IntentFilter filter = new IntentFilter();
      filter.addAction("com.android.Yao.msg");
      this.registerReceiver(receiver, filter);
       
      //初始化时启动服务
      //Intent intent = new Intent(MainActivity.this, MyService.class);
      //this.bindService(intent, conn, BIND_AUTO_CREATE);
     }
      
     @Override
     protected void onDestroy() {
      super.onDestroy();
      //结束服务
      if(conn!=null){
       unbindService(conn);
       myService=null;
      }
        
     }
     
     public class UpdateReceiver extends BroadcastReceiver {
     
      @Override
      public void onReceive(Context context, Intent intent) {
       //获取service传过来的信息
       msg = intent.getStringExtra("msg");
       txtMsg.append(msg);
      }
     }
     
     private ServiceConnection conn = new ServiceConnection() {
      @Override
      public void onServiceConnected(ComponentName name, IBinder service) {
       myService = ((MyService.LocalBinder) service).getService();
       Log.i(TAG, "onServiceConnected myService: "+myService);
      }
     
      @Override
      public void onServiceDisconnected(ComponentName name) {
        myService = null;
      }
     
     };
     
     @Override
     public void onClick(View v) {
      Intent intent = new Intent(MainActivity.this, MyService.class);
      switch (v.getId()) {
      case R.id.btnStart:
       //判断服务是否启动
       if(false==isServiceRunning(this, MyService.class.getName())){
        Log.i(TAG, "start "+MyService.class.getSimpleName()+" service");
        this.bindService(intent, conn, BIND_AUTO_CREATE);
       }
       Log.i(TAG, MyService.class.getName()+" run status: "+isServiceRunning(this, MyService.class.getName()));
       break;
      case R.id.btnSend:
       //判断服务是否启动
       if(false==isServiceRunning(this, MyService.class.getName())){
        Log.i(TAG, "start "+MyService.class.getSimpleName()+" service");
        this.bindService(intent, conn, BIND_AUTO_CREATE);
       }
        
       Log.i(TAG, MyService.class.getName()+" run status: "+isServiceRunning(this, MyService.class.getName()));
       Log.i(TAG, "onClick myService: "+myService); //第一次启动服务时此处为null(小编认为虽然服务已启动成功,但是还没全部初始化)
        
       if(myService!=null){
           myService.sendMsgtoServer("i am sending msg to server");
           //从activity传递信息给service
           myService.receiverMsgtoActivity("this is a msg");
          }
       break;
      }
     }
      
     /**
      * 判断服务是否正在运行
      * 
      * @param context
      * @param className 判断的服务名字:包名+类名
      * @return true在运行 false 不在运行
      */
     public static boolean isServiceRunning(Context context, String className) {
      boolean isRunning = false;
       
      ActivityManager activityManager = (ActivityManager) context
        .getSystemService(Context.ACTIVITY_SERVICE);
      //获取所有的服务
      List<ActivityManager.RunningServiceInfo> services= activityManager.getRunningServices(Integer.MAX_VALUE);
      if(services!=null&&services.size()>0){
       for(ActivityManager.RunningServiceInfo service : services){
        if(className.equals(service.service.getClassName())){
         isRunning=true;
         break;
        }
       }
      }
     
      return isRunning;
     }
     
    }
    复制代码

    4、main.xml布局文件

    复制代码
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:orientation="vertical" android:layout_width="fill_parent"
     android:layout_height="fill_parent">
     <TextView android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      android:id="@+id/txtMsg" />
     <LinearLayout
      xmlns:android="http://schemas.android.com/apk/res/android"
      android:orientation="horizontal"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content">
      <Button android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text="start service"
       android:id="@+id/btnStart"/>
      <Button android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text="send msg to server"
       android:id="@+id/btnSend"/>
     </LinearLayout>
    </LinearLayout>
    复制代码

    5、清单文件AndroidManifest.xml,用来配置组件等信息

    复制代码
    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.ljq.activity"
          android:versionCode="1"
          android:versionName="1.0">
        <application android:icon="@drawable/icon" android:label="@string/app_name">
            <activity android:name=".MainActivity"
                      android:label="@string/app_name">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
            <service android:name=".MyService"/> 
            <receiver android:name=".MyBroadcastreceiver" />
     
        </application>
        <uses-sdk android:minSdkVersion="7" />
     
    </manifest>
    复制代码
  • 相关阅读:
    【翻译】ASP.NET MVC4 入门(七) 为Movie实体和表添加一个新字段
    【翻译】ASP.NET MVC4 入门(九) 查看一下Details和Delete方法中的代码(完结)
    mac 清理其他【自杀式】
    android.content.res.Resources$NotFoundException: String resource ID #0x0
    Button需要点击两次才触发点击事件问题
    android recyclerview notifyItemChanged 一闪一闪
    wpf中使用ocx控件
    LINQ使用总结
    [翻译]ASP.NET MVC4新特性之脚本压缩和合并
    C#实例解析适配器设计模式
  • 原文地址:https://www.cnblogs.com/ericyuan/p/3380650.html
Copyright © 2020-2023  润新知