2 wto1314159 wto1314159 于 2014.06.03 15:22 提问

“构造一个虚拟位置信息给谷歌地图,让其定位错误”失败
用以下代码“构造一个虚拟位置信息给谷歌地图,让其定位错误”无法实现,给位大神指点迷津,小弟开始研究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);
        }
    }


}

}

Csdn user default icon
上传中...
上传图片
插入图片