文档章节

Android 蓝牙防丢(二)

iSnowFlake
 iSnowFlake
发布于 2015/10/17 17:40
字数 1973
阅读 1195
收藏 6
点赞 0
评论 0

 

github 源码: https://github.com/AnyLifeZLB/Bluetooth-AntiLost

 

Demo 地址:https://play.google.com/store/apps/details?id=com.bipbip.ble  (翻墙下载)

 

/**
 * 防丢核心算法,早期整理版本不完善,根据自身业务完善,
 * @anylife.zlb@gmail.com
 */

public class BlePreventLostCore {
 private static String TAG=BlePreventLostCore.class.getSimpleName();
 private final  static int leastNum=3; // 设备采集到的SSID[] size>3才是有意义的值
 private final  static double deviateBaseFlag=0.1; //
 private final  static double WCF=0.5;         //Weight Compensation Flag,权重补偿因子
 
 private static Map<String,List<Integer>> sacnedBleDevicesData;
 /**
  * 去除采集到数据中的脏值
  * deviateBaseFlag 为基准的脏值偏移标志,如果长度比较大的话,可以适当的加大             
  * 先简单的以算术平均数作为参照,大于average 的deviateBaseFlag*average 就判断是脏值。
  * 
  * 
  */
 public static void clearDigest() {
//  double deviateFlag=0.2**……&&N; //
  Map<String,Double> sAverageSSID=new HashMap<>();   //简单算术平均数
  Set<String> ks =sacnedBleDevicesData.keySet();
  
  //求对应手表的算术平均数。
  for(String key : ks ){
   double average=0.0;   
   List<Integer> ssidList=sacnedBleDevicesData.get(key);
   int size=sacnedBleDevicesData.get(key).size();
   for(int i=0;i<size;i++){
    average=average+ssidList.get(i);
   }   
   average=(double)average/size;
   sAverageSSID.put(key, average);  
  }
  
  //去除脏值。
  for(String key : ks ){
//   double average=0.0;   
   List<Integer> ssidList=sacnedBleDevicesData.get(key);
   int size=sacnedBleDevicesData.get(key).size();
   if(size>leastNum){
    double averageTemp=sAverageSSID.get(key);
    while(--size!=-1){
     Log.e(TAG,key+"i: "+size);
     if(Math.abs(ssidList.get(size)-averageTemp) >  Math.abs(deviateBaseFlag*averageTemp)){
      Log.d(TAG,key+"移除 脏值索引 i: "+size);
      ssidList.remove(size);
     }
    } 
    sacnedBleDevicesData.put(key, ssidList);
   }
  }
  
 }
 
 /**
  * ssid 对用的权重分布[... , ...]
  * 
  * @return
  */
 public static Map<String,List<Double>> getWeghtCompensationMap(){
  Map<String,List<Double>> weghtCompensationDatas =  new HashMap<String,List<Double>>(); //权数分布
//  Map<String,Double>  weghtCompensationDecreasing; //权重递减因子
  //1.初始化权数分布
  Set<String> ks =sacnedBleDevicesData.keySet();
  for(String key : ks ){
   final int size=sacnedBleDevicesData.get(key).size();
   List<Double> weghtCompDataList=new ArrayList<Double>(size-1);
   if(size>leastNum){
    //1.权重分布的前半部分初始化
    for(int i=0;i<size;i++){
                 double decreasing=WCF-WCF*2*(i+1)/size;
     if(decreasing>0&&i<size/2){
      weghtCompDataList.add(i, decreasing);
     }else{
      weghtCompDataList.add(i, (double) 0);
     }
    }
    
    //2.权重分布的后半部分初始化
    for(int j=size-1;j>size/2;j--){
     double temp=weghtCompDataList.get(size-j-1);
     weghtCompDataList.set(j,temp);
    }
 
    //3.权重分布的 实际处理
    for(int i=0;i<size/2;i++){
     weghtCompDataList.set(i, (1-weghtCompDataList.get(i))/size);
    }
    for(int j=size-1;j>size/2;j--){
     weghtCompDataList.set(j, (1+weghtCompDataList.get(j))/size);
    }
    
    //4.权重分布的 中位数实际处理
    if(size%2==0){
     weghtCompDataList.set(size/2,1.0/size);
    }else{
     weghtCompDataList.set(size/2, 1.0/size);
     weghtCompDataList.set(size/2-1, 1.0/size);
    }
    
    //5.权重分布测试,相加应该无限接近    100/100=1
    double test=0;
    for(int s=0;s<size;s++){
     test=test+weghtCompDataList.get(s);
    }
    Log.e(TAG,key+" test 和: "+test);
   }else{
    for(int k=0;k<size;k++){
     weghtCompDataList.add(k, 1.0/size);
    }
   }
   weghtCompensationDatas.put(key, weghtCompDataList);
  }//权重分布完成

 /**
  * 时间越后,权重越大
  * 
  * @param sacnedBleDD
  * @return
  */
 public static Map<String,Double> getDeviceState(final Map<String,List<Integer>> sacnedBleDD){
  sacnedBleDevicesData=sacnedBleDD;
  clearDigest(); //去除脏值
  
  Map<String,List<Double>> weightCompensation=getWeghtCompensationMap();      //权数分布因子 
  Log.e(TAG,"  "+weightCompensation);
  
  Map<String,Double> averageSSID=new HashMap<>();
  Set<String> ks =sacnedBleDevicesData.keySet();
  for(String key : ks ){
   double average=0.0;
   List<Double> weghtCompDataList=weightCompensation.get(key);
   List<Integer> ssidList=sacnedBleDevicesData.get(key);
   for(int i=0;i<weghtCompDataList.size();i++){
    average=average+weghtCompDataList.get(i)*ssidList.get(i);
   }   
   
   Log.d(TAG,key+" 加权算术平均:"+average);
   averageSSID.put(key, average);  
   //bingo.
  }
  return averageSSID;
 }
}

 

Activity

package com.bipbip.ble;

import com.bipbip.main.BaseActivity;

/**
 * 
 * 
 * @author anylife.zlb@gmail.com
 */
@SuppressLint("NewApi")
public class BlePreventLostActivity extends BaseActivity implements OnClickListener{
    private String TAG=BlePreventLostActivity.class.getSimpleName();
    private TextView instruction_tips; 
    private ListView bleListView;
    
    //已经扫描出来的设备列表集Set,自定义obj是否重复
    private List<BleDevice> findedBleDevicesList = new ArrayList<BleDevice>(); 
    
    private List<BleDevice> sacnedBleDevicesList = new ArrayList<BleDevice>();              

    //已经扫描出来的设备(MAC作为Key)数据集合(List<?>   ?需要是BleDevice?不如integer  )
    private Map<String,List<Integer>> sacnedBleDevicesData = new HashMap<String,List<Integer>>();

    private BleDeviceListAdapter mDeviceListAdapter;
    private BluetoothAdapter mBluetoothAdapter;
    private boolean mFindDevice=true;  //true : 刚刚进入蓝牙防丢的设备扫描阶段;    false:对扫描出来的设备进行蓝牙防丢
    private boolean mLiveDevice=false;  //true : 刚刚进入蓝牙防丢的设备扫描阶段;    false:对扫描出来的设备进行蓝牙防丢

    private Handler mHandler;
    private DeviceLiveThread deviceLiveThread;
    private static final int REQUEST_ENABLE_BT = 1;
    // Stops scanning after 10 seconds.
    private static final long SCAN_PERIOD = 1000*10;       //点击开始扫描后的10秒停止扫描
    private static final long LIVE_PERIOD = 1000*7;       //点击开始扫描后的10秒停止扫描

    @Override
    public void onCreate(Bundle savedInstanceState) {    //
        super.onCreate(savedInstanceState);
        setContentView(R.layout.ble_prevent_lost);
        instruction_tips=(TextView) findViewById(R.id.instruction_tips);
        instruction_tips.setOnClickListener(this);
        bleListView=(ListView) findViewById(R.id.ble_device_list);
   
        // Initializes list view adapter.
        mDeviceListAdapter =new BleDeviceListAdapter(this,findedBleDevicesList);// new mDeviceListAdapter(this);
        bleListView.setAdapter(mDeviceListAdapter);

        mHandler = new Handler();
        // Use this check to determine whether BLE is supported on the device.  Then you can
        // selectively disable BLE-related features.
        
        //如果手机不支持蓝牙4.0,api>18. 那么直接退出
        if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
            Toast.makeText(this, R.string.ble_not_supported, Toast.LENGTH_SHORT).show();
            finish();
        }
   
        // Initializes a Bluetooth adapter.  For API level 18 and above, get a reference to
        // BluetoothAdapter through BluetoothManager.
        final BluetoothManager bluetoothManager =(BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
        mBluetoothAdapter = bluetoothManager.getAdapter();

        // Checks if Bluetooth is supported on the device.
        if (mBluetoothAdapter == null) {
            Toast.makeText(this, R.string.error_bluetooth_not_supported, Toast.LENGTH_SHORT).show();
            finish();
            return;
        }
        
        Log.e(TAG," test"+BleDeviceState.UNKNOW.getStateName());
        
        findDevice(true);
            
    }
     
    
    /**
     * 扫描设备蓝牙设备
     * 
     * 
     * @param enable  
     *        true:扫描设备,并在SCAN_PERIOD后停止         
     *        false:不扫描,直接就停止了(在onPause中停止了)
     */
    private void findDevice(final boolean enable) {
        if (enable) {
            
            setInstructStytle(true);
            mFindDevice = true;
            mBluetoothAdapter.startLeScan(mLeScanCallback);   //开始扫描设备    
            mDeviceListAdapter.notifyDataSetChanged();

            mHandler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    Log.d(TAG,"\n\n设备个数:"+findedBleDevicesList.size()+"\n设备信息 :\n"+findedBleDevicesList.toString());
                    if(mFindDevice){
                        if(findedBleDevicesList!=null&&findedBleDevicesList.size()>0){
                            instruction_tips.setVisibility(View.VISIBLE);
//                            findedBleDevicesList -->  sacnedBleDevicesData
                            
                            for(int i=0;i<findedBleDevicesList.size();i++){
                                List<Integer> tempList=new ArrayList<Integer>();
                                tempList.add(findedBleDevicesList.get(i).getSsid());
                                sacnedBleDevicesData.put(findedBleDevicesList.get(i).getMacAddr(), tempList);
                            }
                          
                        }              
                    }
                    mBluetoothAdapter.stopLeScan(mLeScanCallback);

                    mFindDevice=false;
                    invalidateOptionsMenu();
                    
                }
            }, SCAN_PERIOD);

        } else {
            setInstructStytle(false);
            mFindDevice = false;
            mBluetoothAdapter.stopLeScan(mLeScanCallback);
        }
          
      invalidateOptionsMenu();

    }
    
    /** 
     * Device scan callback.
     * 
     * if you call  [mBluetoothAdapter.startLeScan(mLeScanCallback);]this will call back.
     * 
     */
    private BluetoothAdapter.LeScanCallback mLeScanCallback =
            new BluetoothAdapter.LeScanCallback() {
        @Override
        public void onLeScan(final BluetoothDevice device, final int rssi, final byte[] scanRecord) {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    Log.e(TAG,"设备"+device.getName()+"    Rssi强度:"+rssi+" "+device.getAddress());
                    BleDevice bleDevice=new BleDevice(0, device.getName(), device.getAddress(), "uuid", rssi, device.getBondState(), device.getType());                    
                    
                    if(mFindDevice){ //处于第一次的发现设备阶段
                        if(findedBleDevicesList!=null&&!findedBleDevicesList.contains(bleDevice)){
                            findedBleDevicesList.add(bleDevice);
                            mDeviceListAdapter.notifyDataSetChanged();
                        }
                    }else{
                           
                        //
                        if(sacnedBleDevicesList!=null&&!sacnedBleDevicesList.contains(bleDevice)){
                            sacnedBleDevicesList.add(bleDevice);
//                            mDeviceListAdapter.notifyDataSetChanged();
                        }
                        
                        //2. 向MAC 地址对应的List<Integer> 添加一个值。
                        List<Integer> bleDevices=sacnedBleDevicesData.get(bleDevice.getMacAddr());
                        if(null==bleDevices){
                            bleDevices=new ArrayList<Integer>();
                        }
                        bleDevices.add(rssi);
                        sacnedBleDevicesData.put(bleDevice.getMacAddr(), bleDevices);    
                    }
                  }
            });
        }
    };

    
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        // User chose not to enable Bluetooth.
        if (requestCode == REQUEST_ENABLE_BT && resultCode == Activity.RESULT_CANCELED) {
            finish();
            return;
        }
        super.onActivityResult(requestCode, resultCode, data);
    }
    
    /**
     * 设置一些样式
     * 
     * @param needReScan
     */
    private void setInstructStytle(boolean needReScan){
        
        if(needReScan){
            instruction_tips.setVisibility(View.INVISIBLE);
            mDeviceListAdapter.clear(); 
        }else{//要那种慢慢显示出来的效果
            instruction_tips.setVisibility(View.VISIBLE);
        }
            
    }
    
    
    
    public class DeviceLiveThread extends Thread {
        private boolean isRunning=true;
        
        private void stopThread(){
            isRunning=false;
        }
        
        @Override
        public void run() {
            // TODO Auto-generated method stub
            while(isRunning){
                if(mLiveDevice){
                    Log.d(TAG,"统计结果,采集数据为==================\n");
                    Set<String> keyset=sacnedBleDevicesData.keySet();
                    for(String key:keyset){
                        Log.e(TAG,"size="+sacnedBleDevicesData.get(key).size()+" "+sacnedBleDevicesData.get(key));
                    }
                    Log.d(TAG,"统计结束,清除本次统计*****************************************************\n");
                    
                    if(null!=sacnedBleDevicesData&&sacnedBleDevicesData.size()>0){
                        Map<String,Double> rssiValueList=BlePreventLostCore.getDeviceState(sacnedBleDevicesData); //根据换回的结果统计
                        displayLiveResult(rssiValueList);
                        rssiValueList.clear();
                        sacnedBleDevicesData.clear();//一次分析完后,清除
                    } else{  //上一次分析完后再也没有采集到数据,全部丢失
                        displayLiveResult(null);
                    }

                    try {
                        Thread.sleep(LIVE_PERIOD);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }else{
                    try {
                        Thread.sleep(LIVE_PERIOD);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }

            }    
        }
    }
    
    
    
    /**
     * 开始进入
     * 
     */
    private void startDeviceLiving(){
        if(deviceLiveThread==null){
            deviceLiveThread=new DeviceLiveThread();
            deviceLiveThread.start();
        }
    }
    
    /**
     * 更新数据显示的结果
     * 
     * @param rssiValueList
     */
    private void displayLiveResult(Map<String,Double> rssiValueList){
        
        //0.处理异常的情况
        if(null==rssiValueList||rssiValueList.size()==0){
            int size=findedBleDevicesList.size();
            for(int i=0;i<size;i++){
                findedBleDevicesList.get(i).setSsid(0);
            }
        }else{
            
            //1.处理返回来的适配数据
            Set<String> keySet=rssiValueList.keySet();
            int size=findedBleDevicesList.size();
            for(int i=0;i<size;i++){
                String findedDeviceKey=findedBleDevicesList.get(i).getMacAddr(); //
                if(keySet.contains(findedDeviceKey)){ //假如以前扫描到的设备在监听阶段还是存在,那么重新赋值RSSI,否则丢失了
                    findedBleDevicesList.get(i).setSsid(rssiValueList.get(findedDeviceKey).intValue());
                }else{  //置设备状态为丢失,震动报警
                    findedBleDevicesList.get(i).setSsid(0);
                }
            }
        }
        
        //2.更新显示数据。
        runOnUiThread(new Runnable() {
            
            @Override
            public void run() {
                // TODO Auto-generated method stub
                mDeviceListAdapter.notifyDataSetChanged();
            }
        });
    }

    @Override
    public void onClick(View v) {
        // TODO Auto-generated method stub
        switch (v.getId()) {
        case R.id.instruction_tips:
            mLiveDevice=!mLiveDevice;
            invalidateOptionsMenu();
                                        
            if(mLiveDevice){
                instruction_tips.setText(R.string.device_live_stop);
                mBluetoothAdapter.startLeScan(mLeScanCallback);   //开始扫描设备    
                startDeviceLiving();
            }else{
                instruction_tips.setText(R.string.device_live_start);
                mBluetoothAdapter.stopLeScan(mLeScanCallback);   //开始扫描设备    
                stopDeviceLiving();
            }

            break;
        default:
            break;
        }
    }

      
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.blemenu, menu);
        if(mLiveDevice){
            menu.findItem(R.id.menu_stop).setVisible(false);
            menu.findItem(R.id.menu_scan).setVisible(false);
            menu.findItem(R.id.menu_refresh).setActionView(null);
        }else if (!mFindDevice) {
            menu.findItem(R.id.menu_stop).setVisible(false);
            menu.findItem(R.id.menu_scan).setVisible(true);
            menu.findItem(R.id.menu_refresh).setActionView(null);
        } else {
            menu.findItem(R.id.menu_stop).setVisible(true);
            menu.findItem(R.id.menu_scan).setVisible(false);
            menu.findItem(R.id.menu_refresh).setActionView(
                    R.layout.actionbar_indeterminate_progress);
        }
        return true;
    }
             
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.menu_scan:
                findDevice(true);
                break;
            case R.id.menu_stop:
                findDevice(false);
                break;
        }
        return true;
    }
    
    private long exitTime = 0;
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if(keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN){
            if((System.currentTimeMillis()-exitTime) > 2000){
                Toast.makeText(getApplicationContext(), R.string.double_return_exit, Toast.LENGTH_SHORT).show();   
                exitTime = System.currentTimeMillis();
            }else{
                BlePreventLostActivity.this.finish();
            }
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }
       
    
    
    //========================Activity life cycle=======================================================
    
      @Override
      protected void onStart(){
          super.onStart();        
          Log.e(TAG,"*************onStart");
        // Ensures Bluetooth is enabled on the device.  If Bluetooth is not currently enabled,
        // fire an intent to display a dialog asking the user to grant permission to enable it.
        if (!mBluetoothAdapter.isEnabled()) {
            if (!mBluetoothAdapter.isEnabled()) {
                Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
            }  
        }
      }

      @Override
      protected void onRestart(){
          super.onRestart();

      }
    
    @Override
    protected void onResume() {
        super.onResume();

    }

    @Override
    protected void onPause() {
        super.onPause();
        Log.e(TAG,"onPause");
    }

      @Override
      protected void onStop() {
          super.onStop();
          Log.e(TAG,"*************onStop");
      }

      @Override
      protected void onDestroy(){
          super.onDestroy();
          Log.e(TAG,"*************onDestroy");
        if(deviceLiveThread!=null){
            deviceLiveThread.stopThread();
        }
          mLiveDevice=false;
          findDevice(false);
        sacnedBleDevicesList.clear();
        findedBleDevicesList.clear();
        sacnedBleDevicesData.clear();
        mDeviceListAdapter.notifyDataSetChanged();
      }   
}

 

 

© 著作权归作者所有

共有 人打赏支持
iSnowFlake
粉丝 32
博文 80
码字总数 53599
作品 0
深圳
高级程序员
android -------- 蓝牙Bluetooth

什么是蓝牙? 也可以说是蓝牙技术。所谓蓝牙(Bluetooth)技术,实际上是一种短距离无线电技术,是由爱立信公司公司发明的。利用“蓝牙”技术,能够有效地简化掌上电脑、笔记本电脑和移动电话手...

切切歆语 ⋅ 04/17 ⋅ 0

Android蓝牙库-FastBle的简易使用

发布自Kindem的博客,欢迎大家转载,但是要注意注明出处 最近在做物联网课设,过程中需要用到Android的蓝牙API,奈何原生的蓝牙API使用有点麻烦。于是上网搜索看有没有好用的Android蓝牙库,...

Kindem ⋅ 05/25 ⋅ 0

Android项目实战(四十五):Usb转串口通讯(CH34xUARTDriver)

需求为:手机usb接口插入一个硬件,从硬件上获取数据 例如:手机usb插入硬件A,A通过蓝牙通讯获取设备a、b的数据,作为中转站(可以做些数据处理)将数据(设备a、b产生的)传给手机程序。 ...

听着music睡 ⋅ 04/28 ⋅ 0

Android 蓝牙防丢实现(一)

今天看见朋友分享的一个项目:TrackR bravo 一个声称是同类产品中最轻薄小巧的蓝牙物品防丢器,金属材质的外壳,厚度为3.5mm,直径34mm,仅有一元硬币大小。可以系在钥匙串、钱包、手机、平板...

iSnowFlake ⋅ 2015/10/15 ⋅ 0

android studio 编译缓存

现象:能编译生成apk,但是编译器中找不到新代码。无论是clean还是invalidate Caches /restart 还是到.android将build-cache删除,或者是更改gradle的service directory path都无效。 尝试以...

jimmy2012 ⋅ 05/24 ⋅ 0

微信智能跑鞋技术解密

微信硬件平台官方最近发布了一款接入微信的智能跑鞋,借力微信社交进行品牌营销。相比之前运动手环一般通过微信精简协议来接入微信运动,智能跑鞋是使用微信蓝牙airsync协议实现接入,其支持...

yueqian_scut ⋅ 2016/07/01 ⋅ 0

Windows 10 新功能 Nearby Share 支持 Android 、iOS

Windows 10 April Update 中引入了诸多新功能,其中一项功能是 Nearby Share/Near Share,它可让用户轻松地将文件从一台 Windows 10 PC 传输到另一台,在 Build 2018 大会上,微软确认该功能...

雨田桑 ⋅ 05/15 ⋅ 0

仓库pda app开发,android系统

任务描述: 仓库pda app开发android系统,我方出接口 开发周期: 1.兼职时间:20~30个工作日。 2.兼职人员要求深圳地区,坐班 人员要求: 1. 两年以上Android开发经验。 2. 沟通能力较强 3....

封生 ⋅ 05/16 ⋅ 0

AndroidThings之基础二 设计理念

转载自:https://blog.csdn.net/tangxiaoyin/article/details/75273491 (PS:目前AndroidThings已经走向消费级别,发布正式版本1.0版,开发板推荐树莓派3B+) 前言 2012 年 6 月,由 IoT-GSI(...

qq_28831197 ⋅ 05/09 ⋅ 0

介绍TTC CC2541 SDK 蓝牙4.0开发套件

简介 TTC CC2541 SDK 是由我司针对TI的CC2541芯片开发提供的快速开发工具。旨在让开发人员不再需要将大量精力放在蓝牙调试方面,只需将精力放在对CC2541芯片功能的应用开发上。 TTC CC2541 S...

昇润科技 ⋅ 05/21 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

RabbitMQ学习以及与Spring的集成(三)

本文介绍RabbitMQ与Spring的简单集成以及消息的发送和接收。 在RabbitMQ的Spring配置文件中,首先需要增加命名空间。 xmlns:rabbit="http://www.springframework.org/schema/rabbit" 其次是模...

onedotdot ⋅ 17分钟前 ⋅ 0

JAVA实现仿微信红包分配规则

最近过年发红包拜年成为一种新的潮流,作为程序猿对算法的好奇远远要大于对红包的好奇,这里介绍一种自己想到的一种随机红包分配策略,还请大家多多指教。 算法介绍 一、红包金额限制 对于微...

楠木楠 ⋅ 29分钟前 ⋅ 0

Python 数电表格格式化 xlutils xlwt xlrd的使用

需要安装 xlutils xlwt xlrd 格式化前 格式化后 代码 先copy读取的表格,然后按照一定的规则修改,将昵称中的学号提取出来替换昵称即可 from xlrd import open_workbookfrom xlutils.copy ...

阿豪boy ⋅ 59分钟前 ⋅ 0

面试题:使用rand5()生成rand7()

前言 读研究生这3 年,思维与本科相比变化挺大的,这几年除了看论文、设计方案,更重要的是学会注重先思考、再实现,感觉更加成熟吧,不再像个小P孩,人年轻时总会心高气傲。有1 道面试题:给...

初雪之音 ⋅ 59分钟前 ⋅ 0

Docker Toolbox Looks like something went wrong

Docker Toolbox 重新安装后提示错误:Looks like something went wrong in step ´Checking if machine default exists´ 控制面板-->程序与应用-->启用或关闭windows功能:找到Hyper-V,如果处......

随你疯 ⋅ 今天 ⋅ 0

Guacamole 远程桌面

本文将Apache的guacamole服务的部署和应用,http://guacamole.apache.org/doc/gug/ 该链接下有全部相关知识的英文文档,如果水平ok,可以去这里仔细查看。 一、简介 Apache Guacamole 是无客...

千里明月 ⋅ 今天 ⋅ 0

nagios 安装

Nagios简介:监控网络并排除网络故障的工具:nagios,Ntop,OpenVAS,OCS,OSSIM等开源监控工具。 可以实现对网络上的服务器进行全面的监控,包括服务(apache、mysql、ntp、ftp、disk、qmail和h...

寰宇01 ⋅ 今天 ⋅ 0

AngularDart注意事项

默认情况下创建Dart项目应出现以下列表: 有时会因为不知明的原因导致列表项缺失: 此时可以通过以下步骤解决: 1.创建项目涉及到的包:stagehand 2.执行pub global activate stagehand或pub...

scooplol ⋅ 今天 ⋅ 0

Java Web如何操作Cookie的添加修改和删除

创建Cookie对象 Cookie cookie = new Cookie("id", "1"); 修改Cookie值 cookie.setValue("2"); 设置Cookie有效期和删除Cookie cookie.setMaxAge(24*60*60); // Cookie有效时间 co......

二营长意大利炮 ⋅ 今天 ⋅ 0

【每天一个JQuery特效】淡入淡出显示或隐藏窗口

我是JQuery新手爱好者,有时间就练练代码,防止手生,争取每天一个JQuery练习,在这个博客记录下学习的笔记。 本特效主要采用fadeIn()和fadeOut()方法显示淡入淡出的显示效果显示或隐藏元...

Rhymo-Wu ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部