最终效果
HelloWord工程应用代码:
package com.pateo;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
import com.pateo.R;
import android.content.pm.PackageManager;
public class HelloWordActivity extends Activity {
TextView tv ;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
tv = (TextView)findViewById(R.id.tv);
PackageManager pm = getPackageManager();
try{
tv.setText("result : " + pm.getAppVoiceEntryInfo("packageName", "xmlName", "bnfName").speechContent);
}catch( android.content.pm.PackageManager.NameNotFoundException e){
tv.setText("" + e);
}
}
}
上面getAppVoiceEntryInfo不是PackageManager自带的方法是我自己添加的方法
我是自己写了个HelloWord工程,放入到源码中,自己的应用怎么放入框架中要遵循:修改/bulid/target/product/generic.mk 把工程编译到系统中
generic.mk
#
# Copyright (C) 2007 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# This is a generic product that isn't specialized for a specific device.
# It includes the base Android platform.
PRODUCT_PACKAGES := \
AccountAndSyncSettings \
CarHome \
DeskClock \
AlarmProvider \
Bluetooth \
Calculator \
Calendar \
Camera \
CertInstaller \
DrmProvider \
Email \
Gallery3D \
LatinIME \
Launcher2 \
Mms \
Music \
Provision \
Protips \
QuickSearchBox \
Settings \
Sync \
Updater \
CalendarProvider \
SyncProvider \
Helloworld
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_PACKAGE_NAME := HelloWord
LOCAL_CERTIFICATE := platform
include $(BUILD_PACKAGE)
# Use the folloing include to make our test apk.
include $(call all-makefiles-under,$(LOCAL_PATH))
到这里基本应用的代码完成了
下面是框架中的一些实现步骤
Ctrl+Shift+T [Eclipse的快捷键方式,下同]搜索类:PackageManager为其添加如下代码:
/**
* 语音识别获取应用的识别词条的动作的启动信息
* @param packageName 应用的包名
* @param xmlName 词条对应的动作定义的文件
* @param bnfName 词条识别的入科大库的文件
* @return
* @throws NameNotFoundException
*/
public abstract AppVoiceEntryInfo getAppVoiceEntryInfo(String packageName,
String xmlName,String bnfName)throws NameNotFoundException;
PackageManager是个抽象类,我们F4找到它的实现类之一:MockPackageManager为其添加如下代码:
@Override
public AppVoiceEntryInfo getAppVoiceEntryInfo(String packageName,
String xmlName, String bnfName) throws NameNotFoundException {
// TODO Auto-generated method stub
throw new UnsupportedOperationException();
}
找到PackageManager的实现类之二:MockPackageManager为其添加如下代码:
@Override
public AppVoiceEntryInfo getAppVoiceEntryInfo(String packageName,
String xmlName, String bnfName) throws NameNotFoundException {
try {
AppVoiceEntryInfo appVoiceEntryInfo = mPM.getAppVoiceEntryInfo(
"packageName", "xmlName", "bnfName");
Log.d(TAG,
"============================getAppVoiceEntryInfo====================================");
return appVoiceEntryInfo;
} catch (RemoteException e) {
throw new RuntimeException("Package manager has died", e);
}
}
上面的mPM的定义:
private final IPackageManager mPM;
ApplicationPackageManager(ContextImpl context, IPackageManager pm) {
mContext = context;
mPM = pm;
}
@Override
public PackageManager getPackageManager() {
if (mPackageManager != null) {
return mPackageManager;
}
IPackageManager pm = ActivityThread.getPackageManager();
if (pm != null) {
// Doesn't matter if we make more than one instance.
return (mPackageManager = new ApplicationPackageManager(this, pm));
}
return null;
}
public static IPackageManager getPackageManager() {
if (sPackageManager != null) {
//Slog.v("PackageManager", "returning cur default = " + sPackageManager);
return sPackageManager;
}
IBinder b = ServiceManager.getService("package");
//Slog.v("PackageManager", "default service binder = " + b);
sPackageManager = IPackageManager.Stub.asInterface(b);
//Slog.v("PackageManager", "default service = " + sPackageManager);
return sPackageManager;
}
这个aidl文件中加一个 AppVoiceEntryInfo getAppVoiceEntryInfo(String packageName, String xmlName, String bnfName);接口方法
/*
**
** Copyright 2007, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
package android.content.pm;
import android.content.ComponentName;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.FeatureInfo;
import android.content.pm.IPackageInstallObserver;
import android.content.pm.IPackageDeleteObserver;
import android.content.pm.IPackageDataObserver;
import android.content.pm.IPackageMoveObserver;
import android.content.pm.IPackageStatsObserver;
import android.content.pm.InstrumentationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.ProviderInfo;
import android.content.pm.PermissionGroupInfo;
import android.content.pm.PermissionInfo;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.net.Uri;
import android.content.IntentSender;
import android.content.pm.AppVoiceEntryInfo;
/**
* See {@link PackageManager} for documentation on most of the APIs
* here.
*
* {@hide}
*/
interface IPackageManager {
AppVoiceEntryInfo getAppVoiceEntryInfo(String packageName, String xmlName, String bnfName);
PackageInfo getPackageInfo(String packageName, int flags);
int getPackageUid(String packageName);
int[] getPackageGids(String packageName);
String[] currentToCanonicalPackageNames(in String[] names);
String[] canonicalToCurrentPackageNames(in String[] names);
PermissionInfo getPermissionInfo(String name, int flags);
List queryPermissionsByGroup(String group, int flags);
PermissionGroupInfo getPermissionGroupInfo(String name, int flags);
List getAllPermissionGroups(int flags);
ApplicationInfo getApplicationInfo(String packageName, int flags);
ActivityInfo getActivityInfo(in ComponentName className, int flags);
ActivityInfo getReceiverInfo(in ComponentName className, int flags);
ServiceInfo getServiceInfo(in ComponentName className, int flags);
int checkPermission(String permName, String pkgName);
int checkUidPermission(String permName, int uid);
boolean addPermission(in PermissionInfo info);
void removePermission(String name);
boolean isProtectedBroadcast(String actionName);
int checkSignatures(String pkg1, String pkg2);
int checkUidSignatures(int uid1, int uid2);
String[] getPackagesForUid(int uid);
String getNameForUid(int uid);
int getUidForSharedUser(String sharedUserName);
ResolveInfo resolveIntent(in Intent intent, String resolvedType, int flags);
List queryIntentActivities(in Intent intent,
String resolvedType, int flags);
List queryIntentActivityOptions(
in ComponentName caller, in Intent[] specifics,
in String[] specificTypes, in Intent intent,
String resolvedType, int flags);
List queryIntentReceivers(in Intent intent,
String resolvedType, int flags);
ResolveInfo resolveService(in Intent intent,
String resolvedType, int flags);
List queryIntentServices(in Intent intent,
String resolvedType, int flags);
List getInstalledPackages(int flags);
List getInstalledApplications(int flags);
/**
* Retrieve all applications that are marked as persistent.
*
* @return A List containing one entry for each persistent
* application.
*/
List getPersistentApplications(int flags);
ProviderInfo resolveContentProvider(String name, int flags);
/**
* Retrieve sync information for all content providers.
*
* @param outNames Filled in with a list of the root names of the content
* providers that can sync.
* @param outInfo Filled in with a list of the ProviderInfo for each
* name in 'outNames'.
*/
void querySyncProviders(inout List outNames,
inout List outInfo);
List queryContentProviders(
String processName, int uid, int flags);
InstrumentationInfo getInstrumentationInfo(
in ComponentName className, int flags);
List queryInstrumentation(
String targetPackage, int flags);
/**
* Install a package.
*
* @param packageURI The location of the package file to install.
* @param observer a callback to use to notify when the package installation in finished.
* @param flags - possible values: {@link #FORWARD_LOCK_PACKAGE},
* {@link #REPLACE_EXISITING_PACKAGE}
* @param installerPackageName Optional package name of the application that is performing the
* installation. This identifies which market the package came from.
*/
void installPackage(in Uri packageURI, IPackageInstallObserver observer, int flags,
in String installerPackageName);
void finishPackageInstall(int token);
/**
* Delete a package.
*
* @param packageName The fully qualified name of the package to delete.
* @param observer a callback to use to notify when the package deletion in finished.
* @param flags - possible values: {@link #DONT_DELETE_DATA}
*/
void deletePackage(in String packageName, IPackageDeleteObserver observer, int flags);
String getInstallerPackageName(in String packageName);
void addPackageToPreferred(String packageName);
void removePackageFromPreferred(String packageName);
List getPreferredPackages(int flags);
void addPreferredActivity(in IntentFilter filter, int match,
in ComponentName[] set, in ComponentName activity);
void replacePreferredActivity(in IntentFilter filter, int match,
in ComponentName[] set, in ComponentName activity);
void clearPackagePreferredActivities(String packageName);
int getPreferredActivities(out List outFilters,
out List outActivities, String packageName);
/**
* As per {@link android.content.pm.PackageManager#setComponentEnabledSetting}.
*/
void setComponentEnabledSetting(in ComponentName componentName,
in int newState, in int flags);
/**
* As per {@link android.content.pm.PackageManager#getComponentEnabledSetting}.
*/
int getComponentEnabledSetting(in ComponentName componentName);
/**
* As per {@link android.content.pm.PackageManager#setApplicationEnabledSetting}.
*/
void setApplicationEnabledSetting(in String packageName, in int newState, int flags);
/**
* As per {@link android.content.pm.PackageManager#getApplicationEnabledSetting}.
*/
int getApplicationEnabledSetting(in String packageName);
/**
* Free storage by deleting LRU sorted list of cache files across
* all applications. If the currently available free storage
* on the device is greater than or equal to the requested
* free storage, no cache files are cleared. If the currently
* available storage on the device is less than the requested
* free storage, some or all of the cache files across
* all applications are deleted (based on last accessed time)
* to increase the free storage space on the device to
* the requested value. There is no guarantee that clearing all
* the cache files from all applications will clear up
* enough storage to achieve the desired value.
* @param freeStorageSize The number of bytes of storage to be
* freed by the system. Say if freeStorageSize is XX,
* and the current free storage is YY,
* if XX is less than YY, just return. if not free XX-YY number
* of bytes if possible.
* @param observer call back used to notify when
* the operation is completed
*/
void freeStorageAndNotify(in long freeStorageSize,
IPackageDataObserver observer);
/**
* Free storage by deleting LRU sorted list of cache files across
* all applications. If the currently available free storage
* on the device is greater than or equal to the requested
* free storage, no cache files are cleared. If the currently
* available storage on the device is less than the requested
* free storage, some or all of the cache files across
* all applications are deleted (based on last accessed time)
* to increase the free storage space on the device to
* the requested value. There is no guarantee that clearing all
* the cache files from all applications will clear up
* enough storage to achieve the desired value.
* @param freeStorageSize The number of bytes of storage to be
* freed by the system. Say if freeStorageSize is XX,
* and the current free storage is YY,
* if XX is less than YY, just return. if not free XX-YY number
* of bytes if possible.
* @param pi IntentSender call back used to
* notify when the operation is completed.May be null
* to indicate that no call back is desired.
*/
void freeStorage(in long freeStorageSize,
in IntentSender pi);
/**
* Delete all the cache files in an applications cache directory
* @param packageName The package name of the application whose cache
* files need to be deleted
* @param observer a callback used to notify when the deletion is finished.
*/
void deleteApplicationCacheFiles(in String packageName, IPackageDataObserver observer);
/**
* Clear the user data directory of an application.
* @param packageName The package name of the application whose cache
* files need to be deleted
* @param observer a callback used to notify when the operation is completed.
*/
void clearApplicationUserData(in String packageName, IPackageDataObserver observer);
/**
* Get package statistics including the code, data and cache size for
* an already installed package
* @param packageName The package name of the application
* @param observer a callback to use to notify when the asynchronous
* retrieval of information is complete.
*/
void getPackageSizeInfo(in String packageName, IPackageStatsObserver observer);
/**
* Get a list of shared libraries that are available on the
* system.
*/
String[] getSystemSharedLibraryNames();
/**
* Get a list of features that are available on the
* system.
*/
FeatureInfo[] getSystemAvailableFeatures();
boolean hasSystemFeature(String name);
void enterSafeMode();
boolean isSafeMode();
void systemReady();
boolean hasSystemUidErrors();
/**
* Ask the package manager to perform dex-opt (if needed) on the given
* package, if it already hasn't done mode. Only does this if running
* in the special development "no pre-dexopt" mode.
*/
boolean performDexOpt(String packageName);
/**
* Update status of external media on the package manager to scan and
* install packages installed on the external media. Like say the
* MountService uses this to call into the package manager to update
* status of sdcard.
*/
void updateExternalMediaStatus(boolean mounted, boolean reportStatus);
String nextPackageToClean(String lastPackage);
void movePackage(String packageName, IPackageMoveObserver observer, int flags);
boolean addPermissionAsync(in PermissionInfo info);
boolean setInstallLocation(int loc);
int getInstallLocation();
}
public AppVoiceEntryInfo getAppVoiceEntryInfo(String packageName, String xmlName,String bnfName){
AppVoiceEntryInfo appVoiceEntryInfo = new AppVoiceEntryInfo();
appVoiceEntryInfo.speechContent = voiceContent;
Log.d(TAG,"getAppVoiceEntryInfo method appVoiceEntryInfo.speechContent : " + appVoiceEntryInfo.speechContent);
return appVoiceEntryInfo;
}
package android.content.pm;
import java.util.HashMap;
import android.os.Parcel;
import android.os.Parcelable;
public class AppVoiceEntryInfo implements Parcelable {
public String packageName;
public String activityName;
public String serviceName;
public String xmlName;
public String bnfName;
public String entry;
public String uri;
public String recognitionType;
public String speechContent;
public String action;
public HashMap map = new HashMap();
public int describeContents() {
// TODO Auto-generated method stub
return 0;
}
public void writeToParcel(Parcel dest, int flags) {
// TODO Auto-generated method stub
dest.writeMap(map);
dest.writeString(packageName);
dest.writeString(activityName);
dest.writeString(xmlName);
dest.writeString(bnfName);
dest.writeString(entry);
dest.writeString(uri);
dest.writeString(recognitionType);
dest.writeString(speechContent);
dest.writeString(action);
}
public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
public AppVoiceEntryInfo createFromParcel(Parcel source) {
return new AppVoiceEntryInfo(source);
}
public AppVoiceEntryInfo[] newArray(int size) {
return new AppVoiceEntryInfo[size];
}
};
private AppVoiceEntryInfo(Parcel source){
packageName = source.readString();
activityName = source.readString();
xmlName = source.readString();
bnfName = source.readString();
entry = source.readString();
uri = source.readString();
recognitionType = source.readString();
speechContent = source.readString();
action = source.readString();
map = source.readHashMap(HashMap.class.getClassLoader());
}
public AppVoiceEntryInfo() {
// TODO Auto-generated constructor stub
}
}
public static String voiceContent = null;
private PackageParser.Package scanPackageLI(File scanFile,
int parseFlags, int scanMode) {
mLastScanError = PackageManager.INSTALL_SUCCEEDED;
String scanPath = scanFile.getPath();
parseFlags |= mDefParseFlags;
PackageParser pp = new PackageParser(scanPath);
pp.setSeparateProcesses(mSeparateProcesses);
final PackageParser.Package pkg = pp.parsePackage(scanFile,
scanPath, mMetrics, parseFlags);
voiceContent = pp.voiceContent;
Log.d(TAG,"Voice Contect : " + voiceContent);
public static String voiceContent = null;
public String convertStreamToString(InputStream is) {
/*
* To convert the InputStream to String we use the BufferedReader.readLine()
* method. We iterate until the BufferedReader return null which means
* there's no more data to read. Each line will appended to a StringBuilder
* and returned as String.
*/
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
String line = null;
try {
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return sb.toString();
}
public Package parsePackage(File sourceFile, String destCodePath,
DisplayMetrics metrics, int flags) {
mParseError = PackageManager.INSTALL_SUCCEEDED;
mArchiveSourcePath = sourceFile.getPath();
if (!sourceFile.isFile()) {
Log.w(TAG, "Skipping dir: " + mArchiveSourcePath);
mParseError = PackageManager.INSTALL_PARSE_FAILED_NOT_APK;
return null;
}
if (!isPackageFilename(sourceFile.getName())
&& (flags&PARSE_MUST_BE_APK) != 0) {
if ((flags&PARSE_IS_SYSTEM) == 0) {
// We expect to have non-.apk files in the system dir,
// so don't warn about them.
Log.w(TAG, "Skipping non-package file: " + mArchiveSourcePath);
}
mParseError = PackageManager.INSTALL_PARSE_FAILED_NOT_APK;
return null;
}
if ((flags&PARSE_CHATTY) != 0 && Config.LOGD) Log.d(
TAG, "Scanning package: " + mArchiveSourcePath);
XmlResourceParser parser = null;
AssetManager assmgr = null;
InputStream inputStream = null;
boolean assetError = true;
try {
assmgr = new AssetManager();
int cookie = assmgr.addAssetPath(mArchiveSourcePath);
if(cookie != 0) {
Log.d(TAG, "sourceFile : " + sourceFile + " destCodePath : " + destCodePath + " flags : " + flags + " cookie : " + cookie
+ " ArchiveSourcePath : " + mArchiveSourcePath);
parser = assmgr.openXmlResourceParser(cookie, "AndroidManifest.xml");
try{
inputStream = assmgr.open("voice_recognition.xml");
}catch(Exception e){
Log.d(TAG,"" + e);
}
if(inputStream != null){
Log.d(TAG,"============================= success ==========================" );
voiceContent = convertStreamToString(inputStream);
Log.d(TAG,"Voice Contect : " + voiceContent);
}
有关过程中的停顿
Checking API: checkapi-last
Checking API: checkapi-current
(unknown): error 3: Added class AppVoiceEntryInfo to package android.content.pm
(unknown): error 4: Added public method android.content.pm.PackageManager.getAppVoiceEntryInfo
******************************
You have tried to change the API from what has been previously approved.
To make these errors go away, you have two choices:
1) You can add "@hide" javadoc comments to the methods, etc. listed in the
errors above.
2) You can update current.xml by executing the following command:
make update-api
To submit the revised current.xml to the main Android repository,
you will need approval.
******************************
make: *** [out/target/common/obj/PACKAGING/checkapi-current-timestamp] 错误 38