AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.auto_power_on"
android:versionCode="1"
android:versionName="1.0" >
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"></uses-permission>
<uses-sdk
android:minSdkVersion="7"
android:targetSdkVersion="10" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<!-- 1.app不显示在最近应用列表 -->
<!-- android:excludeFromRecents="true" -->
<!-- 2.启动app不显示界面 -->
<!-- android:theme="@android:style/Theme.NoDisplay" -->
<!-- 3.隐藏app桌面图标 -->
<!-- <category android:name="android.intent.category.LAUNCHER" /> -->
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:excludeFromRecents="true"
android:theme="@android:style/Theme.NoDisplay"
>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name=".ServiceCrack"
android:exported="false">
</service>
<receiver android:name=".BootBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
</application>
</manifest>
package com.example.auto_power_on;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.content.Context;
import android.content.Intent;
import static java.lang.Thread.sleep;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//1.禁止布局
//setContentView(R.layout.activity_main);
//2.把Activity移除,资源并没有回收.
finish();
//3.启动Service
Intent service = new Intent(this,ServiceCrack.class);
startService(service);
Log.d("auto_xxx","启动ServiceCrack服务....");
//stopService(service);
}
}
package com.example.auto_power_on;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
public class ServiceCrack extends Service{
@Override
public IBinder onBind(Intent arg0) {
return null;
}
@Override
public void onCreate(){
super.onCreate();
Log.d("auto_xxx","Service 已经启动成功");
}
}
package com.example.auto_power_on;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
public class BootBroadcastReceiver extends BroadcastReceiver {
static final String ACTION = "android.intent.action.BOOT_COMPLETED";
@Override
public void onReceive(Context context, Intent intent) {
Log.d("xxx", "intent.getAction() ===== " + intent.getAction());
if (intent.getAction().equals(ACTION)) {
Intent mainActivityIntent = new Intent(context, MainActivity.class);
Log.d("auto_xxx","开机自启动一个Activity");
mainActivityIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(mainActivityIntent);
}
}
}
android 保证屏幕黑屏之后线程可以继续运行
最近在做关于android手机端gps定时定位的功能,需要每隔几秒钟将gps定位获取的经纬度上传至后台,但是发现某些手机在屏幕黑屏,进入休眠状态后,后台就没有收到定位信息了,后来通过网上查找资料,发现一旦手机在休眠的时候,手机的cpu也休眠了,创建的线程也会sleep,所以为了让手机屏幕黑屏之后,上传线程可以继续运行,就必须保存手机CPU一直处于运行状态,综合网上所查找的资料,发现可以通过使用android的PowerManager和PowerManager.WakeLock这两个类来控制,具体关于这两个类的使用可以参考:
下面来说一下我的GPS定时定位主要思想:
1、要实现程序退出之后,仍然可以定时上传定位信息,必须采用service,service可以保持在后台一直运行,除非系统资源极其匮乏,否则一般来说service是不会被系统杀死的。
2、要实现定时上传,因为android系统自带的gps定位功能本身自带就有循环定位的功能,所以直接利用此功能即可实现定时上传了。
代码如下所示:
/**
* 获取gps位置信息的service
*
* @author king
*
*/
public class MyService extends Service {
private LocationManager locationManager;
private PowerManager pm;
private PowerManager.WakeLock wakeLock;
private GPSUploadThread myThread;
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
@Override
public void onCreate() {
super.onCreate();
//创建LocationManger对象(LocationMangager,位置管理器。要想操作定位相关设备,必须先定义个LocationManager)
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
//利用Criteria选择最优的位置服务
Criteria criteria = new Criteria();
//设置定位精确度 Criteria.ACCURACY_COARSE比较粗略,Criteria.ACCURACY_FINE则比较精细
criteria.setAccuracy(Criteria.ACCURACY_FINE);
//设置是否需要海拔信息
criteria.setAltitudeRequired(false);
//设置是否需要方位信息
criteria.setBearingRequired(false);
// 设置是否允许运营商收费
criteria.setCostAllowed(true);
// 设置对电源的需求
criteria.setPowerRequirement(Criteria.POWER_LOW);
//获取最符合要求的provider
String provider = locationManager.getBestProvider(criteria, true);
//绑定监听,有4个参数
//参数1,设备:有GPS_PROVIDER和NETWORK_PROVIDER两种
//参数2,位置信息更新周期,单位毫秒
//参数3,位置变化最小距离:当位置距离变化超过此值时,将更新位置信息
//参数4,监听
//备注:参数2和3,如果参数3不为0,则以参数3为准;参数3为0,则通过时间来定时更新;两者为0,则随时刷新
locationManager.requestLocationUpdates(provider, 10000, 0,locationListener);// 2000,10
}
@Override
public void onStart(Intent intent, int startId) {
// TODO Auto-generated method stub
super.onStart(intent, startId);
//创建PowerManager对象
pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
//保持cpu一直运行,不管屏幕是否黑屏
wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "CPUKeepRunning");
wakeLock.acquire();
}
/**
* 实现一个位置变化的监听器
*/
private final LocationListener locationListener = new LocationListener() {
@Override
public void onLocationChanged(Location location) {
// TODO Auto-generated method stub
/**
* 此处实现定位上传功能
*/
}
// 当位置信息不可获取时
@Override
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
/**
*
*/
}
@Override
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub
}
};
@Override
public void onDestroy() {
// TODO Auto-generated method stub
// toggleGPS(false);
if (locationListener != null) {
locationManager.removeUpdates(locationListener);
}
wakeLock.release();
super.onDestroy();
}
}
Android以后台Service的方式获取GPS数据,并定时发送到服务器
在配备Android系统的手机中,一般都配备了GPS设备。Android为我们获取GPS数据提供了很好的接口。本文来说一下如何使用Android获取GPS的经纬度。
1 从Service继承一个类。
2 创建startService()方法。
3 创建endService()方法 重载onCreate方法和onDestroy方法,并在这两个方法里面来调用startService以及endService。
4 在startService中,通过getSystemService方法获取Context.LOCATION_SERVICE。
5 基于LocationListener实现一个新类。默认将重载四个方法onLocationChanged、onProviderDisabled、onProviderEnabled、onStatusChanged。对于onLocationChanged方法是我们更新最新的GPS数据的方法。一般我们的操作都只需要在这里进行处理。
6 调用LocationManager的requestLocationUpdates方法,来定期触发获取GPS数据即可。在onLocationChanged函数里面可以实现我们对得到的经纬度的最终操作。
7 最后在我们的Activity里面通过按钮来启动Service,停止Service。
示意代码如下:
package com.offbye.gpsservice;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;
public class GPSService extends Service {
// 2000ms
private static final long minTime = 2000;
// 最小变更距离 10m
private static final float minDistance = 10;
String tag = this.toString();
private LocationManager locationManager;
private LocationListener locationListener;
private final IBinder mBinder = new GPSServiceBinder();
public void startService() {
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
locationListener = new GPSServiceListener();
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, minTime, minDistance,
locationListener);
}
public void endService() {
if (locationManager != null && locationListener != null) {
locationManager.removeUpdates(locationListener);
}
}
@Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return mBinder;
}
@Override
public void onCreate() {
//
startService();
Log.v(tag, "GPSService Started.");
}
@Override
public void onDestroy() {
endService();
Log.v(tag, "GPSService Ended.");
}
public class GPSServiceBinder extends Binder {
GPSService getService() {
return GPSService.this;
}
}
}
GPSServiceListener的实现
package com.offbye.gpsservice;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.TimeZone;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationProvider;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;
public class GPSServiceListener implements LocationListener {
private static final String tag = "GPSServiceListener";
private static final float minAccuracyMeters = 35;
private static final String hostUrl = "http://doandroid.info/gpsservice/position.php?";
private static final String user = "huzhangyou";
private static final String pass = "123456";
private static final int duration = 10;
private final DateFormat timestampFormat = new SimpleDateFormat("yyyyMMddHHmmss");
public int GPSCurrentStatus;
@Override
public void onLocationChanged(Location location) {
// TODO Auto-generated method stub
if (location != null) {
if (location.hasAccuracy() && location.getAccuracy() <= minAccuracyMeters) {
// 获取时间参数,将时间一并Post到服务器端
GregorianCalendar greg = new GregorianCalendar();
TimeZone tz = greg.getTimeZone();
int offset = tz.getOffset(System.currentTimeMillis());
greg.add(Calendar.SECOND, (offset / 1000) * -1);
StringBuffer strBuffer = new StringBuffer();
strBuffer.append(hostUrl);
strBuffer.append("user=");
strBuffer.append(user);
strBuffer.append("&pass=");
strBuffer.append(pass);
strBuffer.append("&Latitude=");
strBuffer.append(location.getLatitude());
strBuffer.append("&Longitude=");
strBuffer.append(location.getLongitude());
strBuffer.append("&Time=");
strBuffer.append(timestampFormat.format(greg.getTime()));
strBuffer.append("&Speed=");
strBuffer.append(location.hasSpeed());
doGet(strBuffer.toString());
Log.v(tag, strBuffer.toString());
}
}
}
// 将数据通过get的方式发送到服务器,服务器可以根据这个数据进行跟踪用户的行走状态
private void doGet(String string) {
// TODO Auto-generated method stub
//
}
@Override
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
}
@Override
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub
GPSCurrentStatus = status;
}
}
android隐藏式自动拍照相机
Android 实现开机自启动无界面的Apk
我们有时候会遇到这样的需求,需要将一个apk作为一个后台程序为第三方应用提供服务。开发这样的apk我们会遇到两个问题:
1、apk不需要界面。
2、由于apk没有界面,我们需要启动运行,就需要实现开机自启动。
1、我们先来看看如何实现一个无界面的apk.
大家都知道,我们新建一个应用,默认都是有Activity的,如果把默认的Activity去掉会报错。那么我们可以这样修改:打开manifest文件,把默认的category注释掉
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<!--<category android:name="android.intent.category.LAUNCHER" />-->
</intent-filter>
</activity>
并且把Launch Options 设置为Nothing,如下图所示:
这样运行程序之后在Launcher界面就看不见我们的应用图标了。
2、开机应用自启动的实现:首先,我们需要在manifest文件中注册相应的权限
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
接着我们实现一个广播接收器代码如下:
public class BootReceiver extends BroadcastReceiver {
public BootReceiver() {
}
@Override
public void onReceive(Context context, Intent intent) {
//后边的XXX.class就是要启动的服务
Intent service = new Intent(context,ReadSNService.class);
context.startService(service);
Log.v("TAG", "开机自动服务自动启动.....");
}
}
在manifest文件中添加监听开机的action:
<receiver android:name=".BootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"></action>
</intent-filter>
</receiver>
配置好之后,运行我们的程序,安装成功之后可以在设置里面看到我们apk,这样,我们就实现了一个无界面的后台程序,我们可以根据业务需求,在MainActity里面启动一个服务来实现我们具体的功能。