前言:

近期在写一个小程序,需求是手机摇一摇就弹窗出来。第一次使用了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. HDU 2203 亲串(kmp)

    Problem Description 随着人们年龄的增长更大,更聪明还是越大越愚蠢,这是一个值,相同的问题Eddy也一直在思考,由于他在非常小的时候就知道亲和串怎样推断了,可是发现,如今长大了却不知 ...

  2. 鸟哥Linux私房菜 基础学习篇读书笔记(10):Linux磁盘和文件系统管理(3)

    本文总结了Linux操作系统来管理我们的硬盘和文件系统需要使用命令.当我们在系统中增加一个硬盘驱动器.什么是我们需要去通过这个硬盘就可以真正使用步骤?下面步骤: (1)对磁盘进行分区,新建能够使用的分 ...

  3. VS公布 错 到文件失败 复制到

    他自己和构建网站 ASP.MVC4 最近更改写功能 自此从未公布 已经报道 错 15 到文件失败 easyui\themes\gray\images\Thumbs.db  拷贝到 obj\Releas ...

  4. 分析Cocos2d-x横版ACT手游源 1、登录

    我自己的游戏代码 因为 游戏源 盯着外面的 我们能够能够理解 /******************************************************************** ...

  5. poj 1004 Dividing

    大意是,从输入六个数 .第i个数代表价值为i的有几个,平均分给两个人 ,明摆着的背包问题,本来以为把他转化为01背包.可是TLe,后来发现是12万的平方还多,所以妥妥的TLE,后来发现这是一个全然背包 ...

  6. C++“窗体”程序设计启蒙

    [摘要]本文以C++菜菜鸟(仅仅须要学习了C++数据类型和控制结构就可以)为目标读者,用求解一元二次方程作为实例,展示窗体式程序的开发过程,获得初步体验.写作目的包含:(1)让学生通过模仿,开发出类似 ...

  7. Cocos2d-X字体

    Cocos2d-X顺便文本显示在以下三个: CCLabelTTF: 使用系统字体.每一个字符串会生成一个纹理.显示效率比較低下,适合不变化的文字 CCLabelAtlas: 使用NodeAtlas优化 ...

  8. java观察者模式(转)

    简单地说,观察者模式定义了一个一对多的依赖关系,让一个或多个观察者对象监察一个主题对象.这样一个主题对象在状态上的变化能够通知所有的依赖于此对象的那些观察者对象,使这些观察者对象能够自动更新. 不多说 ...

  9. Android利用网络编程HttpClient批量上传(两)AsyncTask+HttpClient监测进展情况,并上传

    请尊重别人的劳动.转载请注明出处: Android网络编程之使用HttpClient批量上传文件(二)AsyncTask+HttpClient并实现上传进度监听 执行效果图: 我曾在<Andro ...

  10. C# 带用户密码访问网络共享

    原文:C# 带用户密码访问网络共享 调用WNetUseConnection API 函数详细参数参考:https://msdn.microsoft.com/en-us/library/windows/ ...