精华内容
下载资源
问答
  • 自动检测技术 自动检测技术自动检测技术自动检测技术
  • MATLAB 实现的物体自动检测、自动分割、自动识别,可以运行,实现一些简单物体的提取!!
  • Tracker服务器是对于BT下载必须的,网上...提供的服务器在中国都ping得通,每24小时自动更新,自动检测,从几个百服务器筛选出在中国可通的服务器列表。 [下载中国可用Tracker服务器列表-每24小时更新 ] 提供的服务...

    Tracker服务器是对于BT下载必须的,网上随便搜索一下就有很多Tracker服务器列表,一个服务器文件少则几十个,多则上百个,但"杂乱无章",要不就是用不了,要不就是在中不可用,要不就是重复,真正能用的就比较少了。

    提供的服务器在中国都ping得通,每24小时自动更新,自动检测,从几个百服务器筛选出在中国可通的服务器列表。

    [下载中国可用Tracker服务器列表-每24小时更新 ]

    提供的服务器在中国都ping得通,每24小时自动更新,自动检测,从几个百服务器筛选出在中国可通的服务器列表

    以下服务器列表,非24小时自动更新

    序号服务器
    1udp://208.83.20.20:6969/announce
    2udp://62.171.179.41:80/announce
    3udp://www.loushao.net:8080/announce
    4udp://retracker.sevstar.net:2710/announce
    5udp://tracker.yoshi210.com:6969/announce
    6udp://211.20.153.139:6969/announce
    7http://tracker.skyts.cn:6969/announce
    8udp://explodie.org:6969/announce
    9udp://exodus.desync.com:6969/announce
    10https://t3.leech.ie:443/announce
    11udp://tracker.btsync.gq:6969/announce
    12http://www.elitezones.ro/announce.php
    13https://tracker.sloppyta.co:443/announce
    14http://tracker.gigatorrents.ws:2710/announce
    15http://mvgroup.org:2710/announce
    16udp://46.148.18.254:2710/announce
    17http://torrents-nn.cn:2710/announce
    18udp://173.82.240.104:6969/announce
    19udp://tracker.army:6969/announce
    20http://data-bg.net/announce.php
    21http://159.89.208.145:8866/announce
    22udp://5.206.3.65:6969/announce
    23http://www.mvgroup.org:2710/announce
    24http://93.158.213.92:1337/announce
    25udp://tracker.tiny-vps.com:6969/announce
    26udp://tracker.opentrackr.org:1337/announce
    27udp://tracker3.itzmx.com:6961/announce
    28http://tracker.nyap2p.com:8080/announce
    29http://tracker.torrentleech.org:2710/announce
    30http://tracker.funfile.org:2710/announce
    31udp://tracker.tntvillage.scambioetico.org:2710/announce
    32http://mediaclub.tv/announce.php
    33udp://open.nyap2p.com:6969/announce
    34udp://qg.lorzl.gq:6969/announce
    35udp://p4p.arenabg.com:1337/announce
    36udp://220.173.37.226:6969/announce
    37https://t1.leech.ie:443/announce
    38udp://37.235.174.46:2710/announce
    39udp://tracker.skyts.net:6969/announce
    40http://mixfiend.com/announce.php
    41wss://tracker.novage.com.ua:443/announce
    42udp://xxxtor.com:2710/announce
    43http://share.camoe.cn:8080/announce
    44http://bt.ali213.net:8000/announce
    45http://datascene.net:80/announce.php
    46udp://31.210.170.169:2710/announce
    47udp://tracker.torrent.eu.org:451/announce
    48https://tracker.nanoha.org:443/announce
    49http://51.38.230.101:80/announce
    50http://www.thegeeks.bz:3210/announce
    51http://www.blackcats-games.net:2228/announce
    52http://www.xwt-classics.net/announce.php
    53http://anidex.moe:6969/announce
    54http://www.worldboxingvideoarchive.com/announce.php
    55http://www.all4nothin.net/announce.php
    56http://149.28.95.5:2710/announce
    57https://tracker.tamersunion.org:443/announce
    58udp://91.216.110.52:451/announce
    59http://www.theplace.bz:2910/announce
    60http://101.200.58.197:6969/announce
    61http://bt.zlofenix.org:81/announce
    62udp://207.246.121.172:2000/announce
    63http://torrent.fedoraproject.org:6969/announce
    64http://trun.tom.ru:80/announce
    65http://blackz.ro/announce.php
    66udp://51.15.40.114:80/announce
    67http://nyaa.tracker.wf:7777/announce
    68http://t.nyaatracker.com:80/announce
    69http://uatracker.net/announce.php
    70http://176.113.71.60:6961/announce
    71udp://open.stealth.si:80/announce
    72http://www.biztorrents.com/announce.php
    73http://tracker.frozen-layer.net:6969/announce
    74http://tracker.ali213.net:8000/announce
    75udp://217.76.183.53:80/announce
    76http://baibako.tv/announce
    77http://t.acg.rip:6699/announce
    78udp://62.210.97.59:1337/announce
    79udp://218.5.43.219:2710/announce
    80http://bt.firebit.org:2710/announce
    81udp://51.81.46.170:6969/announce
    82http://all4nothin.net/announce.php
    83http://funfile.org:2710/announce
    84http://tracker.files.fm:6969/announce
    85udp://tracker.open-internet.nl:6969/announce
    86udp://tracker2.itzmx.com:6961/announce
    87http://secure.pow7.com:80/announce
    88http://bt-club.ws/announce
    89http://pow7.com:80/announce
    90http://51.79.71.167:80/announce
    91http://176.113.68.67:6961/announce
    92udp://retracker.lanta-net.ru:2710/announce
    93http://proaudiotorrents.org/announce.php
    94udp://94.237.82.46:6969/announce
    95https://tracker.torrentsnows.com:443/announce
    96http://tracker.gbitt.info:80/announce
    97http://opentracker.i2p.rocks:6969/announce
    98https://tk.mabo.ltd:443/announce
    99udp://retracker.akado-ural.ru:80/announce
    100http://www.zone-torrent.net:80/announce.php
    101http://95.107.48.115:80/announce
    102http://tracker1.itzmx.com:8080/announce
    103http://potuk.com:2710/announce
    104http://bt.3dmgame.com:2710/announce
    105http://torrent-team.net/announce.php
    106http://tracker.anirena.com:80/announce
    107udp://tracker.swateam.org.uk:2710/announce
    108http://tracker.ygsub.com:6969/announce
    109udp://retracker.netbynet.ru:2710/announce
    110http://www.theoccult.bz:3010/announce
    111udp://212.1.226.176:2710/announce
    112http://tracker.baltracker.net:3390/announce
    113http://184.105.151.164:6969/announce
    114http://atrack.pow7.com:80/announce
    115udp://182.150.53.61:8080/announce
    116udp://188.241.58.209:6969/announce
    117http://tracker.theempire.bz:3110/announce
    118udp://185.181.60.67:80/announce
    119http://t2.pow7.com:80/announce
    120udp://212.47.227.58:6969/announce
    展开全文
  • Android实现app内部自动检测版本更新、自动安装及数据库更新升级1、apk更新流程2、获取本地app内部版本工具类3、请求服务器获取版本数据及新旧版本比对4、下载最新版本apk5、监听下载是否完成并自动安装6、在...

    前言:做一个有梦想的程序猿!

    因为有的app应用不需要上线在应用市场,只需要在内部使用,所以就需要实现app内部检测最新版本功能,最近正好做了这个功能,所以把它分享出来:

    1、apk更新流程

    1. 登录成功后请求服务器接口获取最新版本及更新内容(请求使用的xutils3框架)
    2. 获取本地app应用内版本versionCode与最新版本比较,若小于最新版本则弹框提示更新
    3. 更新下载apk并自动安装,进入主页面删除旧的apk包
    4. 程序启动初始化升级本地数据库

    以上便是全部流程,步骤很简单,接下来就是代码实现

    2、获取本地app内部版本工具类

    package com.gtlxkj.cn.util;
    
    import android.content.Context;
    import android.content.pm.PackageInfo;
    import android.content.pm.PackageManager;
    import android.os.Environment;
    
    public class VersionUtils {
        /**
         * 检查是否存在SDCard
         *
         * @return
         */
        public static boolean hasSdcard() {
            String state = Environment.getExternalStorageState();
            if (state.equals(Environment.MEDIA_MOUNTED)) {
                return true;
            } else {
                return false;
            }
        }
    
        /**
         * 2 * 获取版本
         */
        public static int getVersion(Context context) {
            try {
                PackageManager manager = context.getPackageManager();
                PackageInfo info = manager.getPackageInfo(context.getPackageName(),0);
                int versioncode = info.versionCode;
                return versioncode;
            } catch (Exception e) {
                e.printStackTrace();
            }
            return 0;
        }
        
        /**
         * 2 * 获取版本名称
         */
        public static String getVersionName(Context context) {
            try {
                PackageManager manager = context.getPackageManager();
                PackageInfo info = manager.getPackageInfo(context.getPackageName(),0);
                String version = info.versionName;
                return version;
            } catch (Exception e) {
                e.printStackTrace();
            }
            return "";
        }
     
    }
    
    

    3、请求服务器获取版本数据及新旧版本比对

     /**
     * 主页Activity
     * 
     */
    @ContentView(R.layout.activity_home)
    public class HomeActivity extends BaseActivity implements View.OnClickListener {
    
    	@ViewInject(R.id.btn_upload)
    	private Button btn_upload;
    	@ViewInject(R.id.update_apk)
    	private TextView update_apk;
        private Context context = HomeActivity.this;
        private VersionDialog dialog;
        private boolean flag;//是否检测版本初始化
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            Log.i("HomeActivity", "onCreate"); 
          
           initListener();
           
           Utils.deleteLocal(new File(ConfigurationUtil.APK_PATH_ABSOULT+"GTLXKJ.apk"));//删除旧的apk
           flag=true;
           // 获取本版本号,是否更新
           getVersion(VersionUtils.getVersion(this));
        }
    
        //初始点击事件
        private void initListener(){
        	Log.i("HomeActivity", "initListener"); 
        	update_apk.setOnClickListener(this);
        	update_apk.setText("版本号 V"+Tools.getVersionName(this));
        }
        
    	/**
    	 * 点击事件
    	 * @param view
    	 */
    	public void onClick(View v) {
    		Log.i("HomeActivity", "onClick"); 
    		switch(v.getId()){
    			case R.id.update_apk:
    				flag=false;
    			    getVersion(Tools.getVersion(this));
    				break;	
    		}
    	}
    	
       
        
      //版本更新弹出框
      public  void showUploadApkDialog(String content,String versionName) {
    		Log.i("HomeActivity", "showUploadTaskDialog"); 
    		dialog = new VersionDialog(this,R.style.mystyle,this,R.layout.version__update_dialog,content,versionName);
    		dialog.show();
       }
        
        
        
        // 获取更新版本号
        private void getVersion(final int vision) {
        	if (!NetWorkUtil.isNetworkAvalible(context)) {
        		Toast.makeText(HomeActivity.this,"请检查网络",Toast.LENGTH_SHORT).show();
    			return;
    		}
        	
        	 RequestParams params = new RequestParams(ConfigurationUtil.WEBVERSION);
        	 x.http().get(params, new Callback.ProgressCallback<String>() {
        		@Override
    			public void onSuccess(String result) {
        			Log.i("onSuccess", "onSuccess"); 
        			try{
    					   JSONObject object = new JSONObject(result);
    		               //返回状态
    		               String status = object.optString("code");
    		               //返回的更新内容
    		              String content = object.optString("content");
    		              //返回的版本号
    		              String versionName = object.optString("msg");
    		              //返回版本
    		               String nversion = object.optString("data");
    		               if("1".equals(status)){
    		            	   int newversion = Integer.parseInt(nversion);
    		                   if (newversion != vision) {//新旧版本比较
    		                       if (vision < newversion) {//旧版本低于新版本则更新
    		                           System.out.println("新版本:v"+newversion + "   旧版本v"+ vision);
    		                           // 版本号不同
    		                           showUploadApkDialog(content,versionName);
    		                       }
    		                   }else if(!flag){
    		                  	 Toast.makeText(HomeActivity.this,"已经是最新版本",Toast.LENGTH_SHORT).show();
    		                  }
    		               }
        			}catch(Exception e){
        				e.printStackTrace();
        				Log.e("onSuccess", "Error"); 
        			}
    			}
    			@Override
    			public void onCancelled(CancelledException arg0) {
    				Log.i("onCancelled", "onCancelled"); 
    			}
    			@Override
    			public void onError(Throwable arg0, boolean arg1) {
    				Log.e("onError", "onError"); 
    				 Toast.makeText(HomeActivity.this,"请求服务器无响应",Toast.LENGTH_SHORT).show();
    			}
    			@Override
    			public void onFinished() {
    				Log.i("onFinished", "onFinished"); 
    			}
    			@Override
    			public void onLoading(long arg0, long arg1, boolean arg2) {
    				Log.i("onLoading", "onLoading"); 
    			}
    			@Override
    			public void onStarted() {
    				Log.i("onStarted", "onStarted"); 
    			}
    			@Override
    			public void onWaiting() {
    				Log.i("onWaiting", "onWaiting"); 
    			}
        	});
        }
    }
    
    

    后台用的springboot,具体接口比较简单就不展示了

    AndroidManifest.xml文件中这里配置版本号,发布新版本apk到服务器上时不要忘了修改这里的版本号

    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.gtlxkj.cn"
        android:versionCode="5"
        android:versionName="5.0.0" >
    

    附:Tools获取版本信息工具类

    package com.gtlxkj.cn.util;
    
    import android.content.Context;
    import android.content.pm.PackageInfo;
    import android.content.pm.PackageManager;
    import android.os.Environment;
    
    public class Tools {
        /**
         * 检查是否存在SDCard
         *
         * @return
         */
        public static boolean hasSdcard() {
            String state = Environment.getExternalStorageState();
            if (state.equals(Environment.MEDIA_MOUNTED)) {
                return true;
            } else {
                return false;
            }
        }
    
        /**
         * 2 * 获取版本
         */
        public static int getVersion(Context context) {
            try {
                PackageManager manager = context.getPackageManager();
                PackageInfo info = manager.getPackageInfo(context.getPackageName(),0);
                String version = info.versionName;
                int versioncode = info.versionCode;
                return versioncode;
            } catch (Exception e) {
                e.printStackTrace();
            }
            return 0;
        }
        
        /**
         * 2 * 获取版本名称
         */
        public static String getVersionName(Context context) {
            try {
                PackageManager manager = context.getPackageManager();
                PackageInfo info = manager.getPackageInfo(context.getPackageName(),0);
                String version = info.versionName;
                return version;
            } catch (Exception e) {
                e.printStackTrace();
            }
            return "";
        }
     
    }
    
    

    4、下载最新版本apk

    	//下载apk
        public void downloadApk(String apkUrl) throws PackageManager.NameNotFoundException {
        	Utils.deleteLocal(new File(ConfigurationUtil.APK_PATH_ABSOULT+"GTLXKJ.apk"));//删除旧的apk
            Uri uri = Uri.parse(apkUrl);
            DownloadManager downloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
            DownloadManager.Request request = new DownloadManager.Request(uri);
            // 设置允许使用的网络类型,这里是移动网络和wifi都可以
            request.setAllowedNetworkTypes(request.NETWORK_MOBILE | request.NETWORK_WIFI);
            //设置是否允许漫游
            request.setAllowedOverRoaming(true);
            //设置文件类型
            MimeTypeMap mimeTypeMap = MimeTypeMap.getSingleton();
            String mimeString = mimeTypeMap.getMimeTypeFromExtension(MimeTypeMap.getFileExtensionFromUrl(apkUrl));
            request.setMimeType(mimeString);
            //在通知栏中显示
            request.setNotificationVisibility(request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
            request.setTitle("正在下载");
            request.setVisibleInDownloadsUi(true);
            //sdcard目录下的download文件夹
            request.setDestinationInExternalPublicDir(ConfigurationUtil.APK_PATH, "GTLXKJ.apk");
            // 将下载请求放入队列
            downloadManager.enqueue(request);
        }
    

    此处使用DownloadManager 下载apk

    5、监听下载是否完成并自动安装

    package com.gtlxkj.cn.activity;
    
    import java.io.File;
    
    import com.gtlxkj.cn.util.ConfigurationUtil;
    import com.gtlxkj.cn.util.Utils;
    
    import android.app.DownloadManager;
    import android.content.BroadcastReceiver;
    import android.content.Context;
    import android.content.Intent;
    import android.net.Uri;
    
    public class InstallReceiver extends BroadcastReceiver {
    	 
        // 安装下载接收器
        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction().equals(DownloadManager.ACTION_DOWNLOAD_COMPLETE)) {
                installApk(context);
            }
      }
     
        // 安装Apk
        private void installApk(Context context) {
            try {
                Intent i = new Intent(Intent.ACTION_VIEW);
                String filePath = ConfigurationUtil.APK_PATH_ABSOULT+"GTLXKJ.apk";
                System.out.println(filePath);
                i.setDataAndType(Uri.parse("file://" + filePath), "application/vnd.android.package-archive");
                i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                context.startActivity(i);
            } catch (Exception e) {
                e.printStackTrace();
            }
     
        }
        
    }
    
    

    ConfigurationUtil里面配置的是一些静态的常量,请求后台接口的地址以及其他的一些配置信息在这里面配置,既然有人问了那我就贴出来吧

    package com.gtlxkj.cn.util;
    
    import android.os.Environment;
    
    import java.io.File;
    
    
    public class ConfigurationUtil {
        public static final String URL = "http://192.168.1.98:8011/ams/user?wsdl";
        
       //public static final String HOST = "http://172.16.121.140:8888/test/upload";
        public static final String HOST = "http://192.168.1.98:8011/upload/recieveUploadFile";
        public static final String WEBVERSION = "http://192.168.1.98:8011/upload/queryVersion";
        public static final String APKHOST = "http://192.168.1.98:8011/GTLXKJ.apk";
    
        public static final int SUCCESSCODE = 1;//成功标识
        public static final int FAILURECODE = 0;//失败标识
        public static final int ERRORCODE = 2;//网络请求异常标识
    
        public static final int DBVERSION = 2;//数据库版本
        public static final String DBNAME = "gtlxkj.db";//数据库名称
        public static final String NAMESPACE="http://service.com/";
    
        public static final String SDFILE = Environment.getExternalStoragePublicDirectory("") + File.separator + "hnlx/gt/";
        
        public static final String FILE_PATH = ConfigurationUtil.SDFILE + "camera" + File.separator;
        public static final String APK_PATH = "hnlx/gt/"+ "apk" + File.separator;
        public static final String APK_PATH_ABSOULT = ConfigurationUtil.SDFILE+ "apk" + File.separator;
        public static final String RECORD_PATH_ABSOULT = ConfigurationUtil.SDFILE+ "record" + File.separator;
    }
    
    
    

    Utils类:

    package com.gtlxkj.cn.util;
    
    import java.io.File;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    import android.content.ContentResolver;
    import android.content.ContentUris;
    import android.database.Cursor;
    import android.net.Uri;
    import android.provider.MediaStore;
    
    /**
     * 通用工具类
     * 
     **/
    public class Utils {
    
    	private static SimpleDateFormat DateYMDHMSS = new SimpleDateFormat("yyyyMMddHHmmssSSS");
    
    	 public static String getYMDHMSSToString(long time) {
    	        Date d = new Date(time);
    	        return DateYMDHMSS.format(d);
    	    }
    	 public static boolean StringEx(String str) {
    		 if("".equals(str)||str==null){
    			 return true;
    		 }else{
    			 return false;
    		 }
    		 
    	    }
    	 
    	 //删除本地照片
    	 public static boolean deleteLocalPicture(ContentResolver resolver,String path){
    		    Cursor cursor = MediaStore.Images.Media.query(resolver, MediaStore.Images.Media.EXTERNAL_CONTENT_URI, new String[] { MediaStore.Images.Media._ID }, MediaStore.Images.Media.DATA + "=?",  
    		            new String[] { path }, null);  
    		    boolean result = false;  
    		    if (cursor.moveToFirst()) {  
    		        long id = cursor.getLong(0);  
    		        Uri contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;  
    		        Uri uri = ContentUris.withAppendedId(contentUri, id);  
    		        int count = resolver.delete(uri, null, null);  
    		        result = count == 1;  
    		    } else {  
    		        File file = new File(path);  
    		        result = file.delete();  
    		    }  
    		    return result;
    	 }
    	 
    	   /**
    	     * 删除单个文件
    	     *
    	     * @param fileName
    	     *            要删除的文件的文件名
    	     * @return 单个文件删除成功返回true,否则返回false
    	     */
    	    public static boolean deleteFile(String fileName) {
    	        File file = new File(fileName);
    	        // 如果文件路径所对应的文件存在,并且是一个文件,则直接删除
    	        if (file.exists()) {
    	            if (file.delete()) {
    	                System.out.println("删除单个文件" + fileName + "成功!");
    	                return true;
    	            } else {
    	                System.out.println("删除单个文件" + fileName + "失败!");
    	                return false;
    	            }
    	        } else {
    	            System.out.println("删除单个文件失败:" + fileName + "不存在!");
    	            return false;
    	        }
    	    }
    	    
    	    public static boolean deleteLocal(File file){
    	        if(file.exists()){
    	            if(file.isFile()){
    	                file.delete();//如果为文件,直接删除
    	            }else if(file.isDirectory()){
    	                File []files=file.listFiles();
    	                for(File file1:files){
    	                    deleteLocal(file1);//如果为文件夹,递归调用
    	                }
    	            }
    	            file.delete();
    	            return true;
    	        }
    	        return false;
    	    }
    }
    
    
    
    

    6、在AndroidManifest.xml开权限并配置receiver

    权限:

      <uses-permission android:name="android.permission.INTERNET" />
      <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
      <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    
    

    receiver:

      <receiver
                android:name="com.gtlxkj.cn.activity.InstallReceiver">
                <intent-filter>
                    <action android:name="android.intent.action.DOWNLOAD_COMPLETE" />
                </intent-filter>
            </receiver>
    

    7、弹出框布局Dialog

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
                android:layout_width="300dp"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:background="@drawable/dialog4" >
     
        <LinearLayout
            android:id="@+id/lay_finish"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:orientation="vertical"
            android:scrollbars="vertical" >
     
            <TextView
                android:id="@+id/lay_view"
                android:layout_width="fill_parent"
                android:layout_height="50dp"
                android:gravity="center"
                android:text="版本更新"
                android:textColor="#5b5d61"
                android:textSize="18sp" />
     
            <LinearLayout
                android:layout_width="fill_parent"
                android:layout_height="1dip"
                android:background="#D1D1D1" />
     
           <ScrollView
            android:id="@+id/lay_work"
            android:layout_width="match_parent"
            android:layout_height="250dp"
            android:layout_marginTop="10dp"
            android:layout_marginBottom="10dp"
            android:orientation="vertical"
            android:scrollbars="none">
     
            <TextView
                android:id="@+id/version_content"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginLeft="8dp"
                android:layout_marginRight="8dp"
                android:textColor="#5b5d61"
                android:textSize="16sp" />
    		 </ScrollView>
            
             <LinearLayout
                android:layout_width="fill_parent"
                android:layout_height="1dip"
                android:background="#D1D1D1" />
           
            <LinearLayout
                android:layout_width="fill_parent"
                android:layout_height="40dp"
                android:orientation="horizontal" >
     
                <Button
                    android:id="@+id/cancal"
                    android:layout_width="fill_parent"
                    android:layout_height="fill_parent"
                    android:layout_weight="1"
                    android:background="@null"
                    android:text="稍后"
                    android:textColor="#91c11e"
                    android:textSize="15dp" />
     
                <LinearLayout
                    android:layout_width="1dp"
                    android:layout_height="fill_parent"
                    android:background="#D1D1D1" />
     
                <Button
                    android:id="@+id/update"
                    android:layout_width="fill_parent"
                    android:layout_height="fill_parent"
                    android:layout_weight="1"
                    android:background="@null"
                    android:text="更新"
                    android:textColor="#91c11e"
                    android:textSize="15dp" />
            </LinearLayout>
        </LinearLayout>
     
    </LinearLayout>
    
    

    dialog4代码如下:

    <shape xmlns:android="http://schemas.android.com/apk/res/android" >
        <!--设置渐变色-->
        <gradient
            android:endColor="#ffffff"
            android:startColor="#ffffff" /> 
     
        <solid android:color="#ffffff" />
        <!--设置圆角-->
         <corners 
    	     android:radius="12dp" />
    </shape>
    
    

    8、自定义Dialog

    package com.gtlxkj.cn.dialog;
    
    import com.gtlxkj.cn.R;
    import com.gtlxkj.cn.activity.HomeActivity;
    import com.gtlxkj.cn.util.ConfigurationUtil;
    
    import android.app.Dialog;
    import android.content.Context;
    import android.content.pm.PackageManager.NameNotFoundException;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.Button;
    import android.widget.TextView;
    
    /**
     * 自定义dialog
     */
    public class VersionDialog extends Dialog implements
            View.OnClickListener {
    
        /**
         * 布局文件
         **/
        int layoutRes;
    
        /**
         * 上下文对象
         **/
        Context context;
        
    
        /**
         * 取消按钮
         **/
        private Button bt_cancal;
    
        /**
         * 更新按钮
         **/
        private Button bt_delect;
        
        private String content;//版本内容
        
        private String versionName;//版本号
        
        private HomeActivity homeActivity;
        
        
        public VersionDialog(Context context) {
            super(context);
            this.context = context;
        }
    
        /**
         * 自定义布局的构造方法
         *
         * @param context
         * @param resLayout
         */
        public VersionDialog(Context context, int resLayout) {
            super(context);
            this.context = context;
            this.layoutRes = resLayout;
        }
    
        /**
         * 自定义主题及布局的构造方法
         *
         * @param context
         * @param theme
         * @param resLayout
         * @param postion
         */
        public VersionDialog(Context context,int theme, HomeActivity activity,int resLayout,String content,String versionName) {
            super(context, theme);
            this.context = context;
            this.content = content;
            this.layoutRes = resLayout;
            this.homeActivity = activity;
            this.versionName = versionName;
        }
    
        
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            // 指定布局
            this.setContentView(layoutRes);
            TextView  textView=(TextView) findViewById(R.id.version_content);
            TextView  titleView=(TextView) findViewById(R.id.lay_view);
            textView.setText("更新内容:\n\n"+content);
            titleView.setText("发现新版本 "+versionName);
            // 根据id在布局中找到控件对象
            bt_cancal = (Button) findViewById(R.id.cancal);
            bt_delect = (Button) findViewById(R.id.update);
            // 为按钮绑定点击事件监听器
            bt_cancal.setOnClickListener(this);
            bt_delect.setOnClickListener(this);
        }
    
        @Override
        public void onClick(View v) {
            switch (v.getId()) {
    
                case R.id.update:
                	optUpdateApk();
                    this.dismiss();
                    break;
    
                // 取消按钮
                case R.id.cancal:
                	this.dismiss();
    
                default:
                    break;
            }
        }
        /**
         * 操作  版本更新
         *
         */
        private void optUpdateApk( ) {
        	try {
    			homeActivity.downloadApk(ConfigurationUtil.APKHOST);
    		} catch (NameNotFoundException e) {
    			e.printStackTrace();
    		}
        }
    }
    
    
    

    9、使用xutils3升级最新版本数据库

    注意此升级代码是在onUpgrade方法内实现,
    这样更新完app后重新启动就会初始化升级本地数据库结构了

    public class LXApplication extends Application {
    	
        // Effective Java 第一版推荐写法
        private static class LXApplicationHolder {
            private static final LXApplication INSTANCE = new LXApplication();
        }
        
        public LXApplication() {
        }
    
        public static final LXApplication getInstance() {
            return LXApplicationHolder.INSTANCE;
        }
    
        public static DbManager.DaoConfig daoConfig;
    
        @Override
        public void onCreate() {
            super.onCreate();
            CrashHandler crashHandler = CrashHandler.getInstance();
            crashHandler.init(this);
            x.Ext.init(this);
            x.Ext.setDebug(true);
            dbinit();
        }
    	//xutils3初始化
        private void dbinit() {
            File file = new File(ConfigurationUtil.SDFILE + "db");
            if (!file.exists()) {
                file.mkdirs();
            }
            daoConfig = new DbManager.DaoConfig()
            		.setDbName(ConfigurationUtil.DBNAME)
            		.setDbDir(file).setDbVersion(ConfigurationUtil.DBVERSION)
            		.setAllowTransaction(true)
            		.setDbOpenListener(new DbManager.DbOpenListener() {
                @Override
                public void onDbOpened(DbManager db) {
                    // 开启WAL, 对写入加速提升巨大
                    db.getDatabase().enableWriteAheadLogging();
                }
            }).setDbUpgradeListener(new DbManager.DbUpgradeListener() {
                @Override
                public void onUpgrade(DbManager db, int oldVersion, int newVersion) {//数据库升级
                	try {
                		 for (int j = oldVersion; j <= newVersion; j++) {
    						switch(newVersion){
    			                case 2:
    								//增加表字段
    			                	db.addColumn(Person.class, "name");
    			                   break;
    			                 case 3:
    							   /**
    								*保留历史数据的升级数据库
    							    */
    
    							   // db.execSQL(""); //第一步将旧表改为临时表
    		
    			                   //db.execSQL(""); //第二步创建新表(新添加的字段或去掉 的字段)
    		
    			                   //db.execSQL(""); //第三步将旧表中的原始数据保存到新表中以防遗失
    		
    			                   //db.execSQL(""); //第四步删除临时备份表
    			                   break;
    							case 4://其他操作
    								// TODO: ...
    								// db.dropTable(...);
    								// ...
    								// or
    								// db.dropDb();
    								break;
    			                default:
    			                    break;
    						 }
                		 }
    				} catch (DbException e) {
    					// TODO Auto-generated catch block
    					e.printStackTrace();
    				}
                    
                }
            }).setTableCreateListener(new DbManager.TableCreateListener() {// 设置表创建的监听
    
                @Override
                public void onTableCreated(DbManager arg0, TableEntity<?> arg1) {
                    Log.i("sjl__", "onTableCreated:" + arg1.getName());
                }
            });
        }
    
        
        public DbManager.DaoConfig getDbConfig() {
            if (daoConfig == null) {
                dbinit();
            }
            return daoConfig;
        }
    
        private static List<Activity> activityLists = new ArrayList<Activity>();
    
        // 添加Activity到容器中
        public static void addActivity(Activity activity) {
            activityLists.add(activity);
        }
    
        // 遍历所有Activity并finish
        public static void exit() {
            try {
                for (Activity activity : activityLists) {
                    activity.finish();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    
    

    10、效果图

    demo

    11、总结

    数据库升级在此文中没有过多的说明,有需要的可以百度,有关资料还是很多的,也比较简单,打好的apk包放到服务器上,安卓请求这个apk链接就可以下载,版本升级切记打包的时候要使配置的版本和服务器接口内的版本一致同步,

    最后,如果本篇文章对您有所帮助,可以评论或点赞支持一下哦,感谢感谢!

    在这里插入图片描述

    展开全文
  • 字段自动检测在某个字段第一次出现时,如果之前没有定义过映射,ES会自动检测它可能满足的类型,然后创建对应的映射。JSON数据ES中的数据类型null不会添加字段true or falsebooleanfloating point ...

    一、自动映射:

    ES通过查看定义某文档的json格式就能猜测到文档结构,我们称之为自动映射,在开发过程中需要注意这些特性。

    字段自动检测

    在某个字段第一次出现时,如果之前没有定义过映射,ES会自动检测它可能满足的类型,然后创建对应的映射。

    JSON数据

    ES中的数据类型

    null

    不会添加字段

    true or false

    boolean

    floating point number

    double

    integer

    long

    object

    object

    array

    依赖于第一个非null得值

    string

    如果通过了date检测,则为date

    如果通过了numeric检测,则为Number

    上面就是类型自动检测的结果,除了上面列出的基本类型,其他的高级的类型比如geo,ip就需要手动指定了。

    日期自动检测

    日期自动检测,即date_detection是默认开启的,因此只要符合默认的日期格式,就可以自动创建成date类型

    日期的格式为:

    [ "strict_date_optional_time","yyyy/MM/dd HH:mm:ss || yyyy/MM/dd"]

    例如:

    复制代码
    $ curl -XPUT localhost:9200/test/test/1 -d '{"create":"2015/11/11"}'
    {"_index":"test","_type":"test","_id":"1","_version":1,"created":true}
    
    $ curl -XGET localhost:9200/test/_mapping?pretty
    {
      "test" : {
        "mappings" : {
          "test" : {
            "properties" : {
              "create" : {
                "type" : "date",
                "format" : "yyyy/MM/dd HH:mm:ss||yyyy/MM/dd"
              }
            }
          }
        }
      }
    }
    复制代码

    可以通过修改dynamic_date_formats 修改日期格式:

    复制代码
    PUT my_index
    {
        "mappings":{
            “my_type":{"dynamic_date_formats":["MM/dd/yyyy"]}
        }
    }
    
    PUT my_index/my_type/1{"create_date":"09/25/2015"}
    复制代码

    数字自动检测

    数字自动检测,即numeric_detection默认是关闭的。因此需要手动打开:

    PUT my_index
    {"mappings":{"my_type":{"numeric_detection":true}}}

    当执行索引操作时,如果符合float型,就会自动创建为double,如果符合int型,ES默认创建为long

    可能通过类似curl -XPUT localhost:9200/test1/test1/_mapping?pretty查询自动生成的映射。

    二、动态映射:

    ES中有一个非常重要的特性——动态映射,即索引文档前不需要创建索引、类型等信息,在索引的同时会自动完成索引、类型、映射的创建。那么什么是映射呢?映射就是描述字段的类型、如何进行分析、如何进行索引等内容。

    当ES在文档中碰到一个以前没见过的字段时,它会利用动态映射来决定该字段的类型,并自动地对该字段添加映射。

    有时这正是需要的行为,但有时不是,需要留意。你或许不知道在以后你的文档中会添加哪些字段,但是你想要它们能够被自动地索引。或许你只是想要忽略它们。或者,尤其当你将ES当做主要的数据存储使用时,大概你会希望这些未知的字段会抛出异常来提醒你注意这一问题。

    幸运的是,你可以通过dynamic设置来控制这一行为,它能够接受以下的选项:

    • true:默认值。动态添加字段
    • false:忽略新字段
    • strict:如果碰到陌生字段,抛出异常

    dynamic设置可以适用在根对象上或者object类型的任意字段上。你应该默认地将dynamic设置为strict,但是为某个特定的内部对象启用它:

    PUT /my_index
    {
        "mappings": {
            "my_type": {
                "dynamic":      "strict", 
                "properties": {
                    "title":  { "type": "string"},
                    "stash":  {
                        "type":     "object",
                        "dynamic":  true 
                    }
                }
            }
        }
    }

    my_type对象上如果碰到了未知字段则会抛出一个异常。 在stash对象上会动态添加新字段。

    通过以上的映射,你可以向stash添加新的可搜索的字段:

    PUT /my_index/my_type/1
    {
      "title": "This doc adds a new field",
      "stash": {
        "new_field": "Success!"
      }
    }

    但是,如果在顶层对象上试图添加新字段则会失败:

    PUT /my_index/my_type/1
    {
        "title":     "This throws a StrictDynamicMappingException",
        "new_field": "Fail!"
    }

    NOTE

    dynamic设置为false并不会改变_source字段的内容,_source字段仍然会保存你索引的整个JSON文档。只不过是陌生的字段将不会被添加到映射中,以至于它不能被搜索到。


    自定义动态映射

    如果你知道你需要动态的添加的新字段,那么你也许会启用动态映射。然而有时动态映射的规则又有些不够灵活。幸运的是,你可以调整某些设置来让动态映射的规则更加适合你的数据。

    date_detection

    当ES碰到一个新的字符串字段时,它会检查该字串是否含有一个可被识别的日期,比如2014-01-01。如果存在,那么它会被识别为一个date类型的字段。否则会将它作为string进行添加。

    有时这种行为会导致一些问题。如果你想要索引一份这样的文档:

    { "note": "2014-01-01" }

    假设这是note字段第一次被发现,那么根据规则它会被作为date字段添加。但是如果下一份文档是这样的:

    { "note": "Logged out" }

    这时该字段显然不是日期,但是已经太迟了。该字段的类型已经是日期类型的字段了,因此这会导致一个异常被抛出。

    可以通过在根对象上将date_detection设置为false来关闭日期检测:

    PUT /my_index
    {
        "mappings": {
            "my_type": {
                "date_detection": false
            }
        }
    }

    有了以上的映射,一个字符串总是会被当做string类型。如果你需要一个date字段,你需要手动地添加它。

    NOTE

    ES中识别日期的方法可以通过dynamic_date_formats设置改变。

    dynamic_templates

    通过dynamic_templates,你可以拥有对新字段的动态映射规则拥有完全的控制。你设置可以根据字段名称或者类型来使用一个不同的映射规则。

    每个模板都有一个名字,可以用来描述这个模板做了什么。同时它有一个mapping用来指定具体的映射信息,和至少一个参数(比如match)用来规定对于什么字段需要使用该模板。

    模板的匹配是有顺序的 - 第一个匹配的模板会被使用。比如我们可以为string字段指定两个模板:

    • es:以_es结尾的字段名应该使用spanish解析器
    • en:其它所有字段使用english解析器

    我们需要将es模板放在第一个,因为它相比能够匹配所有字符串字段的en模板更加具体:

    PUT /my_index
    {
        "mappings": {
            "my_type": {
                "dynamic_templates": [
                    { "es": {
                          "match":              "*_es", 
                          "match_mapping_type": "string",
                          "mapping": {
                              "type":           "string",
                              "analyzer":       "spanish"
                          }
                    }},
                    { "en": {
                          "match":              "*", 
                          "match_mapping_type": "string",
                          "mapping": {
                              "type":           "string",
                              "analyzer":       "english"
                          }
                    }}
                ]
    }}}

    match_mapping_type允许你只对特定类型的字段使用模板,正如标准动态映射规则那样,比如stringlong等。

    match参数只会匹配字段名,path_match参数用于匹配对象中字段的完整路径,比如address.*.name可以匹配如下字段:

    {
        "address":
            "city":
                "name": "New York"
            }
        }
    }

    unmatchpath_unmatch模式能够用来排除某些字段,没有被排除的字段则会被匹配。

    参考官方文档:https://www.elastic.co/guide/en/elasticsearch/reference/1.4//mapping-root-object-type.html



    展开全文
  • IE自动检测设置的作用

    千次阅读 2016-06-17 13:18:44
    自动检测设置适用于使用ISA等企业内部网络环境下使用特别方便,能够自动检测ISA代理,配合WPAD自动下载配置文件。 自动检测设置是IE的默认设置,但当用户环境没有使用代理服务器这类上网方式,勾选自动检测设置会...

    自动检测设置适用于使用ISA等企业内部网络环境下使用特别方便,能够自动检测ISA代理,配合WPAD自动下载配置文件。

    自动检测设置是IE的默认设置,但当用户环境没有使用代理服务器这类上网方式,勾选自动检测设置会让打开第一个网页变的非常之慢。

     

    工具->internet选项->连接->局域网设置->自动检测设置

    这个设置是你所使用的局域网中可能有服务器会向网内计算机自动发送网络配置文件和信息。开启该选项后会自动获得相关配置。

    是否勾选是看你所使用的局域网有没有这个要求了。

    有些局域网配置相对静态,一般不更改设置,那我们手动配置完就可以了。但有些局域网可能经常会变动设置,并且服务器会下发这些配置更改,那开启自动检测设置就可以节省手动配置的时间,会比较方便。

     

    遇到自动检测设置为灰色时的参考

    有时会遇到IE中自动检测设置无法取消的情况,具体表现为“自动检测设置”默认是打勾的却显示为灰色无法操作,这时我们可以通过修改注册表来取消IE中的“自动检测设置”,具体方法如下:

    新建一个记事本文档写入以下内容

    Windows Registry Editor Version 5.00

    [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings\Connections]
    "DefaultConnectionSettings"=hex:3c,00,00,00,05,00,00,00,01,00,00,00,00,00,00,\
    00,00,00,00,00,00,00,00,00,01,00,00,00,00,00,00,00,90,b1,e4,38,dc,92,c6,01,\
    01,00,00,00,c0,a8,71,fa,00,00,00,00,00,00,00,00
    "SavedLegacySettings"=hex:3c,00,00,00,85,00,00,00,01,00,00,00,00,00,00,00,00,\
    00,00,00,00,00,00,00,01,00,00,00,00,00,00,00,90,b1,e4,38,dc,92,c6,01,01,00,\
    00,00,c0,a8,71,fa,00,00,00,00,00,00,00,00

    保存为REG后缀文件,双击运行即可。

    展开全文
  • IPTV Checker(直播源自动检测工具)

    千次阅读 2020-10-09 19:43:38
    IPTV Checker中文版是一款功能实用的直播源自动检测工具,IPTV检查器使用方便,而且检测速度非常快速,使用后可以帮助用户更轻松便捷的检测电视直播源,省去了我们一个个排查直播源是否可用 公众号:【代码集中营】 ...
  • 传感器与自动检测技术课后答案

    热门讨论 2009-06-02 13:29:34
    传感器与自动检测技术课后答案 高等教育出版社 于成波
  • vs code语言模式自动检测设置

    千次阅读 2019-05-14 11:02:05
    那我们怎么设置回来呢,点击右下角的存文本(这里可能不只是纯文本也可能是其他格式 ,这是语言自动检测出的问题)。 点击后会出现这个界面我们在依次点开“配置文件关联” 出现这个界面后找到对应文件的格式,...
  • 自动检测图像中的圆形或圆形对象

    千次阅读 2019-03-28 10:54:18
    此示例显示如何使用imfindcircles自动检测图像中的圆形或圆形对象。 它还使用viscircles来显示检测到的圆圈。
  •     该论文提出了一种基于深度学习的方法实现黑色素瘤病变的自动检测和分割。该方法包含一种增强的编码-解码网络用于提取特征,该网络通过一系列跳步路径(skip pathway)连接编码子网络和解码器子网络,使两者...
  • 基于深度学习的城市垃圾自动检测

    千次阅读 2018-05-24 19:06:02
    基于城市场景照片快速准确地自动检测垃圾在“智慧城管”等应用中具有重要的研究价值。城市垃圾在颜色纹理、几何形态上具有极大的多样性,甚至部分垃圾的认定具有一定的主观性,这给垃圾自动检测带来很大的挑战。文章...
  • iOS 【在iOS中自动检测内存泄漏】

    千次阅读 2016-07-17 01:14:55
    iOS中如何自动检测内存泄漏
  • 摄像头型号检测工具,可以自动检测各种杂牌摄像头并安装驱动
  • QT自动检测系统语言代码

    千次阅读 2016-08-16 22:34:15
    但是最友好的方式,自动检测操作系统的语言的,根据语言自动加载相关界面翻译文件。查阅QT帮助文档,发现QSystemLocale 是有语言和国家检测功能,这里如果要区别简,繁体区别,必须查CountryId. 经过实验,代码成功...
  • 传感器与自动检测技术考试题及答案详解~~~~~~~~~~~
  • 给大家介绍一个内存检测神器,只需要用cocoaPods安装,无需导入任何头文件即可自动检测内存泄漏。GitHub地址 https://github.com/Zepo/MLeaksFindercocoaPods安装代码:pod ‘MLeaksFinder’安装后效果如下:最后如果...
  • 网络安全的自动检测与预警

    千次阅读 2017-01-19 04:22:38
    网络安全的自动检测与预警 近日,两办发布《关于促进移动互联网健康有序发展的意见》,大快人心。按照《意见》的要求,必须清除网络不良信息,保证网络健康有序发展。 据报道,每年国内需要清除十多亿条不良...
  • Android自动检测版本及自动升级

    万次阅读 多人点赞 2011-10-19 00:25:30
    步骤: 1.检测当前版本的信息AndroidManifest.xml-->manifest-->android:versionName。...3.当提示用户进行版本升级时,如果用户点击了确定,系统将自动从服务器上下载并进行自动升级,如果点击取消将进入程序主界面
  • 项目中一直在用串口通讯,但没有实现可用串口的自动检测和热插拔检测。今天通过查找资料实现了这些功能,所以在这里坐下记录。 参考资料:http://blog.csdn.net/flydream0/article/details/8086976 实现环境:VC6.0 ...
  • 自己做的一个串口通信小程序 用C#做的,可以自动检测串口数量,可以同时显示输入与输出。自己做的一个串口通信小程序 用C#做的,可以自动检测串口数量,可以同时显示输入与输出。
  • windows自动检测某进程,存在就杀掉

    千次阅读 2019-07-05 16:53:10
    windows自动检测某进程,存在就杀掉 run.vbs do strComputer="." Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2") Set colProcessList=objWMIService.ExecQuery ("select * ...
  • Windows批处理自动检测、安装Python

    万次阅读 2020-12-05 15:06:02
    使用注册表检测Python是否安装,检测注册表项hklm\software\Python\pythoncore是否存在指定版本信息。经试验发现该注册表项对于较早的安装包无效。 使用py -3.7 --version检测Python解释器是否正常运行,较早的...
  • 问题:vs2017写C++代码不能自动检测错误和提示 解决方法: 工具》选项》文本编辑器》C/C++》高级》把Intellisense中的禁用全部改为false
  • 自动检测TXT文件编码

    千次阅读 2012-05-16 09:00:40
    自动检测文本文件编码的代码(只能简单判断是UTF-8或不是UTF-8),因为一般除了UTF-8之外就是GBK,所以就设置默认为GBK。 String charsetDetect(String path) {  String _charset="";  try {  File file ...
  • 1、使用前请先安装netframework4.0或以上版本,或安装vs2010以上版本 2、无需安装halcon 3、更改采集设备中的图像路径,指定到你所需要处理图像的位置
  • 但是,常常有时候场景中需要的不只有文档分隔的功能还有自动检测并删除空白页的功能。本篇文章将简单介绍如何利用Dynamic Web TWAIN 在网页文档扫描的过程中实现空白页自动检测删除的功能。 方法一 如果设备的...
  • Android Studio代码自动检测错误提示

    万次阅读 2014-07-02 17:44:19
    Android Studio的代码自动检测的错误提示方式感觉有点奇葩,和Eclipse差别很大,Eclipse检测到某个资源文件找不到或者错误,都会在Project中对应的文件前面打叉,但是Android Studio不用这种方式,所以估计你刚开始...
  • 关闭sublime自动检测更新提示

    万次阅读 多人点赞 2016-09-29 15:40:00
    关注&微&&信&...在使用sublime text 3的时候,有自动更新的话再打开的时候总是提醒更新,这让我这个强迫症重度患者非常难受,要取消自动检查更新,点击菜单栏“Preferences”=>...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 924,601
精华内容 369,840
关键字:

自动检测