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

Posted

技术标签:

【中文标题】尝试为我的应用程序创建一个 Android 小部件按钮,该按钮打开一个 Java 活动,发送 URI 数据【英文标题】:Trying to create a Android widget button for my application that opens a Java activity, sending URI data 【发布时间】:2021-08-28 20:54:51 【问题描述】:

因此,对此有很多问题,但没有一个答案有效,我的问题是独一无二的。我正在尝试设置 URI 数据,以便可以从我创建的小部件按钮将其发送到 java 类。我知道小部件按钮设置正确,因为它在单击时会发送 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
    

【问题讨论】:

你能展示你想要做什么的代码吗?不仅是进口…… 您可以使用putExtra 方法来代替setData。 reference 列出整个小部件 Java 类,包括导入。你必须向下滚动。有问题的部分在 onReceive 中。 为什么要发起广播?你真的需要一个,或者你可以启动这个活动? @Zain,这就是 Android Widget 架构的工作原理。如果您有更好的方法,请发布,我会看看。我尝试了putExtra 而不是setData @YaMiN,但它没有用。注意:我意识到代码有intent.setData 而不是i.setData。我正在测试多种不同的方法。当它更改为i.setData 的正确语法时,它不起作用。任何帮助表示赞赏。 【参考方案1】:

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

所以,如果你真的想发送Uri 数据到活动而不需要广播接收器;您可以将其附加到与按钮关联的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 发送到活动:

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

【讨论】:

以上是关于尝试为我的应用程序创建一个 Android 小部件按钮,该按钮打开一个 Java 活动,发送 URI 数据的主要内容,如果未能解决你的问题,请参考以下文章

如何在 android 中探索样式

带有集合(ListView)的Android小部件不显示项目

带有 ListView 的 Android 小部件无法正确加载项目

android 小部件是不是在与其应用程序相同的进程中运行

从 AsyncTask 填充 ListView 的 Android 小部件

带有 ListView 自定义项的 Android 小部件