前言:

近期在写一个小程序,需求是手机摇一摇就弹窗出来。第一次使用了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,文中假设有错误请大家指正。

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

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

  1. 【Android开发日记】之入门篇(五)——Android四大组件之Service

    这几天忙着驾校考试,连电脑都碰不到了,今天总算告一段落了~~Service作为Android的服务组件,默默地在后台为整个程序服务,辅助应用与系统中的其他组件或系统服务进行沟通.它跟Activity的 ...

  2. 【Android开发日记】之入门篇(六)——Android四大组件之Broadcast Receiver

    广播接受者是作为系统的监听者存在着的,它可以监听系统或系统中其他应用发生的事件来做出响应.如设备开机时,应用要检查数据的变化状况,此时就可以通过广播来把消息通知给用户.又如网络状态改变时,电量变化时都 ...

  3. 【Android开发日记】之入门篇(十二)——Android组件间的数据传输

    组件我们有了,那么我们缺少一个组件之间传递信息的渠道.利用Intent做载体,这是一个王道的做法.还有呢,可以利用文件系统来做数据共享.也可以使用Application设置全局数据,利用组件来进行控制 ...

  4. 【Android开发日记】之入门篇(八)——Android数据存储(下)

    废话不多说了,紧接着来讲数据库的操作吧.Come On! 提到数据存储问题,数据库是不得不提的.数据库是用来存储关系型数据的不二利器.Android为开发者提供了强大的数据库支持,可以用来轻松地构造基 ...

  5. 【Android开发日记】之入门篇(十三)——Android的控件解析

    Android的控件都派生自android.view.View类,在android.widget包中定义了大量的系统控件供开发者使用,开发者也可以从View类及其子类中,派生出自定义的控件. 一.An ...

  6. 【Android开发日记】之入门篇(七)——Android数据存储(上)

    在讲解Android的数据源组件——ContentProvider之前我觉得很有必要先弄清楚Android的数据结构. 数据和程序是应用构成的两个核心要素,数据存储永远是应用开发中最重要的主题之一,也 ...

  7. 【Android开发日记】之入门篇(九)——Android四大组件之ContentProvider

    数据源组件ContentProvider与其他组件不同,数据源组件并不包括特定的功能逻辑.它只是负责为应用提供数据访问的接口.Android内置的许多数据都是使用ContentProvider形式,供 ...

  8. 【Android开发日记】之入门篇(四)——Android四大组件之Activity

    在Android中,无论是开发者还是用户,接触最多的就算是Activity.它是Android中最复杂.最核心的组件.Activity组件是负责与用户进行交互的组件,它的设计理念在很多方面都和Web页 ...

  9. 【Android开发日记】之入门篇(十一)——Android的Intent机制

    继续我们的Android之路吧.今天我要介绍的是Android的Intent. 对于基于组件的应用开发而言,不仅需要构造和寻找符合需求的组件,更重要的是要将组件有机的连接起来,互联互通交换信息,才能够 ...

随机推荐

  1. SQL Server 2008 R2 安全性专题(一):安全原则

    原文:SQL Server 2008 R2 安全性专题(一):安全原则 本系列主要专注与SQL Server 2005以后的DBMS,由于本人工作使用2008 R2,所以目前就针对2008 R2来做说 ...

  2. 装双系统(win7/win8/ubuntu)问题总结

    1.假设你要安装双系统,装系统是最好安装winows,然后再装ubuntu,因此,不解决它自己入选,我一般装ubuntu时刻.第一分区删除.然后用U硬盘直接安装ubuntu.在这一刻ubuntu将投入 ...

  3. 走向DBA[MSSQL篇] 积跬步行千里

    原文:走向DBA[MSSQL篇] 积跬步行千里 不知道大家对SQL系列的感不感兴趣 先在这里探个路 本文针对的读者为SQL菜鸟 欢迎大牛驳论或者补充 既然是探路篇 就先说下数据过滤中的偏门匹配 希望能 ...

  4. Linux下is not in the sudoers file(转)

    用sudo时提示"xxx is not in the sudoers file. This incident will be reported.其中XXX是你的用户名,也就是你的用户名没有权 ...

  5. document.all使用

    document.all 一个. document.all它是在页面中的所有元素的集合.例如:      document.all(0)一个元素 二. document.all能够推断浏览器是否是IE ...

  6. jquery的智能提示控件

    福利到~分享一个基于jquery的智能提示控件intellSeach.js   一.需求 我们经常会遇到[站内搜索]的需求,为了提高用户体验,我们希望能做到像百度那样的即时智能提示.例如:某公司人事管 ...

  7. 对“demo!demo.Index+HookProc::Invoke”垃圾收集的类型已委托回调。这可能会导致应用程序崩溃、损坏和数据丢失。当传递委托给非托管代码,托管应用程序必须让这些委托保持活着

    对"demo!demo.Index+HookProc::Invoke"垃圾收集的类型已委托回调.这可能会导致应用程序崩溃.损坏和数据丢失.当传递委托给非托管代码,托管应用程序必须承 ...

  8. (大数据工程师学习路径)第四步 SQL基础课程----SQL介绍及mysql的安装

    一.数据库和SQL介绍 数据库(Database)是按照数据结构来组织.存储和管理数据的仓库,它的产生距今已有六十多年.随着信息技术和市场的发展,数据库变得无处不在:它在电子商务.银行系统等众多领域都 ...

  9. Bind和Eval的区别详解

    原文:Bind和Eval的区别详解 1.简单描述Eval和Bind的区别 绑定表达式 <%# Eval("字段名") %> <%# Bind("字段名& ...

  10. 解决 TortoiseGit 诡异的 Bad file number 问题(转)

    问题描述 昨天,以及今天(2014-11-29),使用 TortoiseGit 时碰到了一个诡异的问题. 卸载,清理注册表,重装,重启,各种折腾以后,还是不能解决. 但是23.45分一过,突然灵光一闪 ...