最近需要写个app方便工作,第一次写app,这里做个记录,方便以后代码的粘贴复制。
首先编写activity_main.xml,其中添加了四个按钮,对应四个功能,分别为添加服务,关闭服务,发送邮件和提权:
主界面MainActivity:
import android.annotation.SuppressLint;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.IBinder;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.security.Provider;
import javax.mail.MessagingException;
public class MainActivity extends AppCompatActivity {
public static Context mContext;
@SuppressLint("ResourceType")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mContext = this;
setContentView(R.xml.activity_main);
inti();//调用init()方法
}
//inti()方法,在该方法中获取界面控件并实现控件的点击事件。
private void inti() {
Button btn_start = findViewById(R.id.btn_start);
Button btn_stop = findViewById(R.id.btn_stop);
Button btn_emain = findViewById(R.id.btn_emain);
Button btn_quanxian = findViewById(R.id.btn_quanxian);
btn_start.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//开启服务
// Intent intent = new Intent(MainActivity.this, MyService.class);
// startService(intent);
Intent service = new Intent(getApplicationContext(), MyService.class);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
startService(service);
}
}
});
btn_stop.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//关闭服务
Intent intent = new Intent(MainActivity.this, MyService.class);
stopService(intent);
}
});
btn_emain.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//发送邮件测试
SendEmail sendEmail = new SendEmail();
sendEmail.execute();
}
});
btn_quanxian.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// 在后台线程中执行获取root权限和执行shell命令的操作
new Thread(new Runnable() {
@Override
public void run() {
executeShellCommandWithRoot();
}
}).start();
}
});
}
}
添加服务,并创建服务内容为定时执行:
import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.util.Log;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Calendar;
public class MyService extends Service {
private static final String TAG = "Servicelog";
private static final long INTERVAL_MS = 24 * 60 * 60 * 1000; // 每24小时执行一次任务
private static final int MORNING_HOUR = 12;
private static final int EVENING_HOUR = 20;
private Handler handler;
private Runnable runnable;
//重写Service生命周期中的onCreate()方法
@Override
public void onCreate(){
super.onCreate();
handler = new Handler();
runnable = new Runnable() {
@Override
public void run() {
checkAndSendEmail();
handler.postDelayed(this, INTERVAL_MS);
}
};
}
//重写Service生命周期中的onStartCommand()方法
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// 获取当前时间
Calendar calendar = Calendar.getInstance();
int currentHour = calendar.get(Calendar.HOUR_OF_DAY);
// 计算下一个执行任务的时间
long delayMs;
if (currentHour < MORNING_HOUR) {
// 计算时间差
calendar.set(Calendar.HOUR_OF_DAY, MORNING_HOUR);
delayMs = calendar.getTimeInMillis() - System.currentTimeMillis();
} else if (currentHour < EVENING_HOUR) {
// 计算时间差
calendar.set(Calendar.HOUR_OF_DAY, EVENING_HOUR);
delayMs = calendar.getTimeInMillis() - System.currentTimeMillis();
} else {
// 计算时间差
calendar.add(Calendar.DAY_OF_MONTH, 1);
calendar.set(Calendar.HOUR_OF_DAY, MORNING_HOUR);
delayMs = calendar.getTimeInMillis() - System.currentTimeMillis();
}
// 启动定时任务
handler.postDelayed(runnable, delayMs);
return START_STICKY;
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
//重写Service生命周期中的onStartCommand()方法
@Override
public void onDestroy() {
Log.i("Myservice","关闭服务,执行onDestroy()方法");
super.onDestroy();
}
private void checkAndSendEmail() {
//发送邮件测试
SendEmail sendEmail = new SendEmail();
sendEmail.execute();
}
private void createScreenCapture(){
String command1 = "input keyevent 224\n";
String command2 = "input swipe 300 1000 300 500\n";
try {
// 执行Shell命令
// 执行su命令获取root权限
Process suProcess = Runtime.getRuntime().exec("su");
// 获取su进程的输出流
DataOutputStream outputStream = new DataOutputStream(suProcess.getOutputStream());
Log.d(TAG,command1);
// 执行id命令获取用户身份信息
outputStream.writeBytes(command1);
outputStream.writeBytes(command2);
outputStream.flush();
// 关闭输出流
outputStream.writeBytes("exit\n");
outputStream.flush();
outputStream.close();
// 等待命令执行完成
suProcess.waitFor();
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
}
使用 QQ邮件发送邮件,并在邮件中添加图片:
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.Context;
import android.content.DialogInterface;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Environment;
import android.os.Handler;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.widget.Toast;
import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.util.ByteArrayDataSource;
public class SendEmail extends AsyncTask{
private static final String SMTP_HOST = "smtp.qq.com";
private static final int SMTP_PORT = 465;
private static final String USERNAME = "[email protected]";
private static final String PASSWORD = "password";
private static final String SENDER_EMAIL = "[email protected]";
private static final String RECIPIENT_EMAIL = "[email protected]";
private static final String EMAIL_SUBJECT = "Test";
private static final String EMAIL_BODY = "邮件正文";
private static final String IMAGE_PATH = "/sdcard/Pictures/01.png";;
@Override
protected void onPostExecute(Boolean success) {
if (success) {
SendEmail.show(MainActivity.mContext, "邮件发送成功");
// 邮件发送成功的处理
Log.d("MyTag", "邮件发送成功");
} else {
SendEmail.show(MainActivity.mContext, "邮件发送失败");
// 邮件发送失败的处理
Log.d("MyTag", "邮件发送失败");
}
}
@Override
protected Boolean doInBackground(Void... voids) {
try {
Log.d("MyTag", "邮件发送。。。。。");
Properties props = new Properties();
props.put("mail.smtp.host", SMTP_HOST);
props.put("mail.smtp.port", SMTP_PORT);
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
Session session = Session.getInstance(props, new javax.mail.Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(USERNAME, PASSWORD);
}
});
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress(SENDER_EMAIL));
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(RECIPIENT_EMAIL));
message.setSubject(EMAIL_SUBJECT);
// 创建邮件内容
MimeMultipart content = new MimeMultipart();
// 添加文本内容
MimeBodyPart textPart = new MimeBodyPart();
textPart.setText(EMAIL_BODY);
content.addBodyPart(textPart);
// 添加图片
MimeBodyPart imagePart = new MimeBodyPart();
Bitmap bitmap = BitmapFactory.decodeFile(IMAGE_PATH);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);
byte[] byteArray = stream.toByteArray();
ByteArrayDataSource dataSource = new ByteArrayDataSource(byteArray, "image/png");
imagePart.setDataHandler(new javax.activation.DataHandler(dataSource));
imagePart.setFileName("image.png");
content.addBodyPart(imagePart);
// 设置邮件内容
message.setContent(content);
Transport.send(message);
return true;
} catch (MessagingException e) {
e.printStackTrace();
return false;
}
}
private static final int DEFAULT_DURATION = Toast.LENGTH_SHORT;
public static void show(Context context, String message) {
show(context, message, DEFAULT_DURATION);
}
public static void show(Context context, String message, int duration) {
final Toast toast = Toast.makeText(context, message, duration);
// 显示Toast
toast.show();
// 延迟一段时间后自动取消Toast
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
toast.cancel();
}
}, duration == Toast.LENGTH_LONG ? 3500 : 2000); // 使用不同的延迟时间来适应不同的Toast持续时间
}
}
使用shell命令提升权限,需要有root权限:
private void executeShellCommandWithRoot() {
try {
Process process = Runtime.getRuntime().exec("su");
DataOutputStream outputStream = new DataOutputStream(process.getOutputStream());
// 在这里执行需要root权限的shell命令
// 例如,执行 "ls" 命令
outputStream.writeBytes("id\n");
outputStream.flush();
// 读取命令执行的结果
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
StringBuilder output = new StringBuilder();
output.append(reader.readLine()).append("\n");
// 输出结果
String outputStr = output.toString();
Log.d("Root", "Output: " + outputStr);
// 关闭流
outputStream.writeBytes("exit\n");
outputStream.flush();
outputStream.close();
process.waitFor();
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
最后AndroidManifest.xml中添加权限:
上述代码实现了发送邮件和创建服务,并执行定时任务,但是由于android回收机制,一段时间后服务就会被kill,不能长久在后台运行,需要注意。