一学期的课程设计又开始了,虽然以后不搞安卓,但是课设还是想好好完成的,因为之前做过地图开发,所以选了一个跟

这个相关的题目,其实有一个校车系统也可以选,但是之前做过一个相似度接近80%的东西,不想混混过关,就算了,这是题目

实现思路并不难,孩子端启动一个后台服务,每隔3分钟向后台服务器发送一次位置信息,后端保存,家长端通过时间段来获得孩子位置,实际上就是根据时间戳

来了,然后标注在家长端地图上,至于打电话什么的,调系统API就可以,从星期二到今天,将孩子端完成,后端完成,父亲端也差不多了,现在还有一个

难点就是最后的要求15分钟没有信息汇报就需要警告,还没搞清楚怎么实现...明天要考六级,今天得知软考挂了伤心死了,就差那么几分啊,要

是没看错最后的那个大题就过了

整个课设的技术包括:前端:安卓,七牛云SDK,Volley网络框架,百度地图SDK

后台:SpringBoot+Mybatis+mysql

现在记录一下每个三分钟发布一次信息的实现和上传头像的实现(之前还没弄过安卓上传文件所以想试试)

都知道安卓四大组件,其中service就是一个重要的东西,这里我说的是非绑定的service,它是不停的运行的,所以我们可以利用它来给我们的应用添加一些有趣的功能

比如我们退出软件仍旧下载东西就是用这个实现的,但是对于本题来讲,光是有服务是行不通的,我们还需要一个定时器,而且,还需要是稳定的,而不是那种退出APP就

停止的,综合考虑,当然是用AlarmManager了,他是安卓的系统服务,所以不会随着应用退出而停止,闹钟就是用这个来实现的.,AlarmManager如果参照网上的一些demo

基本都会遇到坑,因为谷歌官方更新了这个,用错了会有很大误差,这里推荐看一下这个博客:我也是看了他的

https://www.cnblogs.com/leipDao/p/8203684.html

从这个博客里了解到AlarmManager在安卓高版本里会有误差,但还好谷歌有新的API来对付误差,但定时的功能就不好实现了,那么这里采用的办法就是在调用一次之后在重新

发送,就达到了计时的目的

首先是一个工具类,负责实例化AlarmManager对象,唤醒闹钟

  1. import android.annotation.SuppressLint;
  2. import android.app.AlarmManager;
  3. import android.app.PendingIntent;
  4. import android.content.Context;
  5. import android.content.Intent;
  6. import android.os.Build;
  7. import android.util.Log;
  8.  
  9. import software.com.safelocatechild.BroadcastReceiver.LocateInfoReceiver;
  10.  
  11. /**
  12. * Created by 31786 on 2018/12/11.
  13. * 计时器,用于隔断时间发送自己的位置
  14. */
  15. public class AlarmManagerUtils {
  16.  
  17. private static final long TIME_INTERVAL = 15 * 1000;//闹钟执行任务的时间间隔
  18. private Context context;
  19. public static AlarmManager am;
  20. public static PendingIntent pendingIntent;
  21.  
  22. private AlarmManagerUtils(Context aContext) {
  23. this.context = aContext;
  24. }
  25.  
  26. private static AlarmManagerUtils instance = null;
  27.  
  28. public static AlarmManagerUtils getInstance(Context aContext) {
  29. if (instance == null) {
  30. synchronized (AlarmManagerUtils.class) {
  31. if (instance == null) {
  32. Log.d("Alarm","实例化");
  33. instance = new AlarmManagerUtils(aContext);
  34. }
  35. }
  36. }
  37. return instance;
  38. }
  39.  
  40. public void createGetUpAlarmManager() {
  41. Log.d("Alarm","创建");
  42. am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
  43. Intent intent = new Intent(context, LocateInfoReceiver.class);
  44. intent.putExtra("msg", "测试");
  45. pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);//每隔5秒发送一次广播
  46. }
  47.  
  48. @SuppressLint("NewApi")
  49. public void getUpAlarmManagerStartWork() {
  50. //版本适配
  51. Log.d("Alarm","开始工作");
  52. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {// 6.0及以上
  53. am.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP,
  54. System.currentTimeMillis(), pendingIntent);
  55. } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {// 4.4及以上
  56. am.setExact(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(),
  57. pendingIntent);
  58. } else {
  59. am.setRepeating(AlarmManager.RTC_WAKEUP,
  60. System.currentTimeMillis(), TIME_INTERVAL, pendingIntent);
  61. }
  62. }
  63.  
  64. @SuppressLint("NewApi")
  65. public void getUpAlarmManagerWorkOnReceiver() {
  66. //高版本重复设置闹钟达到低版本中setRepeating相同效果
  67. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {// 6.0及以上
  68. am.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP,
  69. System.currentTimeMillis() + TIME_INTERVAL, pendingIntent);
  70. } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {// 4.4及以上
  71. am.setExact(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()
  72. + TIME_INTERVAL, pendingIntent);
  73. }
  74. }
  75. }

  

在这时候,就是在服务里启动它,并且在一次计时过后重新开启一次计时,从而达到不断计时的目的

下面是个服务,负责发送广播,好像这样不太好,但我对这个不熟,先这样再说吧...

  1. import android.app.Service;
  2. import android.content.Intent;
  3. import android.os.IBinder;
  4. import android.util.Log;
  5.  
  6. import software.com.safelocatechild.activity.Welcome;
  7. import software.com.safelocatechild.util.AlarmManagerUtils;
  8.  
  9. public class LocateService extends Service {
  10. public LocateService() {
  11. }
  12.  
  13. @Override
  14. public void onCreate(){
  15. Log.d("-------","服务创建");
  16. super.onCreate();
  17. }
  18. @Override
  19. public int onStartCommand(Intent intent,int flagId,int startId){
  20. Log.d("-------","服务运行");
  21. // onStartCommand(intent,flagId,startId);
  22. testAlarm();
  23. return super.onStartCommand(intent,flagId,startId);
  24. }
  25. @Override
  26. public void onDestroy(){
  27. //发送结束信息,告知parent
  28. super.onDestroy();
  29. }
  30. @Override
  31. public IBinder onBind(Intent intent) {
  32. // TODO: Return the communication channel to the service.
  33. throw new UnsupportedOperationException("Not yet implemented");
  34. }
  35. public void testAlarm(){
  36. AlarmManagerUtils alarmManagerUtils = AlarmManagerUtils.getInstance(getApplicationContext());
  37. alarmManagerUtils.createGetUpAlarmManager();
  38. alarmManagerUtils.getUpAlarmManagerStartWork();
  39. }
  40. }

  

广播接收:

  1. package software.com.safelocatechild.BroadcastReceiver;
  2.  
  3. import android.content.BroadcastReceiver;
  4. import android.content.Context;
  5. import android.content.Intent;
  6. import android.content.SharedPreferences;
  7. import android.util.Log;
  8. import android.widget.Toast;
  9.  
  10. import com.android.volley.AuthFailureError;
  11. import com.android.volley.DefaultRetryPolicy;
  12. import com.android.volley.Request;
  13. import com.android.volley.RequestQueue;
  14. import com.android.volley.Response;
  15. import com.android.volley.VolleyError;
  16. import com.android.volley.toolbox.StringRequest;
  17. import com.android.volley.toolbox.Volley;
  18. import com.baidu.location.BDLocation;
  19. import com.baidu.location.LocationClient;
  20. import com.baidu.mapapi.map.BaiduMap;
  21.  
  22. import org.json.JSONException;
  23. import org.json.JSONObject;
  24.  
  25. import java.util.HashMap;
  26. import java.util.Map;
  27.  
  28. import software.com.safelocatechild.R;
  29. import software.com.safelocatechild.activity.Child;
  30. import software.com.safelocatechild.activity.Login;
  31. import software.com.safelocatechild.listener.LocationListener;
  32. import software.com.safelocatechild.util.AlarmManagerUtils;
  33. import software.com.safelocatechild.util.Const;
  34.  
  35. public class LocateInfoReceiver extends BroadcastReceiver {
  36.  
  37. @Override
  38. public void onReceive(final Context context, Intent intent) {
  39. // TODO: This method is called when the BroadcastReceiver is receiving
  40. String extra = intent.getStringExtra("msg");
  41. Log.d("---------------", "extra = " + extra);
  42. Log.d("-------","接收到了");
  43. LocationClient client = new LocationClient(context);
  44. client.registerLocationListener(new LocationListener(){
  45. /*
  46. * 通过GPS定位起点
  47. * */
  48. @Override
  49. public void onReceiveLocation(BDLocation location){
  50. System.out.print("LocationClient----");
  51. if (location!=null){
  52. //定时发送经纬度,写接口
  53. String childid = Const.context.getSharedPreferences("Setting",Context.MODE_MULTI_PROCESS).
  54. getString("childid","");
  55. Log.d("childid = ",childid);
  56. Log.d("Send longitude",location.getLongitude()+"");
  57. Toast.makeText(Const.context,childid+location.getLongitude()+"-"+location.getLatitude(),Toast.LENGTH_SHORT).show();
  58. //Log.d("Send latitude",location.getLatitude()+"");
  59. sendLocation(childid,location.getLatitude(),location.getLongitude());
  60. //再次启动闹钟
  61. AlarmManagerUtils.getInstance(context).getUpAlarmManagerWorkOnReceiver();
  62. }else {
  63. Log.d("location = ","null");
  64. }
  65.  
  66. }
  67. });
  68. client.start();
  69.  
  70. }
  71. //发送位置
  72. public boolean sendLocation(final String childid,final Double latitude, final Double longitude){
  73. //请求地址,需要换接口
  74. String url = Const.context.getResources().getString(R.string.insertLocation);
  75. String tag = "Login";
  76. //取得请求队列
  77. RequestQueue requestQueue = Volley.newRequestQueue(Const.context);
  78. //防止重复请求,所以先取消tag标识的请求队列
  79. requestQueue.cancelAll(tag);
  80. //创建StringRequest,定义字符串请求的请求方式为POST(省略第一个参数会默认为GET方式)
  81. StringRequest request = new StringRequest(Request.Method.POST, url,
  82. new Response.Listener<String>() {
  83. @Override
  84. public void onResponse(String response) {
  85. try {
  86. JSONObject jsonObject = new JSONObject(response);
  87. if(jsonObject.getBoolean("canInsert")){
  88. //等待接口
  89. Log.d("发送位置成功"," ");
  90. }else{
  91. Log.d("发送位置失败"," ");
  92. }
  93. } catch (JSONException e) {
  94. //做自己的请求异常操作,如Toast提示(“无网络连接”等)
  95. Log.d("LocateInfoReceiver","JsonException");
  96. }
  97. }
  98. }, new Response.ErrorListener() {
  99. @Override
  100. public void onErrorResponse(VolleyError error) {
  101. //做自己的响应错误操作,如Toast提示(“请稍后重试”等)
  102. Log.d("LocateInfoReceiver","VolleyError");
  103. }
  104. }) {
  105. @Override
  106. protected Map<String, String> getParams() throws AuthFailureError {
  107. Map<String,String> params = new HashMap<>();
  108. params.put("childid",childid);
  109. params.put("longitude",String.valueOf(longitude)); //注⑥
  110. params.put("latitude",String.valueOf(latitude));
  111. params.put("time",System.currentTimeMillis()+"");
  112. Log.d("位置发送时间",System.currentTimeMillis()+"");
  113. return params;
  114. }
  115.  
  116. };
  117.  
  118. //设置Tag标签
  119. request.setTag(tag);
  120. request.setRetryPolicy(new DefaultRetryPolicy(20*1000,1,1.0f));
  121. //将请求添加到队列中
  122. requestQueue.add(request);
  123. return true;
  124. }
  125. }

  

好了,从数据库里的结果来看,效果还行,但因为中途有时间损耗,肯定还是有一点影响的

之后再说上传图片,七牛云的使用就不多说了,官方有文档,我的做法是用TakePhoto框架得到图片,然后将图片化成能上传的格式

TakePhoto的使用我之前的博客里有讲:https://www.cnblogs.com/Yintianhao/p/9327191.html

重点的三个函数:一个上传,也就是里面有七牛云的上传和回调,还有一个将Bitmap图片转为byte数组,另一个就是获得一个随机名字

名字直接关系到取图片的链接,同时在我这个题目中也是存在用户信息表里面的

  1. //上传图片
  2. public void uploadImage(final Bitmap bitmap, String fileName) {
  3. //定义数据上传结束后的处理动作
  4. final UpCompletionHandler upCompletionHandler = new UpCompletionHandler() {
  5. @Override
  6. public void complete(String key, ResponseInfo info, JSONObject response) {
  7. headSculpture.setImageBitmap(bitmap);
  8. }
  9. };
  10. final UploadOptions uploadOptions = new UploadOptions(null, null, false, new UpProgressHandler() {
  11. @Override
  12. public void progress(String key, final double percent) {
  13. //百分数格式化
  14. NumberFormat fmt = NumberFormat.getPercentInstance();
  15. fmt.setMaximumFractionDigits(2);//最多两位百分小数,如25.23%
  16. }
  17. }, new UpCancellationSignal() {
  18. @Override
  19. public boolean isCancelled() {
  20. return false;
  21. }
  22. });
  23. try {
  24. //上传图片
  25. QiNiuInitialize.getSingleton().put(getByte(bitmap), fileName, getUpToken(), upCompletionHandler, uploadOptions);
  26. } catch (Exception e) {
  27. e.printStackTrace();
  28. }
  29. }
  30.  
  31. //通过UUID获得一个随机的文件名
  32. public String getRandomName(){
  33. String randomName = UUID.randomUUID().toString().replaceAll("-","")+".jpeg";
  34. return randomName;
  35. }
  36.  
  37. //获取图片的byte数组
  38. public byte[] getByte(Bitmap bm) {
  39. ByteArrayOutputStream baos = new ByteArrayOutputStream();
  40. bm.compress(Bitmap.CompressFormat.JPEG, 80, baos);
  41. return baos.toByteArray();
  42. }

  

好了,上传到这里,那么我们如何根据图片的链接来获取图片并显示在控件里呢,看这里:

  1. //根据URL获取图片,path即url
  2. public Bitmap getBitmap(String path) throws IOException {
    //严格模式否则会出错,具体作用可以查
  3. StrictMode.setThreadPolicy(new
  4. StrictMode.ThreadPolicy.Builder().detectDiskReads().detectDiskWrites().detectNetwork().penaltyLog().build());
  5. StrictMode.setVmPolicy(
  6. new StrictMode.VmPolicy.Builder().detectLeakedSqlLiteObjects().detectLeakedClosableObjects().penaltyLog().penaltyDeath().build());
  7. Log.d("path","="+path);
  8. try {
  9. URL url = new URL(path);
  10. HttpURLConnection conn = (HttpURLConnection) url.openConnection();
  11. conn.setConnectTimeout(5000);
  12. conn.setRequestMethod("GET");
  13. if (conn.getResponseCode() == 200) {
  14. InputStream inputStream = conn.getInputStream();
  15. Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
  16. return bitmap;
  17. }
  18. } catch (IOException e) {
  19. // TODO Auto-generated catch block
  20. e.printStackTrace();
  21. }
  22. return null;
  23. }

 

好了,先写到这了,听听听力准备明天的六级去了!!

AlarmManager的使用和七牛云android SDK上传图片的更多相关文章

  1. PHP 下载七牛云的sdk

    1,语法 composer require qiniu/php-sdk 2,出现以下图片内容就是下载七牛云的sdk成功

  2. 在ThinkPHP框架(5.0.24)下引入Ueditor并实现向七牛云对象存储上传图片同时将图片信息保存到MySQL数据库,同时实现lazyload懒加载

    这是我花了很多天的时间才得以真正实现的一组需求. 文章后面有完整Demo的GitHub链接. 一. 需求描述 1. 应用是基于ThinkPHP5开发的: 2. 服务器环境是LNMP,PHP版本是7.2 ...

  3. 七牛云 PHP SDK服务器鉴权失败!参数解释

    昨天搞了一下午,用7牛官方的SDK demo 1.上传凭证 $policy = array( 'callbackUrl' => 'http://api.example.com/qiniu/upl ...

  4. BAE Flask UEditor 使用七牛云

    1. 配置BAE支持七牛云的SDK BAE的python requirements当然不支持竞争对手了. 解决方法: 把qiniu这个文件包直接放置在你项目的目录中(与其他app同级) 运行会发现缺少 ...

  5. Python实现七牛云视频播放

    这篇文章是使用Python的Web框架Django Rest Framework来提供视频相关的api接口,主要功能包括视频上传.视频转码.视频访问授权.删除视频文件.视频截图功能. 七牛云上的基本概 ...

  6. SpringSpringBoot上传文件到七牛云

    准备工作 maven pom.xml添加七牛云的sdk依赖 <dependency> <groupId>com.qiniu</groupId> <artifa ...

  7. php利用七牛云的对象存储完成图片上传-高效管理图片

    在搭建个人博客时,大家都会买一台云服务器.可是图片的存放一直是一个问题,冷月帮大家找到一个免费的第三方平台对象存储-七牛云.大家可以把图片上传到七牛云的对象存储,大大节约服务器的压力. 首先,大家在使 ...

  8. Android开发中使用七牛云存储进行图片上传下载

    Android开发中的图片存储本来就是比较耗时耗地的事情,而使用第三方的七牛云,便可以很好的解决这些后顾之忧,最近我也是在学习七牛的SDK,将使用过程在这记录下来,方便以后使用. 先说一下七牛云的存储 ...

  9. 七牛云存储Python SDK使用教程 - 上传策略详解

    文 七牛云存储Python SDK使用教程 - 上传策略详解 七牛云存储 python-sdk 七牛云存储教程 jemygraw 2015年01月04日发布 推荐 1 推荐 收藏 2 收藏,2.7k  ...

随机推荐

  1. [leetcode]15. 3Sum三数之和

    Given an array nums of n integers, are there elements a, b, c in nums such that a + b + c = 0? Find ...

  2. centos7 下安装pycharm

    CentOS 7环境下Pycharm安装流程记录: 1.准备安装文件: 方法1: 使用内置火狐浏览器访问下载最新格式为tar.gz的压缩包 网址:https://www.jetbrains.com/p ...

  3. java 远程debug

    在启动jar包添加如下参数16091是端口 java -Xdebug -Xrunjdwp:transport=dt_socket,address=16091,server=y,suspend=n -j ...

  4. arguments.callee的作用及替换方案

    arguments.callee的作用 arguments 的主要用途是保存函数参数, 但这个对象还有一个名叫 callee 的属性,返回正被执行的 Function 对象,也就是所指定的 Funct ...

  5. C#部分试题实例

    1.在C#中,下列选项中自定义方法的语句错误的是().(选择一项) 正确答案:AD 解析:本题考查自定义方法的定义及调用.A项void是无返回值类型,D项定义方法的时候没有写返回值类型:故选AD. 2 ...

  6. spring-boot json数据交互

    SpringBoot学习之Json数据交互 最近在弄监控主机项目,对javaweb又再努力学习.实际的项目场景中,前后分离几乎是所以项目的标配,全栈的时代的逐渐远去,后端负责业务逻辑处理,前端负责数据 ...

  7. 关于java poi itext生成pdf文件的例子以及方法

    最近正在做导出pdf文件的功能,所以查了了一些相关资料,发现不是很完善,这里做一些小小的感想,欢迎各位“猿”童鞋批评指正. poi+itext,所需要的jar包有itext-2.1.7.jar,poi ...

  8. adb Android Debug Bridge 安卓调试桥

    adb devices 获取设备列表及设备状态 adb get-state 获取设备的状态,设备的状态有 3 钟,device , offline , unknown device:设备正常连接 of ...

  9. Clion pycharm激活码(可使用到2019年2月)

    D87IQPUU3Q-eyJsaWNlbnNlSWQiOiJEODdJUVBVVTNRIiwibGljZW5zZWVOYW1lIjoiTnNzIEltIiwiYXNzaWduZWVOYW1lIjoiI ...

  10. The Python Challenge 0-4

    The Python Challenge 0-4 项目地址:http://www.pythonchallenge.com/ Level-0 提示Hint: try to change the URL ...