zoukankan      html  css  js  c++  java
  • 【Android开发日记】第一个任务Android Service!Service靴+重力感应器+弹出窗口+保持执行

    前言:

          近期在写一个小程序,需求是手机摇一摇就弹窗出来。第一次使用了Service,学习了两天,实现了Service弹窗,开机启动,Service启动和销毁,Service保持一直执行。

    满足了自己的需求。现记录学习心得。

    希望能给你带来一些帮助。


    1.Service创建:重写4个方法

    • onBind():返回一个IBinder对象,这个对象能够使应用程序与Service通信。假设用startService、stopService启动和关闭Service的话。Service和訪问者是无法通信交换数据的。onBind()返回值设为null就可以。

      可是假设想要交换数据,就要用bindService、unbindService来启动和关闭Service。这时,onBind()要返回一个有效的IBinder对象。

    • onCreate():Service第一次被创建时调用此方法。
    • onStartCommand():理解为onStart()的新一代。每次通过startService(Intent)启动Service时都会调用此方法。
    • onDestroy():Service被关闭之前调用此方法。

    package com.service;
    
    import android.app.Service;
    import android.content.Context;
    import android.content.Intent;
    import android.util.Log;
    
    public class PopupService extends Service {
    
        @Override
        public IBinder onBind(Intent intent) {
    		// TODO Auto-generated method stub
    		return null;
        }  
          
        @Override  
        public void onCreate() {  
            super.onCreate();  
            System.out.println("Service is Created");
        }  
     
        @Override  
        public int onStartCommand(Intent intent, int flags, int startId) {  
        	 System.out.println("Service is Started");
        	 
             
             return START_STICKY;
        }
    
        @Override  
        public void onDestroy() {  
            super.onDestroy();  
            System.out.println("Service is Destroyed");
    
        } 
        
    }

    2.Service配置:在AndroidManifest.xml中声明

    <service 
         android:name="com.service.PopupService" 
         android:priority = "1000"    <!-- 提高优先级-->
         android:persistent="true">  <!-- 免杀,不知道有没有起作用-->
         <intent-filter>
              <action android:name="com.service.POPUP_SERVICE" />               
         </intent-filter>
    </service>

    3.Service开机启动:使用BroadcastReceiver

       文件创建:

    package com.service;  
        
    import android.content.BroadcastReceiver;  
    import android.content.Context;  
    import android.content.Intent;  
         
        public class StartupReceiver extends BroadcastReceiver  
        {  
            @Override  
            public void onReceive(Context context, Intent intent)  
            {  
                //  启动一个Service  
                Intent serviceIntent = new Intent(context, PopupService.class);          
                context.startService(serviceIntent);   
            }  
        } 

        文件配置:在AndroidManifest.xml中声明

     <receiver android:name="com.service.StartupReceiver"> 
          <intent-filter> 
                <action android:name="android.intent.action.BOOT_COMPLETED" /> 
                <category android:name="android.intent.category.LAUNCHER" /> 
          </intent-filter> 
     </receiver> 

        注意权限:
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> 

    4.Service从Activity中启动:

       在主Activity中使用startService(Intent)

    Intent popupintent=new Intent();
    popupintent.setAction("com.service.POPUP_SERVICE");
    startService(popupintent);

    5.Service监听重力感应而且弹窗:

    •    这里使用Sensor.TYPE_ACCELEROMETER加速度感应器。和其它监听器比方手势等一样,包含声明、注冊、监听等
    •    弹窗使用的是theme定义为dialog。notitle的activity。

       弹窗相关代码:


    Intent activityIntent = new Intent(this, SelectFriendsActivity.class);  
    //要想在Service中启动Activity,必须设置例如以下标志  
    activityIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);  
    startActivity(activityIntent);  
    

       完整代码:

    package com.service;
    
    import com.task.SelectFriendsActivity;
    
    import android.app.Service;
    import android.content.Context;
    import android.content.Intent;
    import android.hardware.Sensor;
    import android.hardware.SensorEvent;
    import android.hardware.SensorEventListener;
    import android.hardware.SensorManager;
    import android.os.IBinder;
    import android.os.Vibrator;
    import android.util.Log;
    
    public class PopupService extends Service implements SensorEventListener{
    	
    	//sensorManager
    	private SensorManager sensorManager;  
    	private Vibrator vibrator;  
    	Intent activityIntent;
    	
    	@Override
    	public IBinder onBind(Intent intent) {
    		// TODO Auto-generated method stub
    		return null;
    	}  
          
        @Override  
        public void onCreate() {  
            super.onCreate();  
            System.out.println("Service is Created");
            
            sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);  
    	    vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE); 
        }  
     
        @Override  
        public int onStartCommand(Intent intent, int flags, int startId) {  
        	 System.out.println("Service is Started");
        	 //启动service,将serviceon置为TRUE,可弹窗。
        	 SelectFriendsActivity.serviceon = true;
        	 if (sensorManager != null) {// 注冊监听器  
                 sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL);  
                 // 第一个參数是Listener。第二个參数是所得传感器类型。第三个參数值获取传感器信息的频率  
             } 
        	 activityIntent = new Intent(this, SelectFriendsActivity.class);  
             //  要想在Service中启动Activity,必须设置例如以下标志  
             activityIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);  
             
             return START_STICKY;
        }
    
        @Override  
        public void onDestroy() {  
            super.onDestroy();  
            System.out.println("Service is Destroyed");
    
        } 
        
        /** 
         * 重力感应监听 
         */  
        public void onSensorChanged(SensorEvent event) {  
            // 传感器信息改变时运行该方法  
            float[] values = event.values;  
            float x = values[0]; // x轴方向的重力加速度,向右为正  
            float y = values[1]; // y轴方向的重力加速度。向前为正  
            float z = values[2]; // z轴方向的重力加速度,向上为正  
            Log.i("group", "x轴方向的重力加速度" + x +  ";y轴方向的重力加速度" + y +  "。z轴方向的重力加速度" + z);  
            // 一般在这三个方向的重力加速度达到40就达到了摇晃手机的状态。  
            int medumValue = 19;// 三星 i9250怎么晃都不会超过20,没办法。仅仅设置19了  
            if (Math.abs(x) > medumValue || Math.abs(y) > medumValue || Math.abs(z) > medumValue) {  
               
                if(SelectFriendsActivity.serviceon){
                	vibrator.vibrate(200);  
                	System.out.println("Service:shaked and popup!!!!!!!");
                	startActivity(activityIntent);  
                }else{
                	System.out.println("Service:shaked only!!!!!!!");
                }
            }  
        }  
    
        @Override  
        public void onAccuracyChanged(Sensor sensor, int accuracy) {  
    
        }  
    
    }

    
    弹出的Activity就是一般的Activity,仅仅只是要在其xml中设置其大小,在AndroidManifest.xml中将其theme设置为notitle。dialog类型
    

    能够使用这个style:

        <style name="dialogTheme" parent="android:Theme.Dialog"> 
            <item name="android:windowNoTitle">true</item>
        </style>

    弹窗要求加入权限:

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

    6.Service 保持一直执行,不被杀死 的方法:

       重写onDestroy():

        @Override  
        public void onDestroy() {  
           // super.onDestroy();  
           // System.out.println("Service is Destroyed");
              System.out.println("Service is Destroyed,and is Restarted");
              Intent localIntent = new Intent(); localIntent.setClass(this, PopupService.class); //销毁时又一次启动
              Service this.startService(localIntent); 
         }
    

    
        这样不管怎样Service都一直在后台执行了。
    

    7.图文记录:

    7.1 启动app,MainActivity中调用了startService(popupintent);

       结果:说明依次调用了Service中的onCreate()、onStartCommand()方法,Service開始执行

     7.2 震动手机,Service响应弹窗

        结果:弹窗,Service正常执行,重力感应器正常执行

    7.3 杀死应用进程,震动手机,Service仍然响应弹窗

        结果:弹窗,说明尽管应用进程被杀死,可是Service仍保持正常执行,重力感应器正常执行

    7.4 点击弹窗的Avtivity中的button,button监听代码:

    Intent popupintent=new Intent();
    popupintent.setAction("com.service.POPUP_SERVICE");		    
    stopService(popupintent);
    即调用了stopService(Intent) 方法

    结果:打印出Service is Destroyed,说明调用了Service的onDestroy()方法

    7.5 再次震动手机,发现还是有打印输出:

       结果:说名尽管调用了onDestroy()方法。可是其Context未被清除,Service仍然存在

    7.6 杀死全部有关此弹窗的进程。再次震动手机。发现没有打印输出了:

        结果:一旦其Context被全然清除。Service就真正停止了。



    感谢newcj 的博客 文章 Android 中的 Service 全面总结 让我受益匪浅。大家能够去看看,评论区非常精彩:




    第一次学着用Service,文中假设有错误请大家指正。



     




    版权声明:本文博客原创文章,博客,未经同意,不得转载。

  • 相关阅读:
    HDU 1002 A + B Problem II
    leetcode 42.接雨水
    无向图 及其术语
    C++优先队列详解
    C++优先队列详解
    最短路
    最短路
    CF DP练习题
    CF DP练习题
    干货
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/4671153.html
Copyright © 2011-2022 走看看