第一次提交
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
package com.miraclegarden.smsmessage;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.view.ViewTreeObserver;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.miraclegarden.smsmessage.databinding.DialogActionConfirmBinding;
|
||||
|
||||
/**
|
||||
* 通用弹窗
|
||||
*/
|
||||
public class ActionConfirmDialog extends Dialog {
|
||||
private final Context context;
|
||||
OnToActionListener onToActionListener;
|
||||
AppInfo appInfo;
|
||||
int index;
|
||||
DialogActionConfirmBinding actionConfirmBinding;
|
||||
public interface OnToActionListener {
|
||||
void toSumbit(AppInfo appInfo);
|
||||
void toCancel();
|
||||
|
||||
}
|
||||
|
||||
public void setOnToActionListener(OnToActionListener onNextCallListener) {
|
||||
this.onToActionListener = onNextCallListener;
|
||||
}
|
||||
|
||||
|
||||
public ActionConfirmDialog(Context context, AppInfo appInfo) {
|
||||
super(context, R.style.MaterialDesignDialog);
|
||||
this.context = context;
|
||||
this.appInfo = appInfo;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
actionConfirmBinding = DialogActionConfirmBinding.inflate(getLayoutInflater());
|
||||
setContentView(actionConfirmBinding.getRoot());
|
||||
actionConfirmBinding.ivIcon.setImageDrawable(appInfo.getIcon());
|
||||
actionConfirmBinding.tvAppname.setText(appInfo.getAppName());
|
||||
actionConfirmBinding.tvPackage.setText(appInfo.getPackageName());
|
||||
if(!TextUtils.isEmpty(appInfo.getName())){
|
||||
actionConfirmBinding.tvName.setText(appInfo.getName());
|
||||
}
|
||||
if(!TextUtils.isEmpty(appInfo.getCode())){
|
||||
actionConfirmBinding.tvCode.setText(appInfo.getCode());
|
||||
}
|
||||
if(!TextUtils.isEmpty(appInfo.getRemark())){
|
||||
actionConfirmBinding.tvRemark.setText(appInfo.getRemark());
|
||||
}
|
||||
|
||||
actionConfirmBinding.sumbitTv.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
if(TextUtils.isEmpty(actionConfirmBinding.tvName.getText().toString().trim())){
|
||||
Toast.makeText(context,"名称不能为空",Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
if(TextUtils.isEmpty(actionConfirmBinding.tvCode.getText().toString().trim())){
|
||||
Toast.makeText(context,"Code不能为空",Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
appInfo.setName(actionConfirmBinding.tvName.getText().toString().trim());
|
||||
appInfo.setCode(actionConfirmBinding.tvCode.getText().toString().trim());
|
||||
appInfo.setRemark(actionConfirmBinding.tvRemark.getText().toString().trim());
|
||||
if(onToActionListener!=null){
|
||||
dismiss();
|
||||
onToActionListener.toSumbit(appInfo);
|
||||
}
|
||||
}
|
||||
});
|
||||
actionConfirmBinding.cancelTv.setOnClickListener(view -> {
|
||||
dismiss();
|
||||
if(onToActionListener!=null){
|
||||
onToActionListener.toCancel();
|
||||
}
|
||||
});
|
||||
|
||||
Window window = getWindow();
|
||||
WindowManager.LayoutParams wlp = window.getAttributes();
|
||||
wlp.gravity = Gravity.CENTER;
|
||||
wlp.width = WindowManager.LayoutParams.WRAP_CONTENT;
|
||||
wlp.height = WindowManager.LayoutParams.WRAP_CONTENT;
|
||||
|
||||
window.setAttributes(wlp);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
package com.miraclegarden.smsmessage.Activity;
|
||||
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.miraclegarden.library.app.MiracleGardenActivity;
|
||||
import com.miraclegarden.smsmessage.ActionConfirmDialog;
|
||||
import com.miraclegarden.smsmessage.App;
|
||||
import com.miraclegarden.smsmessage.AppInfo;
|
||||
import com.miraclegarden.smsmessage.AppListUtil;
|
||||
import com.miraclegarden.smsmessage.R;
|
||||
import com.miraclegarden.smsmessage.comm.CommonAdapter;
|
||||
import com.miraclegarden.smsmessage.comm.ViewHolder;
|
||||
import com.miraclegarden.smsmessage.databinding.AppListSettingBinding;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class AppListActivity extends MiracleGardenActivity<AppListSettingBinding> {
|
||||
public static SharedPreferences sp;
|
||||
private ArrayList<AppInfo> appList = new ArrayList<>();
|
||||
CommonAdapter userAdapter;
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
sp = getSharedPreferences("server", MODE_PRIVATE);
|
||||
|
||||
initData();
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
new LoadAppTask().execute();
|
||||
|
||||
}
|
||||
|
||||
// 异步加载
|
||||
private class LoadAppTask extends AsyncTask<Void, Void, ArrayList<AppInfo>> {
|
||||
@Override
|
||||
protected ArrayList<AppInfo> doInBackground(Void... voids) {
|
||||
// 获取全部APP
|
||||
return AppListUtil.getAllInstalledApps(AppListActivity.this);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(ArrayList<AppInfo> result) {
|
||||
super.onPostExecute(result);
|
||||
appList.clear();
|
||||
appList.addAll(result);
|
||||
userAdapter.notifyDataSetChanged();
|
||||
if(appList.size()<=1){
|
||||
binding.oneLy.setVisibility(View.VISIBLE);
|
||||
}else{
|
||||
binding.oneLy.setVisibility(View.GONE);
|
||||
}
|
||||
binding.loadingLy.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void initData() {
|
||||
binding.backIv.setOnClickListener(view -> finish());
|
||||
binding.recyclerview.setLayoutManager(new LinearLayoutManager(this));
|
||||
userAdapter = new CommonAdapter<>(AppListActivity.this, R.layout.item_user, appList) {
|
||||
@Override
|
||||
public void convert(ViewHolder holder, AppInfo info, int index) {
|
||||
info = App.getAppInfoByNotiList(AppListActivity.this,info);
|
||||
((ImageView) holder.getView(R.id.iv_icon)).setImageDrawable(info.getIcon());
|
||||
holder.setText(R.id.tv_appname, info.getAppName());
|
||||
holder.setText(R.id.tv_package, info.getPackageName());
|
||||
|
||||
if (!TextUtils.isEmpty(info.getName())) {
|
||||
holder.setText(R.id.tv_name, info.getName()+"/");
|
||||
}else{
|
||||
holder.setText(R.id.tv_name, "--/");
|
||||
}
|
||||
if (!TextUtils.isEmpty(info.getCode())) {
|
||||
holder.setText(R.id.tv_code, info.getCode()+"/");
|
||||
}else{
|
||||
holder.setText(R.id.tv_code, "--/");
|
||||
}
|
||||
if (!TextUtils.isEmpty(info.getRemark())) {
|
||||
holder.setText(R.id.tv_remark, info.getRemark());
|
||||
}else{
|
||||
holder.setText(R.id.tv_remark, "--");
|
||||
}
|
||||
AppInfo finalInfo = info;
|
||||
holder.getView(R.id.layout_big).setOnClickListener(view -> {
|
||||
ActionConfirmDialog actionConfirmDialog = new ActionConfirmDialog(AppListActivity.this, finalInfo);
|
||||
actionConfirmDialog.setOnToActionListener(new ActionConfirmDialog.OnToActionListener() {
|
||||
@Override
|
||||
public void toSumbit(AppInfo appInfo) {
|
||||
appList.set(index,appInfo);
|
||||
userAdapter.notifyItemChanged(index,appInfo);
|
||||
App.saveNotiBean(AppListActivity.this,appInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toCancel() {
|
||||
|
||||
}
|
||||
});
|
||||
actionConfirmDialog.show();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
binding.recyclerview.setAdapter(userAdapter);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
package com.miraclegarden.smsmessage.Activity;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.PermissionInfo;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.app.ActivityCompat;
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import com.miraclegarden.library.app.MiracleGardenActivity;
|
||||
import com.miraclegarden.smsmessage.databinding.ActivityMainBinding;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class MainActivity extends MiracleGardenActivity<ActivityMainBinding> {
|
||||
public static SharedPreferences sp;
|
||||
private static final String TAG = "MainActivity";
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
sp = getSharedPreferences("server", MODE_PRIVATE);
|
||||
|
||||
initData();
|
||||
initView();
|
||||
}
|
||||
|
||||
private void initData() {
|
||||
if (sp == null) {
|
||||
return;
|
||||
}
|
||||
binding.host.setText(sp.getString("host", ""));
|
||||
|
||||
}
|
||||
|
||||
private void initView() {
|
||||
binding.yes.setOnClickListener(v -> {
|
||||
if (sp == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
binding.host.setText(sp.getString("host", "https://www.judy88.xin/api/bills/app-upload"));
|
||||
|
||||
if (binding.host.getText().toString().length() == 0) {
|
||||
Toast.makeText(this, "服务器和添加参数不能为空", Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!binding.host.getText().toString().startsWith("http")) {
|
||||
Toast.makeText(this, "服务器地址错误", Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
SharedPreferences.Editor edit = sp.edit();
|
||||
edit.putString("host", binding.host.getText().toString());
|
||||
edit.apply();
|
||||
startActivity(new Intent(MainActivity.this, NotificationActivity.class));
|
||||
finish();
|
||||
});
|
||||
new Handler().postDelayed(() -> binding.yes.performClick(),2000);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,207 @@
|
||||
package com.miraclegarden.smsmessage.Activity;
|
||||
|
||||
import android.Manifest;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.provider.Settings;
|
||||
import android.text.TextUtils;
|
||||
import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.ScrollView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.RequiresApi;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.core.widget.NestedScrollView;
|
||||
|
||||
import com.miraclegarden.library.app.MiracleGardenActivity;
|
||||
import com.miraclegarden.smsmessage.AppInfo;
|
||||
import com.miraclegarden.smsmessage.AppListUtil;
|
||||
import com.miraclegarden.smsmessage.MessageInfo;
|
||||
import com.miraclegarden.smsmessage.databinding.ActivityNotificationBinding;
|
||||
import com.miraclegarden.smsmessage.service.NotificationService;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
import okhttp3.Call;
|
||||
import okhttp3.Callback;
|
||||
import okhttp3.FormBody;
|
||||
import okhttp3.MediaType;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.RequestBody;
|
||||
import okhttp3.Response;
|
||||
|
||||
public class NotificationActivity extends MiracleGardenActivity<ActivityNotificationBinding> {
|
||||
|
||||
private static final Handler handler = new Handler(Looper.myLooper()) {
|
||||
@Override
|
||||
public void handleMessage(@NonNull Message msg) {
|
||||
super.handleMessage(msg);
|
||||
String str = (String) msg.obj;
|
||||
if (str != null) {
|
||||
@SuppressLint("SimpleDateFormat") SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd-HH:mm:ss");
|
||||
String t = format.format(new Date());
|
||||
if (textView != null) {
|
||||
textView.append(t + ":" + str + "\n\r");
|
||||
scrollView.post(() -> scrollView.fullScroll(ScrollView.FOCUS_DOWN));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public static SharedPreferences sharedPreferences;
|
||||
|
||||
public static void sendMessage(String str) {
|
||||
Message message = new Message();
|
||||
message.obj = str;
|
||||
NotificationActivity.handler.sendMessage(message);
|
||||
}
|
||||
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
private static TextView textView;
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
private static NestedScrollView scrollView;
|
||||
private final String[] permissions = new String[]{
|
||||
Manifest.permission.RECEIVE_BOOT_COMPLETED
|
||||
};
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
sharedPreferences = getSharedPreferences("server", MODE_PRIVATE);
|
||||
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
||||
NotificationActivity.textView = binding.text;
|
||||
NotificationActivity.scrollView = binding.scrollable;
|
||||
initPermission();
|
||||
initView();
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void initView() {
|
||||
binding.button2.setOnClickListener(v -> {
|
||||
//打开监听引用消息Notification access
|
||||
Intent intent_s = new Intent(Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS);
|
||||
startActivity(intent_s);
|
||||
});
|
||||
binding.button.setOnClickListener(v -> {
|
||||
AppInfo appInfo = AppListUtil.getAppByPackageName(NotificationActivity.this,"com.miraclegarden.smsmessage");
|
||||
appInfo.setCode("111");
|
||||
appInfo.setName("测试");
|
||||
appInfo.setRemark("测试备注");
|
||||
MessageInfo messageInfo = MessageInfo.AppInfoToMessageInfo(appInfo);
|
||||
Submit(messageInfo,"我是标题","我是正文");
|
||||
});
|
||||
|
||||
binding.button1.setOnClickListener(view -> {
|
||||
if (textView != null) {
|
||||
textView.setText("");
|
||||
}
|
||||
});
|
||||
|
||||
binding.toolbar.setOnLongClickListener(view -> {
|
||||
// Toast.makeText(NotificationActivity.this,"点我干嘛",Toast.LENGTH_SHORT).show();
|
||||
startActivity(new Intent(NotificationActivity.this,SettingActivity.class));
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
private void initPermission() {
|
||||
checkPermission();
|
||||
for (String permission : permissions) {
|
||||
if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) {
|
||||
sendMessage("没有" + permission + "权限");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//打开设置界面
|
||||
private void checkPermission() {
|
||||
if (!isEnabled()) {
|
||||
startActivity(new Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 判断是否打开了通知监听权限
|
||||
private boolean isEnabled() {
|
||||
String pkgName = getPackageName();
|
||||
final String flat = Settings.Secure.getString(getContentResolver(), "enabled_notification_listeners");
|
||||
if (!TextUtils.isEmpty(flat)) {
|
||||
final String[] names = flat.split(":");
|
||||
for (String name : names) {
|
||||
final ComponentName cn = ComponentName.unflattenFromString(name);
|
||||
if (cn != null) {
|
||||
if (TextUtils.equals(pkgName, cn.getPackageName())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public MediaType JSON = MediaType.parse("application/json; charset=utf-8");
|
||||
|
||||
public void Submit(MessageInfo messageInfo, String title, String context) {
|
||||
OkHttpClient client = new OkHttpClient();
|
||||
SharedPreferences sharedPreferences = getSharedPreferences("server", MODE_PRIVATE);
|
||||
try {
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("name", messageInfo.getName());
|
||||
jsonObject.put("code", messageInfo.getCode());
|
||||
jsonObject.put("remark", messageInfo.getRemark());
|
||||
jsonObject.put("appName", messageInfo.getAppName());
|
||||
jsonObject.put("packageName", messageInfo.getPackageName());
|
||||
JSONObject jsonObject1 = new JSONObject();
|
||||
jsonObject1.put("title", title);
|
||||
jsonObject1.put("context", context);
|
||||
jsonObject.put("data", jsonObject1);
|
||||
String json = jsonObject.toString();
|
||||
RequestBody body = RequestBody.create(json, JSON);
|
||||
// 构建请求
|
||||
Request request = new Request.Builder()
|
||||
.url(sharedPreferences.getString("host", ""))
|
||||
.post(body)
|
||||
.build();
|
||||
client.newCall(request).enqueue(new Callback() {
|
||||
@Override
|
||||
public void onFailure(@NonNull Call call, @NonNull IOException e) {
|
||||
NotificationActivity.sendMessage("提交失败:" + e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
|
||||
if (response.isSuccessful()) {
|
||||
String str = response.body().string();
|
||||
NotificationActivity.sendMessage(title + "提交成功:" + str);
|
||||
return;
|
||||
}
|
||||
NotificationActivity.sendMessage("提交失败:");
|
||||
}
|
||||
});
|
||||
} catch (JSONException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,151 @@
|
||||
package com.miraclegarden.smsmessage.Activity;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.PermissionInfo;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.app.ActivityCompat;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
|
||||
import com.miraclegarden.library.app.MiracleGardenActivity;
|
||||
import com.miraclegarden.smsmessage.ActionConfirmDialog;
|
||||
import com.miraclegarden.smsmessage.App;
|
||||
import com.miraclegarden.smsmessage.AppInfo;
|
||||
import com.miraclegarden.smsmessage.AppListUtil;
|
||||
import com.miraclegarden.smsmessage.DeleteConfirmDialog;
|
||||
import com.miraclegarden.smsmessage.MessageInfo;
|
||||
import com.miraclegarden.smsmessage.R;
|
||||
import com.miraclegarden.smsmessage.comm.CommonAdapter;
|
||||
import com.miraclegarden.smsmessage.comm.ViewHolder;
|
||||
import com.miraclegarden.smsmessage.databinding.ActivityMainBinding;
|
||||
import com.miraclegarden.smsmessage.databinding.ActivitySettingBinding;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class SettingActivity extends MiracleGardenActivity<ActivitySettingBinding> {
|
||||
public static SharedPreferences sp;
|
||||
private static final String TAG = "SettingActivity";
|
||||
private ArrayList<MessageInfo> appList = new ArrayList<>();
|
||||
CommonAdapter userAdapter;
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
sp = getSharedPreferences("server", MODE_PRIVATE);
|
||||
initData();
|
||||
initList();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
initChangeList();
|
||||
}
|
||||
|
||||
private void initChangeList() {
|
||||
List<MessageInfo> appList1 = App.getNotiList(SettingActivity.this);
|
||||
if(appList1 == null){
|
||||
appList = new ArrayList<>();
|
||||
}else{
|
||||
appList = (ArrayList<MessageInfo>) appList1;
|
||||
}
|
||||
userAdapter.setDates(appList);
|
||||
if(appList.size()>0){
|
||||
binding.recyclerview.setVisibility(View.VISIBLE);
|
||||
binding.nodataIv.setVisibility(View.GONE);
|
||||
}else{
|
||||
binding.recyclerview.setVisibility(View.GONE);
|
||||
binding.nodataIv.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
private void initData() {
|
||||
binding.host.setText(sp.getString("host", "https://www.judy88.xin/api/bills/app-upload"));
|
||||
binding.addBt.setOnClickListener(view -> startActivity(new Intent(SettingActivity.this,AppListActivity.class)));
|
||||
binding.backIv.setOnClickListener(view -> finish());
|
||||
|
||||
binding.yes.setOnClickListener(v -> {
|
||||
if (sp == null) {
|
||||
return;
|
||||
}
|
||||
if (binding.host.getText().toString().length() == 0) {
|
||||
Toast.makeText(this, "服务器和添加参数不能为空", Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!binding.host.getText().toString().startsWith("http")) {
|
||||
Toast.makeText(this, "服务器地址错误", Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
SharedPreferences.Editor edit = sp.edit();
|
||||
edit.putString("host", binding.host.getText().toString());
|
||||
edit.apply();
|
||||
Toast.makeText(this, "服务器地址修改成功", Toast.LENGTH_SHORT).show();
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void initList() {
|
||||
binding.recyclerview.setLayoutManager(new LinearLayoutManager(this));
|
||||
userAdapter = new CommonAdapter<>(SettingActivity.this, R.layout.item_user, appList) {
|
||||
@Override
|
||||
public void convert(ViewHolder holder, MessageInfo info, int index) {
|
||||
AppInfo appInfo = AppListUtil.getAppByPackageName(SettingActivity.this,info.getPackageName());
|
||||
ImageView delete_img = holder.getView(R.id.delete_img);
|
||||
delete_img.setVisibility(View.VISIBLE);
|
||||
delete_img.setOnClickListener(view -> {
|
||||
DeleteConfirmDialog deleteConfirmDialog = new DeleteConfirmDialog(SettingActivity.this,info);
|
||||
deleteConfirmDialog.setOnToActionListener(() -> {
|
||||
App.deleteNotiBean(SettingActivity.this,info);
|
||||
initChangeList();
|
||||
});
|
||||
deleteConfirmDialog.show();
|
||||
|
||||
});
|
||||
if(appInfo!=null){
|
||||
((ImageView) holder.getView(R.id.iv_icon)).setImageDrawable(appInfo.getIcon());
|
||||
}else{
|
||||
((ImageView) holder.getView(R.id.iv_icon)).setImageResource(R.mipmap.app_logo);
|
||||
}
|
||||
holder.setText(R.id.tv_appname, info.getAppName());
|
||||
holder.setText(R.id.tv_package, info.getPackageName());
|
||||
|
||||
if (!TextUtils.isEmpty(info.getName())) {
|
||||
holder.setText(R.id.tv_name, info.getName()+"/");
|
||||
}else{
|
||||
holder.setText(R.id.tv_name, "--/");
|
||||
}
|
||||
if (!TextUtils.isEmpty(info.getCode())) {
|
||||
holder.setText(R.id.tv_code, info.getCode()+"/");
|
||||
}else{
|
||||
holder.setText(R.id.tv_code, "--/");
|
||||
}
|
||||
if (!TextUtils.isEmpty(info.getRemark())) {
|
||||
holder.setText(R.id.tv_remark, info.getRemark());
|
||||
}else{
|
||||
holder.setText(R.id.tv_remark, "--");
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
binding.recyclerview.setAdapter(userAdapter);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
162
app/src/main/java/com/miraclegarden/smsmessage/App.java
Normal file
162
app/src/main/java/com/miraclegarden/smsmessage/App.java
Normal file
@@ -0,0 +1,162 @@
|
||||
package com.miraclegarden.smsmessage;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.Application;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.Signature;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Base64;
|
||||
import android.util.Log;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class App extends Application {
|
||||
private static final String TAG = "App";
|
||||
public static String Hash_value;
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
String packageName = getApplicationContext().getPackageName();
|
||||
MessageDigest messageDigest = getMessageDigest();
|
||||
String signature = getSignature(this, packageName);
|
||||
Hash_value = getHashCode(packageName, messageDigest, signature);
|
||||
}
|
||||
|
||||
public static MessageDigest getMessageDigest() {
|
||||
MessageDigest messageDigest = null;
|
||||
try {
|
||||
messageDigest = MessageDigest.getInstance("SHA-256");
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
Log.e(TAG, "No Such Algorithm.", e);
|
||||
}
|
||||
return messageDigest;
|
||||
}
|
||||
|
||||
public static String getSignature(Context context, String packageName) {
|
||||
PackageManager packageManager = context.getPackageManager();
|
||||
Signature[] signatureArrs;
|
||||
try {
|
||||
signatureArrs = packageManager.getPackageInfo(packageName, PackageManager.GET_SIGNATURES).signatures;
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
Log.e(TAG, "Package name inexistent.");
|
||||
return "";
|
||||
}
|
||||
if (null == signatureArrs || 0 == signatureArrs.length) {
|
||||
Log.e(TAG, "signature is null.");
|
||||
return "";
|
||||
}
|
||||
return signatureArrs[0].toCharsString();
|
||||
}
|
||||
|
||||
private String getHashCode(String packageName, MessageDigest messageDigest, String signature) {
|
||||
String appInfo = packageName + " " + signature;
|
||||
messageDigest.update(appInfo.getBytes(StandardCharsets.UTF_8));
|
||||
byte[] hashSignature = messageDigest.digest();
|
||||
hashSignature = Arrays.copyOfRange(hashSignature, 0, 9);
|
||||
String base64Hash = Base64.encodeToString(hashSignature, Base64.NO_PADDING | Base64.NO_WRAP);
|
||||
base64Hash = base64Hash.substring(0, 11);
|
||||
return base64Hash;
|
||||
}
|
||||
|
||||
|
||||
public static void saveNotiList(Context context, String value) {
|
||||
SharedPreferences sp = context.getSharedPreferences("server", Activity.MODE_PRIVATE);
|
||||
SharedPreferences.Editor editor = sp.edit();
|
||||
editor.putString("saveNotiList", value);
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
public static List<MessageInfo> getNotiList(Context context) {
|
||||
SharedPreferences sp = context.getSharedPreferences("server", Activity.MODE_PRIVATE);
|
||||
String messages = sp.getString("saveNotiList", "");
|
||||
if (TextUtils.isEmpty(messages)) {
|
||||
return null;
|
||||
}
|
||||
List<MessageInfo> messageInfos = GsonUtils.getListFromJSON(messages, MessageInfo.class);
|
||||
return messageInfos;
|
||||
}
|
||||
|
||||
|
||||
public static void deleteNotiBean(Context context, MessageInfo appInfo) {
|
||||
List<MessageInfo> messageInfos = getNotiList(context);
|
||||
if (messageInfos == null) {
|
||||
saveNotiList(context, "");
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < messageInfos.size(); i++) {
|
||||
if (messageInfos.get(i).getPackageName().equals(appInfo.getPackageName())) {
|
||||
messageInfos.remove(i);
|
||||
if (messageInfos.size() == 0) {
|
||||
saveNotiList(context, "");
|
||||
} else {
|
||||
saveNotiList(context, GsonUtils.beanToJSONString(messageInfos));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void saveNotiBean(Context context, AppInfo appInfo) {
|
||||
List<MessageInfo> messageInfos = getNotiList(context);
|
||||
if (messageInfos == null) {
|
||||
messageInfos = new ArrayList<>();
|
||||
messageInfos.add(MessageInfo.AppInfoToMessageInfo(appInfo));
|
||||
saveNotiList(context, GsonUtils.beanToJSONString(messageInfos));
|
||||
return;
|
||||
}
|
||||
boolean isAdd = true;
|
||||
for (int i = 0; i < messageInfos.size(); i++) {
|
||||
if (messageInfos.get(i).getPackageName().equals(appInfo.getPackageName())) {
|
||||
messageInfos.get(i).setName(appInfo.getName());
|
||||
messageInfos.get(i).setCode(appInfo.getCode());
|
||||
messageInfos.get(i).setRemark(appInfo.getRemark());
|
||||
isAdd = false;
|
||||
}
|
||||
}
|
||||
if(isAdd){
|
||||
messageInfos.add(MessageInfo.AppInfoToMessageInfo(appInfo));
|
||||
}
|
||||
saveNotiList(context, GsonUtils.beanToJSONString(messageInfos));
|
||||
}
|
||||
|
||||
|
||||
public static AppInfo getAppInfoByNotiList(Context context, AppInfo appInfo) {
|
||||
List<MessageInfo> messageInfos = getNotiList(context);
|
||||
if (messageInfos == null) {
|
||||
return appInfo;
|
||||
}
|
||||
for (int i = 0; i < messageInfos.size(); i++) {
|
||||
if (messageInfos.get(i).getPackageName().equals(appInfo.getPackageName())) {
|
||||
appInfo.setName(messageInfos.get(i).getName());
|
||||
appInfo.setCode(messageInfos.get(i).getCode());
|
||||
appInfo.setRemark(messageInfos.get(i).getRemark());
|
||||
return appInfo;
|
||||
}
|
||||
}
|
||||
return appInfo;
|
||||
}
|
||||
|
||||
|
||||
public static MessageInfo getMessageByNotiList(Context context, String packageName) {
|
||||
List<MessageInfo> messageInfos = getNotiList(context);
|
||||
if (messageInfos == null) {
|
||||
return null;
|
||||
}
|
||||
for (int i = 0; i < messageInfos.size(); i++) {
|
||||
if (messageInfos.get(i).getPackageName().equals(packageName)) {
|
||||
return messageInfos.get(i);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
53
app/src/main/java/com/miraclegarden/smsmessage/AppInfo.java
Normal file
53
app/src/main/java/com/miraclegarden/smsmessage/AppInfo.java
Normal file
@@ -0,0 +1,53 @@
|
||||
package com.miraclegarden.smsmessage;
|
||||
|
||||
/**
|
||||
* **********************
|
||||
*
|
||||
* @Author bug machine
|
||||
* 创建时间: 2026/3/20 15:30
|
||||
* 用途
|
||||
* **********************
|
||||
*/
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
||||
public class AppInfo {
|
||||
private String appName; // 应用名
|
||||
private String packageName;// 包名
|
||||
private Drawable icon; // 图标
|
||||
private String name;
|
||||
private String code;
|
||||
private String remark;
|
||||
public AppInfo(String appName, String packageName, Drawable icon) {
|
||||
this.appName = appName;
|
||||
this.packageName = packageName;
|
||||
this.icon = icon;
|
||||
}
|
||||
|
||||
public String getAppName() { return appName; }
|
||||
public String getPackageName() { return packageName; }
|
||||
public Drawable getIcon() { return icon; }
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public void setCode(String code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public String getRemark() {
|
||||
return remark;
|
||||
}
|
||||
|
||||
public void setRemark(String remark) {
|
||||
this.remark = remark;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
package com.miraclegarden.smsmessage;
|
||||
|
||||
/**
|
||||
* **********************
|
||||
*
|
||||
* @Author bug machine
|
||||
* 创建时间: 2026/3/20 15:30
|
||||
* 用途
|
||||
* **********************
|
||||
*/
|
||||
import android.content.Context;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class AppListUtil {
|
||||
|
||||
// 获取 所有已安装APP
|
||||
public static ArrayList<AppInfo> getAllInstalledApps(Context context) {
|
||||
ArrayList<AppInfo> list = new ArrayList<>();
|
||||
PackageManager pm = context.getPackageManager();
|
||||
|
||||
// 获取全部应用
|
||||
List<ApplicationInfo> apps = pm.getInstalledApplications(0);
|
||||
Log.i("多少条数据","多少条数据:"+apps.size());
|
||||
for (ApplicationInfo info : apps) {
|
||||
// 只获取有桌面图标的应用(可去掉,获取全部)
|
||||
if (pm.getLaunchIntentForPackage(info.packageName) != null) {
|
||||
String name = info.loadLabel(pm).toString();
|
||||
String pkg = info.packageName;
|
||||
Drawable icon = info.loadIcon(pm);
|
||||
boolean isSystem = (info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
|
||||
|
||||
list.add(new AppInfo(name, pkg, icon));
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
// 只获取 第三方APP(排除系统APP)
|
||||
public static ArrayList<AppInfo> getThirdPartyApps(Context context) {
|
||||
ArrayList<AppInfo> list = new ArrayList<>();
|
||||
PackageManager pm = context.getPackageManager();
|
||||
List<ApplicationInfo> apps = pm.getInstalledApplications(0);
|
||||
|
||||
for (ApplicationInfo info : apps) {
|
||||
// 非系统APP + 有启动图标
|
||||
if ((info.flags & ApplicationInfo.FLAG_SYSTEM) == 0
|
||||
&& pm.getLaunchIntentForPackage(info.packageName) != null) {
|
||||
|
||||
list.add(new AppInfo(
|
||||
info.loadLabel(pm).toString(),
|
||||
info.packageName,
|
||||
info.loadIcon(pm)
|
||||
));
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 判断某个包名是否已安装,并返回应用信息
|
||||
* @param context 上下文
|
||||
* @param packageName 指定包名
|
||||
* @return null = 未安装 / 无权限 / 找不到
|
||||
*/
|
||||
public static AppInfo getAppByPackageName(Context context, String packageName) {
|
||||
try {
|
||||
PackageManager pm = context.getPackageManager();
|
||||
|
||||
// ✅ 关键:直接查询指定包名(不会被系统限制)
|
||||
PackageInfo packageInfo = pm.getPackageInfo(packageName, 0);
|
||||
ApplicationInfo appInfo = packageInfo.applicationInfo;
|
||||
|
||||
String appName = appInfo.loadLabel(pm).toString();
|
||||
Drawable icon = appInfo.loadIcon(pm);
|
||||
|
||||
return new AppInfo(appName, packageName, icon);
|
||||
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
// 没安装
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package com.miraclegarden.smsmessage;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.view.ViewTreeObserver;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.miraclegarden.smsmessage.databinding.DialogDeleteConfirmBinding;
|
||||
|
||||
|
||||
/**
|
||||
* 通用弹窗
|
||||
*/
|
||||
public class DeleteConfirmDialog extends Dialog {
|
||||
DialogDeleteConfirmBinding dialogActionConfirmBinding;
|
||||
OnToActionListener onToActionListener;
|
||||
MessageInfo messageInfo;
|
||||
public interface OnToActionListener {
|
||||
void toSumbit();
|
||||
}
|
||||
|
||||
public void setOnToActionListener(OnToActionListener onNextCallListener) {
|
||||
this.onToActionListener = onNextCallListener;
|
||||
}
|
||||
|
||||
|
||||
public DeleteConfirmDialog(Context context, MessageInfo messageInfo) {
|
||||
super(context, R.style.MaterialDesignDialog);
|
||||
this.messageInfo = messageInfo;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
dialogActionConfirmBinding = DialogDeleteConfirmBinding.inflate(getLayoutInflater());
|
||||
setContentView(dialogActionConfirmBinding.getRoot());
|
||||
dialogActionConfirmBinding.contentTv.setText("删除"+messageInfo.getAppName()+"监听");
|
||||
|
||||
dialogActionConfirmBinding.sumbitTv.setOnClickListener(v -> {
|
||||
dismiss();
|
||||
if(onToActionListener!=null){
|
||||
onToActionListener.toSumbit();
|
||||
}
|
||||
});
|
||||
dialogActionConfirmBinding.cancelTv.setOnClickListener(v -> {
|
||||
dismiss();
|
||||
});
|
||||
|
||||
Window window = getWindow();
|
||||
WindowManager.LayoutParams wlp = window.getAttributes();
|
||||
wlp.gravity = Gravity.CENTER;
|
||||
wlp.width = WindowManager.LayoutParams.WRAP_CONTENT;
|
||||
wlp.height = WindowManager.LayoutParams.WRAP_CONTENT;
|
||||
|
||||
window.setAttributes(wlp);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
package com.miraclegarden.smsmessage;
|
||||
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* json解析工具类 其实对于数组解析有一些问题
|
||||
* @author
|
||||
*/
|
||||
public class GsonUtils {
|
||||
|
||||
public static Gson gson = new Gson();
|
||||
|
||||
/**
|
||||
* 返回List对象
|
||||
* @param str
|
||||
* @param type new TypeToken<ArrayList<T>>(){}.getType()
|
||||
* @param <T>
|
||||
* @return
|
||||
*/
|
||||
public static <T> T getListFromJSON(String str, Type type) {
|
||||
if (!TextUtils.isEmpty(str)) {
|
||||
return gson.fromJson(str, type);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回List对象
|
||||
* @param str
|
||||
* @param cls
|
||||
* @param <T>
|
||||
* @return
|
||||
*/
|
||||
public static <T> List<T> getListFromJSON(String str, Class<T> cls)
|
||||
{
|
||||
Type type = new TypeToken<ArrayList<JsonObject>>()
|
||||
{}.getType();
|
||||
ArrayList<JsonObject> jsonObjects = gson.fromJson(str, type);
|
||||
ArrayList<T> arrayList = new ArrayList<>();
|
||||
for (JsonObject jsonObject : jsonObjects)
|
||||
{
|
||||
arrayList.add(gson.fromJson(jsonObject, cls));
|
||||
}
|
||||
return arrayList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回对象
|
||||
* @param str
|
||||
* @param cls
|
||||
* @param <T>
|
||||
* @return
|
||||
*/
|
||||
public static <T> T getObjFromJSON(String str, Class<T> cls) {
|
||||
try {
|
||||
if (!TextUtils.isEmpty(str)) {
|
||||
// LogUtils.i("参数:"+str);
|
||||
return gson.fromJson(str, cls);
|
||||
}
|
||||
return null;
|
||||
}catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回JsonString
|
||||
* @return
|
||||
*/
|
||||
public static String beanToJSONString(Object bean) {
|
||||
return new Gson().toJson(bean);
|
||||
}
|
||||
|
||||
|
||||
public static String JSONTokener(String in) {
|
||||
// consume an optional byte order mark (BOM) if it exists
|
||||
if (in != null && in.startsWith("\ufeff")) {
|
||||
in = in.substring(1);
|
||||
}
|
||||
return in;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
package com.miraclegarden.smsmessage;
|
||||
|
||||
/**
|
||||
* **********************
|
||||
*
|
||||
* @Author bug machine
|
||||
* 创建时间: 2026/3/20 15:30
|
||||
* 用途
|
||||
* **********************
|
||||
*/
|
||||
|
||||
public class MessageInfo {
|
||||
private String appName; // 应用名
|
||||
private String packageName;// 包名
|
||||
private String name;
|
||||
private String code;
|
||||
private String remark;
|
||||
|
||||
public MessageInfo() {
|
||||
}
|
||||
|
||||
public MessageInfo(String appName, String packageName, String name, String code, String remark) {
|
||||
this.appName = appName;
|
||||
this.packageName = packageName;
|
||||
this.name = name;
|
||||
this.code = code;
|
||||
this.remark = remark;
|
||||
}
|
||||
|
||||
public static MessageInfo AppInfoToMessageInfo(AppInfo appInfo) {
|
||||
MessageInfo messageInfo = new MessageInfo();
|
||||
messageInfo.appName = appInfo.getAppName();
|
||||
messageInfo.packageName = appInfo.getPackageName();
|
||||
messageInfo.name = appInfo.getName();
|
||||
messageInfo.code = appInfo.getCode();
|
||||
messageInfo.remark = appInfo.getRemark();
|
||||
return messageInfo;
|
||||
}
|
||||
|
||||
public String getAppName() {
|
||||
return appName;
|
||||
}
|
||||
|
||||
public void setAppName(String appName) {
|
||||
this.appName = appName;
|
||||
}
|
||||
|
||||
public String getPackageName() {
|
||||
return packageName;
|
||||
}
|
||||
|
||||
public void setPackageName(String packageName) {
|
||||
this.packageName = packageName;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public void setCode(String code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public String getRemark() {
|
||||
return remark;
|
||||
}
|
||||
|
||||
public void setRemark(String remark) {
|
||||
this.remark = remark;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package com.miraclegarden.smsmessage.comm;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 通用列表适配器
|
||||
* @param <T>
|
||||
*/
|
||||
public abstract class CommonAdapter<T> extends RecyclerView.Adapter<ViewHolder> {
|
||||
|
||||
protected Context mContext;
|
||||
protected int mLayoutId;
|
||||
protected List<T> mDatas;
|
||||
protected LayoutInflater mInflater;
|
||||
|
||||
ViewHolder viewHolder;
|
||||
|
||||
|
||||
public CommonAdapter(Context context, int layoutId, List<T> datas) {
|
||||
mContext = context;
|
||||
mInflater = LayoutInflater.from(context);
|
||||
mLayoutId = layoutId;
|
||||
mDatas = datas;
|
||||
}
|
||||
public void setDates(List<T> dates){
|
||||
this.mDatas=dates;
|
||||
// notifyItemRangeChanged(0,mDatas.size());
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
public void addDates(List<T> dates){
|
||||
this.mDatas.addAll(dates);
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public void addDates(int localSize){
|
||||
int size=mDatas.size();
|
||||
notifyItemRangeChanged(size,localSize);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
viewHolder = ViewHolder.get(mContext, parent, mLayoutId);
|
||||
return viewHolder;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
|
||||
|
||||
convert(holder, mDatas.get(position),position);
|
||||
}
|
||||
|
||||
public abstract void convert(ViewHolder holder, T t,int index);
|
||||
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return mDatas.size();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
package com.miraclegarden.smsmessage.comm;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.SparseArray;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
/**
|
||||
* 通用列表ViewHolder
|
||||
*/
|
||||
public class ViewHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
private SparseArray<View> mViews;
|
||||
private View mConvertView;
|
||||
private Context mContext;
|
||||
|
||||
public ViewHolder(Context context, View itemView, ViewGroup parent) {
|
||||
super(itemView);
|
||||
mContext = context;
|
||||
mConvertView = itemView;
|
||||
mViews = new SparseArray<View>();
|
||||
}
|
||||
|
||||
public static ViewHolder get(Context context, ViewGroup parent, int layoutId) {
|
||||
|
||||
View itemView = LayoutInflater.from(context).inflate(layoutId, parent,
|
||||
false);
|
||||
ViewHolder holder = new ViewHolder(context, itemView, parent);
|
||||
return holder;
|
||||
}
|
||||
|
||||
|
||||
public <T extends View> T getView(int viewId) {
|
||||
View view = mViews.get(viewId);
|
||||
if (view == null) {
|
||||
view = mConvertView.findViewById(viewId);
|
||||
mViews.put(viewId, view);
|
||||
}
|
||||
return (T) view;
|
||||
}
|
||||
|
||||
|
||||
public ViewHolder setText(int viewId, String text)
|
||||
{
|
||||
TextView tv = getView(viewId);
|
||||
tv.setText(text);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ViewHolder setOnClickListener(int viewId, View.OnClickListener listener) {
|
||||
View view = getView(viewId);
|
||||
view.setOnClickListener(listener);
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,157 @@
|
||||
package com.miraclegarden.smsmessage.service;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Notification;
|
||||
import android.content.ComponentName;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.service.notification.NotificationListenerService;
|
||||
import android.service.notification.StatusBarNotification;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.miraclegarden.smsmessage.Activity.NotificationActivity;
|
||||
import com.miraclegarden.smsmessage.App;
|
||||
import com.miraclegarden.smsmessage.MessageInfo;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import okhttp3.Call;
|
||||
import okhttp3.Callback;
|
||||
import okhttp3.FormBody;
|
||||
import okhttp3.MediaType;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.RequestBody;
|
||||
import okhttp3.Response;
|
||||
|
||||
public class NotificationService extends NotificationListenerService {
|
||||
private static final String TAG = "NotificationService";
|
||||
|
||||
@Override
|
||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||
NotificationActivity.sendMessage("监听服务成功!");
|
||||
return super.onStartCommand(intent, flags, startId);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onNotificationPosted(StatusBarNotification sbn) {
|
||||
getSbnByNotificatinList(sbn);
|
||||
|
||||
}
|
||||
|
||||
public void getSbnByNotificatinList(StatusBarNotification sbn) {
|
||||
MessageInfo messageInfo = App.getMessageByNotiList(this, sbn.getPackageName());
|
||||
if (messageInfo != null) {
|
||||
initData(messageInfo, sbn);
|
||||
}
|
||||
}
|
||||
|
||||
private String text = "";
|
||||
|
||||
private void initData(MessageInfo messageInfo, StatusBarNotification sbn) {
|
||||
Bundle bundle = sbn.getNotification().extras;
|
||||
String title = bundle.getString(Notification.EXTRA_TITLE, "获取标题失败!");
|
||||
String context = bundle.getString(Notification.EXTRA_TEXT, "获取内容失败!");
|
||||
if (context.equals("获取内容失败!")) {
|
||||
if (sbn.getNotification().tickerText != null) {
|
||||
context = sbn.getNotification().tickerText.toString();
|
||||
}
|
||||
}
|
||||
NotificationActivity.sendMessage(title + " " + context);
|
||||
if (!text.equals(context)) {
|
||||
if (!title.equals("获取标题失败!") && !context.equals("获取内容失败!") && !title.contains("正在运行")) {
|
||||
NotificationActivity.sendMessage("准备发送服务器:成功");
|
||||
Submit(messageInfo,title, context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
|
||||
|
||||
public void Submit(MessageInfo messageInfo,String title, String context) {
|
||||
OkHttpClient client = new OkHttpClient();
|
||||
SharedPreferences sharedPreferences = getSharedPreferences("server", MODE_PRIVATE);
|
||||
try {
|
||||
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("name", messageInfo.getName());
|
||||
jsonObject.put("code", messageInfo.getCode());
|
||||
jsonObject.put("remark", messageInfo.getRemark());
|
||||
jsonObject.put("appName", messageInfo.getAppName());
|
||||
jsonObject.put("packageName", messageInfo.getPackageName());
|
||||
|
||||
JSONObject jsonObject1 = new JSONObject();
|
||||
jsonObject1.put("title", title+System.currentTimeMillis());
|
||||
jsonObject1.put("context", context+System.currentTimeMillis());
|
||||
jsonObject.put("data", jsonObject1);
|
||||
|
||||
String json = jsonObject.toString();
|
||||
|
||||
RequestBody body = RequestBody.create(json, JSON);
|
||||
|
||||
// 构建请求
|
||||
Request request = new Request.Builder()
|
||||
.url(sharedPreferences.getString("host", ""))
|
||||
.post(body)
|
||||
.build();
|
||||
|
||||
client.newCall(request).enqueue(new Callback() {
|
||||
@Override
|
||||
public void onFailure(@NonNull Call call, @NonNull IOException e) {
|
||||
NotificationActivity.sendMessage("提交失败:" + e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
|
||||
if (response.isSuccessful()) {
|
||||
String str = response.body().string();
|
||||
NotificationActivity.sendMessage(title + "提交成功:" + str);
|
||||
text = context;
|
||||
return;
|
||||
}
|
||||
NotificationActivity.sendMessage("提交失败:");
|
||||
}
|
||||
});
|
||||
} catch (JSONException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 监听断开
|
||||
*/
|
||||
@Override
|
||||
public void onListenerDisconnected() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
// 通知侦听器断开连接 - 请求重新绑定
|
||||
requestRebind(new ComponentName(this, NotificationListenerService.class));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param context 反正第二次启动失败
|
||||
*/
|
||||
public static void toggleNotificationListenerService(Context context) {
|
||||
PackageManager pm = context.getPackageManager();
|
||||
pm.setComponentEnabledSetting(new ComponentName(context, NotificationService.class),
|
||||
PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
|
||||
|
||||
pm.setComponentEnabledSetting(new ComponentName(context, NotificationService.class),
|
||||
PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user