提问人:Paul 提问时间:5/8/2023 最后编辑:Paul 更新时间:5/9/2023 访问量:78
Android 共享文本/纯文本,以便能够在小部件中使用
Android share text/plain to be able to use in the widget
问:
我需要在外部应用程序和我的应用程序之间共享文本/纯文本,并将此共享文本用作我需要插入的小部件的 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!");
}
}
编辑:
我已经添加了我正在使用的所有类,这些类开始发挥作用,我设法在共享文本时添加小部件。
但是我无法检索小部件端的文本。
你能帮我一把吗?
答:
0赞
snachmsm
5/8/2023
#1
您不能以任何方式以编程方式将应用程序小部件放置在主屏幕上,用户必须采取一些系统操作才能放置它,例如从应用程序启动器菜单中选择并拖动到主页
但是从 Android 8 / API 26 开始,有一个新方法 requestPinAppWidget
- 因此,请传递您的数据/链接,并使用链接方法强制系统显示 add-app-widget-dialog。一些例子,包括在 HERE 中传递数据Activity
Bundle
评论
0赞
Paul
5/9/2023
我已经添加了我正在使用的所有类,这些类开始发挥作用,我设法在共享文本时添加小部件。但是我无法检索小部件端的文本。你能告诉我在 WidgetService 还是在 MyWidget 上这样做应该更好吗?我都试过了,但都失败了。
评论