新增:获取所有应用列表(方便复制APP包名)

pull/86/head
pppscn 3 years ago
parent 4b856f8d36
commit 2d4352d40f

@ -95,6 +95,9 @@
<activity
android:name=".SenderActivity"
android:label="@string/sender_setting" />
<activity
android:name=".AppListActivity"
android:label="@string/app_list" />
<receiver
android:name=".receiver.RebootBroadcastReceiver"

@ -26,7 +26,7 @@ import com.xuexiang.xupdate.proxy.impl.DefaultUpdateChecker;
@SuppressWarnings("SpellCheckingInspection")
public class AboutActivity extends AppCompatActivity {
private final String TAG = "com.idormy.sms.forwarder.AboutActivity";
private final String TAG = "AboutActivity";
private Context context;
@Override

@ -0,0 +1,157 @@
package com.idormy.sms.forwarder;
import static com.idormy.sms.forwarder.SenderActivity.NOTIFY;
import android.annotation.SuppressLint;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.ListView;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import com.idormy.sms.forwarder.adapter.AppAdapter;
import com.idormy.sms.forwarder.model.AppInfo;
import com.umeng.analytics.MobclickAgent;
import java.util.ArrayList;
import java.util.List;
@SuppressWarnings("deprecation")
public class AppListActivity extends AppCompatActivity {
public static final int APP_LIST = 0x9731991;
private final String TAG = "AppListActivity";
private List<AppInfo> appInfoList = new ArrayList<>();
private ListView listView;
private String currentType = "user";
//消息处理者,创建一个Handler的子类对象,目的是重写Handler的处理消息的方法(handleMessage())
@SuppressLint("HandlerLeak")
private final Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
if (msg.what == NOTIFY) {
Toast.makeText(AppListActivity.this, msg.getData().getString("DATA"), Toast.LENGTH_LONG).show();
} else if (msg.what == APP_LIST) {
AppAdapter adapter = new AppAdapter(AppListActivity.this, R.layout.item_app, appInfoList);
listView.setAdapter(adapter);
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
Log.d(TAG, "onCreate");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_applist);
}
@Override
protected void onStart() {
super.onStart();
Log.d(TAG, "onStart");
Toast.makeText(AppListActivity.this, "加载应用列表中,请稍候...", Toast.LENGTH_LONG).show();
//是否关闭页面提示
TextView help_tip = findViewById(R.id.help_tip);
help_tip.setVisibility(MyApplication.showHelpTip ? View.VISIBLE : View.GONE);
//获取应用列表
getAppList();
//切换日志类别
int typeCheckId = "user".equals(currentType) ? R.id.btnTypeUser : R.id.btnTypeSys;
final RadioGroup radioGroupTypeCheck = findViewById(R.id.radioGroupTypeCheck);
radioGroupTypeCheck.check(typeCheckId);
radioGroupTypeCheck.setOnCheckedChangeListener((group, checkedId) -> {
RadioButton rb = findViewById(checkedId);
currentType = (String) rb.getTag();
getAppList();
});
listView = findViewById(R.id.list_view_app);
listView.setOnItemClickListener((parent, view, position, id) -> {
AppInfo appInfo = appInfoList.get(position);
Log.d(TAG, "onItemClick: " + appInfo.toString());
//复制到剪贴板
ClipboardManager cm = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
ClipData mClipData = ClipData.newPlainText("pkgName", appInfo.getPkgName());
cm.setPrimaryClip(mClipData);
Toast.makeText(AppListActivity.this, "已复制包名:" + appInfo.getPkgName(), Toast.LENGTH_LONG).show();
});
listView.setOnItemLongClickListener((parent, view, position, id) -> {
AppInfo appInfo = appInfoList.get(position);
Log.d(TAG, "onItemClick: " + appInfo.toString());
//启动应用
Intent intent;
intent = getPackageManager().getLaunchIntentForPackage(appInfo.getPkgName());
startActivity(intent);
return true;
});
}
//获取应用列表
private void getAppList() {
new Thread(() -> {
appInfoList = new ArrayList<>();
PackageManager pm = getApplication().getPackageManager();
@SuppressLint("QueryPermissionsNeeded") List<PackageInfo> packages = pm.getInstalledPackages(PackageManager.GET_UNINSTALLED_PACKAGES);
for (PackageInfo packageInfo : packages) {
if ("user".equals(currentType) && (packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 1) { //用户应用
continue;
}
if ("sys".equals(currentType) && (packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { //系统应用
continue;
}
String appName = packageInfo.applicationInfo.loadLabel(pm).toString();
String packageName = packageInfo.packageName;
Drawable drawable = packageInfo.applicationInfo.loadIcon(pm);
String verName = packageInfo.versionName;
int verCode = packageInfo.versionCode;
AppInfo appInfo = new AppInfo(appName, packageName, drawable, verName, verCode);
appInfoList.add(appInfo);
Log.d(TAG, appInfo.toString());
}
Message message = new Message();
message.what = APP_LIST;
message.obj = appInfoList;
handler.sendMessage(message);
}).start();
}
@Override
protected void onDestroy() {
Log.d(TAG, "onDestroy");
super.onDestroy();
}
@Override
protected void onResume() {
super.onResume();
MobclickAgent.onResume(this);
}
@Override
protected void onPause() {
super.onPause();
MobclickAgent.onPause(this);
}
}

@ -36,7 +36,7 @@ import okhttp3.Request;
import okhttp3.Response;
public class CloneActivity extends AppCompatActivity {
private final String TAG = "com.idormy.sms.forwarder.CloneActivity";
private final String TAG = "CloneActivity";
private Context context;
private boolean isRunning = false;
private String serverIp;

@ -0,0 +1,111 @@
package com.idormy.sms.forwarder.adapter;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import com.idormy.sms.forwarder.R;
import com.idormy.sms.forwarder.model.AppInfo;
import java.util.List;
public class AppAdapter extends ArrayAdapter<AppInfo> {
private final int resourceId;
private List<AppInfo> list;
// 适配器的构造函数,把要适配的数据传入这里
public AppAdapter(Context context, int textViewResourceId, List<AppInfo> objects) {
super(context, textViewResourceId, objects);
resourceId = textViewResourceId;
list = objects;
}
@Override
public int getCount() {
return list.size();
}
@Override
public AppInfo getItem(int position) {
return list.get(position);
}
@Override
public long getItemId(int position) {
AppInfo item = list.get(position);
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
AppInfo appInfo = getItem(position); //获取当前项的TLog实例
// 加个判断以免ListView每次滚动时都要重新加载布局以提高运行效率
View view;
AppAdapter.ViewHolder viewHolder;
if (convertView == null) {
// 避免ListView每次滚动时都要重新加载布局以提高运行效率
view = LayoutInflater.from(getContext()).inflate(resourceId, parent, false);
// 避免每次调用getView()时都要重新获取控件实例
viewHolder = new AppAdapter.ViewHolder();
viewHolder.appName = view.findViewById(R.id.appName);
viewHolder.pkgName = view.findViewById(R.id.pkgName);
viewHolder.appIcon = view.findViewById(R.id.appIcon);
viewHolder.verName = view.findViewById(R.id.verName);
viewHolder.verCode = view.findViewById(R.id.verCode);
// 将ViewHolder存储在View中即将控件的实例存储在其中
view.setTag(viewHolder);
} else {
view = convertView;
viewHolder = (AppAdapter.ViewHolder) view.getTag();
}
// 获取控件实例并调用set...方法使其显示出来
if (appInfo != null) {
viewHolder.appName.setText(appInfo.getAppName());
viewHolder.pkgName.setText(appInfo.getPkgName());
viewHolder.appIcon.setBackground(appInfo.getAppIcon());
viewHolder.verName.setText(appInfo.getVerName());
viewHolder.verCode.setText(appInfo.getVerCode() + "");
}
return view;
}
public void add(List<AppInfo> appModels) {
if (list != null) {
list = appModels;
notifyDataSetChanged();
}
}
public void del(List<AppInfo> appModels) {
if (list != null) {
list = appModels;
notifyDataSetChanged();
}
}
public void update(List<AppInfo> appModels) {
if (list != null) {
list = appModels;
notifyDataSetChanged();
}
}
// 定义一个内部类,用于对控件的实例进行缓存
static class ViewHolder {
TextView appName;
TextView pkgName;
ImageView appIcon;
TextView verName;
TextView verCode;
}
}

@ -0,0 +1,47 @@
package com.idormy.sms.forwarder.model;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import lombok.Data;
@Data
public class AppInfo {
public String pkgName;
public String appName;
public Drawable appIcon;
public Intent appIntent;
public String verName;
public int verCode;
public AppInfo() {
}
public AppInfo(String appName) {
this.appName = appName;
}
public AppInfo(String appName, String pkgName) {
this.appName = appName;
this.pkgName = pkgName;
}
public AppInfo(String appName, String pkgName, Drawable appIcon, String verName, int verCode) {
this.appName = appName;
this.pkgName = pkgName;
this.appIcon = appIcon;
this.verName = verName;
this.verCode = verCode;
}
@Override
public String toString() {
return "AppInfo{" +
"appName='" + appName + '\'' +
", pkgName='" + pkgName + '\'' +
", appIcon=" + appIcon +
", verName=" + verName +
", verCode=" + verCode +
'}';
}
}

@ -40,7 +40,7 @@ public class LogVo {
}
}
return R.drawable.app;
return R.drawable.ic_app;
}
public int getStatusImageId() {

@ -0,0 +1,51 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="5dip"
android:orientation="horizontal">
<RadioGroup
android:id="@+id/radioGroupTypeCheck"
style="@style/rg_style"
android:orientation="horizontal">
<RadioButton
android:id="@+id/btnTypeUser"
style="@style/select_style"
android:tag="user"
android:text="@string/user_app"
android:checked="true" />
<RadioButton
android:id="@+id/btnTypeSys"
style="@style/select_style"
android:tag="sys"
android:text="@string/system_app" />
</RadioGroup>
</LinearLayout>
<ListView
android:id="@+id/list_view_app"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_margin="5dp"
android:layout_weight="1" />
<TextView
android:id="@+id/help_tip"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/app_tips"
android:textColor="@color/colorPrimary" />
</LinearLayout>

@ -14,9 +14,11 @@
<string name="about">About</string>
<string name="rule_setting">Rule Setting</string>
<string name="sender_setting">Sender Setting</string>
<string name="app_list">App List</string>
<string name="log_tips">Tips: Pull to refresh; Long press to delete one log entry.</string>
<string name="rule_tips">Tips: Tap "NEW FORWARDING RULE" to add a new rule; Long press one to delete; Tap an existing one to edit.</string>
<string name="sender_tips">Tips: Tap "NEW SENDER" to add a new sender; Long press one to delete; Tap an existing one to edit.</string>
<string name="app_tips">Tips: Tap to copy the package name of APP; Long press one to start and jump to.</string>
<!--AboutActivity-->
<string name="version">Version</string>
<string name="check_for_updates">Check for updates</string>
@ -152,6 +154,7 @@
<string name="retry_interval_tips">Retry five times after it fails</string>
<string name="add_extra">Sim slot info attached</string>
<string name="add_device_name">Device Name attached</string>
<string name="forward_sms">Forward sms</string>
<string name="forward_missed_calls">Forward missed calls</string>
<string name="forward_app_notify">Forward app notify</string>
<string name="enable_custom_templates">Enable custom templates</string>
@ -205,7 +208,10 @@
<string name="no_network">No network at present</string>
<string name="not_connected_wifi">Not connected WIFI</string>
<string name="failed_to_get_ip">Failed to get IP address</string>
<string name="sms">短 信</string>
<string name="call">来 电</string>
<string name="app">应 用</string>
<string name="sms">SMS</string>
<string name="call">Call</string>
<string name="app">App</string>
<string name="appicon">App Icon</string>
<string name="user_app">User App</string>
<string name="system_app">System App</string>
</resources>

@ -6,6 +6,13 @@
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
<item name="actionOverflowMenuStyle">@style/OverflowMenu</item>
</style>
<style name="OverflowMenu" parent="Base.Widget.AppCompat.PopupMenu.Overflow">
<item name="android:dropDownWidth">100dp</item>
<!-- 是否覆盖锚点默认为true即盖住Toolbar -->
<item name="overlapAnchor">false</item>
</style>
<style name="rg_style">

Loading…
Cancel
Save