精华内容
下载资源
问答
  • 我们只想知道该怎么做。 你不应该做的 要明确一点, kubectl run不是您想要的,并且这行不通: $ kubectl run hello-py --image=hello-py:v1 --port=8080 手动管理minikube eval $( minikube docker-env ) docker...
  • 经过两天时间的开源,感谢网友提出一些修改意见...今天了一个操作数据库的演示<这里我拿出我在实际项目中操作数据库的方法,集成在Demo中> 操作数据库比较简单,分两部分功能,第一部分打开SQL proce...

    经过两天时间的开源,感谢网友提出一些修改意见,特别是在XE中,做了一部分优化。

     

    可以在SVN中下载到最新的代码

     

    https://code.google.com/p/diocp/

    今天做了一个操作数据库的演示<这里我拿出我在实际项目中操作数据库的方法,集成在Demo中>

     

    操作数据库比较简单,分两部分功能,第一部分打开SQL

    procedure TfrmMain.btnOpenSQLClick(Sender: TObject);
    var
      lvJSonStream, lvRecvObject:TJsonStream;
      lvStream:TStream;
      lvData:AnsiString;
      l, j, x:Integer;
    begin
      lvJSonStream := TJsonStream.Create;
      try
        lvJSonStream.JSon := SO();
        lvJSonStream.JSon.I['cmdIndex'] := 1001;   //打开一个SQL脚本,获取数据
        lvJSonStream.Json.S['sql'] := mmoSQL.Lines.Text;
    
        FClientSocket.sendObject(lvJSonStream);
      finally
        lvJSonStream.Free;
      end;
    
      //读取数据
      lvRecvObject := TJsonStream.Create;
      try
        FClientSocket.recvObject(lvRecvObject);
    
        if not lvRecvObject.getResult then
        begin
          raise Exception.Create(lvRecvObject.getResultMsg);
        end;
    
        SetLength(lvData, lvRecvObject.Stream.Size);
        lvRecvObject.Stream.Position := 0;
        lvRecvObject.Stream.ReadBuffer(lvData[1], lvRecvObject.Stream.Size);
    
        cdsMain.XMLData := lvData;
      finally
         lvRecvObject.Free;
      end;
    end;

    服务端ClientContext中的处理

    procedure TClientContext.dataReceived(const pvDataObject:TObject);
    var
      lvJsonStream:TJSonStream;
      lvFile:String;
      lvCmdIndex:Cardinal;
      lvXMLData, lvEncodeData:AnsiString;
      lvSQL:String;
    begin
      lvJsonStream := TJSonStream(pvDataObject);
    
      lvCmdIndex := lvJsonStream.JSon.I['cmdIndex'];
    
      //echo测试
      if lvCmdIndex= 1000 then
      begin
        InterlockedIncrement(TesterINfo.__RecvTimes);
        //回写数据
        writeObject(lvJsonStream);
      end else if lvCmdIndex = 1001 then
      begin  //根据sql获取一个数据,放在Stream中
        try
          lvSQL := lvJsonStream.Json.S['sql'];
    
          lvXMLData := dmMain.CDSProvider.QueryXMLData(lvSQL);
    
          lvJsonStream.Clear();
          lvJsonStream.Stream.WriteBuffer(lvXMLData[1], Length(lvXMLData));
          lvJsonStream.setResult(True);
        except
          on e:Exception do
          begin
            lvJsonStream.Clear();
            lvJsonStream.setResult(False);
            lvJsonStream.setResultMsg(e.Message);
          end;
        end;
        
        //回写数据
        writeObject(lvJsonStream);

     

    保存数据用到一个非常好用的DLL

    客户端:

    procedure TfrmMain.btnPostClick(Sender: TObject);
    var
      lvJSonStream, lvRecvObject:TJsonStream;
      lvStream:TStream;
      lvData:AnsiString;
      l, j, x:Integer;
    begin
      if cdsMain.State in [dsInsert, dsEdit] then cdsMain.Post;
      
      if cdsMain.ChangeCount = 0 then
      begin
        ShowMessage('没有做任何修改!');
        exit;
      end;
      lvJSonStream := TJsonStream.Create;
      try
        lvJSonStream.JSon := SO();
        lvJSonStream.JSon.I['cmdIndex'] := 1002;   //打开一个SQL脚本,获取数据
    
        //打包修改记录
        with TCDSOperatorWrapper.createCDSEncode do
        begin
          setTableINfo(PAnsiChar(AnsiString(edtUpdateTable.Text)), PAnsiChar(AnsiString(edtKeyFields.Text)));
          setData(cdsMain.Data, cdsMain.Delta);
          //执行编码
          Execute;
          lvData := getPackageData;
        end;
    
        mmoData.Clear;
        mmoData.Lines.Add(lvData);
    
        lvJSonStream.Stream.Write(lvData[1], Length(lvData));
    
        FClientSocket.sendObject(lvJSonStream);
      finally
        lvJSonStream.Free;
      end;
    
      //读取数据
      lvRecvObject := TJsonStream.Create;
      try
        FClientSocket.recvObject(lvRecvObject);
    
        if not lvRecvObject.getResult then
        begin
          raise Exception.Create(lvRecvObject.getResultMsg);
        end else
        begin
          ShowMessage('保存成功!');
        end;
      finally
         lvRecvObject.Free;
      end;
    
      cdsMain.MergeChangeLog();
    
    end;

    服务端:

    if lvCmdIndex = 1002 then  //保存数据到熟客
      begin
        try
          lvJsonStream.Stream.Position := 0;
          SetLength(lvEncodeData, lvJSonStream.Stream.Size);
          lvJsonStream.Stream.ReadBuffer(lvEnCodeData[1], lvJSonStream.Stream.Size);
    
          dmMain.ExecuteApplyUpdate(lvEncodeData);
    
          lvJsonStream.Clear();
          lvJsonStream.setResult(True);
        except
          on e:Exception do
          begin
            lvJsonStream.Clear();
            lvJsonStream.setResult(False);
            lvJsonStream.setResultMsg(e.Message);
          end;
        end;
        
        //回写数据
        writeObject(lvJsonStream);
      end

     

     

    转载于:https://www.cnblogs.com/DKSoft/archive/2013/05/20/3089022.html

    展开全文
  • 这是宝石渡轮的测试应用程序。 这个应用程序在不同的环境中有几种不同的数据库类型: 'sqlite_development' 'mysql_development' 'postgresql_... 如果有一种方法可以只在特定环境下运行 rakes,我不知道该怎么做
  • 这个demo主要演示用pjsip一个sip client视频对讲。...​不过毕竟是DEMO,只是演示怎么使用,细节还有很多问题。以后会逐步修改再提交。如果大家发现问题请发到上,收到后会及时回复。 详细文档在:
  • 写代码免不了要测试,测试有很多种,对于java来说,最初级的就是写个main函数运行一下看看结果,高级的可以用各种高大上的复杂的测试系统。每种测试都有它的关注点,比如测试功能是不是正确,或者运行状态稳不稳定...
  • 玛德界面库Gif使用Demo

    2015-01-09 16:33:24
    使用玛德界面库(MDui)制作的演示怎么在程序内使用Gif动态酷炫效果的Demo
  • Android检查版本升级应该怎么做

    千次阅读 2018-07-26 10:10:39
    demo演示:https://github.com/pzl237/UpgradeDemo 今年年初项目终于上线,到目前为止发布了4个版本。经历了3.8节,整体表现稳定。在第三个版本我们加入了版本检查升级,发布第四版本,用户就直接体验到了这个功能...

    转载自 https://www.jianshu.com/p/98ea7e866ffd

    demo演示:https://github.com/pzl237/UpgradeDemo

    今年年初项目终于上线,到目前为止发布了4个版本。经历了3.8节,整体表现稳定。在第三个版本我们加入了版本检查升级,发布第四版本,用户就直接体验到了这个功能。

    必要性

    我们开发一个APP,应该是发布第一个版本之后,后续不断的更新迭代。现在大部分APP都是发布到各大应用市场市场,然后用户去搜索我们的应用并下载安装。如果有新的版本,你不可能让每个用户去应用市场重新下载新的版本,又或者用户没注意应用市场的更新提醒导致没有安装最新版本等,所以我们有必要让我们的应用自己检查是否有新的版本。

    升级流程图

    在APP首页自动触发向服务端请求最新的版本信息,如果服务端返回的版本信息中versionCode与当前版本不一致,就弹出升级提示框让用户选择。流程图如下:

    检查更新流程图.png

    “立即更新”:直接启动下载
    “稍后提醒”:什么都不处理
    “忽略该版本”:当前版本不再提醒,如有更新版本还是要提醒。例如:用户版本是1.0,当前检查到的版本是2.0,用户选择了“忽略该版本”,则2.0的版本不再提示,到下个版本时,仍然要提示版本更新。

    实现

    首先看下app module的build.gradle

    每次发布一个新版本时,一般都会修改versionCode以及versionName

    defaultConfig {
            applicationId "com.jemlin.app"
            minSdkVersion 15
            targetSdkVersion 25
            versionCode 1
            versionName "1.0.0"
            ...
        }
    

    其中versionCode是整型,这里定义从1开始,每次迭代一个版本就加1;versionName是字符类型,从1.0.0开始,每次更新可以改为1.0.1、1.1.0、2.0.0等等。

    接着判断是否有升级版本

    通过和后端定好的http api从服务器端请求最新版本的versionCode,然后与当前版本的versionCode比较,如果服务端返回版本信息的versionCode大于当前版本的versionCode,就说明有新的版本需要更新。

    1、http api检查版本更新接口response数据格式(仅供参考):

    {
        "data": {
            "downloadUrl": "http://a5.pc6.com/cx3/weixin.pc6.apk",
            "version": "1.0.1",
            "versionCode": 2,
            "versionDesc": "主要修改:\n1.增加多项新功能;\n2.修复已知bug。"
        },
        "errCode": 0,
        "errMsg": "",
        "success": true
    }
    

    其中,downloadUrl是最新版本的下载地址。

    2、定义VersionInfo模型,用于GSon解析服务端返回的数据:

    public class VersionInfo {
        private int versionCode;
        private String version;
        private String downloadUrl;
        private String versionDesc;
        //......
    }
    

    3、如果有升级版本,随时弹窗提示用户。没有升级版本,就不用提示。

    忽略更新

    我的做法是把用户忽略更新的版本号versionCode存储到sharePreference中,每次发现有升级版本时,在给用户提示之前,先取忽略版本号versionCode与最新版本号versionCode比较是否一样,如果一样就什么都不做,检查更新结束;如果不一样,还是照样给用户提示。

    //取sp中保存的versionCode
    int versionCode = mAppUpgradePersistent.getIgnoreUpgradeVersionCode(appContext);
    if (versionCode == latestVersion.getVersionCode()) {
      //用户之前已经选择"忽略该版本",不更新这个版本。
      Timber.d("[AppUpgradeManager] ignore upgrade version====");
      return;
    }
    

    稍后提醒

    最简单,什么都不做。

    立即更新

    1、项目中我们直接使用系统提供的DownloadManager服务,同时注册两个广播:
    下载完成广播DownloadManager.ACTION_DOWNLOAD_COMPLETE以及
    点击下载通知栏广播DownloadManager.ACTION_NOTIFICATION_CLICKED
    代码片段如下:

        public void init(Context context) {
            Timber.d("[AppUpgradeManager] init====");
            if (isInit) {
                return;
            }
    
            appContext = context.getApplicationContext();
            isInit = true;
            mAppUpgradePersistent = new AppUpgradePersistent();
            appContext.registerReceiver(downloaderReceiver, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
            appContext.registerReceiver(notificationClickReceiver, new IntentFilter(DownloadManager.ACTION_NOTIFICATION_CLICKED));
        }
    
        public void unInit() {
            Timber.d("[AppUpgradeManager] unInit====");
            if (!isInit) {
                return;
            }
            appContext.unregisterReceiver(downloaderReceiver);
            appContext.unregisterReceiver(notificationClickReceiver);
            isInit = false;
            mAppUpgradePersistent = null;
            appContext = null;
        }
    

    2、如果可以的话,在用户选择立即更新之后,您的应用应该判断当前的网络环境,如果是非wifi环境应该弹窗提示用户类似“您当前使用的不是wifi,更新会产生一些网络流量,是否继续下载?”
    代码片段如下:

                // 非wifi网络下,再次提示用户是否继续
                MaterialDialog.Builder builder = new MaterialDialog.Builder(activity);
                final MaterialDialog dialog = builder.title("流量提醒")
                        .theme(Theme.LIGHT)
                        .titleGravity(GravityEnum.CENTER)
                        .content("您当前使用的不是wifi,更新会产生一些网络流量,是否继续下载?")
                        .positiveText("确定")
                        .negativeText("取消")
                        .onPositive(new MaterialDialog.SingleButtonCallback() {
                            @Override
                            public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
                                dialog.dismiss();
                                //TODO 
                            }
                        })
                        .onNegative(new MaterialDialog.SingleButtonCallback() {
                            @Override
                            public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
                                dialog.dismiss();
                                //TODO
                            }
                        })
                        .build();
                dialog.show();
    

    3、真正调用DownloadManager下载前,我们可以判断下本地是否已经过了最新版本,有就直接启动安装界面安装;下载的不是最新版本,就直接删除。
    代码片段如下:

            //先检查本地是否已经有需要升级版本的安装包,如有就不需要再下载
            File targetApkFile = new File(downloadApkPath);
            if (targetApkFile.exists()) {
                PackageManager pm = appContext.getPackageManager();
                PackageInfo info = pm.getPackageArchiveInfo(downloadApkPath, PackageManager.GET_ACTIVITIES);
                if (info != null) {
                    String versionCode = String.valueOf(info.versionCode);
                    //比较已下载到本地的apk安装包,与服务器上apk安装包的版本号是否一致
                    if (String.valueOf(latestVersion.getVersionCode()).equals(versionCode)) {
                        //弹出框提示用户安装
                        mHandler.obtainMessage(WHAT_ID_INSTALL_APK, downloadApkPath).sendToTarget();
                        return;
                    }
                }
            }
    
            //要检查本地是否有安装包,有则删除重新下
            File apkFile = new File(downloadApkPath);
            if (apkFile.exists()) {
                boolean isDelSuc = apkFile.delete();
            }
    

    4、创建下载Reuqst,开始下载。
    代码片段如下:

            Request task = new Request(Uri.parse(latestVersion.getDownloadUrl()));
            //定制Notification的样式
            String title = "应用名称:" + latestVersion.getVersion();
            task.setTitle(title);
            task.setDescription(latestVersion.getVersionDesc());
           //如果我们希望下载的文件可以被系统的Downloads应用扫描到并管理,我们需要调用Request对象的setVisibleInDownloadsUi方法,传递参数true
            task.setVisibleInDownloadsUi(true);
            //设置是否允许手机在漫游状态下下载
            task.setAllowedOverRoaming(false);
            //限定在WiFi下进行下载
            task.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI | DownloadManager.Request.NETWORK_MOBILE);
            task.setMimeType("application/vnd.android.package-archive");
            // 在通知栏通知下载中和下载完成
            // 下载完成后该Notification才会被显示
            if (Build.VERSION.SDK_INT > Build.VERSION_CODES.HONEYCOMB) {
                // 3.0(11)以后才有该方法
                //在下载过程中通知栏会一直显示该下载的Notification,在下载完成后该Notification会继续显示,直到用户点击该Notification或者消除该Notification
                task.allowScanningByMediaScanner();
                task.setNotificationVisibility(Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
            }
            // 可能无法创建Download文件夹,如无sdcard情况,系统会默认将路径设置为/data/data/com.android.providers.downloads/cache/xxx.apk
            if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
                String apkName = UpgradeHelper.downloadTempName(appContext.getPackageName());
                task.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, apkName);
            }
            downloadTaskId = downloader.enqueue(task);
            mAppUpgradePersistent.saveDownloadTaskId(appContext, downloadTaskId);
    

    下载完成广播

    public void init(Context context)方法中已经注册了监听下载完成广播,一旦我们知道下载完成的时机,就可以调用系统安装界面安装我们的APK啦~
    切记,不可在广播的onReceive中做耗时操作,时间不能超过10秒,否则将ANR卡死!
    下载完成广播定义如下:

        /**
         * 下载完成的广播
         */
        class DownloadReceiver extends BroadcastReceiver {
            @Override
            public void onReceive(Context context, Intent intent) {
                if (downloader == null) {
                    return;
                }
                long completeId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, 0);
                long downloadTaskId = mAppUpgradePersistent.getDownloadTaskId(context);
                if (completeId != downloadTaskId) {
                    return;
                }
    
                Query query = new Query();
                query.setFilterById(downloadTaskId);
                Cursor cur = downloader.query(query);
                if (!cur.moveToFirst()) {
                    return;
                }
    
                int columnIndex = cur.getColumnIndex(DownloadManager.COLUMN_STATUS);
                if (DownloadManager.STATUS_SUCCESSFUL == cur.getInt(columnIndex)) {
                    String uriString = cur.getString(cur.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI));
                    mHandler.obtainMessage(WHAT_ID_INSTALL_APK, uriString).sendToTarget();
                } else {
                    ToastHelper.showToast("xxxApp最新版本失败!");
                }
                // 下载任务已经完成,清除
                mAppUpgradePersistent.removeDownloadTaskId(context);
                cur.close();
            }
        }
    

    点击通知栏响应广播

    如果还未下载完成,点击后进入系统默认的下载界面;下载完成后再点击,就直接调用系统安装界面安装。

        /**
         * 点击通知栏下载项目,下载完成前点击都会进来,下载完成后点击不会进来。
         */
        public class NotificationClickReceiver extends BroadcastReceiver {
            @Override
            public void onReceive(Context context, Intent intent) {
                long[] completeIds = intent.getLongArrayExtra(DownloadManager.EXTRA_NOTIFICATION_CLICK_DOWNLOAD_IDS);
                //正在下载的任务ID
                long downloadTaskId = mAppUpgradePersistent.getDownloadTaskId(context);
                if (completeIds == null || completeIds.length <= 0) {
                    openDownloadsPage(appContext);
                    return;
                }
    
                for (long completeId : completeIds) {
                    if (completeId == downloadTaskId) {
                        openDownloadsPage(appContext);
                        break;
                    }
                }
            }
    
            /**
             * Open the Activity which shows a list of all downloads.
             *
             * @param context 上下文
             */
            private void openDownloadsPage(Context context) {
                Intent pageView = new Intent(DownloadManager.ACTION_VIEW_DOWNLOADS);
                pageView.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                context.startActivity(pageView);
            }
        }
    

    大家会发现,在这个广播中我们并没有看到直接处理下载完成点击通知栏的代码。这个功能我一开始也是无法实现,下载完成后点击一直都是进入系统默认的下载页面。后面google查阅了一些资料,发现系统会调用View action根据mimeType去查询。所以我们要在一开始创建DownloadManager.Request时候调用Requset.setMimeType方法来设置文件类型。

    request.setMimeType("application/vnd.android.package-archive");
    

    ok,看到这边,想必让你来实现检查版本升级已然心中有数。
    那接下来我把遇到的坑,以及是如何埋坑的一一列出来,一定要努力接着往下看哦。。。

    坑一

    需求:进入首页后,开启自动检测升级,检测到有升级的版本就随时弹框提示用户,但此时用户可能已经在操作APP进入其他页面,怎么保证弹框可以正常弹出?(APP不会出现异常或者崩溃)
    升级提示弹框设置为:

    dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
    

    同时在AndroidAmanifest.xml加入权限:

    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
    

    我在华为P9上(7.0)上验证测试没有问题,找了谷歌Nexus 5(4.4)验证也没有问题,以为大功告成!
    后面我谷歌上找了下关于WindowManager.LayoutParams.TYPE_SYSTEM_ALERT适配,竟然有很多文章爆出小米会有问题而且解决方案也是麻烦不是很靠谱,鬼知道是不是还有其他品牌机型会有适配问题,没办法android厂商太多了&系统各种定制!

    靠谱的解决方案

    项目中为了解决这个适配问题,达到一劳永逸的目的,我们设计了一个背景透明的UpgradeActivity,当需要弹出升级提示框时,就启动这个UpgradeActivity然后再显示这个弹框。

    public class UpgradeActivity extends BaseActivity {
    
        boolean isShowDialog = false;
    
        public static void startInstance(Context context) {
            Intent intent = new Intent(context, UpgradeActivity.class);
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            context.startActivity(intent);
        }
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_upgrade);
        }
    
        @Override
        public void onWindowFocusChanged(boolean hasFocus) {
            super.onWindowFocusChanged(hasFocus);
            if (hasFocus && !isShowDialog) {
                isShowDialog = true;
                //升级提示框
                AppUpgradeManager.getInstance().foundLatestVersion(this);
            }
        }
    
      //......
    }
    

    有个需要注意的地方就是弹出框关闭的时候要记得同时销毁UpgradeActivity!!这里没有给出代码,相信你有办法自己解决(广播啊、接口listener啊、EventBus啊等等只要能及时正常关闭都可以)

    坑二

    我把下载的apk文件存放在sd卡下 Download目录里面,绝对路径变量命名为uriDownload,启动安装界面安装,代码如下:

            Intent installIntent = new Intent();
            installIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            installIntent.setAction(Intent.ACTION_VIEW);
            Uri apkFileUri = Uri.fromFile(apkFile);
            installIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            installIntent.setDataAndType(apkFileUri, "application/vnd.android.package-archive");
            try {
                appContext.startActivity(installIntent);
            } catch (ActivityNotFoundException e) {
                Timber.d("installAPKFile exception:%s", e.toString());
            }
    

    一切完成后开始在真机上测试,7.0以下的真机测试都没有问题。我也以为任务完成可以交差了,刚好手头有一部华为P9已经升级到7.0,安装后测试下载完成升级版本然后调用系统安装界面安装直接崩溃了,查看log有这么一句:

    android.os.FileUriExposedException: file:///storage/emulated/0/xxx exposed beyond app through Intent.getData()
    

    认真一看,异常FileUriExposedException之前从来没碰到过。赶紧google发现原来是Android N之后,
    Android 框架执行的 StrictMode,API 禁止向您的应用外公开 file://URI。如果一项包含文件 URI 的 Intent 离开您的应用,应用失败并出现 FileUriExposedException异常。
    若要在应用间共享文件,您应发送一项 content://URI,并授予 URI 临时访问权限。进行此授权的最简单方式是使用 FileProvider类。 如需有关权限和共享文件的更多信息,请参阅共享文件。也就是说,对于应用间共享文件这块,Android N中做了强制性要求。

    问题解决

    既然我们知道了是什么问题,那就开始解决问题吧。
    1、首先在你的manifest里面增加<provider>元素

    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.jemlin.app">
        <application
            ...>
            <provider
                android:name="android.support.v4.content.FileProvider"
                android:authorities="com.jemlin.app.provider"
                android:exported="false"
                android:grantUriPermissions="true">
                <meta-data
                    android:name="android.support.FILE_PROVIDER_PATHS"
                    android:resource="@xml/provider_paths" />
            </provider>
            ...
        </application>
    </manifest>
    

    2、res下创建xml目录,在xml下创建provider_paths.xml资源文件

    <?xml version="1.0" encoding="utf-8"?>
    <paths>
        <!--path:需要临时授权访问的路径(.代表所有路径) name:就是你给这个访问路径起个名字-->
        <external-path
            name="external_files"
            path="." />
    </paths>
    

    3、修改我们刚才调用安装界面的代码,最终如下:

            Intent installIntent = new Intent();
            installIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            installIntent.setAction(Intent.ACTION_VIEW);
    
            Uri apkFileUri;
            // 在24及其以上版本,解决崩溃异常:
            // android.os.FileUriExposedException: file:///storage/emulated/0/xxx exposed beyond app through Intent.getData()
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                apkFileUri = FileProvider.getUriForFile(appContext, BuildConfig.APPLICATION_ID + ".provider", apkFile);
            } else {
                apkFileUri = Uri.fromFile(apkFile);
            }
            installIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            installIntent.setDataAndType(apkFileUri, "application/vnd.android.package-archive");
            try {
                appContext.startActivity(installIntent);
            } catch (ActivityNotFoundException e) {
                Timber.d("installAPKFile exception:%s", e.toString());
            }
    

    抹一把汗水 囧!Android检查版本升级就介绍这些。如您有问题请留言;如您觉得好,就给个赞吧~~

    展开全文
  • java 基础演示

    2019-05-09 17:42:00
    原因:转java 的过程中经常百度,但是有些没有演示 都是些基础的东西 用来积累吧 V1 包含 怎么传参,怎么获取cookie设置,aop 简单的实现,常用注解,配置文件怎么读取 地址如下:...

    java 很基础的一些演示

     

    原因:转java 的过程中经常百度,但是有些没有演示 都是些基础的东西 用来做积累吧

     

    V1

    包含 怎么传参,怎么获取cookie设置,aop 简单的实现,常用注解,配置文件怎么读取

    地址如下:https://github.com/skin33/javaDemo.git

    完善中 目前就一点最常用的 

    希望有人一起弄吧

    转载于:https://www.cnblogs.com/dinghuijun/p/10839937.html

    展开全文
  • 这个demo主要是介绍eBay的一个基于apollo的在线拍卖产品,从这次演示来看,主要突出了几个特色: 1.客户端的快速安装与运行 2.客户端数据保存到文件 3.离线拍照并存储图像 4.连线完成本地与远程数据同步 5....
    演示地址,就是播放窗口有点小,不过还挺流畅。 
    这个demo主要是介绍eBay的一个基于apollo的在线拍卖产品,从这次演示来看,主要突出了几个特色:

    1.客户端的快速安装与运行
    2.客户端数据保存到文件
    3.离线拍照并存储图像
    4.连线完成本地与远程数据同步
    5.类似桌面应用的访问方式(双击启动)
    6.基于Flex的应用程序

    其他的没怎么听清楚,大致就这些,他还强调了apollo的跨平台特色,但是还没有进行演示,不过感觉已经很新颖了,这是他对这次演示做的一些介绍
    展开全文
  • vue怎么做风琴折叠 vue-bulma手风琴 (vue-bulma-accordion) A simple, easily configurable accordion or collapsible for Vue, styled with Bulma. 一种简单,易于配置的手风琴,或可折叠的Vue,采用布尔玛风格。 ...
  • Vuex Demo 讲解

    2017-04-26 06:30:15
    vuex官网的专业术语,让有些人还是感觉,摸不着头脑,一些实用场景给大家看 state 用来数据共享数据存储 mutation 用来注册改变数据状态 getters 用来对共享数据进行过滤操作 action 解决异步改变共享数据 这个...
  • 1月14日,Kyligence 产品经理陈思捷开启了我们在 2021 年的首场线上分享,为大家介绍了用户行为分析的应用场景、以及通过一些行业案例展示如何使用 Kyligence 进行用户行为分析,最后用 Demo 演示了具体的行为分析...
  • ember-react-demo-源码

    2021-06-03 19:36:48
    这是一个综合基准测试,可以完成任何实际应用程序永远不会的事情。 此演示的目的是了解在使用惯用方法构建具有每个相应库的应用程序时,一个库比另一个库显示出更多开销的原因。 这个怎么运作 演示页面包含三个...
  • 您需要的只是在/ AirFighter / bin /路径中运行AirFighter.exe 。我们建议您直接在其自己的路径中运行AirFighter.exe ,以避免不必要的麻烦。 运行AirFighter.exe后,将弹出一个新窗口,您会在窗
  • pact-message-demo-源码

    2021-05-02 05:45:10
    怎么做的: 支持JSON文档中新的匹配规则位置 支持providerStates数组对象(曾经是单个providerState字符串) 局限性: 在阵列中仅支持一个提供者状态对象 尚不支持提供者状态参数 不支持v3中引入的任何新匹配...
  • iOS 相册,图片裁剪工具(附demo

    千次阅读 2017-09-18 11:14:20
    上传图片要求裁剪为4比3的比例,iOS自带裁剪功能是1比1,本来想从网上找一些裁剪工具,发现都不怎么理想,于是就自己了一个,可自定义裁剪区域的工具,希望对大家有用(由于排版,部分代码用的截图,demo中有详细...
  • 想明白OLAP的请看演示(综合管理之决策支持演示全安装) 3-3 请下载新的DEMO 回复者:刘清华 时间: 2008-7-4 16:05:24 http://erp.inspur.com/download/downloadfiles.aspx?fileid=3006 请下载新的DEMO。 回复...
  • 想明白OLAP的请看演示(综合管理之决策支持演示全安装) 2-3 请下载新的DEMO 回复者:刘清华 时间: 2008-7-4 16:05:24 http://erp.inspur.com/download/downloadfiles.aspx?fileid=3006 请下载新的DEMO。 回复...
  • 不是我们今天想讨论的重点,今天只是聊一聊怎么做单元测试。如果您最近也对单元测试是怎么做的发现,介绍文章可能是你需要的。 这篇文章在讲什么? 该中会涉及到Mocha,Chai,Karma,Travis-CI,Istanbul,Codecov等...
  • 3、包装之后,怎么去推广,去应用,例如由桃花岛这种交流性质的,转变为强制推广,是不是应该有体制约束? 清华的东西很好,学习了。 回复: 回复者:马建军 时间: 2008-1-24 11:04:13 不错,属于原创优秀...
  • 在Struts中应用标签的... 三、我这几个示例都是没有查询条件传递的,大家想想如果要传递查询条件应怎么做?(test1.jsp有用到大家再深入一些做个例子) <br> 注:如果谁加了示例请给我传一份:E_wsq@msn.com
  • demo演示: http://demo.tolotolo.cn/etanaluBox/ 想看源码的 你懂的怎么做 首先请学基本功 我推荐 张鑫旭 偶像的这篇 好吧,CSS3 3D transform变换,不过如此! 看完基本攻后 你估计会一半了 剩下的理清...
  • 该存储库提供了常用分布式技术的演示,例如一致性哈希,分布式锁,分布式事务,领导者选举等。 技术 模块 地位 评论 一致性哈希 一致性哈希 完毕 分散式锁 分布式锁 正在 分散式交易 分布式交易 完毕 共识算法 ...
  • 如下我创建了一个名为Demo_git的仓库来演示怎么使用Github代码托管 2.把本地的文件push到仓库中 下面的文件可以假设是你的项目文件,我们将这些代码上传到github中 1.首先在这个目录打开git bash,依次执行git ...
  • 在现任公司从事ERP开发,公司的主业是在硬件方面,所以boss主抓硬件发展,但是对于ERP这块却也管得一丝不漏,前段时间接了个项目,演示demo后,整体菜单风格不合他意,改了,然后拿去客户演示,回来后,又要求改...

空空如也

空空如也

1 2 3 4 5 ... 7
收藏数 131
精华内容 52
热门标签
关键字:

demo演示怎么做