2023年11月23日 星期四

Android Studio - FileProvider 介紹(一百一十五)

Android Studio - FileProvider 介紹(一百一十五):

FileProvide 是在Android 7.0 出現的新特性,它是 ContentProvider 的子類,可以通過創建一個 content://格式的 Content URI 並賦予臨時的檔存取權限來代替 File URI 實現檔共用。但在 Android 10 開始引入了分區存儲的概念,Android 11 開始強制執行,FileProvider 類是 AndroidX 核心庫的一部分,也就是以前可以任意的訪問SD卡下任意目錄,Android 11 上則不能隨意訪問,除了 /sdcard/Android/data/ 應用包名目錄下的內容外,其它目錄都已禁止訪問,音樂、視頻、照片、下載目錄、文件(Music、Video、DCIM、Download、Document)下的檔需要向使用者申請許可權,允許後才可訪問。

Android Studio FileProvider
FileProvider 的出現可以解決檔案共用的問題,提升了檔案文件訪問的安全性。FileProvider 默認就具有生成 content:// 格式的 Uri 的功能,因此我們不需要在代碼中編寫它的子類,幾乎所有的代碼都只需要在 XML 檔中進行配置即可。要配置 FileProvider,我們首先需要在 AndroidManifest.xml 檔中通過 標籤進行聲明,並配置自訂的 android:authorities 屬性。

FileProvider 實現檔共用功能的步驟:
在 AndroidManifest.xml 中聲明 FileProvider
創建一個 xml 檔定義 FileProvider 的路徑
創建一個 file_paths.xml 檔,並定義檔路徑
獲取文件的 Uri
啟動其他應用來處理文件

AndroidManifest.xml:
</manifest>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.example.myapp">
        <application
            ...>
            <provider
                android:name="androidx.core.content.FileProvider"
                android:authorities="com.example.myapp.fileprovider"
                android:grantUriPermissions="true"
                android:exported="false">
                <meta-data
                    android:name="android.support.FILE_PROVIDER_PATHS"
                    android:resource="@xml/filepaths" />
            </provider>
            ...
        </application>
    </manifest>

paths下標籤和路徑介紹:

序號

標籤名

對應API

1

android:name

指定FileProvider的類別名,通常使用

androidx.core.content.FileProvider / androidx.support.v4.content.FileProvider

2

android:authorities

指定FileProviderauthority,需要確保它在裝置上是唯一的

3

android:exported

設定為false,表示該FileProvider只能被本應用程式存取

4

android:grantUriPermissions

設定為true,表示授予其他應用程式對該FileProvider傳回的Uri的臨時存取權限

5

<meta-data>

標籤用於指定FileProvider的路徑設定檔,這裡是@xml/file_paths


在 AndroidManifest.xml 的編碼中,android:name 屬性通暢配置為 androidx.core.content.FileProvider(如果當前專案基於Android 7.0,則需要配置為android.support.v4.content.FileProvider);android:authorities 屬性是當前應用的授權字串,是其他應用訪問當前應用中文件的憑證;android:exported 屬性工作表示該 FileProvider 是否是公有的,一般情況下都設為 false;android:grantUriPermissions 屬性工作表示是否可以為檔賦予臨時存取權限,一般情況下都設為true。如果我們想要擴展默認的 FileProvider,則 android:name 屬性需要配置為我們自訂的 FileProvider 類的全路徑。

xml/filepaths.xml:
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <root-path name="root" path="" />
    <files-path name="files" path="images/" />
    <cache-path name="cache" path="" />
    <external-path name="external" path="" />
    <external-files-path  name="external-files" path="" />
    <external-cache-path name="external-cache" path="" />
    <external-media-path name="external-media" path="" />
</paths>

Androidx paths下標籤和路徑介紹:

序號

標籤名

對應API

對應路徑

1

files-path

Context.getFilesDir()

/data/user/0/com.ttxz.testa/files

2

cache-path

Context.getCacheDir()

/data/user/0/com.ttxz.testa/cache

3

external-path

Environment.getExternalStorageDirectory()

/storage/emulated/0

4

external-files-path

Context.getExternalFilesDir(String type)

/storage/emulated/0/Android/data/com.ttxz.testa/files

5

external-cache-path

Context.getExternalCacheDir()

/storage/emulated/0/Android/data/com.ttxz.testa/cache

6

external-media-path

Context.getExternalMediaDirs()

[/storage/emulated/0/Android/media/com.ttxz.testa]


Android 7.0 的paths下標籤和路徑介紹:

標籤

標籤代表路徑

path=files”代表路徑

root-path

設備的根目錄

/files/*

files-path

內部存儲空間應用私有目錄下的 files/ 目錄,等同於context.getFilesDir()

context.getFilesDir()+/files/*

cache-path

內部存儲空間應用私有目錄下的 cache/ 目錄,等同於context.getCacheDir()

context.getCacheDir()+/files/*

external-path

外部存儲空間根目錄,等同於Environment.getExternalStorageDirectory()

Environment.getExternalStorageDirectory()+/files/*

external-files-path

外部存儲空間應用私有目錄下的 files/ 目錄,等同於context.getExternalFilesDirs()

context.getExternalFilesDirs()+/files/*

external-cache-path

外部存儲空間應用私有目錄下的 cache/ 目錄,等同於getExternalCacheDirs()

getExternalCacheDirs()+/files/*


為了讓其他應用可以訪問當前應用下的檔,我們還需要配置哪些資料夾可以被訪問,這個步驟也是在 XML 檔中配置的。我們需要在專案的 /res/xml 資料夾下創建一個路徑設定檔,命名為 filepaths.xml(檔案名可以自訂),這個檔中的根節點是,在這個節點下設定檔夾。

2023年 11月 23日(Thu)天氣報告
氣溫:44.0°F / 7.0°C @ 07:00
風速:每小時 6公里
降雨機會:2%
相對濕度:百分之 62%
天氣:多雲

2023年10月23日 星期一

Hyper Tough 116 件工具套裝(Tool Set)介紹

Hyper Tough 116 件工具套裝(Tool Set)介紹:

筆者發現手頭上的工具不足夠,所以便在網上選購一套工具,用來應付日常的家居維修工作,在網上有很多不同的工具套裝,花多眼亂,要小心選一套適合自已需要的工具套裝,也要花點時間。筆者最後選擇了Hyper Tough 116件工具套裝(Hyper Tough 116-Piece Home repair Tool Set),價格是 US$24.88,這套工具是一款適合一般家庭維修使用,對筆者來說是足夠的。

Hyper Tough 116 件工具套裝(Hyper Tough 116-Piece Home repair Tool Set)箱前面
Hyper Tough 116 件工具套裝(Hyper Tough 116-Piece Home repair Tool Set)箱背面
Hyper Tough 工具套裝(Tool Set)所有工具是放置在 1個塑膠手提箱內,塑膠手提箱尺寸 334mm × 78mm × 270mm(13.00 × 3.00 × 11.00 Inches),總重量 2.92kg / 4.44lb(6.06 lb)。套件配有堅固的錘子(Hammer)、具有 SAE 和公制(Metric)尺寸的套筒套件(Socket Set)、六角扳手(Hex Key)、帶有多個刀頭(Multiple Bits)的螺絲批(Screwdriver)以滿足您的需求等等。此套裝中的每件工具都方便地裝在堅固的吹塑盒中,以便每個工具都有自己特定的位置。箱子鎖緊,並配有手柄,方便移動。這款 Hyper Tough 116 件工具組合有多種使用方式,是適合所有 DIY 專案和修復的完美多功能套件。

Hyper Tough 116件工具套裝(Hyper Tough 116-Piece Home repair Tool Set)內部
Hyper Tough 116 件工具套裝(Hyper Tough 116-Piece Home repair Tool Set)的工具
品牌型號:Hyper Tough 116-Piece Home repair Tool Set
型號:8UJ0001G
綜合套裝:116 件
Features:手提箱易於護理,符合人體工學的手柄,防滑手柄(Easy Care, Ergonomic Handle, Non-slip Handle)
機身尺寸(L x W x H):334mm × 78mm × 270mm(規格:13.00 × 3.00 × 11.00 Inches)
重量:2.92kg / 4.44lb(規格:6.06 lb)
顏色:黑色手提箱
保証期間:5 年 Limited Manufacturer's Warranty
生產地區:越南製造(Made in Vietnam)
發售日期:估計 2022年
參考價格:$24.88美元(≒港幣$194.06)

2023年 10月 23日(Mon)天氣報告
氣溫:50.0°F / 10.0°C @ 08:00
風速:每小時 10 公里
降雨機會:9%
相對濕度:百分之 84%
天氣:多雲時陰

2023年9月21日 星期四

Android Studio - JSON 資料交換格式(一百一十四)

Android Studio - JSON 資料交換格式(一百一十四):

JSON(JavaScript Object Notation)是由美國程式設計師設計和構想出的資料交換格式,擁有易讀、易寫的特點,並且機器解析和生成容易。是依據 JavaScript 物件語法的資料格式,屬於 JavaScript 的子集,也採用了 C 語言家族的習慣用法。

- JSON 資料交換格式
JSON 格式主要包含兩種數據結構:對象(Object)和數組(Array):
  • 對象(Object):對象是由零個或多個鍵值對(key-value pairs)組成的無序集合,鍵值對之間用逗號分隔,用大括號 {} 包裹。鍵是字符串,值可以是字符串、數字、布爾值、null、對象或數組。
  • 數組(Array):數組是由零個或多個值組成的有序列表,值之間用逗號分隔,用方括號 [] 包裹。值可以是字符串、數字、布爾值、null、對象或數組。

JSON 的格式:

{ 

  "name": "a",

  "email":"a@a.com,

  "password": "0000"

}


JSON 的格式:

{ 

  "name": "a",

  "email":"a@a.com,

  "password": "0000",

  "contents" [

    {

      "age": 28,

      "address": "Taiwan,

    }

  ],

  "member": true

}


JSON 是個以純文字為基底去儲存和傳送簡單結構資料,可以透過特定的格式去儲存任何資料(字串、數字、陣列、物件),也可以透過物件或陣列來傳送較複雜的資料。一旦建立了您的 JSON 資料,就可以非常簡單的跟其他程式溝通或交換資料,因為 JSON 就只是個純文字格式。

PHP JSON 函數:

Plugin version

Required Gradle version

json_encode

對變數進行 JSON 編碼

json_decode

JSON 格式的字串進行解碼,轉換為 PHP 變數

json_last_error

返回最後發生的錯誤


2023年 9月 21日(Wed)天氣報告
氣溫:50.0°F / 10.0°C @ 07:00
風速:每小時 5公里
降雨機會:2%
相對濕度:百分之 86%
天氣:多雲時陰

2023年9月20日 星期三

Android Studio - Android Java Login PHP 登入程式(一百一十三)

Android Studio - Android Java Login PHP 登入程式(一百一十三):

完成了 Android Java 的登入程式,便需要在 NAS 上的 PHP Server 編寫程式,PHP 程式主要是接收從 Android 傳送(POST)過來的資料,資料是用 JSON 格式,這 2個資料變數是 email ($_POST['email'])和 password($_POST['password']),並透過 PHP 程式連接 MySQL 資料庫,用 MySQL 連接資料庫的查詢指令,將判斷 email 帳號與密碼是否正確,然後將結果用 JSON 格式回傳到 Android。

Android PHP MySQL 連接
PHP Provided Information:
Linux 系統:Debian 2.6.12.6-arm1 版本
Apache 系統:Apache 2.2.3 版本
PHP 系統:PHP 5.2.0-8 版本
MySQL 系統:MySQL 5.0.32 版本
JSON 系統:JSON 1.2.1 版本

Login.php PHP 登入程式:

<?php

 

if ($_SERVER['REQUEST_METHOD']=='POST') {

 

    $email = $_POST['email'];

    $pass = $_POST['password'];

    require_once 'connect.php';

 

    $sql = "SELECT * FROM users WHERE email='$email' ";

    $response = mysqli_query($conn, $sql);

   

    $result = array();

    $result['login'] = array();

   

    if ( mysqli_num_rows($response) === 1 ) {

        $row = mysqli_fetch_assoc($response);

       

        if ( $pass== $row['password'] ) {

          

            $index['Name'] = $row['Name'];

            $index['email'] = $row['email'];

            $index['id'] = $row['id'];

            $index['pass'] = $row['password'];

            $index['no'] = $row['no'];

            $index['add'] = $row['address'];

 

            array_push($result['login'], $index);

 

            $result['success'] = "1";

            $result['message'] = "success";

            echo json_encode($result);

           

            mysqli_close($conn);

 

        } else {

            $result['success'] = "0";

            $result['message'] = "Worng Password";

            echo json_encode($result);

 

            mysqli_close($conn);

        }

 

    }else{

        $result['success'] = "0";

        $result['message'] = "error";

        echo json_encode($result);

        mysqli_close($conn);

    }

}

?>


user.sql 資料庫:

DROP TABLE IF EXISTS `users`;

CREATE TABLE `users` (

  `id` int(255) NOT NULL auto_increment,

  `Name` varchar(20) NOT NULL,

  `email` varchar(30) NOT NULL,

  `password` varchar(20) NOT NULL,

  `no` bigint(20) NOT NULL,

  `address` varchar(100) NOT NULL,

  PRIMARY KEY  (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

 

INSERT INTO `users` (`id`, `Name`, `email`, `password`, `no`, `address`) VALUES

(1,'a','a@a.com','0000',0,'A123 CA'),

(2,'b','b@a.com','0000',0,'A222 CA'),

(3,'c','c@a.com','0000',0,'A333 CA'),

(4, 'd', 'd@a.com', '0000', '0', 'A443 CA'),

(5, 'e', 'e@a.com', '0000', '0', 'A555 CA');


2023年 9月 20日(Wed)天氣報告
氣溫:52.0°F / 11.0°C @ 07:00
風速:每小時 3公里
降雨機會:15%
相對濕度:百分之 94%
天氣:多雲