Android的未决意图不会被调用构件内 [英] Android pending intent not being called within widget

查看:348
本文介绍了Android的未决意图不会被调用构件内的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题(接受的答案),我想从我的应用程序的部件之一,推出语音识别。我成功地设法打开对话框,要求语音输入与此code里面的的onUpdate()控件的方法:

  //这个意图指向应该处理结果的活动,不工作
    意图activityIntent =新意图(SoulissApp.getAppContext(),WrapperActivity.class);
    //不能正常工作,以及
    //activityIntent.setComponent(new单元名(it.angelic.soulissclient,it.angelic.soulissclient.WrapperActivity));
    //这个意图包装效果的活动意图
    的PendingIntent resultsPendingIntent = PendingIntent.getActivity(SoulissApp.getAppContext(),0,activityIntent,0);    //这个意图调用语音识别
    意图voiceIntent =新意图(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
    voiceIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
    voiceIntent.putExtra(RecognizerIntent.EXTRA_PROMPT,语音识别演示);
    voiceIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    voiceIntent.putExtra(RecognizerIntent.EXTRA_RESULTS_PENDINGINTENT,resultsPendingIntent);    捆绑fakeBun =新包();
    fakeBun.putChar(假货,F);
    voiceIntent.putExtra(RecognizerIntent.EXTRA_RESULTS_PENDINGINTENT_BUNDLE,fakeBun);    //这个意图包装语音识别意图,作品
    的PendingIntent pendingInt = PendingIntent.getActivity(上下文,0,voiceIntent,0);
    updateViews.setOnClickPendingIntent(R.id.button1,pendingInt);

语音识别工作,但是在识别过程结束后,我的 resultsPendingIntent 不叫。为什么呢?

从SYS日志中,我读到这样的:

  ... I / ActivityManager:开始U0 {CMP = it.angelic.soulissclient / .SoulissWidgetVoice(有临时演员)}从UID 10152陈列0 ......

而我期望这样的:

  ... I / ActivityManager:开始U0 {CMP = it.angelic.soulissclient / .WrapperActivity(有临时演员)} ...

SoulissWidgetVoice 是Widget类

由于 .WrapperActivity 正在等待意图。需要注意的是 WrapperActivity 本身可以从其他活动的正确启动,这是一个 Theme.NoDisplay 基本活动:

 <活动
        机器人:名字=。WrapperActivity
        机器人:标签=@字符串/ APP_NAME
        机器人:主题=@安卓风格/ Theme.NoDisplay/>


解决方案

这是全功能的,它是基于关闭在Android SDK ListView控件。这不是特别的小部件,但我敢肯定,使其适用于一个小部件,您可以修改它。

创建一个名为活动SearchActivity:

  // CustomSearch(查看)及ISEARCH(接口)是我创建的对象和无关
公共类SearchActivity扩展AppCompatActivity实现ISEARCH
{
    //变量
    私人CustomSearch mSearchView;
    @覆盖
    公共无效的onCreate(捆绑savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        的setContentView(R.layout.activity_search);        mSearchView =(CustomSearch)findViewById(R.id.search);
        mSearchView.setPendingComponentName(getComponentName());
        mSearchView.setSearchListener(本);
    }    @覆盖
    保护无效onNewIntent(意向意图)
    {
        如果(Intent.ACTION_SEARCH.equals(intent.getAction()))
        {
            查询字符串= intent.getStringExtra(SearchManager.QUERY);
            Log.i(搜索>中,你说:+查询);
        }
    }
}

添加活动到的Andr​​oidManifest.xml

 <活动
    机器人:名字=。activities.SearchActivity
    机器人:标签=@字符串/ APP_NAME
    机器人:主题=@风格/ CustomTheme.NoActionBar>
    &所述;意图滤光器>
        <作用机器人:名字=android.intent.action.SEARCH/>
    &所述; /意图滤光器>
< /活性GT;

在自定义的Widget /视图:

  buttonVoice.setOnClickListener(新View.OnClickListener()
{
    @覆盖
    公共无效的onClick(视图v)
    {
        //无论从SearchableInfo或组件名获取活动
        组件名searchActivity = mComponentName;        在意图//裹组件
        意图queryIntent =新意图(Intent.ACTION_SEARCH);
        queryIntent.setComponent(searchActivity);        在悬而未决的意图//包裹的查询意图
        的PendingIntent未决= PendingIntent.getActivity(的getContext(),0,queryIntent,PendingIntent.FLAG_ONE_SHOT);        //现在创建包,因为如果我们在挂起的意图把它包起来,就成了不可改变
        捆绑queryExtras =新包();        //创建语音意图
        意图voiceIntent =新意图(RecognizerIntent.ACTION_RECOGNIZER_SPEECH);
        voiceIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
        voiceIntent.putExtra(RecognizerIntent.EXTRA_PROMPT,说话);
        voiceIntent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE,searchActivity
        voiceIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);        //裹挂起的意图和放大器;捆绑的声音里面的意图
        voiceIntent.putExtra(RecognizerIntent.EXTRA_RESULTS_PENDINGINTENT,待定);
        voiceIntent.putExtra(RecognizerIntent.EXTRA_RESULTS_PENDINGINTENT_BUNDLE,queryExtras);        //启动语音搜索
        。的getContext()startActivity(voiceIntent);
    }
}

Like in this question (accepted answer), I'm trying to launch voice recognition from one of my app's widgets. I succesfully managed to open dialog that requests voice input with this code inside onUpdate() method of the Widget:

    // this intent points to activity that should handle results, doesn't work
    Intent activityIntent = new Intent(SoulissApp.getAppContext(), WrapperActivity.class );
    //doesn't work as well
    //activityIntent.setComponent(new ComponentName("it.angelic.soulissclient", "it.angelic.soulissclient.WrapperActivity"));
    // this intent wraps results activity intent
    PendingIntent resultsPendingIntent = PendingIntent.getActivity(SoulissApp.getAppContext(), 0, activityIntent, 0);

    // this intent calls the speech recognition
    Intent voiceIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
    voiceIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
    voiceIntent.putExtra(RecognizerIntent.EXTRA_PROMPT, "Speech recognition demo");
    voiceIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    voiceIntent.putExtra(RecognizerIntent.EXTRA_RESULTS_PENDINGINTENT, resultsPendingIntent);

    Bundle fakeBun = new Bundle();
    fakeBun.putChar("fake", 'f');
    voiceIntent.putExtra(RecognizerIntent.EXTRA_RESULTS_PENDINGINTENT_BUNDLE, fakeBun);

    // this intent wraps voice recognition intent, works
    PendingIntent pendingInt = PendingIntent.getActivity(context, 0, voiceIntent, 0);
    updateViews.setOnClickPendingIntent(R.id.button1, pendingInt);

The speech recognition works, but at the end of the recognition process, my resultsPendingIntent is not called. Why?

From sys log, I read this:

 ...I/ActivityManager﹕ START u0 {cmp=it.angelic.soulissclient/.SoulissWidgetVoice (has extras)} from uid 10152 on display 0......

while I'd expect something like:

  ...I/ActivityManager﹕ START u0 {cmp=it.angelic.soulissclient/.WrapperActivity(has extras)}...

because .WrapperActivity is pending Intent while SoulissWidgetVoice is the widget class. Note that WrapperActivity itself can be correctly launched from other activities and it's a Theme.NoDisplay basic activity:

 <activity
        android:name=".WrapperActivity"
        android:label="@string/app_name"
        android:theme="@android:style/Theme.NoDisplay"/>

解决方案

This is fully functional, and it's based off the ListView in the Android SDK. It's not particularly for a widget, but I'm sure you can modify it so that it works for a widget.

Create an activity called SearchActivity:

// CustomSearch (View) & ISearch (Interface) are objects that I created and are irrelevant
public class SearchActivity extends AppCompatActivity implements ISearch
{
    // Variables
    private CustomSearch mSearchView;


    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_search);

        mSearchView = (CustomSearch)findViewById(R.id.search);
        mSearchView.setPendingComponentName(getComponentName());
        mSearchView.setSearchListener(this);
    }

    @Override
    protected void onNewIntent(Intent intent)
    {
        if (Intent.ACTION_SEARCH.equals(intent.getAction()))
        {
            String query = intent.getStringExtra(SearchManager.QUERY);
            Log.i("SEARCH >", "You said: " + query);
        }
    }
}

Add activity to the AndroidManifest.xml

<activity
    android:name=".activities.SearchActivity"
    android:label="@string/app_name"
    android:theme="@style/CustomTheme.NoActionBar">
    <intent-filter>
        <action android:name="android.intent.action.SEARCH"/>
    </intent-filter>
</activity>

In your custom Widget/View:

buttonVoice.setOnClickListener(new View.OnClickListener() 
{
    @Override
    public void onClick(View v)
    {
        // Get activity from either SearchableInfo or ComponentName
        ComponentName searchActivity = mComponentName;

        // Wrap component in intent
        Intent queryIntent = new Intent(Intent.ACTION_SEARCH);
        queryIntent.setComponent(searchActivity);

        // Wrap query intent in pending intent
        PendingIntent pending = PendingIntent.getActivity(getContext(), 0, queryIntent, PendingIntent.FLAG_ONE_SHOT);

        // Create bundle now because if we wrap it in pending intent, it becomes immutable
        Bundle queryExtras = new Bundle();

        // Create voice intent
        Intent voiceIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZER_SPEECH);
        voiceIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
        voiceIntent.putExtra(RecognizerIntent.EXTRA_PROMPT, "Speak");
        voiceIntent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, searchActivity
        voiceIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

        // Wrap the pending intent & bundle inside the voice intent
        voiceIntent.putExtra(RecognizerIntent.EXTRA_RESULTS_PENDINGINTENT, pending);
        voiceIntent.putExtra(RecognizerIntent.EXTRA_RESULTS_PENDINGINTENT_BUNDLE, queryExtras);

        // Start the voice search
        getContext().startActivity(voiceIntent);
    }
}

这篇关于Android的未决意图不会被调用构件内的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆