2021年6月3日 星期四

如何建立桌面捷徑(適應不同的SDK版本)

要求權限
Manifest(AndroidManifest.xml) 裡加上權限要求
<uses-permission android:name=
"com.android.launcher.permission.INSTALL_SHORTCUT" />


import 會用到的物件類別
import android.content.Intent;
import android.content.pm.ShortcutInfo;
import android.content.pm.ShortcutManager;
import android.app.PendingIntent;


程式內容
//可以當成參數傳入的設定
String id = "testID";
String labelShort = "testA";//直接出現在桌面時使用的標題名稱
int iconID = R.mipmap.ic_heart;
Class targetClass = ActText.class;

//設定要攜帶的參數
String paraTitle = "FILENAME";
String paraVal = _fileLog;
//定義要開啟的 Activity
Intent intentTask = new Intent(this, targetClass)
        .setAction(Intent.ACTION_VIEW);

//攜帶參數
intentTask.putExtra(paraTitle, paraVal);
task 說明
//如果裝置版本較舊, 可以執行舊版SDK
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.O)
{
 android.content.Intent intent = new android.content.Intent();
 intent.setAction("com.android.launcher.action.INSTALL_SHORTCUT");
 intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, labelShort);
 intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, intentTask);
 intent.putExtra(Intent.EXTRA_SHORTCUT_ICON,
        android.graphics.drawable.Icon.createWithResource(this, iconID));
 this.sendBroadcast(intent);
 return;
}
版本問題應對
//建立捷徑的外觀
ShortcutInfo pinShortcutInfo = new ShortcutInfo.Builder(this, id)
        .setShortLabel(labelShort)
        .setIcon(android.graphics.drawable.Icon.createWithResource(this, iconID))
        .setIntent(intentTask)
        .build();
//建立捷徑
ShortcutManager shortcutManager = this.getSystemService(ShortcutManager.class);
Intent pinnedShortcutCallbackIntent = shortcutManager.createShortcutResultIntent(pinShortcutInfo);
PendingIntent successCallback = PendingIntent.getBroadcast(this, 0, pinnedShortcutCallbackIntent, 0);
shortcutManager.requestPinShortcut(pinShortcutInfo, successCallback.getIntentSender());



確保 目標 Activity 能直接被啟動
activity 宣告要有這一段
<intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
</intent-filter>




Activity 開啟後接收參數
import android.os.Bundle;
Bundle bundle = this.getIntent().getExtras();
if (bundle != null)
 {
        _id = (String) bundle.get(PARA_ID);
        _filename = (String) bundle.get(PARA_FILE);
 }



Intent-Task

意義在於
桌面捷徑被點選後觸發的事件內容

定義要啟動的 activity
以及要帶進的參數

設定 Task 基本內容
Intent task = new Intent(this, [類別名稱].class)
        .setAction(Intent.ACTION_VIEW);
必須要 setAction 為 ACTION_VIEW

為 task 加上參數
task.putExtra( [參數名稱] , [參數內容] );
設定參數名稱
必須要與接收的 Activity 端對應

啟免參數對應錯誤
可以將參數名稱寫成 final 字串共用
設定常數:
public static final String PARA_FILE= "FILENAME";
task 設定參數內容:
task.putExtra(PARA_FILE ,filename);
Activity 接收參數內容:
_filename = (String) bundle.get(PARA_FILE);

相關文章

如何讓程式在不同版本的SDK執行

相關資源

ShortcutManager 官方文件

ShortcutInfo 官方文件

PendingIntent 官方文件

如何讓程式在不同版本的SDK執行

Android 的 API 很多
compiler 時,常因版本問題無法通過
可以透過以下方法解決


使用 RequiresApi
格式:
@RequiresApi(api = [SDK版本編號])
sample:
@RequiresApi(api = 26)
private void test()
{
....
}
裝置在執行這個函式時會檢查
如果 API 版本不夠高,整個函式都不會被執行
雖然比較簡單(Android Studio 可以自動產生)
但,遇到舊版API,雖不致當掉,但整段函式都不執行
官方說明:
RequiresApi@Android Developers


(程式內)執行前檢查 SDK 版本
if (android.os.Build.VERSION.SDK_INT >=[ver])
{
執行程式
}
sample:
if (Build.VERSION.SDK_INT >= 26)
{
  myVibrator.vibrate (VibrationEffect.createWaveform(pattern, repeat));
}
else
{
  myVibrator.vibrate(pattern, repeat);
}
執行到底該處
如果 API 版本不夠高時,不執行該段程式
(不會因執行該段而當掉)
稍好一點
遇到 API 版本不夠高時,仍會執行函式
但會跳過新版功能,以免掛掉


Android 的 SDK 很多
還是希望程式盡可能多種裝置都正常執行

程式內依版本決定執行方式
if (android.os.Build.VERSION.SDK_INT >=[ver])
{
 使用新版方法
}
else
{
 使用舊版方法
}
有時候會遇到較複雜狀況:

if (android.os.Build.VERSION.SDK_INT >=28)
{
  SDK> 28 可用的API
}
else if (android.os.Build.VERSION.SDK_INT >=26)
{
  SDK> 26 可用的API
}
else
{
  SDK<26 可用的API
}

官方文件

這裡可以查到版本對應 API Levels@Android Developers