用以下代码“构造一个虚拟位置信息给谷歌地图,让其定位错误”无法实现,给位大神指点迷津,小弟开始研究Android编程不久,有点小白望谅解
正常情况下是:在本应用横纵有一个数据库,记录用户对不同需要获取位置信息的应用按精确度进行分类,分别为城镇级,精确级,街道级,不同级别对应的位置模糊程度不同,虚构的位置信息也不同
代码如下:
package com.example.hermit;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Random;
import android.app.ActivityManager;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.database.Cursor;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;
public class service extends Service {
LocationManager locationManager;
private PackageManager pm;// Package Manager(包管理)-用来找到关于安装在设备上的应用程序包的相关信息。
private ArrayList<String> default1 = new ArrayList<String>();// 城镇;创建default1来保存字符串数组
private ArrayList<String> default2 = new ArrayList<String>();// 街道;创建default2来保存字符串数组
private ArrayList<String> default3 = new ArrayList<String>();// 精准;创建default3来保存字符串数组
private ArrayList<String> user1 = new ArrayList<String>();// 城镇
private ArrayList<String> user2 = new ArrayList<String>();// 街道
private ArrayList<String> user3 = new ArrayList<String>();// 精准
private Strategy_DB DB = new Strategy_DB(this);
double test1;
private String mocLocationProvider;
private String currentProvider;
private String Provider;
// Android的location定义新的变量
private Location currentLocation;
Location LOCtmp;
Location Location;
Location Loc;
Location l;
// 精确
double latitude;// 经度
double longitude;// 纬度
// 城镇
double latitude1;
double longitude1;
// 街道
double latitude2;
double longitude2;
double ltd_tmp;
double lng_tmp;
private String AN;
private String TAG = "service";
static final int DELAY = 4000; // 相当于定义常量DELAY
String name;
int flag = 0;
static final String ACTION_FOREGROUND = "com.example.android.apis.FOREGROUND";
static final String ACTION_BACKGROUND = "com.example.android.apis.BACKGROUND";
private final IBinder mBinder = new localBinder();
/*
* Handler在android里负责发送和处理消息。它的主要用途有: 1)按计划发送消息或执行某个Runnanble(使用POST方法);
* 2)从其他线程中发送来的消息放入消息队列中,避免线程冲突(常见于更新UI线程)/用来向不属于自己的线程的队列中加入某个动作
*/
Handler handler;
Runnable runnable;
private static final Class<?>[] mSetForegroundSignature = new Class[] { boolean.class };
private static final Class<?>[] mStartForegroundSignature = new Class[] {
int.class, Notification.class };
private static final Class<?>[] mStopForegroundSignature = new Class[] { boolean.class };
private NotificationManager mNM;
private Method mSetForeground;
private Method mStartForeground;
private Method mStopForeground;
private Object[] mSetForegroundArgs = new Object[1];
private Object[] mStartForegroundArgs = new Object[2];
private Object[] mStopForegroundArgs = new Object[1];
/*
* 可以看出,对于一个对象的方法调用来说,如果这个方法能够被分派出去,
* 如上面的“hello”方法,可以在InvokeTestor1类中找到,就被分派给InvokeTestor1类的“hello”方法;
* 如果不能被分派,如上面的“foo”方法,则调用“invokeMethod”方法
*/
void invokeMethod(Method method, Object[] args) {
try {
method.invoke(this, args);
} catch (InvocationTargetException e) {
// Should not happen.
Log.w("ApiDemos", "Unable to invoke method", e);
} catch (IllegalAccessException e) {
// Should not happen.
Log.w("ApiDemos", "Unable to invoke method", e);
}
}
/**
* This is a wrapper around the new startForeground method, using the older
* APIs if it is not available.
*/
void startForegroundCompat(int id, Notification notification) {
// If we have the new startForeground API, then use it.
if (mStartForeground != null) {
mStartForegroundArgs[0] = Integer.valueOf(id);
mStartForegroundArgs[1] = notification;
Log.d(TAG, "Updater running");
invokeMethod(mStartForeground, mStartForegroundArgs);
return;
}
// Fall back on the old API.
mSetForegroundArgs[0] = Boolean.TRUE;
Log.d(TAG, "Updater sdsf");
invokeMethod(mSetForeground, mSetForegroundArgs);
mNM.notify(id, notification);
}
/**
* This is a wrapper around the new stopForeground method, using the older
* APIs if it is not available.
*/
void stopForegroundCompat(int id) {
// If we have the new stopForeground API, then use it.
if (mStopForeground != null) {
mStopForegroundArgs[0] = Boolean.TRUE;
invokeMethod(mStopForeground, mStopForegroundArgs);
return;
}
// Fall back on the old API. Note to cancel BEFORE changing the
// foreground state, since we could be killed at that point.
mNM.cancel(id);
mSetForegroundArgs[0] = Boolean.FALSE;
invokeMethod(mSetForeground, mSetForegroundArgs);
}
public class localBinder extends Binder {
service getService() {
return service.this;
}
}
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
Log.i(TAG, "this is on binder");
return null;
}
public void OnCreate() {
// 获得系统级的服务Notification Manager,调用getSystemService()方法实现
mNM = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
// 为了兼容Android1的代码。即如果mStartForeground / mStopForeground
// 为空就表示是Android1的环境。
try {
mStartForeground = getClass().getMethod("startForeground",
mStartForegroundSignature);
mStopForeground = getClass().getMethod("stopForeground",
mStopForegroundSignature);
return;
} catch (NoSuchMethodException e) {
// Running on an older platform.
mStartForeground = mStopForeground = null;
}
try {
mSetForeground = getClass().getMethod("setForeground",
mSetForegroundSignature);
} catch (NoSuchMethodException e) {
// 抛出一个异常
throw new IllegalStateException(
"OS doesn't have Service.startForeground OR Service.setForeground!");
}
}
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "recived start id" + startId + ":" + intent);
// //获得系统级的服务Location Manager,调用getSystemService()方法实现
locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
// mocLocationProvider 存放gps信息
mocLocationProvider = LocationManager.GPS_PROVIDER;
// 根据设置的Criteria对象,获取最符合此标准的provider对象
currentProvider = locationManager.getProvider(
LocationManager.GPS_PROVIDER).getName();
// 获取网络位置信息
Provider = locationManager
.getProvider(LocationManager.NETWORK_PROVIDER).getName();
// 根据当前provider对象获取最后一次位置信息
l = locationManager.getLastKnownLocation(Provider);
latitude = l.getLatitude();// 精确
longitude = l.getLongitude();
chose();
if (flag == 1) {
ltd_tmp = latitude1;// 城镇
lng_tmp = longitude1;
}
if (flag == 2) {
ltd_tmp = latitude2;// 街道
lng_tmp = longitude2;
}
if (flag == 3) {
ltd_tmp = latitude;// 精确
lng_tmp = longitude;
}
if (flag == 0) {
ltd_tmp = latitude1;// 精确
lng_tmp = longitude1;
}
//创建 一个 “用于模拟的坐标提供者”
// 创建一个仿真位置信息并添加到当前正在运行的provider中
locationManager.addTestProvider(mocLocationProvider, false, false, false,
false, false, false, false, 0, 5);
// 让创建好的仿真位置信息对于正在运行的provider可用。并且该值会替代原有真实provider中的数据
locationManager.setTestProviderEnabled(mocLocationProvider, true);
Location = new Location(mocLocationProvider);
// Location.setTime(currentLocation.getTime() );
// Location.setLatitude(Loc.getLatitude());
// Location.setLongitude(Loc.getLongitude());
float x = 5.0f, y = 0.0f, s = 10.0f;
Location.setAccuracy(x);// 设置精度
Location.setSpeed(s);
Location.setAltitude(y);// 设置
// Log.e("location", Location.toString());
// 获得已安装的应用程序信息 。可以通过getPackageManager()方法获得
pm = getPackageManager();
// 通过系统服务获取ActivityManager
ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
// 获得当前正在运行的activity
ComponentName cn = am.getRunningTasks(1).get(0).topActivity;
name = cn.getPackageName();
// 在android中提供了一种异步回调机制Handler,使用它,我们可以在完成一个很长时间的任务后做出相应的通知。
handler = new Handler();
// 实现多线程
runnable = new Runnable() {
public void run() {
DB.closeDB();// 关闭数据库
DB.openDB();// 打开数据库
opDB();
ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
ComponentName cn2 = am.getRunningTasks(1).get(0).topActivity;
String cmp = cn2.getPackageName();
// Log.d(TAG, "Updater running");
if (!name.equals(cmp) && cmp.equals("com.example.hermit")) {
name = cmp;
}
if (!name.equals(cmp) && !cmp.equals("com.android.launcher")
&& !cmp.equals("com.example.hermit")) {
Log.d(TAG, cmp);
try {
ApplicationInfo info = pm.getApplicationInfo(cmp, 0);
AN = (String) pm.getApplicationLabel(info);// AN表示获取的应用标签
Log.i("AN", AN);
} catch (NameNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
chose();
if (flag == 1) {
ltd_tmp = latitude1;// 城镇
lng_tmp = longitude1;
}
if (flag == 2) {
ltd_tmp = latitude2;// 街道
lng_tmp = longitude2;
}
if (flag == 3) {
ltd_tmp = latitude;// 精确
lng_tmp = longitude;
}
if (flag == 0) {
ltd_tmp = latitude1;// 精确
lng_tmp = longitude1;
}
Location.setTime(System.currentTimeMillis());
Location.setLatitude(ltd_tmp);
Location.setLongitude(lng_tmp);
//locationManager.setTestProviderLocation(mocLocationProvider, Location);
Log.e("l", l.toString());
Log.i("test1", "lat long" + latitude + longitude);
Log.i("location", Location.toString());
Log.i("location", "flag=" + flag + " " + ltd_tmp + lng_tmp);
try {
locationManager.setTestProviderLocation(
mocLocationProvider, Location);
} catch (IllegalArgumentException e) {
Log.d("test", "location error");
String mess = e.getLocalizedMessage();
Log.d("test", mess);
}
locationManager.requestLocationUpdates(currentProvider, 0, 0,
locationListener);
currentLocation = locationManager
.getLastKnownLocation(currentProvider);
if (currentLocation == null) {
// Log.d("test","location error");
locationManager.requestLocationUpdates(currentProvider, 0,
0, locationListener);
currentLocation = locationManager
.getLastKnownLocation(currentProvider);
} else {
// Log.e("location", currentLocation.toString());
}
// 获取当前运行的activity并放于cn2中
// ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
// ComponentName cn2 = am.getRunningTasks(1).get(0).topActivity;
// String cmp = cn2.getPackageName();
//
// // Log.d(TAG, "Updater running");
// if (!name.equals(cmp) && cmp.equals("com.example.hermit")) {
// name = cmp;
// }
// if (!name.equals(cmp) && !cmp.equals("com.android.launcher")
// && !cmp.equals("com.example.hermit")) {
// Log.d(TAG, cmp);
// try {
// ApplicationInfo info = pm.getApplicationInfo(cmp, 0);
// AN = (String) pm.getApplicationLabel(info);// AN表示获取的应用标签
// Log.i("AN", AN);
// } catch (NameNotFoundException e1) {
// // TODO Auto-generated catch block
// e1.printStackTrace();
// }
Log.d("falg", "flag=" + flag);
// chose();
// if (flag == 1) {
// ltd_tmp = latitude1;// 城镇
// lng_tmp = longitude1;
// }
// if (flag == 2) {
// ltd_tmp = latitude2;// 街道
// lng_tmp = longitude2;
// }
// if (flag == 3) {
// ltd_tmp = latitude;// 精确
// lng_tmp = longitude;
// }
// if (flag == 0) {
// ltd_tmp = latitude1;// 精确
// lng_tmp = longitude1;
// }
// Location.setTime(System.currentTimeMillis());
// Location.setLatitude(ltd_tmp);
// Location.setLongitude(lng_tmp);
// locationManager.setTestProviderLocation(mocLocationProvider, Location);
// 监听到用户打开了需要访问位置信息的应用
Log.d("falg", "flag=" + flag);
if (flag == 1) {
Intent i = new Intent(service.this, Dialog.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Bundle b = new Bundle();
b.putString("textview", "粒度策略:城镇级 ");
i.putExtras(b);
startActivity(i);
flag = 0;
}
if (flag == 2) {
Intent i = new Intent(service.this, Dialog.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Bundle b = new Bundle();
b.putString("textview", "粒度策略:街道级 ");
i.putExtras(b);
startActivity(i);
flag = 0;
}
if (flag == 3) {
Intent i = new Intent(service.this, Dialog.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Bundle b = new Bundle();
b.putString("textview", "粒度策略:精确级 ");
i.putExtras(b);
startActivity(i);
flag = 0;
}
name = cmp;
}
handler.postDelayed(this, 3000);
}
};
handler.postDelayed(runnable, 3000);
handleCommand(intent);
// new ClientThread().run();
return START_STICKY;
}
private void chose() {
double x1, y1, x2, y2;
Random rdr = new Random();// rdr为一组随机数流
Random rdz = new Random();
int Z = rdz.nextInt(360);// 随机数的生成范围小于360
double R2 = 1 + rdr.nextDouble() * 10;// x2街道
double R1 = 9 + rdr.nextDouble() * 20;// x1城镇
if (Z <= 90 && Z >= 0) {
x1 = R1 * Math.sin(Z * Math.PI / 180);// (Z*Math.PI/180)为弧度制
y1 = R1 * Math.cos(Z * Math.PI / 180);
x2 = R2 * Math.sin(Z * Math.PI / 180);
y2 = R2 * Math.cos(Z * Math.PI / 180);
} else if (Z <= 180 && Z > 90) {
x1 = R1 * Math.cos((Z - 90) * Math.PI / 180);
y1 = R1 * Math.sin((Z - 90) * Math.PI / 180) * -1;
x2 = R2 * Math.cos((Z - 90) * Math.PI / 180);
y2 = R2 * Math.sin((Z - 90) * Math.PI / 180) * -1;
} else if (Z <= 270 && Z > 180) {
x1 = R1 * Math.sin((Z - 180) * Math.PI / 180) * -1;
y1 = R1 * Math.cos((Z - 180) * Math.PI / 180) * -1;
x2 = R2 * Math.sin((Z - 180) * Math.PI / 180) * -1;
y2 = R2 * Math.cos((Z - 180) * Math.PI / 180) * -1;
} else {
x1 = R1 * Math.cos((Z - 270) * Math.PI / 180) * -1;
y1 = R1 * Math.sin((Z - 270) * Math.PI / 180);
x2 = R2 * Math.cos((Z - 270) * Math.PI / 180) * -1;
y2 = R2 * Math.sin((Z - 270) * Math.PI / 180);
}
Log.i("r", "R1=" + R1 + "R2=" + R2);
Log.i("x1= y1=", "x1=" + x1 + "y1=" + y1);// 城镇
Log.i("x2= y2=", "x2=" + x2 + "y2=" + y2);
// latitude=location.getLatitude();//精确
// longitude=location.getLongitude();
latitude1 = latitude + x1 / 111;// 城镇
longitude1 = longitude + y1 / (111 * Math.cos(Z * Math.PI / 180));
latitude2 = latitude + x2 / 111;// 街道
longitude2 = longitude + y2 / (111 * Math.cos(Z * Math.PI / 180));
// location1.setLatitude(latitude1);//城镇
// location1.setLongitude(longitude1);
//
// location2.setLatitude(latitude2);//街道
// location2.setLongitude(longitude2);
// Log.d("test1111","哈哈");
if (user1.contains(AN) == true) {// 如果应用在用户城镇级
flag = 1;
// Log.d("test222","哈哈");
} else {
if (user2.contains(AN) == true)
flag = 2;// 如果应用在用户街道级
else {
if (user3.contains(AN) == true)
flag = 3;// 如果应用在用户精确级
else {
if (default1.contains(AN) == true) {
Log.d("默认城镇级", "哈哈");
flag = 1;
} else {
if (default2.contains(AN) == true) {
Log.d("默认街道级", "哈哈");
flag = 2;
} else {
if (default3.contains(AN) == true) {
Log.d("默认精确级", "哈哈");
flag = 3;
} else {
flag = 0;
}
}
}
}
}
}
}
private LocationListener locationListener = new LocationListener() {
// 位置发生改变时调用 @Override
public void onLocationChanged(Location location) {
Log.d("Location", "onLocationChanged");
// handler.removeCallbacks(runnable);
}
// provider失效时调用 @Override
public void onProviderDisabled(String provider) {
Log.d("Location", "onProviderdisabled");
}
// provider启用时调用 @Override
public void onProviderEnabled(String provider) {
Log.d("Location", "onProviderEnabled");
Location.setLatitude(ltd_tmp);
Location.setLongitude(lng_tmp);
}
// 状态改变时调用 @Override
public void onStatusChanged(String provider, int status, Bundle extras) {
Log.d("Location", "onStatusChanged");
Location.setLatitude(ltd_tmp);
Location.setLongitude(lng_tmp);
}
};
void handleCommand(Intent intent) {
if (service.ACTION_FOREGROUND.equals(intent.getAction())) {
// In this sample, we'll use the same text for the ticker and the
// expanded notification
CharSequence text = getText(R.string.foreground_service_started);
// Set the icon, scrolling text and timestamp
Notification notification = new Notification(
R.drawable.ic_launcher, text, System.currentTimeMillis());
// The PendingIntent to launch our activity if the user selects this
// notification
// 用户点击service的通知时返回到主界面
PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
new Intent(this, TownactivityActivity.class), 0);
// Set the info for the views that show in the notification panel.
notification.setLatestEventInfo(this,
getText(R.string.local_service_label), text, contentIntent);
startForeground(1000, notification);
// startForegroundCompat(R.string.foreground_service_started,
// notification);
} else if (service.ACTION_BACKGROUND.equals(intent.getAction())) {
stopForegroundCompat(R.string.foreground_service_started);
}
}
public void onDestroy() {
Log.i(TAG, "this is ondestroy");
handler.removeCallbacks(runnable);
Toast.makeText(this, "service stopped", Toast.LENGTH_SHORT).show();
}
public boolean onUnbind(Intent intent) {
Log.i(TAG, "this is onUnbind");
return super.onUnbind(intent);
}
private void opDB() {
// 清空所有元素
user1.clear();
user2.clear();
user3.clear();
default1.clear();
default2.clear();
default3.clear();
// Log.d("1","test");
Cursor tmp1 = DB.select("USER1");
Cursor tmp2 = DB.select("USER2");
Cursor tmp3 = DB.select("USER3");
// Log.d("1","test");
if (tmp1.moveToFirst() == false)
;
else {
String T1 = tmp1.getString(1);
if (user1.contains(T1) == true)
;
else
user1.add(T1);
while (tmp1.moveToNext()) {
T1 = tmp1.getString(1);
if (user1.contains(T1) == true)
;
else
user1.add(T1);
// Log.d("test",T1);
}
}
if (tmp2.moveToFirst() == false)
;
else {
String T2 = tmp2.getString(1);
if (user2.contains(T2) == true)
;
else
user2.add(T2);
while (tmp2.moveToNext()) {
T2 = tmp2.getString(1);
if (user2.contains(T2) == true)
;
else
user2.add(T2);
// Log.d("test",T2);
}
}
if (tmp3.moveToFirst() == false)
;
else {
String T3 = tmp3.getString(1);
if (user3.contains(T3) == true)
;
else
user3.add(T3);
while (tmp3.moveToNext()) {
T3 = tmp3.getString(1);
if (user3.contains(T3) == true)
;
else
user3.add(T3);
// Log.d("test",T3);
}
}
}
}