国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Qt安卓開發(fā):調(diào)用java代碼的獲取usb權(quán)限

這篇具有很好參考價值的文章主要介紹了Qt安卓開發(fā):調(diào)用java代碼的獲取usb權(quán)限。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

最近換了工作,新工作是負(fù)責(zé)用qml做qt安卓開發(fā)。

工作中遇到一個問題:安卓設(shè)備有USB口,需要插入一個U盤在程序里讀寫U盤中的文件,由于安卓系統(tǒng)的安全性的問題導(dǎo)致QFile、c++的文件操作相關(guān)方法都不能讀寫成功,想要讀寫成功只能調(diào)用java代碼,在java代碼里面使用安卓的DocumentFile庫。

經(jīng)過一番探索,成功解決了問題。qt如何添加java代碼不說了,網(wǎng)上有。

下面是具體的java代碼:

package com.example.myapplication;

import android.annotation.TargetApi;
import android.content.Context;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.ParcelFileDescriptor;
import android.preference.PreferenceManager;
import android.provider.DocumentsContract;
import android.util.Log;

import androidx.documentfile.provider.DocumentFile;

import java.io.File;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.List;


public class DocumentsUtils {

    private static final String TAG = DocumentsUtils.class.getSimpleName();

    public static final int OPEN_DOCUMENT_TREE_CODE = 8000;
    public static String as;

    private static List<String> sExtSdCardPaths = new ArrayList<>();

    private DocumentsUtils() {

    }


    public static void cleanCache() {
        sExtSdCardPaths.clear();
    }

    /**
     * Get a list of external SD card paths. (Kitkat or higher.)
     *
     * @return A list of external SD card paths.
     */
    @TargetApi(Build.VERSION_CODES.KITKAT)
    private static String[] getExtSdCardPaths(Context context) {
        if (sExtSdCardPaths.size() > 0) {
            return sExtSdCardPaths.toArray(new String[0]);
        }
        for (File file : context.getExternalFilesDirs("external")) {
            if (file != null && !file.equals(context.getExternalFilesDir("external"))) {
                int index = file.getAbsolutePath().lastIndexOf("/Android/data");
                if (index < 0) {
                    Log.w(TAG, "Unexpected external file dir: " + file.getAbsolutePath());
                } else {
                    String path = file.getAbsolutePath().substring(0, index);
                    try {
                        path = new File(path).getCanonicalPath();
                    } catch (IOException e) {
                        // Keep non-canonical path.
                    }
                    sExtSdCardPaths.add(path);
                }
            }
        }
        if (sExtSdCardPaths.isEmpty()) sExtSdCardPaths.add("/storage/sdcard1");
        return sExtSdCardPaths.toArray(new String[0]);
    }

    /**
     * Determine the main folder of the external SD card containing the given file.
     *
     * @param file the file.
     * @return The main folder of the external SD card containing this file, if the file is on an SD
     * card. Otherwise,
     * null is returned.
     */
    @TargetApi(Build.VERSION_CODES.KITKAT)
    private static String getExtSdCardFolder(final File file, Context context) {
        String[] extSdPaths = getExtSdCardPaths(context);
        try {
            for (int i = 0; i < extSdPaths.length; i++) {
                if (file.getCanonicalPath().startsWith(extSdPaths[i])) {
                    return extSdPaths[i];
                }
            }
        } catch (IOException e) {
            return null;
        }
        return null;
    }

    /**
     * Determine if a file is on external sd card. (Kitkat or higher.)
     *
     * @param file The file.
     * @return true if on external sd card.
     */
    @TargetApi(Build.VERSION_CODES.KITKAT)
    public static boolean isOnExtSdCard(final File file, Context c) {
        return getExtSdCardFolder(file, c) != null;
    }

    /**
     * Get a DocumentFile corresponding to the given file (for writing on ExtSdCard on Android 5).
     * If the file is not
     * existing, it is created.
     *
     * @param file        The file.
     * @param isDirectory flag indicating if the file should be a directory.
     * @return The DocumentFile
     */
    public static DocumentFile getDocumentFile(final File file, final boolean isDirectory,
                                               Context context ) {

        if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) {
            return DocumentFile.fromFile(file);
        }

        String baseFolder = getExtSdCardFolder(file, context);
        //    Log.i(TAG,"lum_ baseFolder " + baseFolder);
        boolean originalDirectory = false;
        if (baseFolder == null) {
            return null;
        }

        String relativePath = null;
        try {
            String fullPath = file.getCanonicalPath();
            if (!baseFolder.equals(fullPath)) {
                relativePath = fullPath.substring(baseFolder.length() + 1);
            } else {
                originalDirectory = true;
            }
        } catch (IOException e) {
            return null;
        } catch (Exception f) {
            originalDirectory = true;
            //continue
        }

       // String as = PreferenceManager.getDefaultSharedPreferences(context).getString(baseFolder, null);
        //as = androidx.preference.PreferenceManager.getDefaultSharedPreferences(context).getString(baseFolder, null);

        String st = as;
        Uri treeUri = null;
        if (as != null) treeUri = Uri.parse(as);
        if (treeUri == null) {
            return null;
        }

        // start with root of SD card and then parse through document tree.
        DocumentFile document = DocumentFile.fromTreeUri(context, treeUri);
        if (originalDirectory) return document;
        String[] parts = relativePath.split("/");
        for (int i = 0; i < parts.length; i++) {
            DocumentFile nextDocument = document.findFile(parts[i]);

            if (nextDocument == null) {
                if ((i < parts.length - 1) || isDirectory) {
                    nextDocument = document.createDirectory(parts[i]);
                } else {
                    nextDocument = document.createFile("image", parts[i]);
                }
            }
            document = nextDocument;
        }

        return document;
    }

    public static boolean mkdirs(Context context, File dir) {
        boolean res = dir.mkdirs();
        if (!res) {
            if (DocumentsUtils.isOnExtSdCard(dir, context)) {
                DocumentFile documentFile = DocumentsUtils.getDocumentFile(dir, true, context);
                res = documentFile != null && documentFile.canWrite();
            }
        }
        return res;
    }

    public static boolean delete(Context context, File file) {
        boolean ret = file.delete();

        if (!ret && DocumentsUtils.isOnExtSdCard(file, context)) {
            DocumentFile f = DocumentsUtils.getDocumentFile(file, false, context);
            if (f != null) {
                ret = f.delete();
            }
        }
        return ret;
    }

    public static boolean canWrite(File file) {
        boolean res = file.exists() && file.canWrite();

        if (!res && !file.exists()) {
            try {
                if (!file.isDirectory()) {
                    res = file.createNewFile() && file.delete();
                } else {
                    res = file.mkdirs() && file.delete();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return res;
    }

    public static boolean canWrite(Context context, File file) {
        boolean res = canWrite(file);

        if (!res && DocumentsUtils.isOnExtSdCard(file, context)) {
            DocumentFile documentFile = DocumentsUtils.getDocumentFile(file, true, context);
            res = documentFile != null && documentFile.canWrite();
        }
        return res;
    }

    /**
     * 重命名
     * @param context
     * @param src
     * @param dest
     * @return
     */
    public static boolean renameTo(Context context, File src, File dest) {
        boolean res = src.renameTo(dest);

        if (!res && isOnExtSdCard(dest, context)) {
            DocumentFile srcDoc;
            if (isOnExtSdCard(src, context)) {
                srcDoc = getDocumentFile(src, false, context);
            } else {
                srcDoc = DocumentFile.fromFile(src);
            }
            DocumentFile destDoc = getDocumentFile(dest.getParentFile(), true, context);
            if (srcDoc != null && destDoc != null) {
                try {
                    Log.i("renameTo", "src.getParent():" + src.getParent() + ",dest.getParent():" + dest.getParent());
                    if (src.getParent().equals(dest.getParent())) {//同一目錄
                        res = srcDoc.renameTo(dest.getName());
                    } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {//不同一目錄
                        Uri renameSrcUri = DocumentsContract.renameDocument(context.getContentResolver(),//先重命名
                                srcDoc.getUri(), dest.getName());
                        res = DocumentsContract.moveDocument(context.getContentResolver(),//再移動
                                renameSrcUri,
                                srcDoc.getParentFile().getUri(),
                                destDoc.getUri()) != null;
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }

        return res;
    }

    public static InputStream getInputStream(Context context, File destFile) {
        InputStream in = null;
        try {
            if (!canWrite(destFile) && isOnExtSdCard(destFile, context)) {
                DocumentFile file = DocumentsUtils.getDocumentFile(destFile, false, context);
                if (file != null && file.canWrite()) {
                    in = context.getContentResolver().openInputStream(file.getUri());
                }
            } else {
                in = new FileInputStream(destFile);

            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        return in;
    }

    public static OutputStream getOutputStream(Context context, File destFile) {
        OutputStream out = null;
        try {
            if (!canWrite(destFile) && isOnExtSdCard(destFile, context)) {
                DocumentFile file = DocumentsUtils.getDocumentFile(destFile, false, context);
                if (file != null && file.canWrite()) {
                    out = context.getContentResolver().openOutputStream(file.getUri());
                }
            } else {
                out = new FileOutputStream(destFile);

            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        return out;
    }

    /**
     * 獲取文件流
     * @param context
     * @param destFile 目標(biāo)文件
     * @param mode May be "w", "wa", "rw", or "rwt".
     * @return
     */
    public static OutputStream getOutputStream(Context context, File destFile, String mode) {
        OutputStream out = null;
        try {
            if (!canWrite(destFile) && isOnExtSdCard(destFile, context)) {
                DocumentFile file = DocumentsUtils.getDocumentFile(destFile, false, context);
                if (file != null && file.canWrite()) {
                    out = context.getContentResolver().openOutputStream(file.getUri(), mode);
                }
            } else {
                out = new FileOutputStream(destFile, mode.equals("rw") || mode.equals("wa"));

            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        return out;
    }

    public static FileDescriptor getFileDescriptor(Context context, File destFile) {
        FileDescriptor fd = null;
        try {
            if (/*!canWrite(destFile) && */isOnExtSdCard(destFile, context)) {
                DocumentFile file = DocumentsUtils.getDocumentFile(destFile, false, context);
                if (file != null && file.canWrite()) {
                    ParcelFileDescriptor out = context.getContentResolver().openFileDescriptor(file.getUri(), "rw");
                    fd = out.getFileDescriptor();
                }
            } else {
                RandomAccessFile file = null;
                try {
                    file = new RandomAccessFile(destFile, "rws");
                    file.setLength(0);
                    fd = file.getFD();
                } catch (Exception e){
                    e.printStackTrace();
                } finally {
                    if (file != null) {
                        try {
                            file.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        return fd;
    }

    public static boolean saveTreeUri(Context context, String rootPath, Uri uri) {
        DocumentFile file = DocumentFile.fromTreeUri(context, uri);
        if (file != null && file.canWrite()) {
            SharedPreferences perf = PreferenceManager.getDefaultSharedPreferences(context);
            perf.edit().putString(rootPath, uri.toString()).apply();
            Log.e(TAG, "save uri" + rootPath);
            return true;
        } else {
            Log.e(TAG, "no write permission: " + rootPath);
        }
        return false;
    }

    /**
     * 返回true表示沒有權(quán)限
     * @param context
     * @param rootPath
     * @return
     */
    public static boolean checkWritableRootPath(Context context, String rootPath) {
        File root = new File(rootPath);
        if (!root.canWrite()) {
            Log.e(TAG,"sd card can not write:" + rootPath + ",is on extsdcard:" + DocumentsUtils.isOnExtSdCard(root, context));
            if (DocumentsUtils.isOnExtSdCard(root, context)) {
                DocumentFile documentFile = DocumentsUtils.getDocumentFile(root, true, context);
                if (documentFile != null) {
                    Log.i(TAG, "get document file:" + documentFile.canWrite());
                }
                return documentFile == null || !documentFile.canWrite();
            } else {
                SharedPreferences perf = PreferenceManager.getDefaultSharedPreferences(context);
                String documentUri = perf.getString(rootPath, "");
                Log.i(TAG,"lum_2 get perf documentUri:" + documentUri);
                if (documentUri == null || documentUri.isEmpty()) {
                    return true;
                } else {
                    DocumentFile file = DocumentFile.fromTreeUri(context, Uri.parse(documentUri));
                    if (file != null)
                        Log.i(TAG,"lum get perf documentUri:" + file.canWrite());
                    return !(file != null && file.canWrite());
                }
            }
        }else{
            Log.e(TAG,"sd card can write...");
        }
        return false;
    }
}

在網(wǎng)上搜索DocumentFile就會搜出一段處理處理DocumentFile的java代碼,都一樣的抄來抄去,這段代碼也是根據(jù)那段代碼改的,經(jīng)過修改可直接放到qt工程里使用。

程序第一次運(yùn)行時調(diào)用(用的qt5):

    QAndroidJniObject androidJinObject = QtAndroid::androidActivity();
    androidJinObject.callMethod<void>("showOpenDocumentTree");

這會彈出申請讀寫設(shè)備權(quán)限的彈窗。這個彈窗只彈出一次,再次執(zhí)行也不會彈出除非卸載應(yīng)用重新安裝。

之后就可以讀寫了,讀寫也只能用DocumentFile,QFile依舊不行。

注意這里獲取QAndroidJniObject 使用的是QtAndroid::androidActivity(),直接創(chuàng)建一個QAndroidJniObject 對象調(diào)用java的static方法可以,非static方法會崩潰,原因未知。

復(fù)制文件的例子(不完整):

        File dest;
        if(dest.exists())
        {
            dest.delete();
        }

        File source;

        InputStream input = null;
        OutputStream output = null;
        try
        {
            input = getInputStream(this,source);//通過DocumentFile獲取流
            output = getOutputStream(this,dest);
            byte[] buf = new byte[1024];
            int bytesRead;
            while ((bytesRead = input.read(buf)) > 0)
            {
               output.write(buf, 0, bytesRead);
            }
        }
        finally
        {
            input.close();
            output.close();
        }

java導(dǎo)入庫后,qt編譯時如果提示庫文件不存在那么把庫文件添加到build.gradle文件中,如:

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar', '*.aar'])
    implementation "androidx.documentfile:documentfile:1.0.1"
    implementation 'androidx.appcompat:appcompat:1.3.0'
    implementation 'com.google.android.material:material:1.4.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
    implementation 'androidx.navigation:navigation-fragment:2.3.5'
    implementation 'androidx.navigation:navigation-ui:2.3.5'
    implementation 'androidx.preference:preference:1.1.1'
}

此文件編譯時會自動生成,若要往build.gradle文件添加內(nèi)容需要先把這個文件添加到qt工程中,那么再次編譯時就用的工程中的此文件。文章來源地址http://www.zghlxwxcb.cn/news/detail-461361.html

到了這里,關(guān)于Qt安卓開發(fā):調(diào)用java代碼的獲取usb權(quán)限的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 安卓adb獲取remount權(quán)限

    remount失敗時策略問題 安卓操作 fastboot權(quán)限 工程模式啟用(eng版本) 指令啟動(userdebug) 打開電腦的cmd窗口 若窗口中打印了remount succeeded 即表示remount權(quán)限獲取成功 若窗口中打印了remount of the / superblock failed: Permission denied(這里是策略問題,需要reboot) 策略問題輸入以下指

    2024年02月12日
    瀏覽(23)
  • Java:使用java調(diào)用shell命令并獲取返回結(jié)果的代碼

    ?????? 如下提供一段簡單的使用java調(diào)用shell命令并獲取返回結(jié)果的代碼,其中有獲取正常返回結(jié)果和異常返回結(jié)果的處理方法,在實(shí)際使用時可根據(jù)實(shí)際情況進(jìn)行調(diào)整。 調(diào)用此方法時傳入實(shí)際執(zhí)行的shell命令即可:

    2024年02月12日
    瀏覽(18)
  • uniapp 安卓如何獲取通話權(quán)限,監(jiān)聽通話情況

    uniapp 安卓如何獲取通話權(quán)限,監(jiān)聽通話情況

    本篇文章還是主要講解uniapp知識,那么在uniapp中如何去實(shí)現(xiàn)監(jiān)聽通話的權(quán)限?接下來請看代碼 在頁面中調(diào)用方法 監(jiān)聽通話狀態(tài)

    2024年02月16日
    瀏覽(26)
  • uniapp:安卓一次性獲取所需權(quán)限

    使用

    2024年02月11日
    瀏覽(20)
  • 如何在非root安卓設(shè)備上讓Termux獲取root權(quán)限

    在經(jīng)過root的安卓手機(jī)上,我們可以獲取管理權(quán)限,可以在系統(tǒng)權(quán)限級別上調(diào)整和編輯應(yīng)用程序,如SuperSu、 Kingroot、 Magisk等等方式。如果要root設(shè)備,那么建議使用magisk方式,畢竟它是不會輕易修改系統(tǒng)文件的。而如果你不想root設(shè)備,那么就可以用FakeRoot這個方法來安裝sudo命

    2023年04月19日
    瀏覽(24)
  • Spring Security安全登錄的調(diào)用過程以及獲取權(quán)限的調(diào)用過程

    Spring Security安全登錄的調(diào)用過程以及獲取權(quán)限的調(diào)用過程

    (0)權(quán)限授理 首先調(diào)用SecurityConfig.java中的config函數(shù)將jwtAuthenticationTokenFilter過濾器放在UsernamePasswordAuthenticationFilter之前 (1)首先運(yùn)行JwtAuthenticationTokenFilter extends OncePerRequestFilter中的doFilterInternal函數(shù) 這里由于沒有獲取到token,因此調(diào)用!StringUtils.hasText(token),這里使用 繼續(xù)運(yùn)行其他

    2024年02月09日
    瀏覽(20)
  • 安卓開發(fā)-調(diào)用相機(jī)

    在AndroidManifest.xml文件中manifest下添加相機(jī)權(quán)限 設(shè)置界面,包含一個按鈕Button和一個ImageView,Button用來顯示按鈕,ImageView用來放置拍攝后的照片,全部代碼如下: MainActivity代碼: BitmapUtil.java 文件代碼: 詳細(xì)說明MainActivity代碼 private static final int REQUEST_CAMERA_PERMISSION = 100; 是用來

    2024年02月08日
    瀏覽(25)
  • OpenCV調(diào)用USB攝像頭/相機(jī),并解決1080p下的延遲卡頓問題(附Python代碼)

    首先直接放上一段加載USB相機(jī)的例程供參考 攝像頭成功加載出來,但是默認(rèn)分辨率太低(我的相機(jī)支持的是1080p),通過如下代碼設(shè)置分辨率和幀率: 此時分辨率是1080p了,但是延遲嚴(yán)重,在網(wǎng)上找了一堆方法, 幾乎都不可用?。。?: 設(shè)置格式為MJPG: == 無法解決問題,依

    2024年02月09日
    瀏覽(158)
  • Android動態(tài)獲取權(quán)限(詳細(xì)教程附代碼)

    Android動態(tài)獲取權(quán)限(詳細(xì)教程附代碼)

    如果是android6.0以下的版本,只需要在manifest聲明對應(yīng)的權(quán)限即可。但是這樣會大大降低系統(tǒng)的安全性。所以在android6.0及其以后,app獲取權(quán)限需要得到用戶的反饋才可以。 動態(tài)獲取權(quán)限,可以分為兩種情況。 情況一 ,操作到app特定的功能,需要某些權(quán)限時進(jìn)行動態(tài)獲取,這種

    2024年02月11日
    瀏覽(20)
  • Qt搭建安卓開發(fā)平臺詳細(xì)步驟

    Qt搭建安卓開發(fā)平臺詳細(xì)步驟

    ? ? ? ?因最近想學(xué)下Qt關(guān)于安卓平臺的開發(fā),特此對環(huán)境的搭建,期間遇到一些問題,在網(wǎng)上查詢各種資料,終于是搭建完成,特此寫下這篇文檔,記錄下,也分享給大家,共同進(jìn)步! ? ? ? ? 本人實(shí)測此方法是真實(shí)有效的,能在安卓上運(yùn)行Qt程序,如若哪里步驟有疑問或者

    2024年02月15日
    瀏覽(20)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包