距离上一篇文章发表都已经差不多1个月了,一场席卷全球的肺炎给全球经济和生活带来了巨大的损失,也被誉为人类的第三次世界大战;有幸有不幸吧。而我也有时间专注安卓的开发,现在就关公舞大刀,分享一下安卓开发经验二三事。
第一、Android Studio 生成自定义文件名apk
由于实际需要,有时候同一份代码要修改某些地方然后生成不同的app。但自动生成的app文件名都一样不好区分,生成后改名也常常忘记,于是就有了下面这段代码。
打开build.gradle(APP)文件,在android 下面加入以下代码。
applicationVariants.all {
//判断是release还是debug版本
def buildType = it.buildType.name
def fileName
def date = new Date().format("yyyyMMdd", TimeZone.getTimeZone("Asia/Chongqing"))
def formattedDate = date.format('yyyyMMdd')
it.outputs.each {
//只对Release包起作用,如果不是Release包则不变更名称。
if (buildType == "release") {
//我此处的命名规则是:渠道名_项目名_版本名_创建时间_构建类型.apk
fileName = "${defaultConfig.applicationId}${defaultConfig.versionName}_release_${date}-${buildType}.apk"
//将名字打印出来,以便及时查看是否满意。
println "文件名:-----------------${fileName}"
//重新对apk命名。(适用于Gradle3.0以下版本)
// outputFile = new File(outputFile.parent, fileName)
//重新对apk命名。(适用于Gradle3.0(含)以上版本)如果你Gradle版本是4.0以下版本则将上面的一行代码放开并注释下面的这一行。
it.outputFileName = fileName
}else if(buildType == "debug"){
fileName = "${defaultConfig.applicationId}${defaultConfig.versionName}_debug_${date}-${buildType}.apk"
//将名字打印出来,以便及时查看是否满意。
println "文件名:-----------------${fileName}"
//重新对apk命名。(适用于Gradle3.0以下版本)
// outputFile = new File(outputFile.parent, fileName)
//重新对apk命名。(适用于Gradle3.0(含)以上版本)如果你Gradle版本是4.0以下版本则将上面的一行代码放开并注释下面的这一行。
it.outputFileName = fileName
}
}
}
这样就能自动生成带日期的APK.
第二、Android 防止App退出 或者 启动另一个App
在安卓开发中会遇到主程序被其他程序终止的问题或退出的问题,于是就用一个线程来检测任务栈中第一个是否自己的程序,如果不是就。。好吧还是直接上代码。
public class MainActivity extends AppCompatActivity {
String m_sMonitorAppName = "app"; //要监测的App的包名
//这里我起了一个线程
/*********************************************************************/
class MyThread implements Runnable {
public void run(){
while(true){
ActivityManager manager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
List<ActivityManager.RunningAppProcessInfo> runningTasks = manager.getRunningAppProcesses();
// 获得当前最顶端的任务栈,即前台任务栈
ActivityManager.RunningAppProcessInfo runningTaskInfo = runningTasks.get(0);
String packageName = runningTaskInfo.processName.toString();
if(!packageName.equals(m_sMonitorAppName)){
PackageManager packageManager = getPackageManager();
PackageInfo packageInfo = null;
//在这里,该App虽然没在前台运行,也有可能在后台运行(未被结束),
//为了更合理,应该先结束掉,但是注释的方法总是崩溃..........
//android.os.Process.killProcess(runningTaskInfo.pid); //结束进程
try {
packageInfo = getPackageManager().getPackageInfo(packageName, 0);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
if(packageInfo != null){
Intent intent = packageManager.getLaunchIntentForPackage(m_sMonitorAppName);
startActivity(intent);//启动App
}
}
try {
Thread.sleep(3000); //延时3s
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
/*********************************************************************/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/*
TimerTask task= new TimerTask() {
@Override
public void run() {
}
};
new Timer().schedule(task,2000,3000);
起初,没想用线程,想用一个定时器来看守,怎想,一直崩溃
*/
MyThread startThread = new MyThread();
new Thread(startThread ).start(); //启动线程
}
}
最后记得加任务权限,要不白忙乎的。<uses-permission android:name="android.permission.GET_TASKS"/>
第三、串口读写。
由于有些安卓不知道串口返回的数据会断截或分行,旧的代码有问题,于是找来了新的串口代码。代码如下:
protected class LReadThread extends Thread {
@Override
public void run() {
super.run();
while (!interrupted()) {
int bytes;
int ch;//读取字符串变量
try {
if (lInputStream == null)
return;
//处理读取
byte[] buffer = new byte[64];
bytes=0;
while ((ch = lInputStream.read()) != '\n'){
if (ch != -1) {
buffer[bytes] = (byte) ch;
bytes++;
}
}
buffer[bytes] = '\n';
bytes++;
if (bytes > 0) {
onDataReceived(buffer, bytes, 0);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
以上代码串口返回必须是\n,即是说每条串口的返回结尾必须要\n.
如果无法控制,那就下面这个代码吧。
private class MReadThread extends Thread {
@Override
public void run() {
super.run();
while (!isInterrupted()) {
try {
if (mInputStream == null)
return;
byte[] buffer = new byte[64];
int mcount;
if (mInputStream.available() <= 0) {
continue;
} else {
Thread.sleep(300);
}
mcount = mInputStream.read(buffer);
if (mcount > 8) {
onDataReceived(buffer, mcount, 1);
}
} catch (IOException e) {
e.printStackTrace();
return;
} catch (InterruptedException e) {
e.printStackTrace();
return;
}
}
}
}
这个就不限制最后的结尾,但必须要大于8位的字符。
好了,今天就分享到这来,青山不改,绿水长流。有缘的我再发表其他资料吧。感谢大家的阅读,好的记得给赞啊。。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。