通过Android客户端UI界面布局设计,前端与后端的数据交互,数据的读取、加载、写入,实现技术架构的论证。主要通过Fragment实现界面导航、OkHttp3实现网络通讯(数据加载、递交、更新)、smartrefresh(下拉刷新、上拉加载),同时编写APP版本自动升级模块。
一、开发
1、Android Studio下载。https://developer.android.google.cn/studio/
【2021年01月26日更新】
2、引用okhttp3。在build.gradle文件中添加库,然后点击工具栏“Sync Project With Gradle Files”。
dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation 'com.android.support.constraint:constraint-layout:1.1.3' testImplementation 'junit:junit:4.12' androidTestImplementation 'com.android.support.test:runner:1.0.2' androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' implementation 'com.android.support:design:27.1.1' implementation 'com.squareup.okhttp3:okhttp:3.11.0' implementation 'com.squareup.okio:okio:1.15.0' }
3、引用smartrefresh下拉刷新/上拉加载控件。在build.gradle文件中添加库,然后点击工具栏“Sync Project With Gradle Files”。
implementation ‘com.android.support:recyclerview-v7:27.1.0’
implementation ‘com.scwang.smartrefresh:SmartRefreshLayout:1.0.5.1’
implementation ‘com.scwang.smartrefresh:SmartRefreshHeader:1.0.5.1’
二、真机调试
1、华为p10开启 “开发者选项”。
进入“设置”界面,点击“关于手机”,连续点击7次“版本号”,直到屏幕提示“您正处于开发者模式!”。
2、返回“设置”界面,点击“开发者选项”。
开启USB调试。
3、华为p10关闭 “开发者选项”。
进入“设置”界面,应用管理->设置->存储->删除数据。
4、部署Apk到真机上。工具栏,点击“Edit Configurations”,打开“Run/Debug Configurations”,在“Deployment Target Options”中,选择“USB Device”。
5、如果无法安装部署,则安装“华为手机助手”。
三、开发日志
1、Fragment中view.findViewById取值为null。因为layout中两级嵌套,不能用findViewById在父一级中去寻找子一级的控件,所以把inflater.inflate的第二个参数赋值从container修改为null。
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_task, null, false); }
2、App访问PHP服务器保持在同一个session的方式。在请求中增加Cookie、PHPSESSID。PHPSESSID是第一请求服务器返回的session_id()。
OkHttpClient client = new OkHttpClient(); Request request = new Request.Builder().url(url).addHeader("Cookie", "PHPSESSID=" + ctsApp.getSession_id()).build();
四、主界面
五、升级
1、动态获取权限。
/** * 动态获取权限,一些保护权限,除了要在AndroidManifest中声明权限,还要使用如下代码动态获取 */ if (Build.VERSION.SDK_INT >= 23) { int REQUEST_CODE_CONTACT = 101; String[] permissions = {Manifest.permission.WRITE_EXTERNAL_STORAGE}; // 验证是否许可权限 for (String str : permissions) { if (ActivityCompat.checkSelfPermission(LoginActivity.this, str) != PackageManager.PERMISSION_GRANTED) { // 申请权限 ActivityCompat.requestPermissions(LoginActivity.this, permissions, REQUEST_CODE_CONTACT); return; } } }
2、 通过设置FileProvider允许访问安装文件的路径。
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="cn.mf.cts"> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" /> <uses-permission android:name="android.permission.DOWNLOAD_WITHOUT_NOTIFICATION" /> <application android:name="CtsApp" android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".LoginActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".MainActivity" android:label="@string/app_name" > </activity> <provider android:name="android.support.v4.content.FileProvider" android:authorities="cn.mf.cts.fileprovider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> </provider> </application> </manifest>