কীভাবে প্রোগ্রামে অ্যান্ড্রয়েডে স্ক্রিনশট নেবেন?


494

আমি কোনও প্রোগ্রামের মাধ্যমে নয়, কোড থেকে ফোন-স্ক্রিনের নির্বাচিত অঞ্চলের স্ক্রিনশট নিতে পারি?


4
এমুলেটর থেকে নয়। আমাকে আমার প্রোগ্রামের অংশের স্ক্রিনশট তৈরি করতে হবে এবং এটি একই প্রোগ্রামে স্মার্ট করতে হবে।
korovisdead

1
আরেকটি ভাল রেফারেন্স: stackoverflow.com/a/10296881/439171
ইতালো Borssatto

উত্তর:


447

এখানে কোডটি যা আমার স্ক্রিনশটটি একটি এসডি কার্ডে সঞ্চয় করতে দেয় এবং আপনার যা প্রয়োজন তা পরে ব্যবহার করা হয়:

প্রথমত, ফাইলটি সংরক্ষণ করার জন্য আপনাকে একটি উপযুক্ত অনুমতি যুক্ত করতে হবে:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

এবং এটি কোড (একটি ক্রিয়াকলাপে চলছে):

private void takeScreenshot() {
    Date now = new Date();
    android.text.format.DateFormat.format("yyyy-MM-dd_hh:mm:ss", now);

    try {
        // image naming and path  to include sd card  appending name you choose for file
        String mPath = Environment.getExternalStorageDirectory().toString() + "/" + now + ".jpg";

        // create bitmap screen capture
        View v1 = getWindow().getDecorView().getRootView();
        v1.setDrawingCacheEnabled(true);
        Bitmap bitmap = Bitmap.createBitmap(v1.getDrawingCache());
        v1.setDrawingCacheEnabled(false);

        File imageFile = new File(mPath);

        FileOutputStream outputStream = new FileOutputStream(imageFile);
        int quality = 100;
        bitmap.compress(Bitmap.CompressFormat.JPEG, quality, outputStream);
        outputStream.flush();
        outputStream.close();

        openScreenshot(imageFile);
    } catch (Throwable e) {
        // Several error may come out with file handling or DOM
        e.printStackTrace();
    }
}

এবং এভাবেই আপনি সম্প্রতি তৈরি হওয়া চিত্রটি খুলতে পারেন:

private void openScreenshot(File imageFile) {
    Intent intent = new Intent();
    intent.setAction(Intent.ACTION_VIEW);
    Uri uri = Uri.fromFile(imageFile);
    intent.setDataAndType(uri, "image/*");
    startActivity(intent);
}

আপনি যদি টুকরো টুকরোতে এটি ব্যবহার করতে চান তবে ব্যবহার করুন:

View v1 = getActivity().getWindow().getDecorView().getRootView();

পরিবর্তে

View v1 = getWindow().getDecorView().getRootView();

উপর takeScreenshot () ফাংশন

দ্রষ্টব্য :

আপনার ডায়লগটিতে কোনও পৃষ্ঠের দৃশ্য ধারণ করা থাকলে এই সমাধানটি কাজ করে না। বিস্তারিত জানার জন্য নীচের প্রশ্নের উত্তর চেক করুন:

সারফেস ভিউয়ের অ্যান্ড্রয়েড টেক স্ক্রিনশটটি কালো স্ক্রিন দেখায়


23
হাই, আপনি কী বর্ণনা করতে পারবেন এমকন্টেনআরআলমাস্ক? আমি এই কোডটি চেষ্টা করেছি তবে এটি আমাকে সর্বদা বিটম্যাপ.ক্রেটবিটম্যাপ (v1.getDrawingCache ()) এ নলপয়েন্টারএক্সসেপশন দিচ্ছে, কেউ কি বলতে পারে যে আমি কী ভুল করছি? কোন সাহায্য প্রশংসা করা হয়। ধন্যবাদ।
মিতেশ সরধারা

4
@ মিতেশসারধারা mCurrentUrlMaskঅবশ্যই একটি Viewঅ্যান্ড্রয়েড এপিআইয়ের অনন্য শ্রেণি হতে হবে যা getRootView()পদ্ধতি রয়েছে। সম্ভবত ইউআই-তে একটি দৃশ্য।
জিপি

6
আপনি কি দয়া করে আমাকে বলতে পারবেন, এমক্রেনআরআলমাস্ক কী?
জয়েশকুমার সোজিত্রা

37
ইনসটেড View v1 = mCurrentUrlMask.getRootView();আমি ব্যবহার করেছি View v1 = getWindow().getDecorView().getRootView();এবং এটি আমার পক্ষে কাজ করে।
এনাডুন

9
এই উত্তরটি কেবল অ্যাপ্লিকেশনটির স্ক্রিনশট নেয় - প্রশ্নে জিজ্ঞাসা করা "ফোন স্ক্রিন" নয় - বা আমি কিছু ভুল করছি doing
অ্যালিকেলজিন-কিলাকা

126

আপনি যেটির স্ক্রিন শট চান তার বহিরাগত ভিউগ্রুপে এই পদ্ধতিটি কল করুন:

public Bitmap screenShot(View view) {
    Bitmap bitmap = Bitmap.createBitmap(view.getWidth(),
            view.getHeight(), Config.ARGB_8888);
    Canvas canvas = new Canvas(bitmap);
    view.draw(canvas);
    return bitmap;
}

9
এটি গ্রহণযোগ্য উত্তরের চেয়ে ক্লিনার কোড বলে মনে হচ্ছে। এটিও পারফর্ম করে?
জোফদে

2
আমি এটি কয়েকটি ভিন্ন অ্যাপগুলিতে কিছুক্ষণ ব্যবহার করেছি এবং কোনও সমস্যা হয়নি।
জাস্টিনমরিস

3
আপনি যদি ফোনের স্ক্রিনশট পেতে চান যেখানে আপনার অ্যাপটি ব্যাকগ্রাউন্ডে রয়েছে, আপনি কী হিসাবে পাস করবেন view? `
অলিকএলজিন-কিলাকা

2
getWindow().getDecorView().getRootView()দৃশ্য হিসাবে পাস করার ফলে কেবল অ্যাপ্লিকেশনটির স্ক্রিনশট নেওয়ার ফলাফল পাওয়া যায় - স্ক্রিনটি নয়।
অ্যালিকেলজিন-কিলাকা

এই উত্তরটি কেবল অ্যাপ্লিকেশনটির স্ক্রিনশট নেয় - প্রশ্নে জিজ্ঞাসা করা "ফোন স্ক্রিন" নয় - বা আমি কিছু ভুল করছি doing
অ্যালিকেলজিন-কিলাকা

42

দ্রষ্টব্য: কেবল রুটযুক্ত ফোনের জন্যই কাজ করে

প্রোগ্রামক্রমে, আপনি adb shell /system/bin/screencap -p /sdcard/img.pngনীচের হিসাবে চালাতে পারেন

Process sh = Runtime.getRuntime().exec("su", null,null);
OutputStream os = sh.getOutputStream();
os.write(("/system/bin/screencap -p " + "/sdcard/img.png").getBytes("ASCII"));
os.flush();
os.close();
sh.waitFor();    

তারপর পড়া img.pngযেমন Bitmapএবং আপনার ইচ্ছা ব্যবহার করুন।


এটিতে কি রুট অ্যাক্সেস দরকার?
জুম 9

3
হ্যাঁ আপনার রুট অ্যাক্সেস দরকার। দয়া করে শিরোনামে
নোটটি দেখুন

হাই, আমি পেয়েছি System.err : java.io.IOException: Error running exec(). Command: [su] Working Directory: null Environment: null , আমার ডিভাইসটি অ্যান্ড্রয়েড 5.0
এডি

@ এডি এটি আপনার ডিভাইসের উপর নির্ভর করে
ডেমিয়ান

ফলাফলটি ফাইলে না সঞ্চয় করে আউটপুট সরাসরি পড়ার উপায় কি আবার তা পড়ে? stackoverflow.com/questions/43914035
ইয়াজান ডাব্লু ইউসুফ

35

সম্পাদনা: নিম্নবিত্তদের সাথে দয়া করুন। 2010 সালে আমি প্রশ্নের উত্তর দিয়েছিলাম যখন এটি সত্য ছিল।

সমস্ত প্রোগ্রাম যা স্ক্রিনশটগুলি কেবল রুট ফোনগুলিতে কাজ করে on


দেখে মনে হচ্ছে আজকাল টেগ্রা ভিত্তিক চিপসেট সহ অ্যান্ড্রয়েডগুলিতে এটি সম্ভব
জিডিআর

4.0.3 - তারপরে এটি সম্ভবত এই নতুন বিদ্যালয়ের টেগ্রা ট্যাবলেটগুলির মধ্যে একটি
জিডিআর

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

2
কড়া কথায় বলতে গেলে, রুট এডিবির "শেল" ব্যবহারকারীর অ্যাকাউন্টের সাথে সর্বদা এটি করার অনুমতি ছিল কারণ এটি ব্যবহারের ক্ষেত্রে ছিল। Historতিহাসিকভাবে যা উপলভ্য ছিল না (ভুল হিসাবে মাঝে মাঝে বিল্ড ব্যতীত) অ্যাপ্লিকেশন ব্যবহারকারী আইডি এর পক্ষে এটি করার একটি উপায় ছিল was
ক্রিস স্ট্রাটন

26

এই পদ্ধতির জন্য কোনও রুটের অনুমতি বা কোনও বড় কোডিং প্রয়োজন নেই।


নীচে কমান্ডটি ব্যবহার করে অ্যাডবি শেলটিতে আপনি স্ক্রিন শট নিতে পারেন।

input keyevent 120

আপনি এই অ্যান্ড্রয়েড অ্যাপ্লিকেশন জাভা কোড থেকে সঞ্চালন করতে পারেন তাই এই আদেশের কোনও রুট অনুমতি প্রয়োজন হয় না।

Process process;
process = Runtime.getRuntime().exec("input keyevent 120");

অ্যান্ড্রয়েডে কীভেন্ট কোড সম্পর্কে আরও দেখুন http://developer.android.com/references/android/view/KeyEvent.html

এখানে আমরা ব্যবহার করেছি। KEYCODE_SYSRQ এর মান 120 এবং সিস্টেম অনুরোধ / মুদ্রণ স্ক্রিন কী জন্য ব্যবহৃত হয়।


সিজেবিএস যেমন বলেছে, আউটপুট ছবিটি / এসডিকার্ড / ছবি / স্ক্রিনশটগুলিতে সংরক্ষণ করা হবে


আউটপুট ছবি এখানে সংরক্ষণ করা হবে:/sdcard/Pictures/Screenshots
সিজেবিএস

এটির জন্য কি রুট অনুমতি প্রয়োজন ??
তারানমিত সিং

1
এটি মার্শমেলোতে কাজ করবে? বা এটি পরিষেবা পটভূমিতে কাজ করবে @ জাইগারপ্যাটেল
করণতওয়াল.github.io

2
প্রোগ্রামগতভাবে কাজ করে না, তবে শেল থেকে কাজ করে। নওগাট দিয়ে চেষ্টা করলেন।
mehmet6parmak

1
su -c "input keyevent 120"ঠিক আছে !!
ipcjs

17

মুলিগ উত্তরটি খুব ভাল, তবে আমার একই সমস্যা ছিল ইওকস বর্ণনা করেছেন, আমি পটভূমি পাচ্ছি না। তাই কখনও কখনও যথেষ্ট ভাল এবং কখনও কখনও আমি কালো ব্যাকগ্রাউন্ড (থিম উপর নির্ভর করে) কালো টেক্সট পেতে।

এই সমাধানটি ভারীভাবে মুলিগের কোড এবং কোডটি রোবোটিয়ামে খুঁজে পেয়েছি। আমি অঙ্কন পদ্ধতিতে সরাসরি কল করে অঙ্কন ক্যাশে ব্যবহার বাতিল করছি। এর আগে আমি বর্তমান ক্রিয়াকলাপটি প্রথম অঙ্কনের জন্য পটভূমিটি অঙ্কনীয় করার চেষ্টা করব।

// Some constants
final static String SCREENSHOTS_LOCATIONS = Environment.getExternalStorageDirectory().toString() + "/screenshots/";

// Get device dimmensions
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);

// Get root view
View view = mCurrentUrlMask.getRootView();

// Create the bitmap to use to draw the screenshot
final Bitmap bitmap = Bitmap.createBitmap(size.x, size.y, Bitmap.Config.ARGB_4444);
final Canvas canvas = new Canvas(bitmap);

// Get current theme to know which background to use
final Activity activity = getCurrentActivity();
final Theme theme = activity.getTheme();
final TypedArray ta = theme
    .obtainStyledAttributes(new int[] { android.R.attr.windowBackground });
final int res = ta.getResourceId(0, 0);
final Drawable background = activity.getResources().getDrawable(res);

// Draw background
background.draw(canvas);

// Draw views
view.draw(canvas);

// Save the screenshot to the file system
FileOutputStream fos = null;
try {
    final File sddir = new File(SCREENSHOTS_LOCATIONS);
    if (!sddir.exists()) {
        sddir.mkdirs();
    }
    fos = new FileOutputStream(SCREENSHOTS_LOCATIONS
            + System.currentTimeMillis() + ".jpg");
    if (fos != null) {
        if (!bitmap.compress(Bitmap.CompressFormat.JPEG, 90, fos)) {
            Log.d(LOGTAG, "Compress/Write failed");
        }
        fos.flush();
        fos.close();
    }

} catch (FileNotFoundException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
} catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}

আমার অ্যান্ড্রয়েডের সাথে আমার একটি লিভিউভিউ রয়েছে: আমার ক্রিয়াকলাপে ক্যাশে কালারহিন্ট = "# 00000000", এবং আমি এই কোডটি স্ক্রিনশটটিতে ব্যবহার করি, আমি এখনও একটি কালো পটভূমি পেয়েছি কারণ আমি খুঁজে পেয়েছি যে থিম থেকে প্রাপ্ত পটভূমিটি কালো, আমি কীভাবে এটি মোকাবেলা করতে পারি? তালিকা দেখুন?
ওয়াংচাও 077

ক্রিয়াকলাপ ক্রিয়াকলাপ = getCurrentActivity ইরোরকে অপরিজ্ঞাত পদ্ধতি প্রদান করে।
শাব্বির ধনগোট

17
private void captureScreen() {
    View v = getWindow().getDecorView().getRootView();
    v.setDrawingCacheEnabled(true);
    Bitmap bmp = Bitmap.createBitmap(v.getDrawingCache());
    v.setDrawingCacheEnabled(false);
    try {
        FileOutputStream fos = new FileOutputStream(new File(Environment
                .getExternalStorageDirectory().toString(), "SCREEN"
                + System.currentTimeMillis() + ".png"));
        bmp.compress(CompressFormat.PNG, 100, fos);
        fos.flush();
        fos.close();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

ম্যানিফেস্টে অনুমতি যুক্ত করুন

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

মার্শমালো বা উপরের সংস্করণগুলিকে সমর্থন করার জন্য দয়া করে ক্রিয়াকলাপের ক্রিয়াকলাপ পদ্ধতিতে নীচের কোডটি যুক্ত করুন

ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},00);

প্রয়োজনীয়: <ব্যবহার-অনুমতি অ্যান্ড্রয়েড: নাম = "android.permission.WRITE_EXTERNAL_STORAGE" />
অ্যান্ড্রয়েডগুই

4
এই উত্তরটি কেবল অ্যাপ্লিকেশনটির স্ক্রিনশট গ্রহণ করে - প্রশ্নে "ফোন স্ক্রিন" নয় - বা আমি কিছু ভুল করছি?
অ্যালিকেলজিন-কিলাকা

আমার কী যদি তালিকার আইটেমের স্ক্রিনশট প্রয়োজন?
আনশুল তায়াগি

আমি অ্যাডাপ্টারের কাছ থেকে কোনও ধারণা পেতে চাই যে আমি এটি কীভাবে করতে পারি?
গভীর ডেভ

16

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

আমি পরীক্ষিত বেশ কয়েকটি ডিভাইস থেকে প্রতিটি ফ্রেমবফার ক্যাপচারে ঠিক থাকে contained একটি স্ক্রিনশট রয়েছে। লোকেরা এটি আরও বেশি রাখার জন্য রিপোর্ট করেছে, আমার ধারণা এটি ফ্রেম / ডিসপ্লে আকারের উপর নির্ভর করে।

আমি ধারাবাহিকভাবে ফ্রেমবফারটি পড়ার চেষ্টা করেছি তবে মনে হয় এটি নির্দিষ্ট পরিমাণ বাইট পড়েছে return আমার ক্ষেত্রে এটি (3 410 432) বাইট, যা 854 * 480 আরজিবিএ (3 279 360 বাইট) এর ডিসপ্লে ফ্রেম সংরক্ষণ করার জন্য যথেষ্ট। হ্যাঁ, ফ্রেম, বাইনারি মধ্যে, fb0 থেকে outputted হয় RGBA আমার ডিভাইস হবে। এটি সম্ভবত ডিভাইস থেকে ডিভাইসে নির্ভর করবে। এটি আপনার ডিকোড করা গুরুত্বপূর্ণ হবে =)

আমার ডিভাইসে / ডিভ / গ্রাফিক্স / এফবি0 অনুমতিগুলি কেবল যাতে গ্রাফিক গ্রাফিক্সের মূল এবং ব্যবহারকারীরা fb0 পড়তে পারে।

গ্রাফিক্স একটি সীমাবদ্ধ গোষ্ঠী তাই আপনি সম্ভবত কেবল কমান্ড ব্যবহার করে একটি রুট ফোন দিয়ে fb0 অ্যাক্সেস করতে পারবেন।

অ্যান্ড্রয়েড অ্যাপ্লিকেশনগুলিতে ব্যবহারকারী আইডি (uid) = অ্যাপ _ ## এবং গ্রুপ আইডি (গাইড) = অ্যাপ _ ## রয়েছে

এডিবি শেল হয়েছে ইউআইডি = শেল এবং GUID = শেল , যা একটি অ্যাপ্লিকেশন তুলনায় আরো অনেক কিছু অনুমতি আছে। আপনি প্রকৃতপক্ষে সেই অনুমতিগুলি / সিস্টেমে / স্পেসিফিকেশন / প্ল্যাটফর্ম.এক্সএমএলে পরীক্ষা করতে পারেন

এর অর্থ আপনি রুট ছাড়াই অ্যাডবি শেল এ fb0 পড়তে সক্ষম হবেন তবে আপনি এটি রুট ছাড়াই অ্যাপের মধ্যে পড়তে পারবেন না।

এছাড়াও, অ্যান্ড্রয়েড ম্যানিফেস্ট.এক্সএমএলে READ_FRAME_BUFFER এবং / অথবা ACCESS_SURFACE_FLINGER অনুমতি দেওয়া কোনও নিয়মিত অ্যাপের জন্য কিছুই করবে না কারণ এগুলি কেবল ' স্বাক্ষর ' অ্যাপ্লিকেশানের জন্য কাজ করবে ।

আরও বিশদের জন্য এই বদ্ধ থ্রেডটিও পরীক্ষা করে দেখুন।


2
এটি কয়েকটি ফোনে কাজ করে?
ক্রিস স্ট্রাটন

15

আমার সমাধানটি হ'ল:

public static Bitmap loadBitmapFromView(Context context, View v) {
    DisplayMetrics dm = context.getResources().getDisplayMetrics(); 
    v.measure(MeasureSpec.makeMeasureSpec(dm.widthPixels, MeasureSpec.EXACTLY),
            MeasureSpec.makeMeasureSpec(dm.heightPixels, MeasureSpec.EXACTLY));
    v.layout(0, 0, v.getMeasuredWidth(), v.getMeasuredHeight());
    Bitmap returnedBitmap = Bitmap.createBitmap(v.getMeasuredWidth(),
            v.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
    Canvas c = new Canvas(returnedBitmap);
    v.draw(c);

    return returnedBitmap;
}

এবং

public void takeScreen() {
    Bitmap bitmap = ImageUtils.loadBitmapFromView(this, view); //get Bitmap from the view
    String mPath = Environment.getExternalStorageDirectory() + File.separator + "screen_" + System.currentTimeMillis() + ".jpeg";
    File imageFile = new File(mPath);
    OutputStream fout = null;
    try {
        fout = new FileOutputStream(imageFile);
        bitmap.compress(Bitmap.CompressFormat.JPEG, 90, fout);
        fout.flush();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        fout.close();
    }
}

চিত্রগুলি বাহ্যিক স্টোরেজ ফোল্ডারে সংরক্ষণ করা হয়।


1
শেষ অবধি আপনার ফাইলআউটপুট স্ট্রিমটি বন্ধ করা উচিত। যদি আপনি এখন ব্যতিক্রমের মুখোমুখি হন তবে স্ট্রিমটি বন্ধ হবে না।
Wotuu

তুমি কী viewযাচ্ছ ImageUtils.loadBitmapFromView(this, view)?
অ্যালিকেলজিন-কিলাকা

1
আপনি কেন v.layout (0, 0, v.getMeasuredWidth (), v.getMeasuredHeight ()) ব্যবহার করেন; ? এর ফলে ভিউ পরিবর্তন হয় না (v)?
সার্জ

11

আপনি নিম্নলিখিত লাইব্রেরিটি চেষ্টা করতে পারেন: http://code.google.com/p/android-screenshot-library/ অ্যান্ড্রয়েড স্ক্রিনশট লাইব্রেরি (এএসএল) রুট অ্যাক্সেস সুবিধাগুলি ছাড়াই অ্যান্ড্রয়েড ডিভাইসগুলি থেকে প্রোগ্রামগতভাবে স্ক্রিনশটগুলি ক্যাপচার করতে সক্ষম করে। পরিবর্তে, এএসএল ব্যাকগ্রাউন্ডে চলমান একটি নেটিভ পরিষেবা ব্যবহার করে, প্রতি ডিভাইস বুটে একবার অ্যান্ড্রয়েড ডিবাগ ব্রিজ (এডিবি) এর মাধ্যমে শুরু হয়েছিল।


1
আমি এটি চেষ্টা করেছিলাম ut তবে এটি কেবল চলমান অ্যাপের স্ক্রিনশট নেয়। আমি হোমস্ক্রিনের স্ক্রিনশট নিতে চাইলে এটির পোষ্য সহায়তা। আপনি কী কোড সহ হোমস্ক্রিনের স্ক্রিনশট নেবেন?
জান্না

1
@ জনার্দনান.এস: এই প্রশ্নটিই জিজ্ঞাসা করছে। আপনি কি আলাদা প্রশ্ন জিজ্ঞাসার পরিবর্তে একটি নতুন উত্তর দিয়ে বিস্তারিত বলতে পারবেন?
ট্র্যাগ্রাগ্লিয়া

3
আমার সাথে একই সমস্যা .. "নেটিভ সার্ভিস চলছে না !!"
যোগেশ মহেশ্বরী

1
আমার সাথে একই "নেটিভ সার্ভিস চলছে না !!" .... কেউ কি এখানে সহায়তা পাঠ্য যুক্ত করতে পারেন?
পঙ্কজ কুমার

1
একই অবস্থা! "নেটিভ সার্ভিস চলছে না !!" এবং তাদের সর্বশেষতম সংস্করণ 1.2 এ তারা উদাহরণস্বরূপ সকেটের মতো এপিআই লেভেল 19 ক্লাস ব্যবহার করে।
ব্যবহারকারী 347187

10

উপরে @ জাস্টিনমরিস এবং @ নীরাভডাঙ্গীর উত্তরের উপর ভিত্তি করে এখানে https://stackoverflow.com/a/8504958/2232148 আমাদের অবশ্যই একটি দৃশ্যের পটভূমি এবং অগ্রভাগ নিতে হবে এবং তাদের এই জাতীয়ভাবে একত্রিত করতে হবে:

public static Bitmap takeScreenshot(View view, Bitmap.Config quality) {
    Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), quality);
    Canvas canvas = new Canvas(bitmap);

    Drawable backgroundDrawable = view.getBackground();
    if (backgroundDrawable != null) {
        backgroundDrawable.draw(canvas);
    } else {
        canvas.drawColor(Color.WHITE);
    }
    view.draw(canvas);

    return bitmap;
}

মানের পরামিতি বিটম্যাপ.কনফিগের একটি ধ্রুবক নেয়, সাধারণত হয় Bitmap.Config.RGB_565বা হয় Bitmap.Config.ARGB_8888


ব্যাকগ্রাউন্ডে সাদা রঙের সাথে ক্যানভাস অঙ্কন আমার পক্ষে কৌশলটি বাতিল করে দিয়েছে। অলিভার ধন্যবাদ
শালীন

8
public class ScreenShotActivity extends Activity{

private RelativeLayout relativeLayout;
private Bitmap myBitmap;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    relativeLayout = (RelativeLayout)findViewById(R.id.relative1);
    relativeLayout.post(new Runnable() {
        public void run() {

            //take screenshot
            myBitmap = captureScreen(relativeLayout);

            Toast.makeText(getApplicationContext(), "Screenshot captured..!", Toast.LENGTH_LONG).show();

            try {
                if(myBitmap!=null){
                    //save image to SD card
                    saveImage(myBitmap);
                }
                Toast.makeText(getApplicationContext(), "Screenshot saved..!", Toast.LENGTH_LONG).show();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }
    });

}

public static Bitmap captureScreen(View v) {

    Bitmap screenshot = null;
    try {

        if(v!=null) {

            screenshot = Bitmap.createBitmap(v.getMeasuredWidth(),v.getMeasuredHeight(), Config.ARGB_8888);
            Canvas canvas = new Canvas(screenshot);
            v.draw(canvas);
        }

    }catch (Exception e){
        Log.d("ScreenShotActivity", "Failed to capture screenshot because:" + e.getMessage());
    }

    return screenshot;
}

public static void saveImage(Bitmap bitmap) throws IOException{

    ByteArrayOutputStream bytes = new ByteArrayOutputStream();
    bitmap.compress(Bitmap.CompressFormat.PNG, 40, bytes);
    File f = new File(Environment.getExternalStorageDirectory() + File.separator + "test.png");
    f.createNewFile();
    FileOutputStream fo = new FileOutputStream(f);
    fo.write(bytes.toByteArray());
    fo.close();
}

}

পারমিশন যুক্ত করুন

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

এই উত্তরটি কেবল অ্যাপ্লিকেশনটির স্ক্রিনশট গ্রহণ করে - প্রশ্নে "ফোন স্ক্রিন" নয় - বা আমি কিছু ভুল করছি?
অ্যালিকেলজিন-কিলাকা

7

আপনি এরকম কিছু করার চেষ্টা করতে পারেন,

বিন্যাস থেকে একটি বিটম্যাপ ক্যাশে পাওয়া বা ভিউয়ের মতো কিছু করে প্রথমে আপনাকে setDrawingCacheEnabledকোনও বিন্যাসে যেতে হবে (লিনিয়ারলআউট বা আপেক্ষিক স্তর বা একটি দৃশ্য)

তারপর

Bitmap bm = layout.getDrawingCache()

তারপরে আপনি যা চান বিটম্যাপটি দিয়ে করুন। হয় এটিকে একটি চিত্র ফাইলে রূপান্তর করুন বা বিটম্যাপের ইউরি অন্য কোথাও প্রেরণ করুন।


1
আপনি যদি কোনও বিটম্যাপে লিখতে থাকেন তবে এটি আপনার অ্যাপ্লিকেশনটি হ'ল এটি সর্বোত্তম পদ্ধতি। এছাড়াও, তালিকা দেখার জন্য ক্যাশে নেওয়ার আগে যে পদ্ধতিগুলিতে বিলম্ব রয়েছে ... এমন বিজ্ঞপ্তি থেকে সাবধান থাকুন ...
ট্রাগ্রগ্লিয়া

শুধু তাই নয় লেআউটটি অবশ্যই প্রথমে স্ক্রিনে প্রদর্শিত হবে। এটি "ক্যাশে" আপনি পুরোপুরি পাচ্ছেন। দৃশ্যটি গোপন করার এবং পটভূমিতে স্ক্রিনশট নেওয়ার চেষ্টা করেছেন (তত্ত্ব অনুসারে), কিন্তু এটি কার্যকর হয়নি।
কেভিন টান

অন্যান্য সমাধানগুলির চেয়ে অনেক বেশি দক্ষতার সাথে
সিভি

6

যারা একটি জিএলসুরফেসভিউ ক্যাপচার করতে চান তাদের জন্য getDrawingCache বা ক্যানভাস পদ্ধতিতে অঙ্কন কাজ করবে না।

ফ্রেমটি রেন্ডার হওয়ার পরে আপনাকে ওপেনজিএল ফ্রেমবফারের সামগ্রীটি পড়তে হবে। এখানে একটি ভাল উত্তর আছে


6

আমি একটি সাধারণ লাইব্রেরি তৈরি করেছি যা একটির থেকে একটি স্ক্রিনশট নেয় Viewএবং আপনাকে একটি বিটম্যাপ অবজেক্ট দেয় বা আপনার যে কোনও পথে সরাসরি সংরক্ষণ করে

https://github.com/abdallahalaraby/Blink


এর জন্য কি রুট ফোন দরকার?
নীলেশ অগ্রওয়াল

1
কোনও মূল প্রয়োজন নেই :)
আবদুল্লাহ আলারাবি

ব্যবহারের ক্ষেত্রে আপনি উল্লেখ করেছেন Screenshot.takeScreenshot(view, mPath); imageView.setImageBitmap(Screenshot.getBitmapScreenshot(view, mPath)); কীভাবে বর্তমান ক্রিয়াকলাপটি দেখুন। আমি এক্সএমএল এর আইডি ব্যবহার করতে চাই না।
নীলেশ অগ্রওয়াল

takeScreenshotForScreen()পরিবর্তে ব্যবহার করুন।
আবদুল্লাহ আলারাবি


5

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

    // Storage Permissions
private static final int REQUEST_EXTERNAL_STORAGE = 1;
private static String[] PERMISSIONS_STORAGE = {
        Manifest.permission.READ_EXTERNAL_STORAGE,
        Manifest.permission.WRITE_EXTERNAL_STORAGE
};

private void verifyStoragePermissions() {
    // Check if we have write permission
    int permission = ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE);

    if (permission != PackageManager.PERMISSION_GRANTED) {
        // We don't have permission so prompt the user
        ActivityCompat.requestPermissions(this, PERMISSIONS_STORAGE, REQUEST_EXTERNAL_STORAGE);
    }else{
        takeScreenshot();
    }
}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);

    if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
        if (requestCode == REQUEST_EXTERNAL_STORAGE) {
            takeScreenshot();
        }
    }
}

এবং অ্যান্ড্রয়েড ম্যানিফেস্ট.এক্সএমএল ফাইলটিতে নিম্নলিখিত প্রবেশদ্বারগুলি অবশ্যই:

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

4

আপনি যদি এটি fragment অনুসরণ করার চেয়ে স্ক্রিনশট নিতে চান তবে :

  1. ওভাররাইড onCreateView():

             @Override
            public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                     Bundle savedInstanceState) {
                // Inflate the layout for this fragment
                View view = inflater.inflate(R.layout.fragment_one, container, false);
                mView = view;
            }
  2. স্ক্রিনশট নেওয়ার জন্য যুক্তি:

     button.setOnClickListener(new View.OnClickListener() {
     @Override
     public void onClick(View v) {
         View view =  mView.findViewById(R.id.scrollView1);
          shareScreenShotM(view, (NestedScrollView) view); 
     }
  3. পদ্ধতি shareScreenShotM)():

    public void shareScreenShotM(View view, NestedScrollView scrollView){
    
         bm = takeScreenShot(view,scrollView);  //method to take screenshot
        File file = savePic(bm);  // method to save screenshot in phone.
        }
  4. পদ্ধতিটি স্ক্রিনশট ():

             public Bitmap takeScreenShot(View u, NestedScrollView z){
    
                u.setDrawingCacheEnabled(true);
                int totalHeight = z.getChildAt(0).getHeight();
                int totalWidth = z.getChildAt(0).getWidth();
    
                Log.d("yoheight",""+ totalHeight);
                Log.d("yowidth",""+ totalWidth);
                u.layout(0, 0, totalWidth, totalHeight);
                u.buildDrawingCache();
                Bitmap b = Bitmap.createBitmap(u.getDrawingCache());
                u.setDrawingCacheEnabled(false);
                u.destroyDrawingCache();
                 return b;
            }
  5. পদ্ধতি সেভপিক ():

     public static File savePic(Bitmap bm){
    
            ByteArrayOutputStream bytes = new ByteArrayOutputStream();
            bm.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
             File sdCardDirectory =  new File(Environment.getExternalStorageDirectory() + "/Foldername");
    
           if (!sdCardDirectory.exists()) {
                sdCardDirectory.mkdirs();
          }
           //  File file = new File(dir, fileName);
          try {
             file = new File(sdCardDirectory, Calendar.getInstance()
                .getTimeInMillis() + ".jpg");
            file.createNewFile();
            new FileOutputStream(file).write(bytes.toByteArray());
            Log.d("Fabsolute", "File Saved::--->" + file.getAbsolutePath());
             Log.d("Sabsolute", "File Saved::--->" + sdCardDirectory.getAbsolutePath());
         } catch (IOException e) {
              e.printStackTrace();
          }
         return file;
       }

ক্রিয়াকলাপের জন্য আপনি কেবল View v1 = getWindow().getDecorView().getRootView();পরিবর্তে ব্যবহার করতে পারেনmView


3

এই প্রশ্নের উত্তরগুলির বেশিরভাগটি Canvasঅঙ্কন পদ্ধতি বা অঙ্কন ক্যাশে পদ্ধতি ব্যবহার করে। তবে, View.setDrawingCache()পদ্ধতিটি এপিআই 28-এ অবমূল্যায়ন করা হয়েছে । বর্তমানে স্ক্রিনশট তৈরির জন্য প্রস্তাবিত এপিআই হ'ল PixelCopyএপিআই 24 থেকে উপলব্ধ ক্লাস (তবে যে Windowপ্যারামিটারগুলি গ্রহণ করে সেগুলি এপিআই 26 == অ্যান্ড্রয়েড 8.0 ওরিও থেকে পাওয়া যায়)। এখানে পুনরুদ্ধারের জন্য একটি নমুনা কোটলিন কোড Bitmap:

@RequiresApi(Build.VERSION_CODES.O)
fun saveScreenshot(view: View) {
    val window = (view.context as Activity).window
    if (window != null) {
        val bitmap = Bitmap.createBitmap(view.width, view.height, Bitmap.Config.ARGB_8888)
        val locationOfViewInWindow = IntArray(2)
        view.getLocationInWindow(locationOfViewInWindow)
        try {
            PixelCopy.request(window, Rect(locationOfViewInWindow[0], locationOfViewInWindow[1], locationOfViewInWindow[0] + view.width, locationOfViewInWindow[1] + view.height), bitmap, { copyResult ->
                if (copyResult == PixelCopy.SUCCESS) {
                    saveBitmap(bitmap)
                }
                // possible to handle other result codes ...
            }, Handler())
        } catch (e: IllegalArgumentException) {
            // PixelCopy may throw IllegalArgumentException, make sure to handle it
        }
    }
}

অঙ্কনকেশির সমাধানের মাধ্যমে পিক্সেলকপি নিয়ে সমস্যা হ'ল এটি কেবল দৃশ্যমান পিক্সেলটি ক্যাপচার বলে মনে হচ্ছে। বাকিটা আমার জন্য কালো। সুতরাং যে জিনিসটি স্ক্রোলযোগ্য এবং আংশিক ফ্রেমের বাইরে রয়েছে সেগুলি ভাগ করা সম্ভব নয়। আপনি কি এই জন্য একটি সমাধান আছে?
হেনিং

তুমি ঠিক. একইভাবে এটি সমস্যার সৃষ্টি করতে পারে যদি আমি স্ক্রিনশটটি দেখতে চাই (যেমন ড্রয়ারটি খোলা থাকে) এর উপরে অন্য ভিউটি দেখানো হয়। এই ক্ষেত্রে আমি কেবল পুরানো ক্যানভাস পদ্ধতিটি ব্যবহার করি :(
মিলিও আর্নিলোভস্ক

1
পিক্সেলকপি ব্যবহার করে কোনও চলমান অ্যাপে স্ক্রিনশট নেওয়া কি সম্ভব?
আমির রেজায়ে

2

কেবলমাত্র সিস্টেম অ্যাপ্লিকেশনগুলির জন্য!

Process process;
process = Runtime.getRuntime().exec("screencap -p " + outputPath);
process.waitFor();

দ্রষ্টব্য: এই কমান্ডটি কার্যকর করতে সিস্টেম অ্যাপ্লিকেশনগুলিকে "su" চালানোর দরকার নেই।


2

প্যারামিটার ভিউ হ'ল মূল বিন্যাস বস্তু।

public static Bitmap screenShot(View view) {
                    Bitmap bitmap = null;
                    if (view.getWidth() > 0 && view.getHeight() > 0) {
                        bitmap = Bitmap.createBitmap(view.getWidth(),
                                view.getHeight(), Bitmap.Config.ARGB_8888);
                        Canvas canvas = new Canvas(bitmap);
                        view.draw(canvas);
                    }
                    return bitmap;
                }

2

পূর্ণ পৃষ্ঠা স্ক্রোলিং স্ক্রিনশট জন্য

আপনি যদি একটি সম্পূর্ণ ভিউ স্ক্রিনশট ক্যাপচার করতে চান (যার মধ্যে একটি স্ক্রোলভিউ বা তাই রয়েছে) তবে এই লাইব্রেরিতে একটি পরীক্ষা করে দেখুন

https://github.com/peter1492/LongScreenshot

আপনাকে যা করতে হবে তা হ'ল গ্রেডেল আমদানি করা, এবং বিগস্ক্রিনশটটির একটি অবজেক্ট তৈরি করা

BigScreenshot longScreenshot = new BigScreenshot(this, x, y);

স্ক্রিন ভিউ গ্রুপের মাধ্যমে স্বয়ংক্রিয়ভাবে স্ক্রোল করার সময় এবং শেষে একত্রে একত্রিত হয়ে নেওয়া স্ক্রিনশটগুলির বিটম্যাপের সাথে একটি কলব্যাক পাবেন।

@Override public void getScreenshot(Bitmap bitmap) {}

যা গ্যালারিতে সংরক্ষণ করা যেতে পারে বা যা ব্যবহারের পরে প্রয়োজন


1

অ্যান্ড্রয়েডে একটি দৃশ্যের স্ক্রিনশট নিন।

public static Bitmap getViewBitmap(View v) {
    v.clearFocus();
    v.setPressed(false);

    boolean willNotCache = v.willNotCacheDrawing();
    v.setWillNotCacheDrawing(false);

    int color = v.getDrawingCacheBackgroundColor();
    v.setDrawingCacheBackgroundColor(0);

    if (color != 0) {
        v.destroyDrawingCache();
    }
    v.buildDrawingCache();
    Bitmap cacheBitmap = v.getDrawingCache();
    if (cacheBitmap == null) {
        return null;
    }

    Bitmap bitmap = Bitmap.createBitmap(cacheBitmap);

    v.destroyDrawingCache();
    v.setWillNotCacheDrawing(willNotCache);
    v.setDrawingCacheBackgroundColor(color);

    return bitmap;
}

-1

আপনি যদি রিলেটিভলআউট বা লিনিয়ারলআউট ইত্যাদির মতো কোনও ভিউ বা লেআউট ক্যাপচার করতে চান তবে কেবল কোডটি ব্যবহার করুন:

LinearLayout llMain = (LinearLayout) findViewById(R.id.linearlayoutMain);
Bitmap bm = loadBitmapFromView(llMain);

এখন আপনি এই বিটম্যাপটি ডিভাইস স্টোরেজে সংরক্ষণ করতে পারবেন:

FileOutputStream outStream = null;
File f=new File(Environment.getExternalStorageDirectory()+"/Screen Shots/");
f.mkdir();
String extStorageDirectory = f.toString();
File file = new File(extStorageDirectory, "my new screen shot");
pathOfImage = file.getAbsolutePath();
try {
    outStream = new FileOutputStream(file);
    bm.compress(Bitmap.CompressFormat.PNG, 100, outStream);
    Toast.makeText(getApplicationContext(), "Saved at "+f.getAbsolutePath(), Toast.LENGTH_LONG).show();
    addImageGallery(file);
    //mail.setEnabled(true);
    flag=true;
} catch (FileNotFoundException e) {e.printStackTrace();}
try {
    outStream.flush();
    outStream.close();
} catch (IOException e) {e.printStackTrace();}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.