Android 共享文本/纯文本,以便能够在小部件中使用

Android share text/plain to be able to use in the widget

提问人:Paul 提问时间:5/8/2023 最后编辑:Paul 更新时间:5/9/2023 访问量:78

问:

enter image description here

我需要在外部应用程序和我的应用程序之间共享文本/纯文本,并将此共享文本用作我需要插入的小部件的 url,请参阅示例图像。

因此,每个小部件都必须具有依赖于此文本的实例。

如何确保在单击共享时,然后在特定应用程序上,小部件会自动插入到主屏幕上。

你能帮我一把吗?

清单:

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

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />

    <application
        android:allowBackup="true"
        android:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.Test"
        tools:targetApi="31">
        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.SEND" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:mimeType="text/plain" />
            </intent-filter>
        </activity>

        <receiver
            android:name=".MyWidget"
            android:exported="true">
            <intent-filter>
                <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
            </intent-filter>

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

        <receiver
            android:name=".WidgetService"
            android:enabled="true" />

    </application>

</manifest>

AlarmHandler:

package com.myapp.test;

import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Build;

import java.util.Calendar;

public class AlarmHandler {

    private final Context context;

    public AlarmHandler(Context context) {
        this.context = context;
    }

    public void setAlarmManager() {
        Intent intent = new Intent(context, WidgetService.class);
        int FlagPendingIntent = Build.VERSION.SDK_INT >= Build.VERSION_CODES.M ? PendingIntent.FLAG_IMMUTABLE : 0;
        PendingIntent sender = PendingIntent.getBroadcast(context, 2, intent, FlagPendingIntent);

        AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);

        //get current time and add 1 hour
        Calendar c = Calendar.getInstance();
        long l = c.getTimeInMillis() + 10000;//1000*60*60=3600000

        //set the alarm for 10 seconds in the future
        if (am != null) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                am.setAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, l, sender);
            } else {
                am.set(AlarmManager.RTC_WAKEUP, l, sender);
            }
        }
    }

    public void cancelAlarmManager() {
        Intent intent = new Intent(context, WidgetService.class);
        int FlagPendingIntent = Build.VERSION.SDK_INT >= Build.VERSION_CODES.M ? PendingIntent.FLAG_IMMUTABLE : 0;
        PendingIntent sender = PendingIntent.getBroadcast(context, 2, intent, FlagPendingIntent);
        AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
        if (am != null) {
            am.cancel(sender);
        }
    }
}

唤醒锁:

package com.myapp.test;

import android.content.Context;
import android.os.PowerManager;

public abstract class WakeLocker {

    private static PowerManager.WakeLock wakeLock;

    //wake the device
    public static void acquire(Context context) {
        if (wakeLock != null) {
            wakeLock.release();
        }

        PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
        wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK |
                PowerManager.ACQUIRE_CAUSES_WAKEUP |
                PowerManager.ON_AFTER_RELEASE, "WIDGET: Wake lock acquired!");
        wakeLock.acquire(2000);
    }

    public static void release() {
        if (wakeLock != null) {
            wakeLock.release();
        }
        wakeLock = null;
    }

}

主要活动:

package com.myapp.test;

import androidx.appcompat.app.AppCompatActivity;

import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.content.ComponentName;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.util.Patterns;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Intent intent = getIntent();
        String action = intent.getAction();
        String type = intent.getType();

        if (Intent.ACTION_SEND.equals(action) && type != null) {
            if ("text/plain".equals(type)) {
                String sharedText = intent.getStringExtra(Intent.EXTRA_TEXT);
                String url = extractLinks(sharedText);
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                    AppWidgetManager mAppWidgetManager = getSystemService(AppWidgetManager.class);

                    ComponentName myProvider = new ComponentName(MainActivity.this, MyWidget.class);

                    Bundle b = new Bundle();
                    b.putString("url", url);
                    if (mAppWidgetManager.isRequestPinAppWidgetSupported()) {
                        Intent pinnedWidgetCallbackIntent = new Intent(MainActivity.this, MyWidget.class);
                        PendingIntent successCallback = PendingIntent.getBroadcast(MainActivity.this, 0,
                                pinnedWidgetCallbackIntent, PendingIntent.FLAG_IMMUTABLE);

                        mAppWidgetManager.requestPinAppWidget(myProvider, b, successCallback);
                    }
                }
            }
        }
    }

    public static String extractLinks(String text) {
        List<String> links = new ArrayList<String>();
        Matcher m = Patterns.WEB_URL.matcher(text);
        while (m.find()) {
            String url = m.group();
            links.add(url);
        }

        return links.toArray(new String[links.size()])[0].split("/")[4];
    }
}

WidgetService:

package com.myapp.test;

import android.appwidget.AppWidgetManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.util.Log;

public class WidgetService extends BroadcastReceiver {
    String values = "Test";
    @Override
    public void onReceive(Context context, Intent intent) {
        //wake the device
        WakeLocker.acquire(context);

        //increase the number in the widget
        SharedPreferences preferences = context.getSharedPreferences("PREFS", 0);
        //int value = preferences.getInt("value", 1);

        //String url = intent.getStringExtra("url");
        //Log.d("WidgetService", url.toString());
        Log.d("WidgetService", values);

        SharedPreferences.Editor editor = preferences.edit();
        editor.putString("value", values);
        editor.apply();

        //force widget update
        Intent widgetIntent = new Intent(context, MyWidget.class);
        widgetIntent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
        int[] ids = AppWidgetManager.getInstance(context).getAppWidgetIds(new ComponentName(context, MyWidget.class));
        widgetIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, ids);
        context.sendBroadcast(widgetIntent);

        Log.d("WIDGET", "Widget set to update!");

        //go back to sleep
        WakeLocker.release();
    }
}

我的小部件:

package com.myapp.test;

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


public class MyWidget extends AppWidgetProvider {
    String values = "MyWidget";

    void updateAppWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId) {
        RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_design);

        Log.d("MyWidget3", values);

        //set the value in the textview
        views.setTextViewText(R.id.text, values);

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

        //reschedule the widget refresh
        AlarmHandler alarmHandler = new AlarmHandler(context);
        alarmHandler.cancelAlarmManager();
        alarmHandler.setAlarmManager();

        Log.d("WIDGET", "Widget updated!");
    }

    @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
        for (int appWidgetId: appWidgetIds) {
            updateAppWidget(context, appWidgetManager, appWidgetId);
        }
    }

    @Override
    public void onDisabled(Context context) {
        //stop updating the widget
        AlarmHandler alarmHandler = new AlarmHandler(context);
        alarmHandler.cancelAlarmManager();

        Log.d("WIDGET", "Widget removed!");
    }
}

编辑:

我已经添加了我正在使用的所有类,这些类开始发挥作用,我设法在共享文本时添加小部件。

但是我无法检索小部件端的文本。

你能帮我一把吗?

java android android 意图 共享 url 方案

评论


答:

0赞 snachmsm 5/8/2023 #1

您不能以任何方式以编程方式将应用程序小部件放置在主屏幕上,用户必须采取一些系统操作才能放置它,例如从应用程序启动器菜单中选择并拖动到主页

但是从 Android 8 / API 26 开始,有一个新方法 requestPinAppWidget - 因此,请传递您的数据/链接,并使用链接方法强制系统显示 add-app-widget-dialog。一些例子,包括在 HERE 中传递数据ActivityBundle

评论

0赞 Paul 5/9/2023
我已经添加了我正在使用的所有类,这些类开始发挥作用,我设法在共享文本时添加小部件。但是我无法检索小部件端的文本。你能告诉我在 WidgetService 还是在 MyWidget 上这样做应该更好吗?我都试过了,但都失败了。