运行应用小部件 - 无法识别启动活动

Posted

技术标签:

【中文标题】运行应用小部件 - 无法识别启动活动【英文标题】:Run app widget - Could not identify launch activity 【发布时间】:2016-11-20 08:02:40 【问题描述】:

androidStudio 中,我创建一个新的 android 项目并创建一个应用小部件并选择配置活动的选项。 AndroidStudio 现在生成 provider-info xml,清单 xml 中的声明和两个 java 类。一项活动,一项小部件提供程序。

这应该是可运行的,但我收到错误:无法识别启动活动:未找到默认活动。启动活动时出错。启动字段也显示一个红十字。

我不明白为什么,因为没有默认活动。配置活动应该在小部件提供程序开始工作时开始。为此,有一个带有 android.appwidget.action.APPWIDGET_CONFIGURE 的活动的意图过滤器。

我还在意图过滤器 LAUNCHER 和 DEFAULT 中添加了类别。在提供者和活动中。但仍然收到错误消息。

如果我在启动配置中选择“无”并运行应用程序,它只会带来许多错误消息:等待应用程序上线:com.example.desktop_win10.myapplication | com.example.desktop_win10.myapplication.test

但是小部件没有安装并且没有运行。我做错了什么?我尝试了 Intellij 和 AndroidStudio。

Manifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.desktop_win10.myapplication" >

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme" >
        <receiver android:name=".NewAppWidget" >
            <intent-filter>
                <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
            </intent-filter>

            <meta-data
                android:name="android.appwidget.provider"
                android:resource="@xml/new_app_widget_info" />
        </receiver>

        <activity android:name=".NewAppWidgetConfigureActivity" >
            <intent-filter>
                <action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
            </intent-filter>
        </activity>
    </application>

</manifest>

widget_info.xml:

<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    android:minWidth="40dp"
    android:minHeight="40dp"
    android:updatePeriodMillis="86400000"
    android:previewImage="@drawable/example_appwidget_preview"
    android:initialLayout="@layout/new_app_widget"
    android:configure="com.example.desktop_win10.myapplication.NewAppWidgetConfigureActivity"
    android:resizeMode="horizontal|vertical"
    android:widgetCategory="home_screen"
    android:initialKeyguardLayout="@layout/new_app_widget">
</appwidget-provider>

还有两个 Java 类。



EDIT1:

现在我添加类别 LAUNCHER 和动作 MAIN:

<activity android:name=".NewAppWidgetConfigureActivity" >
    <intent-filter>
        <action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
        <action android:name="android.intent.action.MAIN"/>
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

如果我启动调试器,有时小部件在小部件商店中,有时不在。

我还看到在生成的java活动类中有一个finish方法叫做:

// If this activity was started with an intent without an app widget ID, finish with an error.
if (mAppWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) 
    finish();
    return;

但如果我删除它也不起作用。我不明白为什么默认的 google 示例不起作用。

这里是java类:

活动:

package com.example.desktop_win10.myapplication;

import android.app.Activity;
import android.appwidget.AppWidgetManager;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;

/**
 * The configuration screen for the @link NewAppWidget NewAppWidget AppWidget.
 */
public class NewAppWidgetConfigureActivity extends Activity 

    int mAppWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;
    EditText mAppWidgetText;
    private static final String PREFS_NAME = "com.example.desktop_win10.myapplication.NewAppWidget";
    private static final String PREF_PREFIX_KEY = "appwidget_";

    public NewAppWidgetConfigureActivity() 
        super();
    

    @Override
    public void onCreate(Bundle icicle) 
        super.onCreate(icicle);

        // Set the result to CANCELED.  This will cause the widget host to cancel
        // out of the widget placement if the user presses the back button.
        setResult(RESULT_CANCELED);

        setContentView(R.layout.new_app_widget_configure);
        mAppWidgetText = (EditText)findViewById(R.id.appwidget_text);
        findViewById(R.id.add_button).setOnClickListener(mOnClickListener);

        // Find the widget id from the intent.
        Intent intent = getIntent();
        Bundle extras = intent.getExtras();
        if (extras != null) 
            mAppWidgetId = extras.getInt(
                    AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
        

        // If this activity was started with an intent without an app widget ID, finish with an error.
        if (mAppWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) 
            finish();
            return;
        

        mAppWidgetText.setText(loadTitlePref(NewAppWidgetConfigureActivity.this, mAppWidgetId));
    

    View.OnClickListener mOnClickListener = new View.OnClickListener() 
        public void onClick(View v) 
            final Context context = NewAppWidgetConfigureActivity.this;

            // When the button is clicked, store the string locally
            String widgetText = mAppWidgetText.getText().toString();
            saveTitlePref(context,mAppWidgetId,widgetText);

            // It is the responsibility of the configuration activity to update the app widget
            AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
            NewAppWidget.updateAppWidget(context, appWidgetManager, mAppWidgetId);

            // Make sure we pass back the original appWidgetId
            Intent resultValue = new Intent();
            resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
            setResult(RESULT_OK, resultValue);
            finish();
        
    ;

    // Write the prefix to the SharedPreferences object for this widget
    static void saveTitlePref(Context context, int appWidgetId, String text) 
        SharedPreferences.Editor prefs = context.getSharedPreferences(PREFS_NAME, 0).edit();
        prefs.putString(PREF_PREFIX_KEY + appWidgetId, text);
        prefs.apply();
    

    // Read the prefix from the SharedPreferences object for this widget.
    // If there is no preference saved, get the default from a resource
    static String loadTitlePref(Context context, int appWidgetId) 
        SharedPreferences prefs = context.getSharedPreferences(PREFS_NAME, 0);
        String titleValue = prefs.getString(PREF_PREFIX_KEY + appWidgetId, null);
        if (titleValue != null) 
            return titleValue;
         else 
            return context.getString(R.string.appwidget_text);
        
    

    static void deleteTitlePref(Context context, int appWidgetId) 
        SharedPreferences.Editor prefs = context.getSharedPreferences(PREFS_NAME, 0).edit();
        prefs.remove(PREF_PREFIX_KEY + appWidgetId);
        prefs.apply();
    

和提供者:

package com.example.desktop_win10.myapplication;

import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.widget.RemoteViews;

/**
 * Implementation of App Widget functionality.
 * App Widget Configuration implemented in @link NewAppWidgetConfigureActivity NewAppWidgetConfigureActivity
 */
public class NewAppWidget extends AppWidgetProvider 

    @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) 
        // There may be multiple widgets active, so update all of them
        for (int appWidgetId : appWidgetIds) 
            updateAppWidget(context, appWidgetManager, appWidgetId);
        
    

    @Override
    public void onDeleted(Context context, int[] appWidgetIds) 
        // When the user deletes the widget, delete the preference associated with it.
        for (int appWidgetId : appWidgetIds) 
            NewAppWidgetConfigureActivity.deleteTitlePref(context, appWidgetId);
        
    

    @Override
    public void onEnabled(Context context) 
        // Enter relevant functionality for when the first widget is created
    

    @Override
    public void onDisabled(Context context) 
        // Enter relevant functionality for when the last widget is disabled
    

    static void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
            int appWidgetId) 

        CharSequence widgetText = NewAppWidgetConfigureActivity.loadTitlePref(context, appWidgetId);
        // Construct the RemoteViews object
        RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.new_app_widget);
        views.setTextViewText(R.id.appwidget_text, widgetText);

        // Instruct the widget manager to update the widget
        appWidgetManager.updateAppWidget(appWidgetId, views);
    

【问题讨论】:

Default Activity not found. 很明显是问题所在。添加默认意图时,错误是什么?另外,很抱歉浪费了您的时间,但是切换 IDE 并不会改变代码的编译方式 @cricket_007 问题是,没有默认活动,因为它是一个没有任何活动的小部件项目。提供者应该通过 action intent-filter android.appwidget.action.APPWIDGET_CONFIGURE 启动唯一的一个(配置活动)。 【参考方案1】:

你添加了吗:

<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER" />

?

据我所知,如果没有它,android 将不知道要启动哪个活动作为主要活动。

【讨论】:

不完全是。但现在我在提供者上试用 - 不起作用。为什么不能在启动配置中选择“无”?并且在活动中将是错误的地方,因为我声明了应该启动配置活动的 android.appwidget.action.APPWIDGET_CONFIGURE。现在我讨厌在活动中尝试它:经过三个试验,它到目前为止工作(它不经常工作)。 现在应用程序已安装,但控制台显示:等待应用程序上线。方便的显示:等待调试器...强制..?等待很少的时间 Activity 直接开始和结束。现在已安装应用程序,但未安装小部件。我不知道为什么,但经过 4 次试验后,小部件现在位于小部件菜单中。但是当我将它添加到主屏幕时,调试器不会注册它。 您是否尝试使用“无效和清除缓存”?

以上是关于运行应用小部件 - 无法识别启动活动的主要内容,如果未能解决你的问题,请参考以下文章

无法识别启动活动:升级到 Android Studio 4.0 后未找到默认活动

未捕获的错误:[Ext.createByAlias] 无法创建无法识别别名的实例:小部件

当小部件具有配置活动时,无法从小部件启动活动

无法识别启动活动,未找到默认活动启动活动时出错

当我有意启动它时,为啥android无法识别第二个活动?

在启动某些活动之前,小部件无法在 Android 11 上的设备启动时启动服务