1,AndroidManifest.xml?
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.goals.shortcutwidgetdemo">
<application
android:name="com.goals.shortcutwidgetdemo.App"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.ShortcutDemo">
<activity
android:name="com.goals.shortcutwidgetdemo.NewMainActivity"
android:exported="true" />
<activity
android:name="com.goals.shortcutwidgetdemo.MainActivity"
android:exported="true">
<!--这种静态配置的写法已经不能满足现有需求,需要带参数跳转到页面去-->
<meta-data
android:name="android.app.shortcuts"
android:resource="@xml/shortcuts"/>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!--微件接受者,和广播接收者一样,需要注册-->
<receiver
android:name=".widget.OpenDoorNewWidget"
android:label="@string/open_door_by_phone">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
<action android:name="com.goals.shortcutwidgetdemo.BROADCAST_TO_WIDGET" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/app_widget_provider_open_door" />
</receiver>
</application>
</manifest>
2,application?
package com.goals.shortcutwidgetdemo
import android.app.Application
import android.os.Build
import androidx.annotation.RequiresApi
class App : Application() {
@RequiresApi(Build.VERSION_CODES.N_MR1)
override fun onCreate() {
super.onCreate()
//动态配置快捷方式
ShortcutHelper.setShortcut(this)
}
}
3,首页,?
package com.goals.shortcutwidgetdemo
import android.content.ComponentName
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import com.goals.shortcutwidgetdemo.widget.BroadcastUtil
import com.goals.shortcutwidgetdemo.widget.OpenDoorNewWidget
class MainActivity : AppCompatActivity() {
private val TAG :String = "tag"
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val btn = findViewById<Button>(R.id.btn)
//https://blog.csdn.net/weixin_42605341/article/details/82656103
//如果此时的广播是发给MyAppwidgetProvider自己的,则需要添加:
//intent_count.setComponent(new ComponentName(context,MyAppWidgetProvider.class));//必须写
//如果此时的广播是发给其他的service或者activity,则不要添加setComponent,调试发现加了广播收不到。
btn.setOnClickListener {
sendOpenDoorBroadcast(BroadcastUtil.TagWidget.LOGOUT)
}
}
private fun sendOpenDoorBroadcast(it: String?) {
val intent = Intent(BroadcastUtil.ACTION_WIDGET)
var tag =
(if (it == null) BroadcastUtil.TagWidget.LOGOUT else BroadcastUtil.TagWidget.LOGIN)
intent.putExtra(TAG, tag)
intent.component = ComponentName(this, OpenDoorNewWidget::class.java)
sendBroadcast(intent)
}
}
4,功能页?(落地页)
package com.goals.shortcutwidgetdemo
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Toast
class NewMainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_new_main)
var routeStr = intent.extras?.get("route") as String
Toast.makeText(this,routeStr,Toast.LENGTH_LONG).show()
}
}
5, widget
package com.goals.shortcutwidgetdemo.widget;
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.widget.RemoteViews;
import com.goals.shortcutwidgetdemo.NewMainActivity;
import com.goals.shortcutwidgetdemo.R;
/**
* Implementation of App Widget functionality.
*/
public class OpenDoorNewWidget extends AppWidgetProvider {
int[] appWidgetIds = {};
@Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
String action = intent.getAction();
if (BroadcastUtil.ACTION_WIDGET.equals(action)) {
Log.d("接收到更新事件:=======" + action + ",", appWidgetIds.length + "");
//接收到广播后更新微件
onUpdate(context,AppWidgetManager.getInstance(context), appWidgetIds);
}
}
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
//这个appWidgetIds你并不需要管他是多少,只是系统记录下你新建了多少个微件,然后系统给他一个编号,用于来刷新这个微件使用的
//同一种微件,系统会在这里返回这类微件的所有编号,用于刷新,对于开发者我觉得用处不大。除非你能分清这两个不同的微件,谁是谁,
//就算分清楚了,又有啥用,其实功能都是一样的,长相也是一样的,只是有两个,仅此而已。
this.appWidgetIds = appWidgetIds;
for (int appWidgetId : appWidgetIds) {
Log.d("","OpenDoorNewWidget-appWidgetIds:"+appWidgetId);
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.layout_open_door_widget);
Intent intent = null;
//更新微件,比如说你可以做,登录和未登录的微件不同跳转
// if (XXXContext.getInstance().isLogin()){
// intent = new Intent(context, AccessControlActivity.class);
// }else {
intent = new Intent(context, NewMainActivity.class);
intent.putExtra("route", "widget/property/opendoor/list");
// }
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
//这里设置PendingIntent,要给整个Layout设置,而不是一个控件
// views.setOnClickPendingIntent(R.id.info_tv, pendingIntent);
views.setOnClickPendingIntent(R.id.open_door_ll, pendingIntent);
appWidgetManager.updateAppWidget(appWidgetId, views);
}
}
}
?6,ShortcutHelper
package com.goals.shortcutwidgetdemo;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ShortcutInfo;
import android.content.pm.ShortcutManager;
import android.graphics.drawable.Icon;
import android.os.Build;
import androidx.annotation.RequiresApi;
import java.util.Arrays;
/**
* 动态设置快捷方式,可以根据用户状态等,再次重新设置快捷方式,就可以达到更新的效果
*/
public class ShortcutHelper {
@RequiresApi(api = Build.VERSION_CODES.N_MR1)
public static void setShortcut(Context context) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N_MR1) return;
ShortcutManager shortcutManager = context.getSystemService(ShortcutManager.class);
/**
* 本来再写下边这两个方法中的内容是复制,然后改下参数名,这样造成了错误,
* 使得手机开门的 .setIntent(intentScan)也写成了,扫码的Intent
* 今后这种复制的写法,还是不要复制着写了。或者复制完成后再单独写成《《《两个单独的方法》》》,这样就可以看出来哪里有问题了。
*/
ShortcutInfo shortcutInfoOpenDoor = getOpenDoorShortcut(context);
ShortcutInfo shortcutInfoScan = getScanShortcut(context);
shortcutManager.setDynamicShortcuts(Arrays.asList(shortcutInfoScan,shortcutInfoOpenDoor));
}
@RequiresApi(api = Build.VERSION_CODES.N_MR1)
private static ShortcutInfo getScanShortcut(Context context) {
Intent intentScan = null;
// if (XXXContext.getInstance().isLogin()){
// intentScan = new Intent(context, QrParseAct.class);
// intentScan.putExtra(ConstantValue.NEED_RETURN_MAIN, true);
// intentScan.putExtra(ConstantValue.FROM_TYPE, ConstantValue.FromType.WIDGET);
// intentScan = QrParseAct.getIntent(context,ConstantValue.FromType.WIDGET,true);
// }else {
intentScan = new Intent(context, NewMainActivity.class);
intentScan.putExtra("route", "dynamic/common/scan_qr");
// }
intentScan.setAction(Intent.ACTION_VIEW);
ShortcutInfo shortcutInfoScan = new ShortcutInfo.Builder(context,"id2")
.setShortLabel("D扫码")
.setLongLabel("D扫一扫")
.setIcon(Icon.createWithResource(context,R.mipmap.ic_short_cut_scan_d))
.setIntent(intentScan)
.build();
return shortcutInfoScan;
}
@RequiresApi(api = Build.VERSION_CODES.N_MR1)
private static ShortcutInfo getOpenDoorShortcut(Context context) {
Intent intentOpenDoor = null;
// if (XXXContext.getInstance().isLogin()){
// intentOpenDoor = new Intent(context, AccessControlActivity.class);
// intentOpenDoor.putExtra(ConstantValue.NEED_RETURN_MAIN, true);
// intentOpenDoor.putExtra(ConstantValue.FROM_TYPE, ConstantValue.FromType.WIDGET);
// intentOpenDoor = AccessControlActivity.getIntent(context,ConstantValue.FromType.WIDGET,true);
// }else {
intentOpenDoor = new Intent(context, NewMainActivity.class);
intentOpenDoor.putExtra("route", "dynamic/property/opendoor/list");
// }
intentOpenDoor.setAction(Intent.ACTION_VIEW);
ShortcutInfo shortcutInfoOpenDoor = new ShortcutInfo.Builder(context,"id1")
.setShortLabel("D开门")
.setLongLabel("D手机开门")
.setIcon(Icon.createWithResource(context, R.mipmap.ic_short_cut_open_door_d))
.setIntent(intentOpenDoor)
.build();
return shortcutInfoOpenDoor;
}
}
7,res--xml--shortcuts.xml?
<?xml version="1.0" encoding="utf-8"?>
<shortcuts xmlns:android="http://schemas.android.com/apk/res/android">
<shortcut
android:enabled="true"
android:icon="@mipmap/ic_short_cut_open_door"
android:shortcutDisabledMessage="@string/open_door_by_phone_disable"
android:shortcutId="access"
android:shortcutLongLabel="@string/open_door_by_phone"
android:shortcutShortLabel="@string/open_door_by_phone">
<!--需要到加载完所有配置信息(经过NewMainActivity)才能到落地页去,否则会出现白屏,获取不到配置信息的问题-->
<!--android:targetClass="com.goals.shortcutwidgetdemo.AccessControlActivity"-->
<!--TODO 这里的路由是写死的,不好,怎么能动态获取值?-->
<intent
android:action="android.intent.action.VIEW"
android:targetClass="com.goals.shortcutwidgetdemo.NewMainActivity"
android:targetPackage="com.goals.shortcutdemo">
<extra android:name="route" android:value="xxx://xxx.com/property/opendoor/list" />
</intent>
</shortcut>
</shortcuts>
demo项目地址:https://github.com/huyongqiang/com.goals.shortcutwidgetdemo
|