【问题标题】:Android pending intent not being called within widget未在小部件中调用 Android 挂起意图
【发布时间】:2015-09-22 17:32:19
【问题描述】:

就像this 问题(已接受的答案)一样,我正在尝试从我的应用程序的一个小部件启动语音识别。我成功地在 Widget 的 onUpdate() 方法中打开了请求语音输入的对话框:

    // 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);

语音识别工作,但在识别过程结束时,我的resultsPendingIntent 没有被调用。为什么?

从系统日志中,我读到了这个:

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

虽然我希望是这样的:

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

因为.WrapperActivity 是待处理的Intent,而SoulissWidgetVoice 是小部件类。注意WrapperActivity 本身可以从其他活动中正确启动,它是Theme.NoDisplay 基本活动:

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

【问题讨论】:

  • 我认为您需要提供完整的类名及其包前缀作为 ComponentName 构造函数的第二个参数。第一个参数是 app 的包名(可以不同于内部 Java 包,但通常不是)。
  • 谢谢@BladeCoder 我更新了代码但还是不行
  • 您的小部件是集合小部件(ListView、StackView)吗?

标签: android android-widget speech-recognition android-pendingintent


【解决方案1】:

这是功能齐全的,它基于 Android SDK 中的 ListView。它不是特别适用于小部件,但我相信您可以对其进行修改,使其适用于小部件。

创建一个名为 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);
        }
    }
}

将活动添加到 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>

在您的自定义小部件/视图中:

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);
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-04-18
    • 1970-01-01
    • 1970-01-01
    • 2012-09-06
    • 1970-01-01
    • 2011-03-15
    • 1970-01-01
    • 2013-11-01
    相关资源
    最近更新 更多