這個項目是機頂盒桌面,用來播放視頻、顯示圖片、利用管理和其他針對機頂盒產品的設置。目前git和CSDN code上面都沒有類似的開源項目,正好本人最近在開發類似產品,網上類似研究還非常少,完全自己實現還是比較困難。所以就把目前的項目開源出來,也有益于其他人少走彎路。
git項目地址
CSDN code項目地址
UI、adapter、實體類、圖片cache、網絡層。
這個層級關系還是和大部份項目是類似的。
這個部份主要講1下機頂盒Launcher實現的幾個難點,如還有其他問題請留言。
1.掃描可啟動的利用
由于原項目效果圖不符合開源要求所以去掉了。
public ArrayList<AppBean> getLaunchAppList() {
PackageManager localPackageManager = mContext.getPackageManager();
Intent localIntent = new Intent("android.intent.action.MAIN");
localIntent.addCategory("android.intent.category.LAUNCHER");
List<ResolveInfo> localList = localPackageManager.queryIntentActivities(localIntent, 0);
ArrayList<AppBean> localArrayList = null;
Iterator<ResolveInfo> localIterator = null;
if (localList != null) {
localArrayList = new ArrayList<AppBean>();
localIterator = localList.iterator();
}
while (true) {
if (!localIterator.hasNext())
break;
ResolveInfo localResolveInfo = (ResolveInfo) localIterator.next();
AppBean localAppBean = new AppBean();
localAppBean.setIcon(localResolveInfo.activityInfo.loadIcon(localPackageManager));
localAppBean.setName(localResolveInfo.activityInfo.loadLabel(localPackageManager).toString());
localAppBean.setPackageName(localResolveInfo.activityInfo.packageName);
localAppBean.setDataDir(localResolveInfo.activityInfo.applicationInfo.publicSourceDir);
localAppBean.setLauncherName(localResolveInfo.activityInfo.name);
String pkgName = localResolveInfo.activityInfo.packageName;
PackageInfo mPackageInfo;
try {
mPackageInfo = mContext.getPackageManager().getPackageInfo(pkgName, 0);
if ((mPackageInfo.applicationInfo.flags & mPackageInfo.applicationInfo.FLAG_SYSTEM) > 0) {//系統預裝
localAppBean.setSysApp(true);
}
} catch (NameNotFoundException e) {
e.printStackTrace();
}
String noSeeApk = localAppBean.getPackageName();
// 屏蔽1些apk
if (!noSeeApk.equals("com.cqsmiletv") && !noSeeApk.endsWith("com.starcor.hunan") && !noSeeApk.endsWith("com.tcl.matrix.tventrance")) {
localArrayList.add(localAppBean);
}
}
return localArrayList;
}
//接收安裝廣播
if (intent.getAction().equals("android.intent.action.PACKAGE_ADDED")) {
String packageName = intent.getDataString();
List<ResolveInfo> list = Tools.findActivitiesForPackage(context, packageName);
ResolveInfo info = list.get(0);
PackageManager localPackageManager = context.getPackageManager();
AppBean localAppBean = new AppBean();
localAppBean.setIcon(info.activityInfo.loadIcon(localPackageManager));
localAppBean.setName(info.activityInfo.loadLabel(localPackageManager).toString());
localAppBean.setPackageName(info.activityInfo.packageName);
localAppBean.setDataDir(info.activityInfo.applicationInfo.publicSourceDir);
mAppList.add(localAppBean);
}
上面的第1個代碼模塊主要是掃描機頂盒上面安裝了哪些利用,把信息填到實體類里面去,還可以根據自己產品要求屏蔽1些apk。
第2個代碼塊是檢測安裝廣播,根據需要更新數據。
2.掃描可卸載的利用
public ArrayList<AppBean> getUninstallAppList() {
PackageManager localPackageManager = mContext.getPackageManager();
Intent localIntent = new Intent("android.intent.action.MAIN");
localIntent.addCategory("android.intent.category.LAUNCHER");
List<ResolveInfo> localList = localPackageManager.queryIntentActivities(localIntent, 0);
ArrayList<AppBean> localArrayList = null;
Iterator<ResolveInfo> localIterator = null;
if (localList != null) {
localArrayList = new ArrayList<AppBean>();
localIterator = localList.iterator();
}
while (true) {
if (!localIterator.hasNext())
break;
ResolveInfo localResolveInfo = (ResolveInfo) localIterator.next();
AppBean localAppBean = new AppBean();
localAppBean.setIcon(localResolveInfo.activityInfo.loadIcon(localPackageManager));
localAppBean.setName(localResolveInfo.activityInfo.loadLabel(localPackageManager).toString());
localAppBean.setPackageName(localResolveInfo.activityInfo.packageName);
localAppBean.setDataDir(localResolveInfo.activityInfo.applicationInfo.publicSourceDir);
String pkgName = localResolveInfo.activityInfo.packageName;
PackageInfo mPackageInfo;
try {
mPackageInfo = mContext.getPackageManager().getPackageInfo(pkgName, 0);
if ((mPackageInfo.applicationInfo.flags & mPackageInfo.applicationInfo.FLAG_SYSTEM) > 0) {//系統預裝
localAppBean.setSysApp(true);
} else {
localArrayList.add(localAppBean);
}
} catch (NameNotFoundException e) {
e.printStackTrace();
}
}
return localArrayList;
}
//接收卸載廣播
if (intent.getAction().equals("android.intent.action.PACKAGE_REMOVED")) {
String receiverName = intent.getDataString();
receiverName = receiverName.substring(8);
AppBean appBean;
for(int i=0;i<mAppList.size();i++){
appBean = mAppList.get(i);
String packageName = appBean.getPackageName();
if(packageName.equals(receiverName)){
mAppList.remove(i);
adapter.notifyDataSetChanged();
}
}
}
由于系統預裝的按常理方法是沒法卸載的,應當屏蔽掉。卸載的時候根據廣播返回標志更新數據。
3.自啟動管理
public ArrayList<AppBean> getAutoRunAppList() {
PackageManager localPackageManager = mContext.getPackageManager();
Intent localIntent = new Intent("android.intent.action.MAIN");
localIntent.addCategory("android.intent.category.LAUNCHER");
List<ResolveInfo> localList = localPackageManager.queryIntentActivities(localIntent, 0);
ArrayList<AppBean> localArrayList = null;
Iterator<ResolveInfo> localIterator = null;
if (localList != null) {
localArrayList = new ArrayList<AppBean>();
localIterator = localList.iterator();
}
while (true) {
if (!localIterator.hasNext())
break;
ResolveInfo localResolveInfo = localIterator.next();
AppBean localAppBean = new AppBean();
localAppBean.setIcon(localResolveInfo.activityInfo.loadIcon(localPackageManager));
localAppBean.setName(localResolveInfo.activityInfo.loadLabel(localPackageManager).toString());
localAppBean.setPackageName(localResolveInfo.activityInfo.packageName);
localAppBean.setDataDir(localResolveInfo.activityInfo.applicationInfo.publicSourceDir);
String pkgName = localResolveInfo.activityInfo.packageName;
String permission = "android.permission.RECEIVE_BOOT_COMPLETED";
try {
PackageInfo mPackageInfo = mContext.getPackageManager().getPackageInfo(pkgName, 0);
if ((PackageManager.PERMISSION_GRANTED == localPackageManager.checkPermission(permission, pkgName)) && !((mPackageInfo.applicationInfo.flags & mPackageInfo.applicationInfo.FLAG_SYSTEM) > 0)) {
localArrayList.add(localAppBean);
}
} catch (NameNotFoundException e) {
e.printStackTrace();
}
}
return localArrayList;
}
掃描利用權限查看是不是是自啟動app,返回所有自啟動app。
public boolean manageBoot(String pkg,boolean able) {
Process process = null;
DataOutputStream dos = null;
String command = null;
try {
process = Runtime.getRuntime().exec("su");
dos = new DataOutputStream(process.getOutputStream());
dos.flush();
command = "export LD_LIBRARY_PATH=/vendor/lib:/system/lib
";
dos.writeBytes(command);
//(有些cls含有$,需要處理1下,不然會制止失敗,比如微信)
//但是獲得利用是不是允許或制止開機啟動的時候就不用途理cls,否則得不到狀態值
// cls = cls.replace("$", "$");
// command = "pm disable " + pkg + "/" + cls + "
";
if(able){
command = "pm enable " + pkg;
}else{
command = "pm disable " + pkg;
}
dos.writeBytes(command);
dos.writeBytes("exit " + "
");
dos.flush();
try {
process.waitFor();
} catch (InterruptedException e) {
e.printStackTrace();
}
int exitValue = process.exitValue();
try {
if (exitValue == 0) {
return true;
} else {
return false;
}
} catch (Exception e) {
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (dos != null) {
try {
dos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (process != null) {
process.destroy();
}
}
return false;
}
制止利用自啟動,需要有root權限。
1.WiFi
掃描附近WiFi
public void StartScan() {
mWifiManager.startScan();
// 得到掃描結果
mWifiList = mWifiManager.getScanResults();
// 得到配置好的網絡連接
mWifiConfigurations = mWifiManager.getConfiguredNetworks();
Log.v("mWifiManager", mWifiManager+"");
Log.v("mWifiList", mWifiList+"");
Log.v("mWifiConfigurations", mWifiConfigurations+"");
}
根據WiFi幾種加密方式配置wificonfiguration
public WifiConfiguration CreatConfiguration(String SSID, String Password,
int Type) {
WifiConfiguration configuration = new WifiConfiguration();
configuration.allowedAuthAlgorithms.clear();
configuration.allowedGroupCiphers.clear();
configuration.allowedKeyManagement.clear();
configuration.allowedPairwiseCiphers.clear();
configuration.allowedProtocols.clear();
configuration.SSID = """ + SSID + """;
WifiConfiguration tempConfiguration = IsExits(SSID, mWifiManager);
if (tempConfiguration != null) {
mWifiManager.removeNetwork(tempConfiguration.networkId);
}
// WIFICIPHER_NOPASS
if (Type == 1) {
configuration.wepKeys[0] = "";
configuration.allowedKeyManagement
.set(WifiConfiguration.KeyMgmt.NONE);
configuration.wepTxKeyIndex = 0;
}
// WIFICIPHER_WEP
if (Type == 2) {
configuration.hiddenSSID = true;
configuration.wepKeys[0] = """ + Password + """;
configuration.allowedAuthAlgorithms
.set(WifiConfiguration.AuthAlgorithm.SHARED);
configuration.allowedGroupCiphers
.set(WifiConfiguration.GroupCipher.CCMP);
configuration.allowedGroupCiphers
.set(WifiConfiguration.GroupCipher.TKIP);
configuration.allowedGroupCiphers
.set(WifiConfiguration.GroupCipher.WEP40);
configuration.allowedGroupCiphers
.set(WifiConfiguration.GroupCipher.WEP104);
configuration.allowedKeyManagement
.set(WifiConfiguration.KeyMgmt.NONE);
configuration.wepTxKeyIndex = 0;
}
// WIFICIPHER_WPA
if (Type == 3) {
configuration.preSharedKey = """ + Password + """;
configuration.hiddenSSID = true;
configuration.allowedAuthAlgorithms
.set(WifiConfiguration.AuthAlgorithm.OPEN);
configuration.allowedGroupCiphers
.set(WifiConfiguration.GroupCipher.TKIP);
configuration.allowedKeyManagement
.set(WifiConfiguration.KeyMgmt.WPA_PSK);
configuration.allowedPairwiseCiphers
.set(WifiConfiguration.PairwiseCipher.TKIP);
configuration.allowedGroupCiphers
.set(WifiConfiguration.GroupCipher.CCMP);
configuration.allowedPairwiseCiphers
.set(WifiConfiguration.PairwiseCipher.CCMP);
configuration.status = WifiConfiguration.Status.ENABLED;
}
return configuration;
}
根據上面得到的信息用WiFimanager連接網絡,返回的信息可判斷是不是連接成功。
public int AddNetwork(WifiConfiguration configuration) {
int configurationId = mWifiManager.addNetwork(configuration);
boolean b = mWifiManager.enableNetwork(configurationId, true);
return configurationId;
}
2.藍牙
在機頂盒中藍牙經常使用于藍牙遙控、鍵盤、游戲手柄。
注冊藍牙狀態廣播(連接、正在連接、已連接)
IntentFilter intent = new IntentFilter();
// 用BroadcastReceiver來獲得搜索結果
intent.addAction(BluetoothDevice.ACTION_FOUND);
//每當掃描模式變化的時候,利用程序可以為通過ACTION_SCAN_MODE_CHANGED值來監聽全局的消息通知。
// 比如,當裝備停止被搜索以后,該消息可以被系統通知
生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈