尝试为我的应用程序创建一个 Android 小部件按钮,打开 Java activity,发送 URI 数据

Trying to create a Android widget button for my application that opens a Java activity, sending URI data

因此,有很多关于此的问题,但 none 的答案有效,我的问题是独一无二的。我正在尝试设置 URI 数据,以便我可以通过我创建的小部件按钮将其发送到 java class。我知道小部件按钮设置正确,因为它会在单击时发送 toast 消息。

问题是: 没有意图,或意图的变化,我发送,点击按钮后,有效。它总是崩溃,logcat 给出了一个几乎非描述性的原因,指向 startActivity(i)。任何帮助将非常感激。小部件的完整代码如下:

package com.matthewbenchimol.cydogbrowser;

import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.view.View;
import android.widget.ImageButton;
import android.widget.RemoteViews;
import android.widget.Toast;

import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
import static androidx.core.content.ContextCompat.startActivity;
import static java.security.AccessController.getContext;

/**
 * Implementation of App Widget functionality.
 */
public class Dashboard extends AppWidgetProvider {

    private static final String MyOnClick = "myOnClickTag";

    void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
                         int appWidgetId) {
        // Construct the RemoteViews object
        RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.dashboard);

        Intent intent = new Intent(context, Dashboard.class);
        intent.setAction(MyOnClick);

        PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
        views.setOnClickPendingIntent(R.id.imageButton, pendingIntent);

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

    public void onReceive(Context context, Intent intent){
        super.onReceive(context, intent);
        String url = "https://test.com";
        if (intent.getAction().equals(MyOnClick)) {
            Toast.makeText(context.getApplicationContext(), "Under-development", Toast.LENGTH_SHORT).show();
            Intent i = new Intent(context, Sandbox.class);
            intent.setData(Uri.parse(url));
            context.startActivity(i);
        }
    }

    @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 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
    }
}

不确定单击小部件按钮时启动的广播的目的;但我相信 Uri 数据应该附加到与 PendingIntent 关联的意图,后者将在 onUpdate() 回调中在系统中注册。

所以,如果你真的想发送 Uri 数据到 activity 而不需要广播接收器;您可以将其附加到与按钮关联的 PendingIntent 的意图。

public class Dashboard extends AppWidgetProvider {

    void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
                         int appWidgetId) {
        // Construct the RemoteViews object
        RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.dashboard);

        Intent intent = new Intent(context, Sandbox.class);
        String url = "https://test.com";
        intent.setData(Uri.parse(url));
        
        PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
        
        views.setOnClickPendingIntent(R.id.imageButton, pendingIntent);
    
        // Instruct the widget manager to update the widget
        appWidgetManager.updateAppWidget(appWidgetId, views);
    }

    //.... 

}

这会将 Uri 发送到 activity:

public class Sandbox extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(....);  

        Intent intent = getIntent();

        if (intent != null) {
            Uri data = intent.getData(); // Should contain `https://test.com`
            Log.d("LOG_TAG", "onCreate: data: " + data); 
        } else {
            Log.d("LOG_TAG", "onCreate: data: Null");
        }
    }
}