IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> android shortcut & widgets使用demo -> 正文阅读

[移动开发]android shortcut & widgets使用demo

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

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-08-07 12:12:20  更:2021-08-07 12:13:46 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/17 10:49:08-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码