我开发的应用程序可以回答某些查询(电话号码查询,也可能是其他查询).
Google在Android 6上引入了一项名为"Google Now On Tap"的新功能(AKA"Assist API"),允许用户查询屏幕上显示的内容(通过长按主页按钮或说出什么东西),不需要输入任何东西.
谷歌在这里提供了开发人员教程
我找不到任何代码片段来展示如何为它准备应用程序.
我注意到的只有我可以从Application类扩展,并在其中添加OnProvideAssistDataListener,并注册到它.
但是,它打开了很多关于如何做到这一点的问题.
可悲的是,因为这个话题很新,我几乎找不到任何关于它的内容,所以我想在这里提出问题.
1)这个新功能是否有任何样本或至少更详细的教程?
2)在文档中说:
在大多数情况下,实施辅助功能支持将使助手能够获得所需的信息.这包括提供android:contentDescription属性,为自定义视图填充AccessibilityNodeInfo,确保自定义ViewGroup正确地公开其子项,并遵循"使应用程序可访问"中描述的最佳实践.
为什么以及如何使用应用程序的辅助功能?与公开子视图(或视图)有什么关系?如果应用程序还没有运行,它甚至可能是关于视图的(因为该功能在任何应用程序,任何地方都被激活).
我认为仅当前景应用程序是我的应用程序时才会调用它,但如果是这样,我如何实际提供针对所有应用程序显示的查询,具体取决于输入内容?
3)从Application扩展的类是否应该实现OnProvideAssistDataListener?如果是这样,为什么需要注册呢?如果没有,Google-Now-On-Tap如何使用呢?它不能只打开所有具有这类课程的应用程序,看看它们是否注册...
4)文档有一个我不明白的样本片段:
@Override
public void onProvideAssistContent(AssistContent assistContent) {
super.onProvideAssistContent(assistContent);
String structuredJson = new JSONObject()
.put("@type", "MusicRecording")
.put("@id", "example.comhttps://example.com/music/recording")
.put("name", "Album Title")
.toString();
assistContent.setStructuredData(structuredJson);
}
Run Code Online (Sandbox Code Playgroud)
新功能对每个键有什么作用?是应用程序还是Google-Now-On-Tap?我有什么选择呢?这是我在哪里定义我的应用程序是否可以处理该功能建议我的内容?AssistContent应该是我看到的输入,并决定我的应用程序是否可以处理它或忽略它?
我发现,有开在WhatsApp的特定联系人的对话屏幕,这是一种在这里.
不仅如此,我发现一款名为" Drupe " 的应用程序也是如此,甚至更多:
我找不到任何以这种方式打开它的官方API,所以我不确定它有多安全.
我找到了SDK,但没有意图说明.
我想更多地了解各种社交网络和聊天应用程序的可用内容:
可能的功能可能是:
这些功能是否适用于每个社交网络和聊天应用?
不确定如何调用,但是当您打开联系人应用程序的“联系人详细信息”屏幕时,您会看到在那里可以单击以执行操作的各种应用程序(例如通过Viber和WhatsApp调用和发送消息),如下所示:
我不知道这些动作的调用方式,所以我不知道如何进行调查。我尝试搜索每个社交网络以及如何使用它,但是这似乎需要很多努力,甚至在将来可能无法正常工作。
我希望针对本机联系人应用程序上显示的所有应用程序查询这些动作,显示它们并进行处理。
我试图调查正在使用的意图,发现对于Viber,这可以用于消息:
intent = new Intent(Intent.ACTION_VIEW, Uri.parse("content://com.android.contacts/data/"+id));
intent.setPackage("com.viber.voip");
Run Code Online (Sandbox Code Playgroud)
但是,我不知道这个“ id”是什么,仅是因为我已经用真实数据测试过它了。我还尝试实际打印所有联系人数据库,以找到要使用的正确值(和映射),但是我没有找到它。
另外,我找不到应该如何找到此信息。我的猜测是,它可能应该包括一个可用的模仿类型的查询,并在指定的联系人上检查它们(可能使用联系人ID)。
给定联系人(ID或电话号码)后,如何显示和执行联系人应用程序的“联系人详细信息”屏幕上所示的操作?
out自动测试使用视图'id来点击它们,所以我们尽可能添加id.
对于弹出菜单,有时需要动态填充它们,但正如我发现的那样,即使我为每个项目添加了id,也找不到id,也无法使用.即使使用DDMS的功能"用于UI自动机的转储视图层次结构",也会显示弹出菜单中的任何视图都没有ID.
这是我使用的示例代码,尝试为单个菜单项设置id.
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
View v=findViewById(R.id.button);
v.setOnClickListener(new OnClickListener() {
@Override
public void onClick(final View v) {
PopupMenu popupMenu = new PopupMenu(MainActivity.this, v);
final Menu menu = popupMenu.getMenu();
menu.add(0, R.id.myMenuItem, 0, R.string.app_name).setOnMenuItemClickListener(new OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(final MenuItem item) {
return false;
}
}) ;
popupMenu.show();
}
});
}
Run Code Online (Sandbox Code Playgroud)
请注意,id在"ids.xml"文件中声明,如下所示:
<item name="myMenuItem" type="id"/>
Run Code Online (Sandbox Code Playgroud)
这就是DDMS工具向我展示的内容:
为什么这段代码没有按预期工作(意味着菜单项视图有id)?我该怎么做才能使其中的视图具有ID?为动态创建的菜单项添加ID的正确方法是什么?
我刚刚发现一个应用程序,允许禁用没有root的三星应用程序,并在后台:
https://play.google.com/store/apps/details?id=com.hecorat.packagedisabler
还有这个免费的:
https://play.google.com/store/apps/details?id=com.ospolice.packagedisabler
怎么会这样?它甚至没有显示系统类型的alertDialog来询问用户是否可以禁用该应用程序.他们找到了允许这样做的缺陷吗?
它仅适用于某些三星应用程序吗?其他应用程序和其他公司怎么样?那也有可能吗?
是否可以将相同的机制用于其他操作?像启用应用程序?
我目前没有三星设备,所以我甚至无法检查这个应用程序.
在大量寻找自动调整 TextView 大小的最佳解决方案(根据内容、大小、最小和最大行数和字体大小限制)之后,我为这一切做了一个合并的解决方案,这里。
注意:我不使用其他解决方案,因为它们不能很好地工作,每个都有自己的问题(不支持某些内容,文本超出 TextView,文本被截断,...)。
演示它的工作原理:
https://raw.githubusercontent.com/AndroidDeveloperLB/AutoFitTextView/master/animationPreview.gif
在某些情况下,一行的最后一个字符会换行到下一行,例如:
绿色是 TextView 的边界,红色在它之外。
基本上,给定 TextView 的大小、它的最小和最大字体大小和最小和最大行数,以及应该在其中的内容(文本),它会找到(使用二进制搜索)什么字体大小应该适合 TextView 的边界。
该代码已经在 Github 中可用,但这里是为了以防万一:
public class AutoResizeTextView extends AppCompatTextView {
private static final int NO_LINE_LIMIT = -1;
private final RectF _availableSpaceRect = new RectF();
private final SizeTester _sizeTester;
private float _maxTextSize, _spacingMult = 1.0f, _spacingAdd = 0.0f, _minTextSize;
private int _widthLimit, _maxLines;
private boolean _initialized = false;
private TextPaint _paint;
private interface SizeTester {
/**
* @param suggestedSize Size of …Run Code Online (Sandbox Code Playgroud) 几个月前,谷歌发布了一个新的 API 来检测位图上的人脸:
它应该比内置的 FaceDetector 类更快更好,并且与它相比没有限制/局限性(例如需要输入位图配置为 565 ,位图宽度均匀,并且最大面部数探测)。
代码也非常简单:
显现:
<meta-data
android:name="com.google.android.gms.vision.DEPENDENCIES"
android:value="face" />
Run Code Online (Sandbox Code Playgroud)
爪哇:
FaceDetector faceDetector = new
FaceDetector.Builder(getApplicationContext()).setTrackingEnabled(false)
.build();
if(!faceDetector.isOperational()){
//show error
return;
}
Frame frame = new Frame.Builder().setBitmap(myBitmap).build();
SparseArray<Face> faces = faceDetector.detect(frame);
Run Code Online (Sandbox Code Playgroud)
似乎该 API 在某些设备上不可用,在调用“isOperational()”时返回“false”。
我发现了一些线索:
在Github(此处)上,其他人也发现了这个问题。
该示例 …
Google已使用Firebase Analytics和Firebase远程配置为A/B测试发布了全新的API和服务.
虽然我尝试将该服务用于其他目的(此处和此处),但我还需要将其用于A/B测试.
事实是,我无法找到如何让它显示分析实验变体结果所需的信息.
它只是没有显示(在这个网站上),或者我没有看到正确的地方:
为了尝试一个实验,我按照教程说我应该做的,包括:
boolean isDebug = AppComponentsHelper.isInDebugFlavour(context);
mFirebaseRemoteConfig = FirebaseRemoteConfig.getInstance();
FirebaseRemoteConfigSettings configSettings = new FirebaseRemoteConfigSettings.Builder().setDeveloperModeEnabled(isDebug).build();
mFirebaseRemoteConfig.setConfigSettings(configSettings);
final HashMap<String, Object> defaults = new HashMap<>();
for (ExperimentType experimentType : ExperimentType.values())
defaults.put(experimentType.experimentId, experimentType.defaultValues);
mFirebaseRemoteConfig.setDefaults(defaults);
long cacheExpiration = isDebug ? 0 : TimeUnit.HOURS.toSeconds(1);
mFirebaseRemoteConfig.fetch(cacheExpiration)
.addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if (task.isSuccessful()) {
mFirebaseRemoteConfig.activateFetched();
final FirebaseAnalytics firebaseAnalytics = FirebaseAnalytics.getInstance(context); …Run Code Online (Sandbox Code Playgroud)Html.fromHtml几乎没有任何关于它支持哪些标签的文档。
据报道,它确实支持许多网站上的“font”标签(如此处),但我无法找出在此标签内设置“face”属性时可用的字体。
我可以假设哪些字体始终可用?其中哪些仅来自特定的 Android 版本?某处有他们的名单吗?
编辑:看来答案应该在“/system/etc/fonts.xml”文件中。以下是 Android 6.0.1 上的内容:
<familyset version="22">
<!-- first font is default -->
<family name="sans-serif">
<font weight="100" style="normal">Roboto-Thin.ttf</font>
<font weight="100" style="italic">Roboto-ThinItalic.ttf</font>
<font weight="300" style="normal">Roboto-Light.ttf</font>
<font weight="300" style="italic">Roboto-LightItalic.ttf</font>
<font weight="400" style="normal">Roboto-Regular.ttf</font>
<font weight="400" style="italic">Roboto-Italic.ttf</font>
<font weight="500" style="normal">Roboto-Medium.ttf</font>
<font weight="500" style="italic">Roboto-MediumItalic.ttf</font>
<font weight="900" style="normal">Roboto-Black.ttf</font>
<font weight="900" style="italic">Roboto-BlackItalic.ttf</font>
<font weight="700" style="normal">Roboto-Bold.ttf</font>
<font weight="700" style="italic">Roboto-BoldItalic.ttf</font>
</family>
<!-- Note that aliases must come after the fonts they reference. -->
<alias name="sans-serif-thin" to="sans-serif" weight="100" />
<alias name="sans-serif-light" to="sans-serif" weight="300" …Run Code Online (Sandbox Code Playgroud) 到目前为止,使用此意图有一种简单的方法来安装APK文件:
final Intent intent=new Intent(Intent.ACTION_VIEW)
.setDataAndType(Uri.fromFile(apkFile), "application/vnd.android.package-archive");
Run Code Online (Sandbox Code Playgroud)
但是,如果你的应用程序中的Android API 24以上(牛轧糖- 7.0),你就可以或更新运行这段代码,你会得到一个异常,如图所示这里,例如:
android.os.FileUriExposedException: file:///storage/emulated/0/sample.apk exposed beyond app through Intent.getData()
Run Code Online (Sandbox Code Playgroud)
所以我做了我被告知的事情:使用支持库的FileProvider类,如下:
final Intent intent = new Intent(Intent.ACTION_VIEW)//
.setDataAndType(android.support.v4.content.FileProvider.getUriForFile(context,
context.getPackageName() + ".provider", apkFile),
"application/vnd.android.package-archive").addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
Run Code Online (Sandbox Code Playgroud)
清单:
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths"/>
</provider>
Run Code Online (Sandbox Code Playgroud)
res/xml/provider_paths.xml:
<?xml version="1.0" encoding="utf-8"?>
<paths>
<!--<external-path name="external_files" path="."/>-->
<external-path
name="files_root"
path="Android/data/${applicationId}"/>
<external-path
name="external_storage_root"
path="."/>
</paths>
Run Code Online (Sandbox Code Playgroud)
但是,现在它仅适用于Android Nougat.在Android 5.0上,它抛出一个异常:ActivityNotFoundException.
我可以添加一个Android OS版本的检查,并使用任何一种方法,但正如我所读,应该使用一种方法:FileProvider.
所以,我尝试使用我自己的ContentProvider充当FileProvider,但我得到了与支持库的FileProvider相同的异常.
这是我的代码:
final Intent intent = new Intent(Intent.ACTION_VIEW)
.setDataAndType(OpenFileProvider.prepareSingleFileProviderFile(apkFilePath),
"application/vnd.android.package-archive")
.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
Run Code Online (Sandbox Code Playgroud)
OpenFileProvider.java …
android android-intent apk android-fileprovider android-7.0-nougat