অ্যান্ড্রয়েড 5.0 (ললিপপ) এর জন্য উপস্থাপিত নতুন এসডি কার্ড অ্যাক্সেস এপিআই কীভাবে ব্যবহার করবেন?


118

পটভূমি

উপর অ্যান্ড্রয়েড 4.4 (KitKat) বিশিষ্ট, গুগল SD কার্ড বেশ সীমাবদ্ধ অ্যাক্সেস করেছে।

অ্যান্ড্রয়েড ললিপপ (৫.০) হিসাবে, বিকাশকারীরা একটি নতুন এপিআই ব্যবহার করতে পারেন যা এই গুগল-গ্রুপ পোস্টে লেখা হিসাবে নির্দিষ্ট ফোল্ডারে অ্যাক্সেসের অনুমতি দিতে ব্যবহারকারীকে জিজ্ঞাসা করতে বলে ।

সমস্যাটি

পোস্টটি আপনাকে দুটি ওয়েবসাইট দেখার জন্য নির্দেশ দেয়:

এটি দেখতে অভ্যন্তরীণ উদাহরণের মতো (সম্ভবত পরে এপিআই ডেমোতে প্রদর্শিত হতে পারে) তবে কী চলছে তা বোঝা বেশ শক্ত।

এটি নতুন এপিআইএর অফিশিয়াল ডকুমেন্টেশন, তবে এটি কীভাবে এটি ব্যবহার করবেন সে সম্পর্কে যথেষ্ট বিবরণ জানায় না।

এটি আপনাকে যা বলে তা এখানে:

আপনার যদি সত্যিই ডকুমেন্টগুলির পুরো সাবট্রিতে সম্পূর্ণ অ্যাক্সেসের প্রয়োজন হয় তবে ব্যবহারকারীকে একটি ডিরেক্টরি বেছে নেওয়ার জন্য ACTION_OPEN_DOCUMENT_TREE চালু করে শুরু করুন। তারপরে ফলস্বরূপ getData () fromTreeUri (প্রসঙ্গ, উরি) মধ্যে পাস করুন ব্যবহারকারীর নির্বাচিত গাছের সাথে কাজ শুরু করতে।

ডকুমেন্টফিলের উদাহরণগুলিতে আপনি যখন ট্রিটি নেভিগেট করেন, আপনি সর্বদা getUri () ব্যবহার করতে পারেন উরিটি সেই অবজেক্টের অন্তর্নিহিত নথিটির প্রতিনিধিত্ব করে, ওপেনআইপুটস্ট্রিম (উরি) ইত্যাদি ব্যবহারের জন্য obtain

KITKAT বা তার আগে চলমান ডিভাইসগুলিতে আপনার কোডটি সহজ করার জন্য, আপনি ফাইল (ফাইল) থেকে ডকুমেন্টস প্রোভাইডারের আচরণ অনুকরণ করে যা ব্যবহার করতে পারেন।

প্রশ্নসমুহ

নতুন এপিআই সম্পর্কে আমার কয়েকটি প্রশ্ন রয়েছে:

  1. কীভাবে আপনি এটি ব্যবহার করবেন?
  2. পোস্ট অনুসারে, ওএস মনে রাখবে যে অ্যাপ্লিকেশনটিকে ফাইল / ফোল্ডার অ্যাক্সেস করার অনুমতি দেওয়া হয়েছিল। আপনি ফাইল / ফোল্ডার অ্যাক্সেস করতে পারবেন কিনা তা কীভাবে পরীক্ষা করবেন? এমন কোনও ফাংশন রয়েছে যা আমি যে ফাইল / ফোল্ডারগুলিতে অ্যাক্সেস করতে পারি তার তালিকা ফিরিয়ে দেয়?
  3. কীটকেটে আপনি কীভাবে এই সমস্যাটি পরিচালনা করেন? এটি কি সমর্থন লাইব্রেরির একটি অংশ?
  4. ওএসে এমন কোনও সেটিংস স্ক্রিন রয়েছে যা দেখায় যে কোন অ্যাপ্লিকেশনগুলিতে কোন ফাইল / ফোল্ডারে অ্যাক্সেস রয়েছে?
  5. যদি কোনও অ্যাপ্লিকেশন একই ডিভাইসে একাধিক ব্যবহারকারীর জন্য ইনস্টল করা থাকে তবে কী হবে?
  6. এই নতুন এপিআই সম্পর্কে কি অন্য কোনও ডকুমেন্টেশন / টিউটোরিয়াল আছে?
  7. অনুমতিগুলি কি বাতিল করা যাবে? যদি তাই হয়, অ্যাপটিতে পাঠানো হচ্ছে এমন কোনও উদ্দেশ্য আছে?
  8. কোনও নির্বাচিত ফোল্ডারে পুনরাবৃত্তভাবে অনুমতি কাজ করার জন্য জিজ্ঞাসা করবেন?
  9. অনুমতি ব্যবহার করা কি ব্যবহারকারীর পছন্দ অনুসারে ব্যবহারকারীর একাধিক নির্বাচনের সুযোগ দিতে পারে? অথবা অ্যাপ্লিকেশনটি কোন ফাইল / ফোল্ডারগুলিকে অনুমতি দেবে তা নির্দিষ্ট করে উদ্দেশ্যটি বলতে হবে?
  10. এমুলেটরটিতে নতুন এপিআই চেষ্টা করার কোনও উপায় আছে? মানে, এটিতে এসডি-কার্ড পার্টিশন রয়েছে তবে এটি প্রাথমিক বাহ্যিক স্টোরেজ হিসাবে কাজ করে, তাই এর সমস্ত অ্যাক্সেস ইতিমধ্যে দেওয়া হয়েছে (একটি সাধারণ অনুমতি ব্যবহার করে)।
  11. যখন ব্যবহারকারী এসডি কার্ডটি অন্য একটিতে প্রতিস্থাপন করে তখন কী ঘটে?

এফডাব্লুআইডাব্লু, অ্যান্ড্রয়েডপোলিসের আজ এই সম্পর্কে একটি সামান্য নিবন্ধ ছিল ।
5:25

আপনাকে ধন্যবাদ তবে তারা ইতিমধ্যে যা পড়েছি তা প্রদর্শন করছে। যদিও এটি ভাল খবর।
অ্যান্ড্রয়েড বিকাশকারী

32
প্রতিবার নতুন ওএস বের হওয়ার সাথে সাথে তারা আমাদের জীবনকে আরও জটিল করে
তুলেছে

নিখুঁত আশা করি তারা কিটকটে এটি করেছে। এখন পরিচালনা করতে 3 ধরণের আচরণ রয়েছে।
অ্যান্ড্রয়েড বিকাশকারী

1
পছন্দ করেছেন আমি এটি অনেক আগে ব্যবহার করেছি। আমার মনে হয় এই চেকটি করা খারাপ নয়। আপনার মনে রাখতে হবে তারাও মানুষ, তাই তারা ভুল করতে পারে এবং সময়ে সময়ে তাদের মন পরিবর্তন করতে পারে ...
অ্যান্ড্রয়েড বিকাশকারী

উত্তর:


143

প্রচুর ভাল প্রশ্ন, আসুন খনন করি। :)

তুমি এটা কিভাবে ব্যবহার কর?

কিটকাটের স্টোরেজ অ্যাক্সেস ফ্রেমওয়ার্কের সাথে আলাপচারিতার জন্য এখানে দুর্দান্ত টিউটোরিয়াল রয়েছে:

https://developer.android.com/guide/topics/providers/document-provider.html#client

ললিপপে নতুন এপিআইয়ের সাথে ইন্টারঅ্যাক্ট করা খুব মিল। ব্যবহারকারীকে ডিরেক্টরি গাছ বাছাই করতে অনুরোধ জানাতে, আপনি এই জাতীয় উদ্দেশ্য চালু করতে পারেন:

    Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
    startActivityForResult(intent, 42);

তারপরে আপনারঅ্যাক্টিভিটিস রেজাল্ট () এ, আপনি ব্যবহারকারী-বাছাই করা উরিটিকে নতুন ডকুমেন্টফিল সহায়ক শ্রেণিতে পাস করতে পারেন। এখানে একটি দ্রুত উদাহরণ রয়েছে যা বাছাই করা ডিরেক্টরিতে ফাইলগুলি তালিকাভুক্ত করে এবং তারপরে একটি নতুন ফাইল তৈরি করে:

public void onActivityResult(int requestCode, int resultCode, Intent resultData) {
    if (resultCode == RESULT_OK) {
        Uri treeUri = resultData.getData();
        DocumentFile pickedDir = DocumentFile.fromTreeUri(this, treeUri);

        // List all existing files inside picked directory
        for (DocumentFile file : pickedDir.listFiles()) {
            Log.d(TAG, "Found file " + file.getName() + " with size " + file.length());
        }

        // Create a new file and write into it
        DocumentFile newFile = pickedDir.createFile("text/plain", "My Novel");
        OutputStream out = getContentResolver().openOutputStream(newFile.getUri());
        out.write("A long time ago...".getBytes());
        out.close();
    }
}

উরি ফিরে এসেছে DocumentFile.getUri()মে বিভিন্ন প্ল্যাটফর্ম এপিআই সহ ব্যবহারের জন্য যথেষ্ট নমনীয়। উদাহরণস্বরূপ, যদি আপনি এটি ব্যবহার ভাগ পারে Intent.setData()সঙ্গে Intent.FLAG_GRANT_READ_URI_PERMISSION

আপনি যদি উরিটি স্থানীয় কোড থেকে অ্যাক্সেস করতে চান তবে আপনি কল করতে পারেন ContentResolver.openFileDescriptor()এবং তারপরে একটি traditionalতিহ্যবাহী POSIX ফাইল বিবরণকারী পূর্ণসংখ্যা ব্যবহার করতে ParcelFileDescriptor.getFd()বা detachFd()পেতে পারেন ।

আপনি ফাইল / ফোল্ডার অ্যাক্সেস করতে পারবেন কিনা তা কীভাবে পরীক্ষা করবেন?

ডিফল্টরূপে, ইউরিস স্টোরেজ অ্যাক্সেস ফ্রেমওয়ার্কগুলির মাধ্যমে ফিরে আসে রিবুটগুলি জুড়ে স্থির থাকে না । প্ল্যাটফর্মটি অনুমতি অব্যাহত রাখার ক্ষমতা "অফার করে", তবে আপনার যদি এটি চান তবে অনুমতিটি "নেওয়া" দরকার। আমাদের উপরের উদাহরণে, আপনি কল করবেন:

    getContentResolver().takePersistableUriPermission(treeUri,
            Intent.FLAG_GRANT_READ_URI_PERMISSION |
            Intent.FLAG_GRANT_WRITE_URI_PERMISSION);

আপনার অ্যাপ্লিকেশনটির কী কী অনুদান মঞ্জুর করে তা ContentResolver.getPersistedUriPermissions()API এর মাধ্যমে অ্যাক্সেস করতে পারে তা আপনি সর্বদা নির্ধারণ করতে পারেন । যদি আপনার আর স্থায়ী উরির অ্যাক্সেসের প্রয়োজন না হয় তবে আপনি এটির সাথে এটি প্রকাশ করতে পারেন ContentResolver.releasePersistableUriPermission()

এটি কিটক্যাট এ পাওয়া যায়?

না, আমরা প্রত্যাহার করে প্ল্যাটফর্মের পুরানো সংস্করণগুলিতে নতুন কার্যকারিতা যুক্ত করতে পারি না।

অ্যাপ্লিকেশনগুলির ফাইল / ফোল্ডারে অ্যাক্সেস রয়েছে তা আমি দেখতে পাচ্ছি?

বর্তমানে এটির কোনও ইউআই নেই যা এটি দেখায়, তবে আপনি adb shell dumpsys activity providersআউটপুট "মঞ্জুরিপ্রাপ্ত উরি অনুমতি" বিভাগে বিশদটি পেতে পারেন ।

যদি কোনও অ্যাপ্লিকেশন একই ডিভাইসে একাধিক ব্যবহারকারীর জন্য ইনস্টল করা থাকে তবে কী হবে?

অন্যান্য সমস্ত মাল্টি-ইউজার প্ল্যাটফর্মের কার্যকারিতার মতোই ইউরি অনুমতি অনুদানগুলি প্রতি ব্যবহারকারী ভিত্তিতে পৃথক করা হয়। অর্থাত, দুটি ভিন্ন ব্যবহারকারীর অধীনে চলমান একই অ্যাপটির ওভারল্যাপিং বা ভাগ করা উরি অনুমতি অনুদান নেই।

অনুমতিগুলি কি বাতিল করা যাবে?

ব্যাকিং ডকুমেন্টপ্রোভাডার যে কোনও সময় অনুমতি বাতিল করতে পারে যেমন মেঘ-ভিত্তিক নথি মুছে ফেলা হয়। এই বাতিল হওয়া অনুমতিগুলি আবিষ্কার করার সর্বাধিক সাধারণ উপায় হ'ল যখন তারা ContentResolver.getPersistedUriPermissions()উপরে বর্ণিত থেকে অদৃশ্য হয়ে যায় ।

অনুদানের সাথে জড়িত যে কোনও অ্যাপের জন্য অ্যাপ্লিকেশন ডেটা সাফ হয়ে গেলে অনুমতিও বাতিল করা হয় rev

কোনও নির্বাচিত ফোল্ডারে পুনরাবৃত্তভাবে অনুমতি কাজ করার জন্য জিজ্ঞাসা করবেন?

হ্যাঁ, ACTION_OPEN_DOCUMENT_TREEঅভিপ্রায়টি আপনাকে বিদ্যমান এবং সদ্য নির্মিত ফাইল এবং ডিরেক্টরি উভয় ক্ষেত্রে পুনরাবৃত্ত অ্যাক্সেস দেয়।

এটি কি একাধিক নির্বাচনের অনুমতি দেয়?

হ্যাঁ, কিটক্যাট থেকে একাধিক নির্বাচনকে সমর্থন করা হয়েছে এবং আপনি EXTRA_ALLOW_MULTIPLEআপনার ACTION_OPEN_DOCUMENTঅভিপ্রায় শুরু করার সময় সেটিংস স্থাপনের মাধ্যমে অনুমতি দিতে পারেন । আপনি যে ধরণের ফাইল বেছে নিতে পারেন তা ব্যবহার করতে Intent.setType()বা EXTRA_MIME_TYPESসংকীর্ণ করতে পারেন:

http://developer.android.com/reference/android/content/Intent.html#ACTION_OPEN_DOCUMENT

এমুলেটরটিতে নতুন এপিআই চেষ্টা করার কোনও উপায় আছে?

হ্যাঁ, প্রাথমিক ভাগ করা স্টোরেজ ডিভাইসটি চয়নকারীতে এমনকি এমুলেটরটিতে উপস্থিত হওয়া উচিত। আপনার অ্যাপ্লিকেশন শুধুমাত্র শেয়ার জমার ব্যবহার করার জন্য সংগ্রহস্থল অ্যাক্সেস ফ্রেমওয়ার্ক ব্যবহার করে, আপনি আর প্রয়োজন READ/WRITE_EXTERNAL_STORAGEঅনুমতি এ সব করতে এবং তাদের সরাতে বা ব্যবহার করতে পারেন android:maxSdkVersionএকমাত্র পুরোনো প্ল্যাটফর্ম সংস্করণের উপর তাদের অনুরোধ বৈশিষ্ট্য।

যখন ব্যবহারকারী এসডি-কার্ডকে অন্য একটিতে প্রতিস্থাপন করেন তখন কী হবে?

যখন শারীরিক মিডিয়া জড়িত থাকে, অন্তর্নিহিত মিডিয়াগুলির ইউআইডি (যেমন FAT ক্রমিক সংখ্যা) সর্বদা ফিরে আসা উড়িতে পোড়া হয়। ব্যবহারকারী একাধিক স্লটের মাঝামাঝি সময়ে মিডিয়াটিকে অদলবদল করলেও সিস্টেমটি আপনাকে ব্যবহারকারীকে প্রাথমিকভাবে নির্বাচিত মিডিয়াগুলির সাথে সংযোগ করতে ব্যবহার করে।

ব্যবহারকারী যদি দ্বিতীয় কার্ডে অদলবদল করে, আপনাকে নতুন কার্ডটিতে অ্যাক্সেস পেতে প্রম্পট করতে হবে। যেহেতু সিস্টেমটি প্রতি ইউআইডি ভিত্তিতে অনুদানগুলি স্মরণ করে, তাই ব্যবহারকারী যদি পরে এটি পুনরায় জমা দেয় তবে আপনি মূল কার্ডটিতে পূর্বে মঞ্জুর করা চালিয়ে যেতে পারবেন।

http://en.wikipedia.org/wiki/Volume_serial_number


2
আমি দেখি. সুতরাং সিদ্ধান্তটি ছিল যে পরিচিত এপিআই-তে আরও যুক্ত করার পরিবর্তে (ফাইলের) একটি আলাদা ব্যবহার করুন। ঠিক আছে. আপনি দয়া করে অন্যান্য প্রশ্নের উত্তর দিতে পারেন (প্রথম মন্তব্যে লেখা)? বিটিডাব্লু, এই সমস্ত উত্তর দেওয়ার জন্য আপনাকে ধন্যবাদ।
অ্যান্ড্রয়েড বিকাশকারী

7
@ জেফশার্কি কোনও প্রারম্ভিক অবস্থানের ইঙ্গিতটি দিয়ে OPEN_DOCUMENT_TREE সরবরাহ করার কোনও উপায়? অ্যাপ্লিকেশনটিতে অ্যাক্সেসের প্রয়োজনের জন্য নেভিগেট করতে ব্যবহারকারীরা সর্বদা সেরা নন।
জাস্টিন 0

2
কোনও উপায় আছে কীভাবে, সর্বশেষ পরিবর্তিত টাইমস্ট্যাম্প ( ফাইল ক্লাসে সেটলাস্টমোডিফায়েড () পদ্ধতি পরিবর্তন করবেন )? সংরক্ষণাগারের মতো অ্যাপ্লিকেশনগুলির জন্য এটি সত্যই মৌলিক।
কোয়ার্ক

1
বলুন যে আপনার কাছে একটি সঞ্চিত ফোল্ডার নথি উরি রয়েছে এবং আপনি ডিভাইস পুনরায় বুট করার পরে কোনও সময়ে ফাইলগুলি তালিকাভুক্ত করতে চান। ডকুমেন্টফিল.ফ্রমেট্রিউরি সর্বদা মূল ফাইলগুলি তালিকাভুক্ত করে, আপনি যতটা উরি (তা এমনকি শিশু উরি) দেন না কেন, আপনি কীভাবে একটি ডকুমেন্টফিল তৈরি করবেন যেখানে আপনি লিস্টফায়ালগুলিতে কল করতে পারেন, যেখানে ডকুমেন্ট ফাইল কোনও রুট বা সিঙ্গলডোকামেন্টের সম্মোহিত নয়।
AndersC

1
@ জেফশার্কি এই ইউআরআই মিডিয়াম্যাক্সারে কীভাবে ব্যবহার করা যায়, যেহেতু এটি একটি স্ট্রিং আউটপুট ফাইলের পথ হিসাবে গ্রহণ করে? মিডিয়াম্যাক্সার (java.lang.String, int
পেট্রাকিয়াস

45

নীচে লিঙ্কিত গিথুবের আমার অ্যান্ড্রয়েড প্রজেক্টে আপনি এমন একটি কার্যকরী কোড পাবেন যা অ্যান্ড্রয়েড 5 এ ExtSdCard এ লিখতে দেয় It এটি ধরে নেওয়া হয় যে ব্যবহারকারী পুরো এসডি কার্ডটিতে অ্যাক্সেস দেয় এবং তারপরে আপনাকে এই কার্ডের যে কোনও জায়গায় লিখতে দেয়। (আপনি যদি কেবল একক ফাইলগুলিতে অ্যাক্সেস পেতে চান তবে জিনিসগুলি সহজ হয়ে যায়))

প্রধান কোড স্নিপলেট

স্টোরেজ অ্যাক্সেস ফ্রেমওয়ার্ক ট্রিগার করা:

@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private void triggerStorageAccessFramework() {
    Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
    startActivityForResult(intent, REQUEST_CODE_STORAGE_ACCESS);
}

স্টোরেজ অ্যাক্সেস ফ্রেমওয়ার্ক থেকে প্রতিক্রিয়া পরিচালনা করছে:

@TargetApi(Build.VERSION_CODES.LOLLIPOP)
@Override
public final void onActivityResult(final int requestCode, final int resultCode, final Intent resultData) {
    if (requestCode == SettingsFragment.REQUEST_CODE_STORAGE_ACCESS) {
        Uri treeUri = null;
        if (resultCode == Activity.RESULT_OK) {
            // Get Uri from Storage Access Framework.
            treeUri = resultData.getData();

            // Persist URI in shared preference so that you can use it later.
            // Use your own framework here instead of PreferenceUtil.
            PreferenceUtil.setSharedPreferenceUri(R.string.key_internal_uri_extsdcard, treeUri);

            // Persist access permissions.
            final int takeFlags = resultData.getFlags()
                & (Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
            getActivity().getContentResolver().takePersistableUriPermission(treeUri, takeFlags);
        }
    }
}

স্টোরেজ অ্যাক্সেস ফ্রেমওয়ার্কের মাধ্যমে কোনও ফাইলের জন্য আউটপুট স্ট্রিম পাওয়া (সঞ্চিত ইউআরএল ব্যবহার করা, এটি বাহ্যিক এসডি কার্ডের মূল ফোল্ডারের URL বলে ধরে নেওয়া)

DocumentFile targetDocument = getDocumentFile(file, false);
OutputStream outStream = Application.getAppContext().
    getContentResolver().openOutputStream(targetDocument.getUri());

এটি নিম্নলিখিত সহায়ক পদ্ধতি ব্যবহার করে:

public static DocumentFile getDocumentFile(final File file, final boolean isDirectory) {
    String baseFolder = getExtSdCardFolder(file);

    if (baseFolder == null) {
        return null;
    }

    String relativePath = null;
    try {
        String fullPath = file.getCanonicalPath();
        relativePath = fullPath.substring(baseFolder.length() + 1);
    }
    catch (IOException e) {
        return null;
    }

    Uri treeUri = PreferenceUtil.getSharedPreferenceUri(R.string.key_internal_uri_extsdcard);

    if (treeUri == null) {
        return null;
    }

    // start with root of SD card and then parse through document tree.
    DocumentFile document = DocumentFile.fromTreeUri(Application.getAppContext(), treeUri);

    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 String getExtSdCardFolder(final File file) {
    String[] extSdPaths = getExtSdCardPaths();
    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;
}

/**
 * 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() {
    List<String> paths = new ArrayList<>();
    for (File file : Application.getAppContext().getExternalFilesDirs("external")) {
        if (file != null && !file.equals(Application.getAppContext().getExternalFilesDir("external"))) {
            int index = file.getAbsolutePath().lastIndexOf("/Android/data");
            if (index < 0) {
                Log.w(Application.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.
                }
                paths.add(path);
            }
        }
    }
    return paths.toArray(new String[paths.size()]);
}

 /**
 * Retrieve the application context.
 *
 * @return The (statically stored) application context
 */
public static Context getAppContext() {
    return Application.mApplication.getApplicationContext();
}

সম্পূর্ণ কোডের রেফারেন্স

https://github.com/jeisfeld/Augendiagnose/blob/master/AugendiagnoseIdea/augendiagnoseLib/src/main/java/de/jeisfeld/augendiagnoselib/fragments/SettingsFragment.java#L521

এবং

https://github.com/jeisfeld/Augendiagnose/blob/master/AugendiagnoseIdea/augendiagnoseLib/src/main/java/de/jeisfeld/augendiagnoselib/util/imagefile/FileUtil.java


1
আপনি কি দয়া করে এটি একটি ন্যূনতম প্রকল্পে রাখতে পারেন, এটি কেবল এসডি-কার্ড পরিচালনা করে? এছাড়াও, আপনি কি জানেন যে আমি কীভাবে যাচাই করতে পারি যে সমস্ত বাহ্যিক স্টোরগুলি পাওয়া যায় যেগুলি অ্যাক্সেসযোগ্য, যাতে আমি কোনও কিছুর জন্য তাদের অনুমতি প্রার্থনা করব না?
অ্যান্ড্রয়েড বিকাশকারী 19

1
আশা করি আমি এই আরও upvote করতে পারে। আমি এই সমাধানে অর্ধেক হয়ে গিয়েছিলাম এবং ডকুমেন্ট নেভিগেশনটি এত ভয়াবহ পেয়েছি যে আমি ভেবেছিলাম যে আমি এটি ভুল করছি। এ সম্পর্কে কিছু নিশ্চিত হওয়া ভাল। ধন্যবাদ গুগল ... কিছুই না বলে।
অ্যান্টনি

1
হ্যাঁ, বাহ্যিক এসডিতে লেখার জন্য আপনি আর সাধারণ ফাইল পদ্ধতির ব্যবহার করতে পারবেন না। অন্যদিকে, পুরানো অ্যান্ড্রয়েড সংস্করণ এবং প্রাথমিক এসডির জন্য, ফাইল এখনও সর্বাধিক দক্ষ পদ্ধতির। সুতরাং আপনার ফাইল অ্যাক্সেসের জন্য একটি কাস্টম ইউটিলিটি ক্লাস ব্যবহার করা উচিত।
জার্গ আইজফিল্ড

15
@ জার্গইফিল্ড: আমার কাছে একটি অ্যাপ রয়েছে যা File254 বার ব্যবহার করে । আপনি কি তা ঠিক করতে পারবেন ?? অ্যান্ড্রয়েড এর পিছনে সামঞ্জস্যের মোট অভাব নিয়ে ডেভসের জন্য দুঃস্বপ্ন হয়ে উঠছে। বাহ্যিক স্টোরেজ সম্পর্কিত গুগল কেন এই সমস্ত বোকা সিদ্ধান্ত নিয়েছিল তা তারা ব্যাখ্যা করার কোনও জায়গা আমি এখনও পাইনি। কিছু দাবি করে "সুরক্ষা", তবে অবশ্যই কোনও বোকামি কারণ কোনও অ্যাপ্লিকেশন অভ্যন্তরীণ স্টোরেজকে গোলযোগ করতে পারে। আমার অনুমান হ'ল আমাদের তাদের ক্লাউড পরিষেবাগুলি ব্যবহার করতে বাধ্য করার চেষ্টা করা। ধন্যবাদ, রুটিং সমস্যার সমাধান করে ... কমপক্ষে অ্যান্ড্রয়েড <6 .... এর জন্য
লুইস এ ফ্লোরিট

1
ঠিক আছে. ম্যাজিকালি, আমি আমার ফোনটি পুনরায় চালু করার পরে এটি কাজ করে :)
sancho21

0

এটি কেবলমাত্র পরিপূরক উত্তর।

আপনি একটি নতুন ফাইল তৈরি করার পরে আপনার নিজের অবস্থানটি আপনার ডাটাবেসে সংরক্ষণ করতে এবং এটি আগামীকাল পড়তে হতে পারে। আপনি এই পদ্ধতিটি ব্যবহার করে এটি পুনরুদ্ধার করতে পারেন:

/**
 * Get {@link DocumentFile} object from SD card.
 * @param directory SD card ID followed by directory name, for example {@code 6881-2249:Download/Archive},
 *                 where ID for SD card is {@code 6881-2249}
 * @param fileName for example {@code intel_haxm.zip}
 * @return <code>null</code> if does not exist
 */
public static DocumentFile getExternalFile(Context context, String directory, String fileName){
    Uri uri = Uri.parse("content://com.android.externalstorage.documents/tree/" + directory);
    DocumentFile parent = DocumentFile.fromTreeUri(context, uri);
    return parent != null ? parent.findFile(fileName) : null;
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == SettingsFragment.REQUEST_CODE_STORAGE_ACCESS && resultCode == RESULT_OK) {
        int takeFlags = Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION;
        getContentResolver().takePersistableUriPermission(data.getData(), takeFlags);
        String sdcard = data.getDataString().replace("content://com.android.externalstorage.documents/tree/", "");
        try {
            sdcard = URLDecoder.decode(sdcard, "ISO-8859-1");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        // for example, sdcardId results "6312-2234"
        String sdcardId = sdcard.substring(0, sdcard.indexOf(':'));
        // save to preferences if you want to use it later
        SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
        preferences.edit().putString("sdcard", sdcardId).apply();
    }
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.