【Android开发日记】初次探秘Android Service!Service开机启动+重力感应+弹窗+保持运行

前言:

最近在写一个小程序,需求是手机摇一摇就弹窗出来。第一次使用了Service,学习了两天,实现了Service弹窗,开机启动,Activity启动和销毁。满足了自己的需求。现记录学习心得。希望能给你带来一些帮助。

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{

<span style="font-family:Microsoft YaHei;">     </span>//sensorManager
<span style="font-family:Microsoft YaHei;">     </span>private SensorManager sensorManager;
<span style="font-family:Microsoft YaHei;">     </span>private Vibrator vibrator;
<span style="font-family:Microsoft YaHei;">     </span>Intent activityIntent;

<span style="font-family:Microsoft YaHei;">      </span>@Override
<span style="font-family:Microsoft YaHei;">      </span>public IBinder onBind(Intent intent) {
		// TODO Auto-generated method stub
		return null;
<span style="font-family:Microsoft YaHei;">      </span>}  

    @Override
    public void onCreate() {
        super.onCreate();
        System.out.println("Service is Created");
        //<span style="font-family:Microsoft YaHei;"></span>监听器
        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,第二个参数是所得传感器类型,第三个参数值获取传感器信息的频率
         }
    	<pre name="code" class="java">         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");
<font size="4" face="Microsoft YaHei"><span style="font-family:Microsoft YaHei;font-size:18px;"><span style="font-family:Microsoft YaHei;font-size:18px;"><span style="font-family:Microsoft YaHei;font-size:18px;"></span></span></span></font><pre name="code" class="java">          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中的按钮,按钮监听代码:

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,文中如果有错误请大家指正。

时间: 2024-10-26 19:27:23

【Android开发日记】初次探秘Android Service!Service开机启动+重力感应+弹窗+保持运行的相关文章

【Android开发日记】妙用 RelativeLayout 实现3 段布局

在设计过程中,我们经常会遇到这样的需求: 把一条线3控制,左对齐左控制,右侧控制右对齐,中间控制,以填补剩余空间. 或者一列内放3个控件,上面的与顶部对齐,以下的沉在最底部,中间控件是弹性的.充满剩余空间. 情况一:水平布局 图示: 这是第一种情形.因为涉及到ImageView.想保持图片原比例不便使用LinearLayout的weight属性. 解决的方法: 1.外层套一个RelativeLayout 2.三个控件分别装进3个LinearLayout中.假如id分别为leftlayout,mi

【Android开发】完美解决Android完全退出程序

背景:假说有两个Activity, Activity1和Activity2, 1跳转到2,如果要在2退出程序,一般网上比较常见的说法是用 System.exit(0) 或是 android.os.Process.killProcess(android.os.Process.myPid()) 但实际应用中,并不是能够真正退出,问题出在?1跳转到2时,如果Activity1你finish掉了,两么是可以退出程序的,但有时1跳转到2时,我们不能将Activity1 finish掉,那么在Activit

Android开发工具全面转向Android Studio(3)——AS project/module的目录结构(与Eclipse对比)

如果AS完全还没摸懂的,建议先看下Android开发工具全面转向Android Studio(2)——AS project/module的CRUD. 1.其实AS project/module的目录结构很简单,我浓缩成2张图给总结了,先看图,再看下面的文字,因为还有些细节图上体现不出来(我这个图上的项目来源于我之前的Eclipse项目,并且有lib项目库相互依赖) 2.上面的图很直观,但也很眼花缭乱,我再针对图总结下重点和疑问点. ①在AS的世界里,文件夹都以模块(module)为单位组织的,其

配置cordova的android开发环境(无android studio)

原文:配置cordova的android开发环境(无android studio) 趁元旦放假想试一下cordova,不想安装庞大的android studio,所以想最小化安装,居然花了一整天的时间才能正常编译cordova工程,记录一下过程,备将来参考. 安装环境:操作系统:windows 10 x64 第一步:安装nodejs,下载最新版本v10.15.0 第二步:设置npm安装源 npm config set registry http://registry.npm.taobao.org

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

前言: 近期在写一个小程序,需求是手机摇一摇就弹窗出来.第一次使用了Service,学习了两天,实现了Service弹窗,开机启动,Service启动和销毁,Service保持一直执行. 满足了自己的需求.现记录学习心得. 希望能给你带来一些帮助. 1.Service创建:重写4个方法 onBind():返回一个IBinder对象,这个对象能够使应用程序与Service通信.假设用startService.stopService启动和关闭Service的话.Service和訪问者是无法通信交换数

Android开发之怎样监听让Service不被杀死

一.Service简单介绍 Service是在一段不定的时间执行在后台,不和用户交互应用组件. 每一个Service必须在manifest中 通过<service>来声明. 能够通过contect.startservice和contect.bindserverice来启动.和其它的应用组件一样,执行在进程的主线程中.这就是说假设service须要非常多耗时或者堵塞的操作,须要在其子线程中实现(或者用系统提供的IntentService,它继承了Service,它处理数据是用自身新开的线程).

【Android开发坑系列】如何让Service尽可能存活

流行的思路如下: 1.让Service杀不死.Service的onStartCommand返回START_STICKY,同时onDestroy里面调用startService启动自身. 2.让Service从后台变成前置.在Android 2.0以前有效,借助setForeground(true). 3.让某个进程不被系统的low memory killer杀死(如数据缓存进程,或状态监控进程,或远程服务进程).add android:persistent="true" into th

android开发步步为营之60:IntentService与Service的区别

这个面试的时候,相信是面试官最爱的问题之一.简单的来说,IntentService继承至Service,Service和Acitivity一样是依附于应用主进程的,它本身不是一个进程或者一个线程.一些耗时的操作可能会引起ANR的bug,(本文测试的时候,Service执行20秒没有报ANR),而IntentService,看它的源代码,onCreate()其实是创建了一个新的线程. /* * Copyright (C) 2008 The Android Open Source Project *

【Android开发日记】妙用 RelativeLayout 实现3段式布局

在设计的过程中我们一定经常会遇到这样的需求: 一行内放3个控件,左边控件左对齐,右面控件右对齐,中间控件来填充剩下的空间. 或者一列内放3个控件,上面的与顶部对齐,下面的沉在最底部,中间控件是弹性的,充满剩余空间. 情况一:水平布局 图示: 这是第一种情形.由于涉及到ImageView,想保持图片原比例不便使用LinearLayout的weight属性. 解决办法: 1.外层套一个RelativeLayout 2.三个控件分别装进3个LinearLayout中,假如id分别为leftlayout