移动设备交互应用 大作业(二)

简介: 移动设备交互应用 大作业(二)

(4)图片识别:


本次大作业中,额外更部署了图片识别功能,也通过调用对应API接口来完成图片的识别,并完成对识别出结果的垃圾分类。


①与语音识别相同,首先要申请权限,如果获得权限则接口就绪,否则弹出权限不足的提示。

private void opemCamera() {  
     PermissionUtils.permission(Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA)  
             .callback(new PermissionUtils.FullCallback() {  
                 @Override  
                 public void onGranted(List<String> permissionsGranted) {  
                     PictureSelector.create(HomeActivity.this)  
                             .openGallery(PictureMimeType.ofImage())  
                             .maxSelectNum(1)  
                             .selectionMode(PictureConfig.SINGLE)  
                             .forResult(9);  
                 }  
                 @Override  
                 public void onDenied(List<String> permissionsDeniedForever, List<String> permissionsDenied) {  
                     LogUtils.e("权限不足");  
                     showToast("权限不足");  
                 }  
             }).request();  
 }  


②获取上传的图片后,调用对应的API接口,然后获取返回数据,并进行垃圾种类的判断。


private void loadImage(String image) {  
     showStatus(mViewLottie, new LoadAbstract(this));  
     OrcLoadUtils.imageTAg(image).subscribe(o -> {  
         LogUtils.e(o.toString());  
         if (o != null && !StringUtils.isEmpty(o.toString())) {  
             mEtSearch.setText(o.toString());  
         } else {  
             hideStatus(mViewLottie);  
         }  
     });  
 }  


(5)网络监测:


这里我使用了广播系统对网络进行判断,并在没有网络的时候toast出提示信息。


public class NetWorkStateReceiver extends BaseBroadcastReceiver {  
 @Override  
 public void onReceive(Context context, Intent intent, int flag) {  
     if (ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) {  
         // 发送网络改变事件  
         ConnectivityManager manager = (ConnectivityManager) Utils.getApp().getSystemService(Context.CONNECTIVITY_SERVICE);  
         //没有网络链接的时候 activeNetwork=null  
         NetworkInfo activeNetwork = manager.getActiveNetworkInfo();  
         if (activeNetwork == null){  
            ToastUtils.showShort("没有网络");  
         }else {  
            //ToastUtils.showShort("有网络");  
         }  
     }  
 } 


(6)版本更新


在我们使用其他APP时,经常会遇到需要版本更新的情况,在本次大作业中,也有类似的设计。在本大作业中,我通过使用蒲公英代码托管平台托管最新版本,并通过对应API接口完成版本号获取,并完成更新。


①首先定义获取更新类:


public static class DataBean {  
    public boolean isForce;//是否强制更新  
    public int version;//版本号  
    public String message;//更新信息  
    public String url;//API接口链接  
} 


②更新检测(判断是否有更新版本):


此处即进行版本号判断,如果没有更新版本,则提示“你已经是最新版本”。否则调用APP更新类对APP进行更新。

public static void checkUpdateVersion(final BaseActivity context) {  
 JKX_API.getInstance().getAppVersion("", new Observer() {  
     @Override  
     public void onSubscribe(Disposable d) {  
     }  
     @Override  
     public void onNext(Object o) {  
         try {  
             VersionEntity versionEntity = (VersionEntity) o;  
             String newVersion = versionEntity.data.version + "";  
             boolean isShowUpdate = AppUpdateUtils.newInstance().isCanUpdateApp(newVersion, context);  
             SPUtils.getInstance().put("is_update", isShowUpdate);  
             if (isShowUpdate)  
                 AppUpdateUtils.newInstance().updateApp(context, versionEntity.data.version + "", versionEntity.data.isForce , versionEntity.data.message, versionEntity.data.url);  
             else  
                 context.showToast("你已经是最新版本");  
         } catch (Exception e) {  
             e.printStackTrace();  
         }  
     }  
     @Override  
     public void onError(Throwable e) {  
         LogUtils.e(e);  
         SPUtils.getInstance().put("is_update", false);  
     }  
     @Override  
     public void onComplete() {  
     }  
 }); 


③弹出更新对话框:


更新时需要弹出更新对话框让用户知晓,因此需要设计一个对话框,让用户明确即将进行版本更新,若为非强制更新,则让用户选择是否进行更新。


public void showDownLoadDialog(final BaseActivity activity, final boolean isForce, String message, final String url) {  
     final WeakReference<BaseActivity> activityWeak = new WeakReference<BaseActivity>(activity);  
     final IosPopupDialog dialog = new IosPopupDialog(activity);  
     if (isForce) {//如果是非强制更新则让用户可以选择更新或取消  
         dialog.setCanceledOnTouchOutside(false);  
         dialog.setCancelable(false);  
     } else {  
         dialog.setCanceledOnTouchOutside(false);  
         dialog.setCancelable(true);//取消使能  
     }  
     dialog.setTextColor(R.id.tv_title, Color.parseColor("#333333"));  
     dialog.setTextColor(R.id.tv_message, Color.parseColor("#333333"));  
     //弹出对话框  
     dialog.setTitle("新版本更新说明")  
             .setMessage(message)  
             .setPositiveButton("确定", true, new View.OnClickListener() {  
                 @Override  
                 public void onClick(View v) {  
                     downLoadApk(activityWeak, isForce, url);  
                 }  
             });  
     if (!isForce) {  
         dialog.setNegativeButton("稍后再说", true, new View.OnClickListener() {  
             @Override  
             public void onClick(View v) {  
                 dialog.dismiss();  
             }  
         });  
     }  
     dialog.show();  
 }  

下载对话框为一个弹窗,布局使用LinearLayout进行布局。

e1c69eda166f400f95b905d824258cd7.png

<TextView  
     android:layout_width="wrap_content"  
     android:layout_height="wrap_content"  
     android:text="正在下载"  
     android:textColor="@color/black"  
     android:textSize="16sp"/>  
 <TextView  
     android:id="@+id/tv_update_app_progress"  
     android:layout_width="wrap_content"  
     android:layout_height="wrap_content"  
     android:layout_marginTop="8dp"  
     android:text="0%"  
     android:textColor="@color/black"  
     android:textSize="14sp"/>  
 <me.android.materialprogressbar.MaterialProgressBar  
     android:id="@+id/mpb_update_app_progress"  
     style="@style/Widget.MaterialProgressBar.ProgressBar.Horizontal"  
     android:layout_width="match_parent"  
     android:layout_height="wrap_content"  
     android:layout_marginLeft="8dp"  
     android:layout_marginRight="8dp"  
     android:layout_marginTop="8dp"  
     android:max="100"  
     app:mpb_progressBackgroundTint="#f0f0f5"  
     app:mpb_progressStyle="horizontal"  
     app:mpb_progressTint="@color/colorPrimary"/> 

④开始下载更新文件:


此处通过API接口完成更新数据流的链接,不断从API中获取更新数据。对于非强制更新,需要在更新时赋予用户取消使能。此时可以重用②中弹出对话框的代码。

显示之后即可新建线程,对线程启用监听,获取下载状态。


baseDownloadTask = FileDownloader.getImpl()  
             .create(url)  
             .setPath(FileDownloadUtils.getDefaultSaveRootPath() + "/" + "download")  
             .setForceReDownload(true)  
             .setListener(new FileDownloadListener()  


若未处于下载状态则提示“等待中”字样。

protected void pending(BaseDownloadTask task, int soFarBytes, int totalBytes) {  
    LogUtils.d("BaseDownloadTask:pending");  
}  

若处于下载状态,则显示当前下载进度

protected void progress(BaseDownloadTask task, int soFarBytes, int totalBytes) {  
  int percent = (int) ((double) soFarBytes / (double) totalBytes * 100);  
  LogUtils.d("BaseDownloadTask:" + percent);  
  bar.setProgress(percent);  
  progress.setText(percent + "%");  
 } 

⑤此外,如果发生错误或警告,需要提示用户取消

protected void error(BaseDownloadTask task, Throwable e) {  
    downDialog.dismiss();  
}   
protected void warn(BaseDownloadTask task) {  
    downDialog.dismiss();  
}


(7)调用商店进行评分


在日常中我们使用的APP都会包含评分功能,通过调用系统的APP商店进行评分。本大作业也实现了这个功能。

只需调用对应的url并加载对应的Activity即可。此处使用了Intent进行传值。


Intent i = new Intent(Intent.ACTION_VIEW);  
             i.setData(Uri.parse("market://details?id=" + AppUtils.getAppPackageName()));  
             i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);  
             startActivity(i);  


(8)退出提示:


在我们日常使用APP的过程中经常遇到,为了防止用户误操作,造成意外退出的情况,此时需要当用户在主页面上连续两次点击返回而不是一次才能进行退出操作。

为了实现这个操作,只需判断用户是否在连续两秒内连续点击回退按钮即可。


   public boolean onKeyDown(int keyCode, KeyEvent event) {  
    if (keyCode == KeyEvent.KEYCODE_BACK) {  
        long time = System.currentTimeMillis();  
        if (time - firstTime > 2000) {  
            showToast("再按一次退出");  
            firstTime = time;  
            return true;  
        } else {  
            finish();  
        }  
    }  
    return super.onKeyDown(keyCode, event);  
}  

(9)打包成APK:


为了方便发布本APP,需要将APP打包成APK的格式,此处需要使用数字秘钥,选择Build->Generate Signed Bundle/APK 并选择APK,点击Next。

12b1504df4d9421fa8e182d4ea440b97.png

然后由于本地没有数字秘钥,可以创建一个,点击new按钮。并在弹出页面中输入对应的信息和密码(此处密码都为SZUDYH)后点击OK,即可创建。到对应目录下即可看到打包好的APK文件

67e408b508634b2e9da7ff9fd5dafa5e.png


相关文章
|
监控 API C++
利用C++构建PC端监控软件:实时屏幕录制
在今天的数字化世界中,监控软件变得越来越重要。无论是家庭用户需要监控他们的孩子,还是企业需要监控员工的电脑活动,实时屏幕录制是一种有效的方法。本文将向您介绍如何使用C++构建PC端监控软件,实现实时屏幕录制功能。此外,我们还将讨论如何自动提交监控到的数据到一个网站上。
484 0
|
编解码 网络协议 Linux
跨平台 scrcpy显示/控制安卓手机方案
• Genymotion、Parallels Desktop 等虚拟机软件 太专业, 需要配置太多软件, 适合开发者. • 国内一批安卓游戏助手都可以一试, 这里我随便下载了一款网易MuMu对字体的显示不太好. 可以尝试一下 傲软投屏(ApowerMirror) • Vysor Pro 收费较贵,免费版广告又多
757 0
|
2月前
|
API 数据安全/隐私保护 开发者
使用MechanicalSoup进行网页自动化交互
使用MechanicalSoup进行网页自动化交互
|
2月前
|
缓存 JavaScript 前端开发
如何设计交互式应用程序?
【10月更文挑战第7天】如何设计交互式应用程序?交互式应用程序
54 5
|
3月前
|
存储 安全 Linux
I/O设备的运行时电源管理框架【ChatGPT】
I/O设备的运行时电源管理框架【ChatGPT】
|
3月前
|
IDE 开发工具
Devres - 管理设备资源 【ChatGPT】
Devres - 管理设备资源 【ChatGPT】
|
4月前
|
小程序 前端开发 JavaScript
微信小程序结合PWA技术,提供离线访问、后台运行、桌面图标及原生体验,增强应用性能与用户交互。
微信小程序结合PWA技术,提供离线访问、后台运行、桌面图标及原生体验,增强应用性能与用户交互。开发者运用Service Worker等实现资源缓存与实时推送,利用Web App Manifest添加快捷方式至桌面,通过CSS3和JavaScript打造流畅动画与手势操作,需注意兼容性与性能优化,为用户创造更佳体验。
109 0
|
7月前
|
调度
LabVIEW使用实时跟踪查看器调试多核应用程序
LabVIEW使用实时跟踪查看器调试多核应用程序
58 4
|
7月前
|
存储 缓存 数据安全/隐私保护
移动应用中的离线模式是一种重要的功能
【5月更文挑战第16天】移动应用的离线模式通过数据缓存和存储确保无网时仍能使用部分功能。数据同步采用延迟策略,用户更改信息后在网络恢复时同步至服务器。为保障安全,敏感数据加密存储并定期备份。开发者还需关注用户体验、电量性能及错误处理,以实现稳定可靠的离线模式,提升用户体验。
161 0
|
7月前
|
并行计算 Linux 异构计算
分享一款刚开源上线3天的音乐人声分离工具!无需联网!页面化操作!
分享一款刚开源上线3天的音乐人声分离工具!无需联网!页面化操作!
101 1
下一篇
无影云桌面