PocketSphinx: How to recognize Keyword followed by dynamic word? - android

I have been working on PocketSphinx Android voice command project where the user can open application listed on their Android by use command "open xxx" (I made "open" as Keyword and xxx is application's name), but sadly it didn't work.
My question is, how PocketSphinx recognize two-words command, where the first word is Keyword and the second word is a dynamic word (user can say any application's name).
Declare keyword:
public class PocketSphinxActivity extends Activity implements
RecognitionListener {
/* Named searches allow to quickly reconfigure the decoder */
private static final String KWS_SEARCH = "wakeup";
/* Keyword we are looking for to activate menu */
private static final String KEYPHRASE = "open";
I tried to Split() two-words keyword (ex: open camera) and successfully opened camera, but what I need is "open xxx" so the user can define any application they want. That's why I change keyword to "open" only.
public void onPartialResult(Hypothesis hypothesis) {
if (hypothesis == null)
return;
String text = hypothesis.getHypstr();
String[] split = text.split("\\s+");
String word1 = split[0];
String word2 = split[1];
if (word2 != null) {
if (word1.equals("open")) {
PackageManager packageManager = getPackageManager();
List<PackageInfo> packs = packageManager.getInstalledPackages(0);
int size = packs.size();
boolean uninstallApp = false;
boolean exceptFlg = false;
for (int v = 0; v < size; v++) {
PackageInfo p = packs.get(v);
String tmpAppName = p.applicationInfo.loadLabel(packageManager).toString();
String pname = p.packageName;
tmpAppName = tmpAppName.toLowerCase();
if (tmpAppName.trim().toLowerCase().equals(word2.trim().toLowerCase())) {
PackageManager pm = this.getPackageManager();
Intent appStartIntent = pm.getLaunchIntentForPackage(pname);
if (null != appStartIntent) {
try {
this.startActivity(appStartIntent);
} catch (Exception e) {
}
}
}
}
finish();
public void onResult(Hypothesis hypothesis) {
((TextView) findViewById(R.id.result_text)).setText("");
if (hypothesis != null) {
String text = hypothesis.getHypstr();
String[] split = text.split("\\s+");
String word1 = split[0];
String word2 = split[1];
makeText(getApplicationContext(), text, Toast.LENGTH_SHORT).show();
}
}
Any help on this would be grateful. I really need it to complete my final project. Thank you.

Related

get name of app which created the notification

I'm working on an android application that listens for notifications. Is there any way to get the name of the app which created the notification.
You need to get the package name first on receiving the new notification from the notification service::
#Override
public void onNotificationPosted(StatusBarNotification sbn) {
String pack = sbn.getPackageName();
String ticker = new String();
if(sbn.getNotification().tickerText != null) {
ticker = sbn.getNotification().tickerText.toString();
}
Bundle extras = sbn.getNotification().extras;
String title = extras.getString("android.title");
String text = extras.getCharSequence("android.text").toString();
int id1 = extras.getInt(Notification.EXTRA_SMALL_ICON);
Bitmap id = sbn.getNotification().largeIcon;
}
And then use the "pack" value to get the app name:
final PackageManager pm = getApplicationContext().getPackageManager();
ApplicationInfo ai;
try {
ai = pm.getApplicationInfo( pack, 0);
} catch (final PackageManager.NameNotFoundException e) {
ai = null;
}
final String applicationName = (String) (ai != null ?
pm.getApplicationLabel(ai) : "(unknown)");

Not able to find android.provider.CONTACTS_STRUCTURE metadata of contact apps

I am trying to get the list of contact writable accounts in my device using the following code
public static final String SYNC_META_DATA = "android.content.SyncAdapter";
public static final String[] METADATA_CONTACTS_NAMES = new String[] {
"android.provider.ALTERNATE_CONTACTS_STRUCTURE",
"android.provider.CONTACTS_STRUCTURE"
};
final Intent intent = new Intent(SYNC_META_DATA).setPackage(resPackageName);
final List<ResolveInfo> intentServices =
pm.queryIntentServices(intent, PackageManager.GET_META_DATA);
if (intentServices != null) {
for (final ResolveInfo resolveInfo : intentServices) {
final ServiceInfo serviceInfo = resolveInfo.serviceInfo;
if (serviceInfo == null) {
continue;
}
for (String metadataName : METADATA_CONTACTS_NAMES) {
final XmlResourceParser parser = serviceInfo.loadXmlMetaData(
pm, metadataName);
if (parser != null) {
return parser;
}
}
}
}
but I am always getting XmlResourceParser parser as null. so please help me how can I fetch the list of contact writable accounts in android
There's an API for that, you need to iterate over all SyncAdapters and check if they supportUploading and have ContactsContract.AUTHORITY as their authority:
final SyncAdapterType[] syncs = ContentResolver.getSyncAdapterTypes();
for (SyncAdapterType sync : syncs) {
Log.d(TAG, "found SyncAdapter: " + sync.accountType);
if (ContactsContract.AUTHORITY.equals(sync.authority)) {
Log.d(TAG, "SyncAdapter supports contacts: " + sync.accountType + " - supportsUploading=" + sync.supportsUploading());
}
}
supportsUploading means that it's a two-way sync, i.e. the user can modify a contact on her device and have the changes synced up to their cloud account.

Start Chrome as Web-App on Android start

i have a quite specific problem. I have realized a Web App on an Android tablet, which will be used on an exhibition (Outform iDisplay). For this reason, the Web App has to start directly after boot. The after-boot thing is no problem (Broadcast with "android.permission.RECEIVE_BOOT_COMPLETED"), but i have a problem to start Chrome as Web-App. For getting the Intent, i have read the Icons in the launcher favorites with this snippet:
//Kitkat, therefore launcher3
url = "content://com.android.launcher3.settings/favorites?Notify=true";
ContentResolver resolver = getContentResolver();
Cursor cursor = resolver.query(Uri.parse(url), null, null, null, null);
if (cursor != null && cursor.moveToFirst())
{
do
{
String ent1 = cursor.getString(0);
String ent2 = cursor.getString(1);
String ent3 = cursor.getString(2); //there is the Intent string
String ent4 = cursor.getString(3);
System.out.println("Test");
String ent5 = cursor.getString(4);
String ent6 = cursor.getString(5);
String ent7 = cursor.getString(6);
String ent8 = cursor.getString(7);
String ent9 = cursor.getString(8);
String ent10 = cursor.getString(9);
String ent11 = cursor.getString(10);
String ent12 = cursor.getString(11);
String ent14 = cursor.getString(13);
String ent15 = cursor.getString(14);
String ent17 = cursor.getString(16);
String ent18 = cursor.getString(17);
String ent19 = cursor.getString(18);
String ent20 = cursor.getString(19);
if(ent2.equals("History Book")) //Get the right intent
{
runAction = ent3;
}
System.out.println(ent3);
} while (cursor.moveToNext());
}
The Intent string contains something like this:
#Intent;action=com.google.android.apps.chrome.webapps.WebappManager.ACTION_START_WEBAPP;package=com.android.chrome;S.org.chromium.chrome.browser.webapp_title=History%20Book;S.org.chromium.chrome.browser.webapp_id=86e362e4-a25d-4142-8a32-c02ffcb176a9;i.org.chromium.content_public.common.orientation=6;S.org.chromium.chrome.browser.webapp_icon=;S.org.chromium.chrome.browser.webapp_mac=3ZaXFbyWnJQaqFFOuUj3OssNz7DrBaaiWfzO2Dd7VIU%3D%0A;S.org.chromium.chrome.browser.webapp_url=http%3A%2F%2F192.168.5.148%2Fstyria%2Fhistorybook%2Findex.html;end
This looks quite good, but how can i start an Intent like this in a small app, which just has the single purpose to start this intent?
Just a small note at the end: I have tried to pack this thing into a webview, but the webview died constantly because of an libc error, so this is no option for me.
Finally i got this thing working. I was on the right way, but some Chrome.apk reverse engineering helped me for the last mile.
I have created a dummy activity with the following code in onCreate:
Search for the right entry on the homescreen, in my case for the AOSP launcher 3:
//Search for the History Book Shortcut on the Homescreen
String url = "";
String runAction="";
final String AUTHORITY = "com.android.launcher3.settings";
final Uri CONTENT_URI = Uri.parse("content://" +
AUTHORITY + "/favorites?notify=true");
final ContentResolver cr = getContentResolver();
Cursor cursor = cr.query(CONTENT_URI,null,null,null,null);
cursor.moveToFirst();
do {
String id = cursor.getString(cursor.getColumnIndex("_id"));
String title = cursor.getString(cursor.getColumnIndex("title"));
String intent = cursor.getString(cursor.getColumnIndex("intent"));
if(title.equals(getResources().getString(R.string.homescreen_link)))
{
runAction = intent;
}
} while (cursor.moveToNext());
At this point, i have hopefully the intent as string. So, parse the string and create a new intent:
Intent intent = new Intent();
intent.setAction("com.google.android.apps.chrome.webapps.WebappManager.ACTION_START_WEBAPP");
intent.setPackage("com.android.chrome");
intent.setClassName("com.android.chrome", "com.google.android.apps.chrome.webapps.WebappManager");
HashMap<String, String> intentVals = getIntentParams(runAction);
intent.putExtra("org.chromium.chrome.browser.webapp_title",intentVals.get("S.org.chromium.chrome.browser.webapp_title"));
intent.putExtra("org.chromium.chrome.browser.webapp_icon",intentVals.get("S.org.chromium.chrome.browser.webapp_icon"));
intent.putExtra("org.chromium.chrome.browser.webapp_id",intentVals.get("S.org.chromium.chrome.browser.webapp_id"));
intent.putExtra("org.chromium.chrome.browser.webapp_url",intentVals.get("S.org.chromium.chrome.browser.webapp_url"));
intent.putExtra("org.chromium.chrome.browser.webapp_mac",intentVals.get("S.org.chromium.chrome.browser.webapp_mac"));
int orientation = 6;
try
{
orientation = Integer.parseInt(intentVals.get("i.org.chromium.content_public.common.orientation"));
}
catch(NumberFormatException _nex)
{
Log.e(TAG, "Wrong format, using default (6)");
}
intent.putExtra("org.chromium.content_public.common.orientation", orientation);
try
{
byte[] abyte0 = Base64.decode(
intentVals.get("S.org.chromium.chrome.browser.webapp_mac"),
0);
System.out.println(new String(abyte0));
}
catch (IllegalArgumentException _iae)
{
Log.e(TAG,
"Wrong webapp_mac: "
+ intentVals
.get("S.org.chromium.chrome.browser.webapp_mac"));
}
startActivity(intent);
finish();
And this function parses the intent parameters out of the intent string:
private HashMap<String, String> getIntentParams(String _runAction)
{
HashMap<String, String> retMap = new HashMap<String, String>();
String[] pairs = _runAction.split(";");
for (int i = 0; i < pairs.length; i++)
{
String[] keyval = pairs[i].split("=");
if(keyval.length==2)
{
String key = keyval[0];
String value = "";
try
{
value = java.net.URLDecoder.decode(keyval[1], "UTF-8");
}
catch (UnsupportedEncodingException _uee)
{
Log.e(TAG, "Unsupported Encoding: " + _uee.getMessage());
}
retMap.put(key, value);
}
}
return retMap;
}
And the strings.xml in res/values:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">WebAppStarter</string>
<string name="homescreen_link">History Book</string>
</resources>
That's it. You can configure the Homescreen link name to search for in strings.xml. When the app finds the string, it parses the intent string and creates a new intent to start Chrome as a Full Screen Activity Web App.

How to check permission is granted for a directory path and won't thorow EACCES error?

I have a photo editing android app that users can choose the output directory of the the result photos. Problem is Google made a change on sdcard write permission with the KITKAT version and devices with Android KITKAT version won't allow apps to write secondary sdcards. Now I need to check if the choosen directory by user has granted the permission and won't throw EACCES error. I am already checking canRead and canWrite but these won't help. Could you please tell me how can I check if the choosen directory won't throw EACCES. My only solution is trying to write a file in a try catch, however I am hoping there is better way to do it.
[update k3b 2016-09-19]
i tried this on my android-4.4 but without success
Uri uri = Uri.fromFile(file);
int permissionCode =
context.checkCallingOrSelfUriPermission(uri,
Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
if (permissionCode == PackageManager.PERMISSION_DENIED) {
// on my android-4.4 i always get PERMISSION_DENIED even
// if i can overwrite the file
return false;
}
try {
Process p = new ProcessBuilder("ls", "-l", "-s", dir.getCanonicalPath()).start();
String line;
ArrayList<String> lineOut = new ArrayList<>();
BufferedReader error = new BufferedReader(new InputStreamReader(p.getErrorStream()));
while ((line = error.readLine()) != null) {
Log.e(TAG, "ls error = "+line);
}
error.close();
BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));
while ((line = input.readLine()) != null) {
lineOut.add(line);
}
input.close();
String[] strings = lineOut.toArray(new String[]{});
List<FilesLS.FileEntry> fileEntries = FilesLS.processNewLines(strings);
for(FilesLS.FileEntry file : fileEntries){
Log.d(TAG, file.name +" = " + file.permissions);
}
} catch (IOException e) {
e.printStackTrace();
}
And some edits to this class
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public final class FilesLS {
/**
* Entry type: File
*/
public static final int TYPE_FILE = 0;
/**
* Entry type: Directory
*/
public static final int TYPE_DIRECTORY = 1;
/**
* Entry type: Directory Link
*/
public static final int TYPE_DIRECTORY_LINK = 2;
/**
* Entry type: Block
*/
public static final int TYPE_BLOCK = 3;
/**
* Entry type: Character
*/
public static final int TYPE_CHARACTER = 4;
/**
* Entry type: Link
*/
public static final int TYPE_LINK = 5;
/**
* Entry type: Socket
*/
public static final int TYPE_SOCKET = 6;
/**
* Entry type: FIFO
*/
public static final int TYPE_FIFO = 7;
/**
* Entry type: Other
*/
public static final int TYPE_OTHER = 8;
/**
* Device side file separator.
*/
public static final String FILE_SEPARATOR = "/"; //$NON-NLS-1$
/**
* Regexp pattern to parse the result from ls.
*/
private static Pattern sLsPattern = Pattern
.compile("^([bcdlsp-][-r][-w][-xsS][-r][-w][-xsS][-r][-w][-xstST])\\s+(\\S+)\\s+ (\\S+)\\s+(\\d{4}-\\d\\d-\\d\\d)\\s+(\\d\\d:\\d\\d)\\s+(.*)$"); //$NON-NLS-1$ \s+([\d\s,]*)
public static List<FileEntry> processNewLines(String[] lines) {
List<FileEntry> listOfFiles = new ArrayList<FileEntry>();
for (String line : lines) {
// no need to handle empty lines.
if (line.length() == 0) {
continue;
}
// run the line through the regexp
Matcher m = sLsPattern.matcher(line);
if (m.matches() == false) {
continue;
}
// get the name
String name = m.group(6);
// get the rest of the groups
String permissions = m.group(1);
String owner = m.group(2);
String group = m.group(3);
// String size = m.group(4);
String date = m.group(4);
String time = m.group(5);
String info = null;
// and the type
int objectType = TYPE_OTHER;
switch (permissions.charAt(0)) {
case '-':
objectType = TYPE_FILE;
break;
case 'b':
objectType = TYPE_BLOCK;
break;
case 'c':
objectType = TYPE_CHARACTER;
break;
case 'd':
objectType = TYPE_DIRECTORY;
break;
case 'l':
objectType = TYPE_LINK;
break;
case 's':
objectType = TYPE_SOCKET;
break;
case 'p':
objectType = TYPE_FIFO;
break;
}
// now check what we may be linking to
if (objectType == TYPE_LINK) {
String[] segments = name.split("\\s->\\s"); //$NON-NLS-1$
// we should have 2 segments
if (segments.length == 2) {
// update the entry name to not contain the link
name = segments[0];
// and the link name
info = segments[1];
// now get the path to the link
String[] pathSegments = info.split(FILE_SEPARATOR);
if (pathSegments.length == 1) {
// the link is to something in the same directory,
// unless the link is ..
if ("..".equals(pathSegments[0])) { //$NON-NLS-1$
// set the type and we're done.
objectType = TYPE_DIRECTORY_LINK;
} else {
// either we found the object already
// or we'll find it later.
}
}
}
// add an arrow in front to specify it's a link.
info = "-> " + info; //$NON-NLS-1$;
}
FileEntry entry = new FileEntry();
entry.permissions = permissions;
entry.name = name;
// entry.size = size;
entry.date = date;
entry.time = time;
entry.owner = owner;
entry.group = group;
if (objectType == TYPE_LINK) {
entry.info = info;
}
listOfFiles.add(entry);
}
return listOfFiles;
}
public final static class FileEntry {
String name;
String info;
String permissions;
String size;
String date;
String time;
String owner;
String group;
int type;
}
}
Add the permission(s) you need to the array:
private static final int REQUEST_CODE_PERMISSION = 2;
String[] mPermission = {
Manifest.permission.INTERNET,
Manifest.permission.CHANGE_WIFI_STATE,
Manifest.permission.CHANGE_NETWORK_STATE,
Manifest.permission.ACCESS_WIFI_STATE
};
Add this to onCreate or where you want it to be:
try {
if (
ActivityCompat.checkSelfPermission(this, mPermission[0])
!= MockPackageManager.PERMISSION_GRANTED ||
ActivityCompat.checkSelfPermission(this, mPermission[1])
!= MockPackageManager.PERMISSION_GRANTED ||
ActivityCompat.checkSelfPermission(this, mPermission[2])
!= MockPackageManager.PERMISSION_GRANTED ||
ActivityCompat.checkSelfPermission(this, mPermission[3])
!= MockPackageManager.PERMISSION_GRANTED
) {
Log.e("TAGTAG", "DENIED");
ActivityCompat.requestPermissions(
this, mPermission, REQUEST_CODE_PERMISSION
);
// 'Will execute recursively if any of the permissions was not granted.
} else {
Log.e("TAGTAG", "GRANTED");
}
} catch (Exception e) {
e.printStackTrace();
}
Don't forget to declare the permissions in AndroidManifest.xml.

this is my code which show all install application

This is my source code below which shows all installed system applications. I want to show only selected applications like only 5 applications which name I provite not show all applications what do I do?? please help me
public class ListInstalledApps extends Activity implements OnItemClickListener {
/* whether or not to include system apps */
private static final boolean INCLUDE_SYSTEM_APPS = false;
private ListView mAppsList;
private AppListAdapter mAdapter;
private List<App> mApps;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mAppsList = (ListView) findViewById(R.id.appslist);
mAppsList.setOnItemClickListener(this);
mApps = loadInstalledApps(INCLUDE_SYSTEM_APPS);
mAdapter = new AppListAdapter(getApplicationContext());
mAdapter.setListItems(mApps);
mAppsList.setAdapter(mAdapter);
new LoadIconsTask().execute(mApps.toArray(new App[]{}));
}
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
final App app = (App) parent.getItemAtPosition(position);
AlertDialog.Builder builder = new AlertDialog.Builder(this);
String msg = app.getTitle() + "\n\n" +
"Version " + app.getVersionName() + " (" +
app.getVersionCode() + ")" +
(app.getDescription() != null ? ("\n\n" + app.getDescription()) : "");
builder.setMessage(msg)
.setCancelable(true)
.setTitle(app.getTitle())
.setIcon(mAdapter.getIcons().get(app.getPackageName()))
.setPositiveButton("Launch", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// start the app by invoking its launch intent
Intent i = getPackageManager().getLaunchIntentForPackage(app.getPackageName());
try {
if (i != null) {
startActivity(i);
} else {
i = new Intent(app.getPackageName());
startActivity(i);
}
} catch (ActivityNotFoundException err) {
Toast.makeText(ListInstalledApps.this, "Error launching app",
Toast.LENGTH_SHORT).show();
}
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
AlertDialog dialog = builder.create();
dialog.show();
}
/**
* Uses the package manager to query for all currently installed apps which are put
into beans and returned
* in form of a list.
*
* #param includeSysApps whether or not to include system applications
* #return a list containing an {#code App} bean for each installed application
*/
private List<App> loadInstalledApps(boolean includeSysApps) {
List<App> apps = new ArrayList<App>();
// the package manager contains the information about all installed apps
PackageManager packageManager = getPackageManager();
List<PackageInfo> packs = packageManager.getInstalledPackages(0);
//PackageManager.GET_META_DATA
for(int i=0; i < packs.size(); i++) {
PackageInfo p = packs.get(i);
ApplicationInfo a = p.applicationInfo;
// skip system apps if they shall not be included
if ((!includeSysApps) && ((a.flags & ApplicationInfo.FLAG_SYSTEM) == 1)) {
continue;
}
App app = new App();
app.setTitle(p.applicationInfo.loadLabel(packageManager).toString());
app.setPackageName(p.packageName);
app.setVersionName(p.versionName);
app.setVersionCode(p.versionCode);
CharSequence description = p.applicationInfo.loadDescription(packageManager);
app.setDescription(description != null ? description.toString() : "");
apps.add(app);
}
return apps;
}
/**
* An asynchronous task to load the icons of the installed applications.
*/
private class LoadIconsTask extends AsyncTask<App, Void, Void> {
#Override
protected Void doInBackground(App... apps) {
Map<String, Drawable> icons = new HashMap<String, Drawable>();
PackageManager manager = getApplicationContext().getPackageManager();
for (App app : apps) {
String pkgName = app.getPackageName();
Drawable ico = null;
try {
Intent i = manager.getLaunchIntentForPackage(pkgName);
if (i != null) {
ico = manager.getActivityIcon(i);
}
} catch (NameNotFoundException e) {
Log.e("ERROR", "Unable to find icon for package '" + pkgName + "': " +
e.getMessage());
}
icons.put(app.getPackageName(), ico);
}
mAdapter.setIcons(icons);
return null;
}
#Override
protected void onPostExecute(Void result) {
mAdapter.notifyDataSetChanged();
}
}
}
try this -
provide the package_name of application you want to show
and compare it with package name present in device
//for browser application given package name as com.android.browser
for (int i = 0; i < packs.size(); i++) {
if ((p.packageName).equals("com.android.browser")) {
App app = new App();
app.setTitle(p.applicationInfo.loadLabel(packageManager).toString());
app.setPackageName(p.packageName);
app.setVersionName(p.versionName);
app.setVersionCode(p.versionCode);
CharSequence description = p.applicationInfo.loadDescription(packageManager);
app.setDescription(description != null ? description.toString() : "");
apps.add(app);
}
}
hope this will help you.
You need a screening process to see if the application is in the list of your mentioned applications store your entered app package name in array and see if the current app is in that list if it is there add it to the list and then display listView using this list
private List<App> loadInstalledApps(boolean includeSysApps) {
List<App> apps = new ArrayList<App>();
// the package manager contains the information about all installed apps
PackageManager packageManager = getPackageManager();
List<PackageInfo> packs = packageManager.getInstalledPackages(0);
//PackageManager.GET_META_DATA
for(int i=0; i < packs.size(); i++) {
PackageInfo p = packs.get(i);
ApplicationInfo a = p.applicationInfo;
// skip system apps if they shall not be included
if ((!includeSysApps) && ((a.flags & ApplicationInfo.FLAG_SYSTEM) == 1)) {
continue;
}
App app = new App();
app.setTitle(p.applicationInfo.loadLabel(packageManager).toString());
app.setPackageName(p.packageName);
app.setVersionName(p.versionName);
app.setVersionCode(p.versionCode);
CharSequence description = p.applicationInfo.loadDescription(packageManager);
app.setDescription(description != null ? description.toString() : "");
if( Arrays.asList(appliation1.packageName,appliation2.packageName,appliation3.packageName).contains(p.packageName) )
apps.add(app);
}
return apps;
}

Categories

Resources