如何根据meta-data内容杀指定应用

应用场景:
在开发一体机上具体应用过程中,发现一体机资源切换及不同的应用使用不同的资源。因为就需要在切换不同的信号源模式下
使用不同的资源。所以就想到使用meta-data这一描述字进行杀死指定的应用。

在AndroidManifest.xml中,<meta-data>元素可以作为子元素,被包含在<activity>、<application> 、<service>和<receiver>元素中,
但不同的父元素,在应用时读取的方法也不同。


我的例子就是:
<meta-data android:name="androidtv.meidasource.mode" android:value='digit-mode" />
放在<application> ... </application> 之层次上


ok,实现此功能很简单,就直接上代码吧!!


下面的代码直接实现了一个kill指定meta-data进程的方法及根据包名运行一个activity的方法


package com.skyworth.dtv;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import android.app.ActivityManager;
import android.content.ComponentName;
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.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo;
import android.util.Log;

public class DtvAppHelper {
	public static final String META_SOURCE_MODE = "androidtv.meidasource.mode";
	public static final String META_SOURCE_MODE_DTV = "dtv";
	static final String TAG = "DtvAppCloseHelper";
	static Method forceStopPackage = null;

	public static void shutdownDtvApps(Context ctx) {
		PackageManager pm = ctx.getPackageManager();
		ActivityManager am = (ActivityManager) ctx
				.getSystemService(Context.ACTIVITY_SERVICE);
		List<String> list = getRunningDtvApps(am, pm);
		for (int i = 0; i < list.size(); i++) {
			Log.i(TAG, "will stop package name : " + list.get(i));
			forceStopPackage(am, list.get(i));
		}
	}

	private static void forceStopPackage(ActivityManager am, String pkgname) {
		try {
			if (forceStopPackage == null) {
				forceStopPackage = am.getClass().getDeclaredMethod(
						"forceStopPackage", String.class);
			}
			if (forceStopPackage != null) {
				forceStopPackage.setAccessible(true);
				forceStopPackage.invoke(am, pkgname);
			}
		} catch (Exception e) {
			Log.e(TAG, "forceStopPackage error:" + e);
		}
	}

	private static List<String> getRunningDtvApps(ActivityManager am,
			PackageManager pm) {
		List<String> plist = new ArrayList<String>();
		List<ActivityManager.RunningAppProcessInfo> applist = am
				.getRunningAppProcesses();
		for (ActivityManager.RunningAppProcessInfo appProcess : applist) {
			String[] pkgNameList = appProcess.pkgList; // 得到包名列表
			int pid = appProcess.pid;
			for (int i = 0; i < pkgNameList.length; i++) {
				String pkgName = pkgNameList[i];
				try {
					ApplicationInfo ai = pm.getApplicationInfo(pkgName,
							PackageManager.GET_META_DATA);
					if (ai.metaData != null) {
						String value = ai.metaData.getString(META_SOURCE_MODE);
						if (META_SOURCE_MODE_DTV.equals(value)) {
							Log.i(TAG, "packageName:" + pkgName
									+ " process pid:" + pid);
							plist.add(pkgName);
						}
					}
				} catch (NameNotFoundException e) {
					Log.e(TAG, "get meta data is empty");
				}
			}
		}
		return plist;
	}
	
	public static void runDtvApps(Context ctx, String packageName) {
		Log.i(TAG, "will start packageName:" + packageName);
		PackageInfo pi = null;
		try {
			pi = ctx.getPackageManager().getPackageInfo(packageName, 0);
			Intent resolveIntent = new Intent(Intent.ACTION_MAIN, null);
			resolveIntent.setPackage(pi.packageName);
			PackageManager pManager = ctx.getPackageManager();
			List<ResolveInfo> apps = pManager.queryIntentActivities(
					resolveIntent, 0);

			ResolveInfo ri = apps.iterator().next();
			if (ri != null) {
				packageName = ri.activityInfo.packageName;
				String className = ri.activityInfo.name;
				Log.i(TAG, "packageName: " + packageName + " className:"
						+ className);
				Intent intent = new Intent(Intent.ACTION_MAIN);
				ComponentName cn = new ComponentName(packageName, className);
				intent.setComponent(cn);
				intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
				ctx.startActivity(intent);
			}
		} catch (Exception e) {
			Log.e(TAG, "start activity failed " + e);
		}
	}
}


下面具体列一下不同父元素,读取的方法情况(为了对比方便写在一个函数中了,可以根据情况拆分):

	void test(Context ctx, String packageName, String className) {
		/* 在application的应用 */
		try {
			ApplicationInfo appInfo = ctx.getPackageManager()
					.getApplicationInfo(packageName,
							PackageManager.GET_META_DATA);

			String msg = appInfo.metaData.getString("myMsg");
			Log.i(TAG, "message :" + msg);
			
			//TODO
			
		} catch (Exception e) {
			Log.e(TAG, "getApplicationInfo error:" + e);
		}		
		
		/* 在Activity的应用 */
		ComponentName cn = new ComponentName(packageName, className);

		try {
			ActivityInfo info = ctx.getPackageManager().getActivityInfo(cn,
					PackageManager.GET_META_DATA);
			
			String msg = info.metaData.getString("myMsg");
			Log.i(TAG, "message :" + msg);
			
			//TODO
			
		} catch (Exception e) {
			Log.e(TAG, "getActivityInfo error:" + e);
		}
		
		/* 在service的应用 */
		try {
			ServiceInfo info = ctx.getPackageManager().getServiceInfo(cn,
					PackageManager.GET_META_DATA);

			String msg = info.metaData.getString("myMsg");
			Log.i(TAG, "message :" + msg);

			// TODO

		} catch (Exception e) {
			Log.e(TAG, "getServiceInfo error:" + e);
		}
		
		/* 在receiver的应用 */
		try {
			ComponentName crn = new ComponentName(ctx, className);
			ActivityInfo info = ctx.getPackageManager().getReceiverInfo(crn,
					PackageManager.GET_META_DATA);
			String msg = info.metaData.getString("myMsg");
			Log.i(TAG, "message :" + msg);

			// TODO

		} catch (Exception e) {
			Log.e(TAG, "getReceiverInfo error:" + e);
		}
	}


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值