Android设置app开机自启,网络监听,主线程完成UI渲染,HTTP网络请求工具,json数据处理,android使用sqlite,Android定时任务,日志打印

Android7.1.1开机自动启动配置

在AndroidManifest.xml文件中添加权限

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

在AndroidManifest.xml文件中注册接收广播配置, 添加到manifest > application节点下

<receiver
    android:name=".MyReceiver"
    android:enabled="true"
    android:exported="true">
    <intent-filter android:priority="1000">
	<action android:name="android.intent.action.BOOT_COMPLETED"></action>
    </intent-filter>
</receiver>

在AndroidManifest.xml文件中添加节点属性, 指定安装目录为内部存储器, 而非SD卡

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:installLocation="internalOnly">

开机启动执行代码

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;

/**
 * 接收开机广播
 */
public class MyReceiver extends BroadcastReceiver {
    
    
    public MyReceiver() {
    
    
    }

    @Override
    public void onReceive(Context context, Intent intent) {
    
    
        if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED")) {
    
    
            Intent i = new Intent(context, MainActivity.class);
            i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            context.startActivity(i);
        }
    }
}

网络联网监听

public class NetWorkUtil {
    
    
    public static boolean checkNetworkState(MainActivity mainActivity) {
    
    
        //使用ConnectivityManager检查网络状态步骤
        ConnectivityManager connectivityManager = (ConnectivityManager) mainActivity.getSystemService(CONNECTIVITY_SERVICE);//1.通过系统服务获取ConnectivityManager类的对象
        NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();//2.调用getActiveNetworkInfo()获取当前活动的网络NetworkInfo对象
        //3.判断当前网络状态是否为连接状态,如果当前没有网络是活动的,则返回null
        if (networkInfo != null && networkInfo.isConnected()) {
    
    
            MainActivity.toast.setText("您已连接网络");
            MainActivity.toast.show();
            MainActivity.timer.schedule(new TimerTask() {
    
    
                @Override
                public void run() {
    
    
                    String res = HttpUtil.get(URLConst.SERVER_URL);
                    if (res == null) {
    
    
                        MainActivity.timer.schedule(new TimerTask() {
    
    
                            @Override
                            public void run() {
    
    
                                MainActivity.toast.setText("您与服务器的通讯异常, 数据可能会同步失败!");
                                MainActivity.toast.show();
                            }
                        }, 3000);
                    } else {
    
    
                        Map map = JSONUtil.toObject(res, Map.class);
                        if (map.get("code").toString().startsWith("200")) {
    
    
                            MainActivity.timer.schedule(new TimerTask() {
    
    
                                @Override
                                public void run() {
    
    
                                    MainActivity.toast.setText("您与服务器的通讯正常!");
                                    MainActivity.toast.show();
                                }
                            }, 3000);
                        } else {
    
    
                            MainActivity.timer.schedule(new TimerTask() {
    
    
                                @Override
                                public void run() {
    
    
                                    MainActivity.toast.setText("您与服务器的通讯异常, 数据可能会同步失败!");
                                    MainActivity.toast.show();
                                }
                            }, 3000);
                        }
                    }
                }
            }, 1000);
            return true;
        } else {
    
    
            MainActivity.toast.setText("您已断开网络");
            MainActivity.toast.show();
            return false;
        }
        // 检测和服务器之间的连接
    }
}

UI主线程才能执行界面渲染, 其他线程执行渲染都会报错

MainActivity.this.runOnUiThread(() -> {
    
    
    EditText edit = (EditText) findViewById(R.id.txt_msg);
    String now = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.CHINESE).format(new Date());
    long tid = Thread.currentThread().getId();
    String txt = String.format("%s\r\n%s - %d: %s", edit.getText(), now, tid, msg);
    edit.setText(txt);
    edit.setSelection(edit.getText().length());
});

网络HTTP请求工具类

import android.util.Log;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;

public class HttpUtil {
    
    
    public static String postJson(String url, HashMap<String, String> headerMap, Object data) {
    
    
        HttpURLConnection conn = null;
        try {
    
    
            Log.d("main", "请求准备" + url);
            conn = (HttpURLConnection) new URL(url).openConnection();
            conn.setRequestMethod("POST");//设置POST请求方式
            conn.setConnectTimeout(5000);//设置超时时间

            conn.setRequestProperty("Content-Type", "application/json");
//            if (data == null) {
    
    
//                data = new Object();
//            }
            String jsonStr = JSONUtil.toJSONString(data);
            Log.d("main", "请求准备 - 已添加参数" + jsonStr);
            byte[] bytes = jsonStr.getBytes(StandardCharsets.UTF_8);
            Log.d("main", "请求准备 - 参数大小" + bytes.length);
            conn.setRequestProperty("Content-Length", String.valueOf(bytes.length));//设置请求头,设置提交数据的长度
            if (headerMap != null) {
    
    
                for (String key : headerMap.keySet()) {
    
    
                    conn.setRequestProperty(key, headerMap.get(key));
                }
            }
            Log.d("main", "请求准备 - 已添加请求头");

            conn.setDoOutput(true);//设置允许向外写数据
            conn.connect();//连接
            Log.d("main", "请求准备 - 连接");

            //4.通过getOutputStream()获得输出流往服务器写数据
            OutputStream outputStream = conn.getOutputStream();//通过getOutputStream()获得输出流
            outputStream.write(jsonStr.getBytes());
            Log.d("main", "请求准备 - 写入数据");

            int code = conn.getResponseCode();//获取HTTP状态码
            Log.d("main", "响应处理 - 获取状态码");
            if (code == HttpURLConnection.HTTP_OK) {
    
    //5.得到响应码并判断连接正常后,通过getInputStream()方法获得携带服务器返回信息的输入流,从流中读取出服务器返回值,并向handler发送消息
                System.out.println(conn.getResponseCode());//控制台输出
                InputStream inputStream = conn.getInputStream();//得到响应流(通过getInputStream()方法获取携带服务器返回信息的输入流)
                byte[] dataBytes = parseResponse(inputStream);
                String msg = new String(dataBytes, StandardCharsets.UTF_8);
                Log.d("main", msg);
                return msg;
            } else {
    
    
                Log.d("main", "请求失败了" + conn.getResponseCode());
            }
        } catch (Exception e) {
    
    
            e.printStackTrace();
            Log.d("main", "请求异常了");
        } finally {
    
    
            if (conn != null) {
    
    
                conn.disconnect();//关闭HTTP连接
            }
        }
        return null;
    }

    public static String get(String url) {
    
    
        HttpURLConnection conn = null;
        try {
    
    
            Log.d("main", "请求准备" + url);
            conn = (HttpURLConnection) new URL(url).openConnection();
            conn.setRequestMethod("GET");
            conn.setConnectTimeout(5000);//设置超时时间

            conn.connect();//连接
            Log.d("main", "请求准备 - 连接");

            int code = conn.getResponseCode();//获取HTTP状态码
            Log.d("main", "响应处理 - 获取状态码");
            if (code == HttpURLConnection.HTTP_OK) {
    
    //5.得到响应码并判断连接正常后,通过getInputStream()方法获得携带服务器返回信息的输入流,从流中读取出服务器返回值,并向handler发送消息
                System.out.println(conn.getResponseCode());//控制台输出
                InputStream inputStream = conn.getInputStream();//得到响应流(通过getInputStream()方法获取携带服务器返回信息的输入流)
                byte[] dataBytes = parseResponse(inputStream);
                String msg = new String(dataBytes, StandardCharsets.UTF_8);
                Log.d("main", msg);
                return msg;
            } else {
    
    
                Log.d("main", "请求失败了" + conn.getResponseCode());
            }
        } catch (Exception e) {
    
    
            e.printStackTrace();
            Log.d("main", "请求异常了" + e.getMessage());
        } finally {
    
    
            if (conn != null) {
    
    
                conn.disconnect();//关闭HTTP连接
            }
        }
        return null;
    }

    private static byte[] parseResponse(InputStream input) {
    
    
        byte[] buff = new byte[1024];
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        int len;
        try {
    
    
            while ((len = input.read(buff)) != -1) {
    
    
                byteArrayOutputStream.write(buff, 0, len);
            }
            return byteArrayOutputStream.toByteArray();
        } catch (IOException e) {
    
    
            e.printStackTrace();
            return null;
        }
    }
}

Android处理json数据, 添加gson依赖

gson是谷歌…
implementation ‘gson-2.8.5’
依赖无法下载, 直接使用jar包, 将jar包放到libs目录下, 然后到build.gradle文件中, dependencies节点下添加implementation(fileTree(“libs”)); 然后创建工具类

import com.google.gson.Gson;

public class JSONUtil {
    
    
    public static String toJSONString(Object o) {
    
    
        Gson gson = new Gson();
        return gson.toJson(o);
    }

    public static <T> T toObject(String json, Class<T> tClass) {
    
    
        Gson gson = new Gson();
        return gson.fromJson(json, tClass);
    }
}

在Android中使用sqlite

SQLite,是一款轻型的数据库,是遵守ACID的关系型数据库管理系统,它包含在一个相对小的C库中。它是D.RichardHipp建立的公有领域项目。它的设计目标是嵌入式的,而且已经在很多嵌入式产品中使用了它,它占用资源非常的低,在嵌入式设备中,可能只需要几百K的内存就够了。它能够支持Windows/Linux/Unix等等主流的操作系统,同时能够跟很多程序语言相结合,比如 Tcl、C#、PHP、Java等,还有ODBC接口,同样比起Mysql、PostgreSQL这两款开源的世界著名数据库管理系统来讲,它的处理速度比他们都快。SQLite第一个Alpha版本诞生于2000年5月。 至2021年已经接近有21个年头,SQLite也迎来了一个版本 SQLite 3已经发布。

历史

从某种程度上说,SQLite最初的构思是在一条军舰上进行的。当时在通用动力工作的SQLite的作者 [1] D. Richard Hipp正在为美国海军编制一种使用在导弹驱逐舰上的程序。那个程序最初运行在Hewlett-Packard UNIX(HPUX)上,后台使用Informix数据库。对那个具体应用而言,Informix有点儿太强大了。一个有经验的数据库管理员(DBA)安装或升级Informix可能需要一整天,如果是没经验的程序员,这个工作可能永远也做不完。真正需要的只是一个自我包含的数据库,它易使用并能由程序控制传导,另外,不管其他软件是否安装,它都可以运行。

2000年1月,Hipp开始和一个同事讨论关于创建一个简单的嵌入式SQL数据库的想法,这个数据库将使用GNU DBM哈希库(gdbm)做后台,同时这个数据库将不需要安装和管理支持。后来,一有空闲时间,Hipp就开始实施这项工作,2000年8月,SQLite 1.0版发布了。

按照原定计划,SQLite 1.0用gdbm作为存储管理器。然而,Hipp不久就用自己实现的能支持事务和记录按主键存储的B-tree替换了gdbm。随着第一次重要升级的进行,SQLite有了稳定的发展,功能和用户也在增长。2001年中期,很多项目–开源的或商业的–都开始使用SQLite。在随后的几年中,开源社区的其他成员开始为他们喜欢的脚本语言和程序库编写SQLite扩展。一个接着一个,既Perl、Python、Ruby、Java和其他主流的程序设计语言的扩展之后,新的扩展如SQLite的ODBC接口出现并证明了SQLite的广泛应用和实用功能。
2004年,SQLite从版本2升级到版本3,这是一次重大升级。

Android中使用sqlite的使用工具类

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

import androidx.annotation.Nullable;

/**
 * MySqliteOpenHelper 工具类 单例模式(1.构造函数私有化,2.对外提供函数。)
 */
// 该类就可以理解为一个数据库了。
public class MySqliteOpenHelper extends SQLiteOpenHelper {
    
    

    // 单例模式
    private static SQLiteOpenHelper mInstance;

    // 提供对外提供的函数。
    public static synchronized SQLiteOpenHelper getInstance(Context context) {
    
    
        if (mInstance == null) {
    
    
            mInstance = new MySqliteOpenHelper(context, "security_detector.db", null, 1);
        }
        return mInstance;
    }

    /**
     * 通过构造函数,将数据库名称,数据库版本号等定义出来。因此,必须要声明一个构造函数。
     *
     * @param context context就是环境,在此环境下进行创建数据库。
     * @param name    数据库名称
     * @param factory 工厂
     * @param version 版本 数据库升级后需要不断加1操作!
     */
    public MySqliteOpenHelper(@Nullable Context context, @Nullable String name, @Nullable SQLiteDatabase.CursorFactory factory, int version) {
    
    
        super(context, name, factory, version);
    }

    /**
     * 数据库初始化用的:
     * 创建表 表数据初始化 数据库第一次创建的时候调用。第二次发现有该表了就不会重复创建了!
     * 此函数只会执行一次。 因此,添加了新的数据库或者修改了数据库,必须要对应项目目录将databases目录下的db等文件删除。
     *
     * @param sqLiteDatabase
     */
    @Override
    public void onCreate(SQLiteDatabase sqLiteDatabase) {
    
    
        String sql = "create table serial_setting(" +
                "_id integer primary key autoincrement," +
                "updated_time DATETIME" +
                ")";
        // 执行sql
        sqLiteDatabase.execSQL(sql);
    }

    // 数据库升级用的
    @Override
    public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
    
    

    }

}

添加数据库 sqlite DDL

增删改都是执行execSQL, 查询用rawQuery

private void initScreenData() {
    
    
    SQLiteOpenHelper helper = MySqliteOpenHelper.getInstance(this);
    // 读数据
    SQLiteDatabase db = helper.getReadableDatabase();
    if (db.isOpen()) {
    
    
        Cursor cursor = db.rawQuery("SELECT * FROM serial_setting;", null);
        if (cursor.getCount() == 0) {
    
    
            Log.d("main", "第一次加载, 开始初始化数据");
            // 初始化
            String sql = "insert into serial_setting(updated_time)";
            sql += "values(?)";
            Object[] args = new Object[]{
    
    
                    new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.CHINESE).format(new Date())
            };
            db.execSQL(sql, args);
        } else {
    
    
            try {
    
    
                cursor.moveToNext();
                int id = cursor.getInt(cursor.getColumnIndex("_id"));
                String updatedTime = cursor.getString(cursor.getColumnIndex("updated_time"));
            } catch (NumberFormatException e) {
    
    
                e.printStackTrace();
                Log.d("main", "设置数据库存储的数据失败, 可能有空值!");
            }
        }
        cursor.close();
        db.close();
    }
}

Android中使用定时任务

同Java一样, 使用java.util.Timer
每个timer都是一个执行者, TimerTask是要完成的事, timer在启动时就会创建一个线程和队列用于执行内部队列任务, 执行schedule会添加任务到任务队列中

Timer timer = new Timer();
// 定时执行数据发送(如果存在)
timer.schedule(new TimerTask() {
    
    
    @Override
    public void run() {
    
    
        if (System.currentTimeMillis() - bufferUpdatedTime >= intervalTime) {
    
    
            // 超过更新时间, 处理本次数据
            if (buffer.length() != 0) {
    
    
                Log.d("main", "发送数据");
                sendBufferData();
            } else {
    
    
                Log.d("main", "数据为空, 放弃发送数据");
            }
        }
    }
}, intervalTime, intervalTime);

打印屏幕提示信息

直接初始化一个Toast或方法, 多页面共用

public static Toast toast = null;

@Override
protected void onCreate(Bundle savedInstanceState) {
    
    
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    if (toast == null) {
    
    
        toast = Toast.makeText(MainActivity.this, "", Toast.LENGTH_SHORT);
    }
}

猜你喜欢

转载自blog.csdn.net/qq_27577113/article/details/131170887