【问题标题】:Android - How to receive shortcut create resultAndroid - 如何接收快捷方式创建结果
【发布时间】:2018-06-13 17:01:14
【问题描述】:

查看代码示例here - 我发现以下评论令人费解:

// ... We assume here that the
// app has implemented a method called createShortcutResultIntent() that
// returns a broadcast intent.

这是什么意思应用已经实现...这个实现在哪里完成?

它是广播接收器吗?注册到哪个意图过滤器?

这是一个抽象方法吗?属于哪一班?

然后我看到this code sample - 它处理完全不同的流程(我认为),我又迷路了

【问题讨论】:

    标签: android android-8.0-oreo android-shortcut android-shortcutmanager


    【解决方案1】:

    您可以通过捕捉您在使用requestPinShortcut函数时设置的广播事件来获得反馈。 首先你需要一个普通的广播接收器(在下面的代码中它的名字是ShortcutReceiver)。您甚至可以使用现有的广播接收器并简单地添加它应该捕获的新动作。
    让操作为"general.intent.action.SHORTCUT_ADDED",并将存储在ShortcutReceiver.kInstalledAction 常量中。在这种情况下,您应该在清单中:

    <receiver android:name=".ShortcutReceiver" >
      <intent-filter>
        <action android:name="general.intent.action.SHORTCUT_ADDED"/>
      </intent-filter>
    </receiver>
    

    之后,您可以在活动中使用以下代码创建固定快捷方式(在其他地方更改 Context 类的对象):

    ShortcutManager manager = this.getSystemService(ShortcutManager.class);
    Intent targetIntent = new Intent(ShortcutReceiver.kInstalledAction);
    targetIntent.setPackage(this.getPackageName());
    PendingIntent intent = PendingIntent.getBroadcast(this, 0, targetIntent, 0);
    manager.requestPinShortcut(info, intent.getIntentSender());
    

    在此代码中,infoShortcutInfo 类的正确对象。
    您可以在捕获广播的同时处理事件:

    public class ShortcutReceiver extends BroadcastReceiver {
      public static final String kInstalledAction = "general.intent.action.SHORTCUT_ADDED";
    
      @Override
      public void onReceive(Context context, Intent intent) {
        
        if (kInstalledAction.equals(intent.getAction())) {
          // Handle the event after the shortcut has been added 
          Toast.makeText(context, "The shortcut has been added", Toast.LENGTH_LONG).show();
        }
      
      }
    
    }
    

    请注意,根据我的经验,广播事件是在添加快捷方式后发生的,但有时可能会有一些延迟(大约几分钟)。但是可能对启动器有一些依赖。

    更新
    如其他答案中所述,Android 8 通过广播捕获隐式意图通常不起作用。 所以我通过设置当前应用程序的包名称简单地将意图更改为显式。所以只有我们的广播接收器才能捕捉到意图。

    【讨论】:

    • 以 Android 8.0 Oreo 及更高版本为目标(请注意,即使您的目标为 developer.android.com/about/versions/oreo/android-8.0-changes
    • 只设置receiver不行,还要注册receiver
    • @xaif,接收方已在清单中注册——无需在代码中注册。我只是更改了答案以使用明确的意图。
    • @AlexTern 是的,正确,使用明确的意图工作。谢谢
    【解决方案2】:

    首先要做的事情。 Android 8.0 Oreo 上的隐式意图:

    由于 Android 8.0(API 级别 26)对广播接收器引入了新限制,因此您应该移除所有为隐式广播 Intent 注册的广播接收器。将它们留在原处不会在构建时或运行时破坏您的应用程序,但当您的应用程序在 Android 8.0 上运行时它们没有任何影响。 显式广播意图(只有您的应用可以响应的意图)在 Android 8.0 上仍然有效。 这个新限制也有例外。有关在面向 Android 8.0 的应用中仍然有效的隐式广播列表,请参阅隐式广播异常。 https://developer.android.com/about/versions/oreo/android-8.0-changes

    注意:有一些例外:https://developer.android.com/guide/components/broadcast-exceptions(很少)

    相反,我们将使用所谓的上下文注册接收器,只要我们的应用程序存在,它就会持续存在,或者直到我们取消注册它。

    另外,ShortcutManager 需要 API 25,这就是为什么我们将使用它的兼容版本,以免重复旧版本和新版本的代码。 (ShortcutManagerCompat 在 26.1.0 版本中添加)

    在主屏幕上创建固定快捷方式的代码:

    public static void addShortcut(Context context, String id) {
        if(context == null || note == null)
            return;
    
        //there may be various Home screen apps, better check it
        if (ShortcutManagerCompat.isRequestPinShortcutSupported(context)){
    
            Intent shortcutIntent = new Intent(context, MainActivity.class);
            shortcutIntent.setAction(Constants.ACTION_SHORTCUT); // !!! intent's action must be set on oreo
    
    
            ShortcutInfoCompat shortcutInfo = new ShortcutInfoCompat.Builder(context, note.get_id().toString())
                    .setIntent(shortcutIntent)
                    .setShortLabel("MyShortcut") //recommend max 10 chars
                    .setLongLabel("Long shortcut name")//recommend max 25 chars
                    .setIcon(IconCompat.createWithResource(context, R.drawable.ic_shortcut))
                    .build();
    
    
            //callback if user allowed to place the shortcut
            Intent pinnedShortcutCallbackIntent = new Intent(ACTION_SHORTCUT_ADDED_CALLBACK);
    
            PendingIntent successCallback = PendingIntent.getBroadcast(context, REQ_CODE_SHORTCUT_ADDED_CALLBACK,
                    pinnedShortcutCallbackIntent,  0);
    
    
            ShortcutManagerCompat.requestPinShortcut(context, shortcutInfo, successCallback.getIntentSender());
        }
    

    例如,这是在您的 Activity 中接收广播的代码。请注意,只有在您的应用正在运行、接收者已注册并且用户允许快捷方式时,才会调用此“回调”:

    private ShortcutAddedReceiver shortcutAddedReceiver;
    
    
    
    private void registerShortcutAddedReceiver(){
        if(shortcutAddedReceiver == null){
            shortcutAddedReceiver = new ShortcutAddedReceiver();
        }
        IntentFilter shortcutAddedFilter = new IntentFilter(ShortcutHelper.ACTION_SHORTCUT_ADDED_CALLBACK);
        registerReceiver(shortcutAddedReceiver, shortcutAddedFilter);
    }
    
    
    private void unregisterShortcutAddedReceiver(){
        if(shortcutAddedReceiver != null){
            unregisterReceiver(shortcutAddedReceiver);
            shortcutAddedReceiver = null;
        }
    }
    
    
    @Override
    public void onStart() {
        super.onStart();
        registerShortcutAddedReceiver();
    }
    
    @Override
    public void onStop() {
        super.onStop();
       unregisterShortcutAddedReceiver();
    }
    
    
    private class ShortcutAddedReceiver extends BroadcastReceiver{
    
        @Override
        public void onReceive(Context context, Intent intent) {
            Snackbar.make(view, "Shortcut added", Snackbar.LENGTH_LONG).show();
        }
    }
    

    希望这会有所帮助!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-07-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-23
      • 2012-03-30
      相关资源
      最近更新 更多