আইওএক্সেপশন: পঠন ব্যর্থ হয়েছে, সকেট বন্ধ হতে পারে - অ্যান্ড্রয়েডে ব্লুটুথ ৪.৩


101

বর্তমানে আমি অ্যান্ড্রয়েড ৪.৩ দিয়ে আমার নেক্সাস ((২০১২) এ একটি ব্লুটুথসকেট খুলতে গিয়ে একটি অদ্ভুত ব্যতিক্রমটি মোকাবিলার চেষ্টা করছি (জেডব্লিউআর 66 ওয়াই তৈরি করুন, আমি দ্বিতীয় 4.3 আপডেট অনুমান করি)। আমি কিছু সম্পর্কিত পোস্টিং দেখেছি (উদাঃ /programming/13648373/bluetuthsocket-connect-throwing-exception-read-failed ) তবে এই সমস্যার জন্য কোনও কাজই করে নি বলে মনে হয় না। এছাড়াও, এই থ্রেডগুলিতে যেমন পরামর্শ দেওয়া হয়েছে, পুনরায় জোড় দেওয়া কোনও উপকারে আসে না এবং অবিচ্ছিন্নভাবে সংযোগ দেওয়ার চেষ্টা করে (একটি নির্বোধ লুপের মাধ্যমে) এরও কোনও প্রভাব থাকে না।

আমি একটি এম্বেড থাকা ডিভাইসটির সাথে কাজ করছি ( http://images04.olx.com/ui/15/53/76/1316534072_254254776_2-OBD-II-BLUTOOTH-ADAPTERSCLEAR-CHECK-ENGINE- আপনার ফোনের সাথে আলোকসজ্জা - Oceanside.jpg )। আমার অ্যান্ড্রয়েড ২.৩..7 ফোনে সংযোগ স্থাপনে কোনও সমস্যা নেই এবং সহকর্মীর এক্সপিরিয়া (অ্যান্ড্রয়েড ৪.১.২) এছাড়াও কাজ করে। অন্য একটি গুগল নেক্সাস ('ওয়ান' বা 'এস' তবে '4' নয় তবে আমি জানি না) এছাড়াও অ্যান্ড্রয়েড 4.3 এ ব্যর্থ হয়।

এখানে সংযোগ স্থাপনার স্নিপেট। এটি একটি সার্ভিসে তৈরি করা নিজস্ব থ্রেডে চলছে।

private class ConnectThread extends Thread {

    private static final UUID EMBEDDED_BOARD_SPP = UUID
        .fromString("00001101-0000-1000-8000-00805F9B34FB");

    private BluetoothAdapter adapter;
    private boolean secure;
    private BluetoothDevice device;
    private List<UUID> uuidCandidates;
    private int candidate;
    protected boolean started;

    public ConnectThread(BluetoothDevice device, boolean secure) {
        logger.info("initiliasing connection to device "+device.getName() +" / "+ device.getAddress());
        adapter = BluetoothAdapter.getDefaultAdapter();
        this.secure = secure;
        this.device = device;

        setName("BluetoothConnectThread");

        if (!startQueryingForUUIDs()) {
            this.uuidCandidates = Collections.singletonList(EMBEDDED_BOARD_SPP);
            this.start();
        } else{
            logger.info("Using UUID discovery mechanism.");
        }
        /*
         * it will start upon the broadcast receive otherwise
         */
    }

    private boolean startQueryingForUUIDs() {
        Class<?> cl = BluetoothDevice.class;

        Class<?>[] par = {};
        Method fetchUuidsWithSdpMethod;
        try {
            fetchUuidsWithSdpMethod = cl.getMethod("fetchUuidsWithSdp", par);
        } catch (NoSuchMethodException e) {
            logger.warn(e.getMessage());
            return false;
        }

        Object[] args = {};
        try {
            BroadcastReceiver receiver = new BroadcastReceiver() {
                @Override
                public void onReceive(Context context, Intent intent) {
                    BluetoothDevice deviceExtra = intent.getParcelableExtra("android.bluetooth.device.extra.DEVICE");
                    Parcelable[] uuidExtra = intent.getParcelableArrayExtra("android.bluetooth.device.extra.UUID");

                    uuidCandidates = new ArrayList<UUID>();
                    for (Parcelable uuid : uuidExtra) {
                        uuidCandidates.add(UUID.fromString(uuid.toString()));
                    }

                    synchronized (ConnectThread.this) {
                        if (!ConnectThread.this.started) {
                            ConnectThread.this.start();
                            ConnectThread.this.started = true;
                            unregisterReceiver(this);
                        }

                    }
                }

            };
            registerReceiver(receiver, new IntentFilter("android.bleutooth.device.action.UUID"));
            registerReceiver(receiver, new IntentFilter("android.bluetooth.device.action.UUID"));

            fetchUuidsWithSdpMethod.invoke(device, args);
        } catch (IllegalArgumentException e) {
            logger.warn(e.getMessage());
            return false;
        } catch (IllegalAccessException e) {
            logger.warn(e.getMessage());
            return false;
        } catch (InvocationTargetException e) {
            logger.warn(e.getMessage());
            return false;
        }           

        return true;
    }

    public void run() {
        boolean success = false;
        while (selectSocket()) {

            if (bluetoothSocket == null) {
                logger.warn("Socket is null! Cancelling!");
                deviceDisconnected();
                openTroubleshootingActivity(TroubleshootingActivity.BLUETOOTH_EXCEPTION);
            }

            // Always cancel discovery because it will slow down a connection
            adapter.cancelDiscovery();

            // Make a connection to the BluetoothSocket
            try {
                // This is a blocking call and will only return on a
                // successful connection or an exception
                bluetoothSocket.connect();
                success = true;
                break;

            } catch (IOException e) {
                // Close the socket
                try {
                    shutdownSocket();
                } catch (IOException e2) {
                    logger.warn(e2.getMessage(), e2);
                }
            }
        }

        if (success) {
            deviceConnected();
        } else {
            deviceDisconnected();
            openTroubleshootingActivity(TroubleshootingActivity.BLUETOOTH_EXCEPTION);
        }
    }

    private boolean selectSocket() {
        if (candidate >= uuidCandidates.size()) {
            return false;
        }

        BluetoothSocket tmp;
        UUID uuid = uuidCandidates.get(candidate++);
        logger.info("Attempting to connect to SDP "+ uuid);
        try {
            if (secure) {
                tmp = device.createRfcommSocketToServiceRecord(
                        uuid);
            } else {
                tmp = device.createInsecureRfcommSocketToServiceRecord(
                        uuid);
            }
            bluetoothSocket = tmp;
            return true;
        } catch (IOException e) {
            logger.warn(e.getMessage() ,e);
        }

        return false;
    }

}

কোডটি ব্যর্থ হচ্ছে bluetoothSocket.connect()। আমি একটি পেয়ে যাচ্ছি java.io.IOException: read failed, socket might closed, read ret: -1। এটি গীতহাবের সংশ্লিষ্ট উত্স: গীতহাবের https://github.com/android/platform_frameworks_base/blob/android-4.3_r2/core/java/android/bluetuth/BluetuthSket.java#L504 এটি https থেকে আহ্বান করা হয়েছে রিডআইন্ট () এর মাধ্যমে বলা হয় : //github.com/android / প্ল্যাটফর্ম_ফ্রেম ওয়ার্কস_বেস / ব্লব / অ্যান্ড্রয়েড ৪.৩_আর ২ / স্কোর / জাভা / অ্যান্ড্রয়েড / ব্লুথুথ / ব্লুথুথসকেট.জভা#L319

ব্যবহৃত সকেটের কিছু মেটাডেটা ডাম্পের ফলে নিম্নলিখিত তথ্যের ফলস্বরূপ। এগুলি Nexus 7 এবং আমার 2.3.7 ফোনে ঠিক একই রকম।

Bluetooth Device 'OBDII'
Address: 11:22:33:DD:EE:FF
Bond state: 12 (bonded)
Type: 1
Class major version: 7936
Class minor version: 7936
Class Contents: 0
Contents: 0

আমার কাছে অন্য কিছু ওবিডি -২ অ্যাডাপ্টার রয়েছে (আরও বিস্তৃত) এবং সেগুলি সব কাজ করে। এমন কি কোনও সুযোগ আছে যে আমি কিছু মিস করছি বা এটি অ্যান্ড্রয়েডে কোনও বাগ থাকতে পারে?


আমি উপরের সমাধান চেষ্টা করেছি, এই বিষয়ে সাহায্য sombody করতে stackoverflow.com/q/52105647/1559331
dileepVikram

উত্তর:


131

আমি অবশেষে একটি workaround খুঁজে পেয়েছি। ম্যাজিকটি BluetoothDeviceক্লাসের আড়ালে লুকানো আছে ( https://github.com/android/platform_frameworks_base/blob/android-4.3_r2/core/java/android/bluetuth/BluetuthDevice.java#L1037 দেখুন )।

এখন, আমি যখন এই ব্যতিক্রমটি পাই, আমি BluetoothSocketনীচের উত্স কোডের মতো একটি ফ্যালব্যাক ইনস্ট্যান্ট করি । যেমন আপনি দেখতে পাচ্ছেন, createRfcommSocketপ্রতিচ্ছবিটির মাধ্যমে লুকানো পদ্ধতিটি চাওয়া। এই পদ্ধতিটি কেন গোপন রয়েছে তা সম্পর্কে আমার কোনও ধারণা নেই। উত্স কোডটি এটিকে এমনভাবে সংজ্ঞায়িত করেছে public...

Class<?> clazz = tmp.getRemoteDevice().getClass();
Class<?>[] paramTypes = new Class<?>[] {Integer.TYPE};

Method m = clazz.getMethod("createRfcommSocket", paramTypes);
Object[] params = new Object[] {Integer.valueOf(1)};

fallbackSocket = (BluetoothSocket) m.invoke(tmp.getRemoteDevice(), params);
fallbackSocket.connect();

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

হালনাগাদ:

এখানে একটি সম্পূর্ণ ক্লাস, কিছু নেস্টেড ক্লাস রয়েছে। বাস্তব বাস্তবায়নের জন্য এগুলি পৃথক শ্রেণি হিসাবে অনুষ্ঠিত হতে পারে।

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Method;
import java.util.List;
import java.util.UUID;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.util.Log;

public class BluetoothConnector {

    private BluetoothSocketWrapper bluetoothSocket;
    private BluetoothDevice device;
    private boolean secure;
    private BluetoothAdapter adapter;
    private List<UUID> uuidCandidates;
    private int candidate;


    /**
     * @param device the device
     * @param secure if connection should be done via a secure socket
     * @param adapter the Android BT adapter
     * @param uuidCandidates a list of UUIDs. if null or empty, the Serial PP id is used
     */
    public BluetoothConnector(BluetoothDevice device, boolean secure, BluetoothAdapter adapter,
            List<UUID> uuidCandidates) {
        this.device = device;
        this.secure = secure;
        this.adapter = adapter;
        this.uuidCandidates = uuidCandidates;

        if (this.uuidCandidates == null || this.uuidCandidates.isEmpty()) {
            this.uuidCandidates = new ArrayList<UUID>();
            this.uuidCandidates.add(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));
        }
    }

    public BluetoothSocketWrapper connect() throws IOException {
        boolean success = false;
        while (selectSocket()) {
            adapter.cancelDiscovery();

            try {
                bluetoothSocket.connect();
                success = true;
                break;
            } catch (IOException e) {
                //try the fallback
                try {
                    bluetoothSocket = new FallbackBluetoothSocket(bluetoothSocket.getUnderlyingSocket());
                    Thread.sleep(500);                  
                    bluetoothSocket.connect();
                    success = true;
                    break;  
                } catch (FallbackException e1) {
                    Log.w("BT", "Could not initialize FallbackBluetoothSocket classes.", e);
                } catch (InterruptedException e1) {
                    Log.w("BT", e1.getMessage(), e1);
                } catch (IOException e1) {
                    Log.w("BT", "Fallback failed. Cancelling.", e1);
                }
            }
        }

        if (!success) {
            throw new IOException("Could not connect to device: "+ device.getAddress());
        }

        return bluetoothSocket;
    }

    private boolean selectSocket() throws IOException {
        if (candidate >= uuidCandidates.size()) {
            return false;
        }

        BluetoothSocket tmp;
        UUID uuid = uuidCandidates.get(candidate++);

        Log.i("BT", "Attempting to connect to Protocol: "+ uuid);
        if (secure) {
            tmp = device.createRfcommSocketToServiceRecord(uuid);
        } else {
            tmp = device.createInsecureRfcommSocketToServiceRecord(uuid);
        }
        bluetoothSocket = new NativeBluetoothSocket(tmp);

        return true;
    }

    public static interface BluetoothSocketWrapper {

        InputStream getInputStream() throws IOException;

        OutputStream getOutputStream() throws IOException;

        String getRemoteDeviceName();

        void connect() throws IOException;

        String getRemoteDeviceAddress();

        void close() throws IOException;

        BluetoothSocket getUnderlyingSocket();

    }


    public static class NativeBluetoothSocket implements BluetoothSocketWrapper {

        private BluetoothSocket socket;

        public NativeBluetoothSocket(BluetoothSocket tmp) {
            this.socket = tmp;
        }

        @Override
        public InputStream getInputStream() throws IOException {
            return socket.getInputStream();
        }

        @Override
        public OutputStream getOutputStream() throws IOException {
            return socket.getOutputStream();
        }

        @Override
        public String getRemoteDeviceName() {
            return socket.getRemoteDevice().getName();
        }

        @Override
        public void connect() throws IOException {
            socket.connect();
        }

        @Override
        public String getRemoteDeviceAddress() {
            return socket.getRemoteDevice().getAddress();
        }

        @Override
        public void close() throws IOException {
            socket.close();
        }

        @Override
        public BluetoothSocket getUnderlyingSocket() {
            return socket;
        }

    }

    public class FallbackBluetoothSocket extends NativeBluetoothSocket {

        private BluetoothSocket fallbackSocket;

        public FallbackBluetoothSocket(BluetoothSocket tmp) throws FallbackException {
            super(tmp);
            try
            {
              Class<?> clazz = tmp.getRemoteDevice().getClass();
              Class<?>[] paramTypes = new Class<?>[] {Integer.TYPE};
              Method m = clazz.getMethod("createRfcommSocket", paramTypes);
              Object[] params = new Object[] {Integer.valueOf(1)};
              fallbackSocket = (BluetoothSocket) m.invoke(tmp.getRemoteDevice(), params);
            }
            catch (Exception e)
            {
                throw new FallbackException(e);
            }
        }

        @Override
        public InputStream getInputStream() throws IOException {
            return fallbackSocket.getInputStream();
        }

        @Override
        public OutputStream getOutputStream() throws IOException {
            return fallbackSocket.getOutputStream();
        }


        @Override
        public void connect() throws IOException {
            fallbackSocket.connect();
        }


        @Override
        public void close() throws IOException {
            fallbackSocket.close();
        }

    }

    public static class FallbackException extends Exception {

        /**
         * 
         */
        private static final long serialVersionUID = 1L;

        public FallbackException(Exception e) {
            super(e);
        }

    }
}

4
কি দারুন! দুর্দান্ত সমাধান!
ববস

4
@ এমডি আমি জানি না কীভাবে। আমি সবেমাত্র পরীক্ষা করে দেখেছি এটি কাজ করছে।
ববস

4
এটি নেক্সাস 4 এ কাজ করে না আপনি কীভাবে এই সমস্যাটি কাটিয়ে উঠবেন তা দয়া করে বলতে পারেন। আমি প্রায় সব চেষ্টা করেছি। ধন্যবাদ
শাহ

4
@ ম্যাটেস বলার জন্য দুঃখিত তবে আপনার ফ্যালব্যাক ব্যবহারের সমাধানটিও আমার সমস্যার সমাধান করতে পারেনি। ত্রুটি নীচে পেতে। Fallback failed. Cancelling. java.io.IOException: Connection refused সাহায্য করুন.
তুষার বানে

4
@ ম্যাথস "এসপিপি-ডিভাইস (প্লাগ অফ / প্লাগ ইন) এ জাতীয় ক্ষেত্রে সহায়তা করে।" অন ​​/ অফ স্টেটমেন্টটি বিশ্বের সর্বাধিক আন্ডাররেটেড। আমি শুধু 3 ঘন্টা নষ্ট এবং সমস্ত আমি কি ছিল এটি চালু এবং বন্ধ -_- ছিল
Adz

99

ঠিক আছে, আমার কোডটি নিয়ে আমারও একই সমস্যা ছিল এবং এটি কারণ অ্যান্ড্রয়েড 4..২ ব্লুটুথ স্ট্যাক পরিবর্তিত হয়েছে। সুতরাং আমার কোডটি অ্যান্ড্রয়েড <4.2 এর সাথে ডিভাইসগুলিতে দুর্দান্ত চলছে, অন্যান্য ডিভাইসে আমি বিখ্যাত ব্যতিক্রম পেয়ে যাচ্ছিলাম "পড়া ব্যর্থ হয়েছে, সকেটটি বন্ধ হতে পারে বা সময়সীমা শেষ হতে পারে, রিট: -1" পড়ুন

সমস্যাটি socket.mPortপরামিতি নিয়ে with আপনি যখন সকেট ব্যবহার করে তৈরি socket = device.createRfcommSocketToServiceRecord(SERIAL_UUID);করেন mPort, তখন পূর্ণসংখ্যার মান " -1 " পায় এবং এই মানটি অ্যান্ড্রয়েড> = 4.2 এর জন্য কাজ করে না বলে মনে হয়, তাই আপনাকে এটি " 1 " এ সেট করতে হবে । খারাপ খবরটি হ'ল createRfcommSocketToServiceRecordকেবল ইউইউডিটিকে প্যারামিটার হিসাবে গ্রহণ করে এবং নাmPort ইউইউডিটিকে তাই যাতে আমাদের অন্যান্য অ্যাপ্রোচ ব্যবহার করতে হয়। @ ম্যাথসের পোস্ট করা উত্তরটিও আমার পক্ষে কাজ করেছিল, তবে আমি এটিকে সহজ করে দিয়েছি:socket =(BluetoothSocket) device.getClass().getMethod("createRfcommSocket", new Class[] {int.class}).invoke(device,1); . আমাদের দুটি সকেট অ্যাপ্রিবি ব্যবহার করা দরকার, দ্বিতীয়টি ফ্যালব্যাক হিসাবে।

সুতরাং কোডটি (কোনও ELM327 ডিভাইসে একটি এসপিপিতে সংযুক্ত হওয়ার জন্য):

BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter();

    if (btAdapter.isEnabled()) {
        SharedPreferences prefs_btdev = getSharedPreferences("btdev", 0);
        String btdevaddr=prefs_btdev.getString("btdevaddr","?");

        if (btdevaddr != "?")
        {
            BluetoothDevice device = btAdapter.getRemoteDevice(btdevaddr);

            UUID SERIAL_UUID = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb"); // bluetooth serial port service
            //UUID SERIAL_UUID = device.getUuids()[0].getUuid(); //if you don't know the UUID of the bluetooth device service, you can get it like this from android cache

            BluetoothSocket socket = null;

            try {
                socket = device.createRfcommSocketToServiceRecord(SERIAL_UUID);
            } catch (Exception e) {Log.e("","Error creating socket");}

            try {
                socket.connect();
                Log.e("","Connected");
            } catch (IOException e) {
                Log.e("",e.getMessage());
                try {
                    Log.e("","trying fallback...");

                    socket =(BluetoothSocket) device.getClass().getMethod("createRfcommSocket", new Class[] {int.class}).invoke(device,1);
                    socket.connect();

                    Log.e("","Connected");
                }
             catch (Exception e2) {
                 Log.e("", "Couldn't establish Bluetooth connection!");
              }
            }
        }
        else
        {
            Log.e("","BT device not selected");
        }
    }

58
মডারেটরদের জন্য: যেহেতু আপনি আমার পূর্ববর্তী উত্তরটি বিনা কারণে মুছে ফেলেছেন, তাই আমি এটি আবার পোস্ট করি।
জর্জ ডিমা

4
mPortপ্যারামিটার অন্তর্দৃষ্টি জন্য জর্জ ধন্যবাদ ! imho কর্মপ্রবাহ একই থাকে, আমি কেবল কিছু ইন্টারফেস প্রয়োগ করে ক্লাস দিয়ে জিনিসগুলিকে আবৃত করি।
ম্যাথস

4
হ্যাঁ, আমি ইতিমধ্যে বলেছি যে আপনার সমাধানটি ভাল ছিল, তবে আমি কেন এন্ড্রয়েড ৪.২ দিয়ে এই পদ্ধতির ব্যবহার করা দরকার তা মানুষকে বোঝাতে চেয়েছিলাম
জর্জ ডিমা

4
এসপিপি = সিরিয়াল পোর্ট প্রোফাইল (এটি ব্লুটুথের উপর একটি সিরিয়াল পোর্ট অনুকরণ করে) এবং ELM327 হ'ল একটি ব্লুটুথ <-> obd গাড়ি ডিভাইস, এটি গুগল।
জর্জ ডিমা

10
বন্দরটির মান 1 থেকে 2 এ পরিবর্তনের পরে এটি আমার পক্ষে কাজ করেছে দয়া করে এই কোডটি দেখুন। সকেট = (ব্লুটুথসকেট) ডিভাইস.সেটক্লাস ()। getMethod ("createRfcommSket", নতুন শ্রেণি [] .c int.class}) .আলোক (ডিভাইস, 2); সকেট.কনেক্ট ();
দিনেশ আইটি

16

প্রথমত, যদি আপনাকে একটি ব্লুটুথ ২.x ডিভাইসের সাথে কথা বলতে হয়, তবে এই ডকুমেন্টেশনে বলা হয়েছে:

ইঙ্গিত: আপনি যদি একটি ব্লুটুথ সিরিয়াল বোর্ডের সাথে সংযোগ স্থাপন করছেন তবে সুপরিচিত এসপিপি ইউআইডিউ 00001101-0000-1000-8000-00805F9B34FB ব্যবহার করে দেখুন । তবে আপনি যদি কোনও অ্যান্ড্রয়েড পিয়ারের সাথে সংযোগ করছেন তবে দয়া করে আপনার নিজস্ব অনন্য ইউআইডি তৈরি করুন।

আমি ভাবিনি যে এটি কাজ করবে, তবে কেবল 00001101-0000-1000-8000-00805F9B34FBএটির সাথে ইউআইডি প্রতিস্থাপন করে কাজ করে। যাইহোক, এই কোড SDK সংস্করণ সমস্যা হ্যান্ডেল বলে মনে হয়, এবং আপনি শুধু ফাংশন প্রতিস্থাপন করতে পারেন device.createRfcommSocketToServiceRecord(mMyUuid);সঙ্গে tmp = createBluetoothSocket(mmDevice);নিম্নলিখিত পদ্ধতি সংজ্ঞায়িত পরে:

private BluetoothSocket createBluetoothSocket(BluetoothDevice device)
    throws IOException {
    if(Build.VERSION.SDK_INT >= 10){
        try {
            final Method m = device.getClass().getMethod("createInsecureRfcommSocketToServiceRecord", new Class[] { UUID.class });
            return (BluetoothSocket) m.invoke(device, mMyUuid);
        } catch (Exception e) {
            Log.e(TAG, "Could not create Insecure RFComm Connection",e);
        }
    }
    return  device.createRfcommSocketToServiceRecord(mMyUuid);
}

উত্স কোডটি আমার নয়, তবে এই ওয়েবসাইট থেকে এসেছে ।


4
এটি প্রায় 2 দিনের কাজের সমাধান করেছে ... ধন্যবাদ দীর্ঘশ্বাস ... এই ইউইউডি ছাড়া সকেটটি তত্ক্ষণাত বন্ধ হয়ে যায় এবং আরও ব্যাখ্যা ছাড়াই ব্যর্থ হয়ে যায়।
ডেভিড সিনক্লেয়ার

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

8

আমি এখানে বর্ণিত হিসাবে একই লক্ষণ ছিল। আমি একবার ব্লুটুথ প্রিন্টারের সাথে সংযোগ করতে পারি তবে পরবর্তীকালে সংযোগগুলি "সকেট বন্ধ" দিয়ে ব্যর্থ হয়েছিল আমি যাই করুক না কেন।

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

আমি যে সংযুক্ত থ্রেডটি ব্যবহার করি তা এখানে উদাহরণ হিসাবে একই:

http://developer.android.com/guide/topics/ সংযুক্তি / ব্লুথুথ html

নোট করুন যে কানেক্টথ্রেড এবং কানেক্টেড থ্রেড দুটি আলাদা ক্লাস।

কানেক্টেড থ্রেড শুরু করা যাই হোক না কেন ক্লাসটি থ্রেডে অবশ্যই বাধা () এবং বাতিল () করতে হবে। আমি সংযুক্তTread.cancel () পদ্ধতিতে mmInStream.close () এবং mmOutStream.close () যুক্ত করেছি।

থ্রেড / স্ট্রিম / সকেটগুলি সঠিকভাবে বন্ধ করার পরে আমি কোনও সমস্যা ছাড়াই নতুন সকেট তৈরি করতে পারি।


ধন্যবাদ, একই সমস্যা হচ্ছে, শুধু এখন আমি মূর্ত হয়েছিল যে আমি স্ট্রীম এবং সংযোগ ... না বন্ধ ছিল
রাফায়েল

উপরের সমস্ত পরিস্থিতি চেষ্টা করে দেখেছেন, (অন্যান্য যুক্তযুক্ত ডিভাইসগুলি অপসারণ ব্যতীত এটি ভাল কারণ হতে পারে যা হ'ল ... এটি সাধারণত তখন ঘটে যখন ইনপুট স্ট্রিম এবং সকেটগুলি সঠিকভাবে বন্ধ না হয়ে যায় ..... !!
আমান সতীজা

7

ঠিক আছে, আমি আসলে সমস্যাটি খুঁজে পেয়েছি।

বেশিরভাগ লোক যারা ব্যবহার করে সংযোগ স্থাপনের চেষ্টা করেন তাদের socket.Connect();ব্যতিক্রম ডাকে Java.IO.IOException: read failed, socket might closed, read ret: -1

কিছু ক্ষেত্রে এটি আপনার ব্লুটুথ ডিভাইসেও নির্ভর করে, কারণ দুটি ভিন্ন ধরণের ব্লুটুথ রয়েছে, নাম বিএলই (কম শক্তি) এবং ক্লাসিক।

আপনি যদি নিজের ব্লুটুথ ডিভাইসের ধরণটি পরীক্ষা করতে চান তবে কোডটি এখানে:

        String checkType;
        var listDevices = BluetoothAdapter.BondedDevices;
        if (listDevices.Count > 0)
        {
            foreach (var btDevice in listDevices)
            {
                if(btDevice.Name == "MOCUTE-032_B52-CA7E")
                {
                    checkType = btDevice.Type.ToString();
                    Console.WriteLine(checkType);
                }
            }
        }

আমি সমস্যার সমাধান করার জন্য কয়েকদিন চেষ্টা করেছিলাম, কিন্তু আজ থেকে আমি সমস্যাটি খুঁজে পেয়েছি। @ ম্যাথসের সমাধানটি ইতিমধ্যে বলেছেন যে দুর্ভাগ্যক্রমে এখনও কয়েকটি সমস্যা রয়েছে তবে আমার সমাধান এখানে's

এই মুহুর্তে আমি জামারিন অ্যান্ড্রয়েডে কাজ করি তবে এটি অন্যান্য প্ল্যাটফর্মগুলির জন্যও কাজ করা উচিত।

সমাধান

যদি একাধিক জোড়াযুক্ত ডিভাইস থাকে তবে আপনার অন্যান্য যুক্তযুক্ত ডিভাইসগুলি অপসারণ করা উচিত। সুতরাং আপনি যেটি সংযোগ করতে চান তার কেবল একটি রাখুন (সঠিক চিত্রটি দেখুন)।

এখানে চিত্র বর্ণনা লিখুন এখানে চিত্র বর্ণনা লিখুন

বাম চিত্রটিতে আপনি দেখতে পাচ্ছেন যে আমার কাছে দুটি জুটিযুক্ত ডিভাইস রয়েছে, যথা "MOCUTE-032_B52-CA7E" এবং "ব্লু ইজি"। এটাই সমস্যা, তবে কেন সমস্যা হয় তা আমার কোনও ধারণা নেই। সম্ভবত ব্লুটুথ প্রোটোকল অন্য ব্লুটুথ ডিভাইস থেকে কিছু তথ্য নেওয়ার চেষ্টা করছে।

তবে socket.Connect(); কাজগুলি এখনই দুর্দান্ত, কোনও সমস্যা ছাড়াই। সুতরাং আমি কেবল এটি ভাগ করে নিতে চেয়েছিলাম, কারণ ত্রুটিটি সত্যই বিরক্তিকর।

শুভকামনা!


এটি এমন এক ডিভাইসে কাজ করেছে যেখানে আমার এই সমস্যার মুখোমুখি হয়, যা কেবল আমার জন্য 5.0 ফোনে ঘটে এবং তারপরেও আমি যখন প্রথমে বিটি সক্ষম করি, তারপরে একটি সংযোগ খোলাম। বিটি যদি ইতিমধ্যে চালু থাকে তবে কোনও সংযোগ সমস্যা নেই! এটি ডিভাইসগুলিতে অ্যান্ড্রয়েডের পরবর্তী সংস্করণ সহ ঘটে না, এটির প্রস্তাব দিয়ে ডেভসরা বাগটি লক্ষ্য করেছে এবং এটি ঠিক করেছে, তবে অ্যান্ড্রয়েড বিটি পৃষ্ঠা এটি সম্পর্কে একটি শব্দও নেয় না। তবে আপনার সমাধান কাজ করে, ধন্যবাদ!
জন পেরি

7

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

একবার আমি অ্যাডাপ্টারের আবিষ্কার বন্ধের জন্য অপেক্ষা করেছিলাম, তারপরে সকেটে সংযুক্ত কলটি সফল হয়েছিল।


6

আপনি registerReceiver(receiver, new IntentFilter("android.bleutooth.device.action.UUID")); "ব্লুটুথ" বানান "ব্লুথুথ" দিয়ে গেছেন।


5

কোটলিনের সাথে কারও সমস্যা দেখা দিলে আমাকে কিছুটা ভিন্নতা সহ গ্রহণযোগ্য উত্তরটি অনুসরণ করতে হবে:

fun print(view: View, text: String) {
    var adapter = BluetoothAdapter.getDefaultAdapter();
    var pairedDevices = adapter.getBondedDevices()
    var uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB")
    if (pairedDevices.size > 0) {
        for (device in pairedDevices) {
            var s = device.name
            if (device.getName().equals(printerName, ignoreCase = true)) {
                Thread {
                    var socket = device.createInsecureRfcommSocketToServiceRecord(uuid)
                    var clazz = socket.remoteDevice.javaClass
                    var paramTypes = arrayOf<Class<*>>(Integer.TYPE)
                    var m = clazz.getMethod("createRfcommSocket", *paramTypes)
                    var fallbackSocket = m.invoke(socket.remoteDevice, Integer.valueOf(1)) as BluetoothSocket
                    try {
                        fallbackSocket.connect()
                        var stream = fallbackSocket.outputStream
                        stream.write(text.toByteArray(Charset.forName("UTF-8")))
                    } catch (e: Exception) {
                        e.printStackTrace()
                        Snackbar.make(view, "An error occurred", Snackbar.LENGTH_SHORT).show()
                    }
                }.start()
            }
        }
    }
}

আশা করি এটা সাহায্য করবে


3

ব্লুটুথ ডিভাইসগুলি একই সময়ে ক্লাসিক এবং এলইডি উভয় মোডে পরিচালনা করতে পারে। আপনি কোন পথে সংযোগ করছেন তার উপর নির্ভর করে কখনও কখনও তারা আলাদা ম্যাক ঠিকানা ব্যবহার করে। ডাকছেsocket.connect() ব্লুটুথ ক্লাসিক ব্যবহার করা , সুতরাং আপনাকে নিশ্চিত করতে হবে যে আপনি যখন স্ক্যান করেছিলেন তখন যে ডিভাইসটি আপনি পেয়েছিলেন তা সত্যই ক্লাসিক ডিভাইস ছিল।

তবে কেবলমাত্র ক্লাসিক ডিভাইসের জন্য ফিল্টার করা সহজ:

if(BluetoothDevice.DEVICE_TYPE_LE == device.getType()){ //socket.connect() }

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


1

আমিও এই সমস্যার মুখোমুখি হয়েছি, আপনি এটি 2 উপায়ে সমাধান করতে পারেন, যেমন আগে উল্লেখ করা সকেট তৈরির জন্য প্রতিবিম্বটি ব্যবহার করুন দ্বিতীয়টি হ'ল, ক্লায়েন্ট প্রদত্ত ইউআইডির সাথে একটি সার্ভার খুঁজছে এবং যদি আপনার সার্ভার ক্লায়েন্টের সাথে সমান্তরালভাবে চলমান না হয় তবে ঘটে। প্রদত্ত ক্লায়েন্ট ইউআইডি সহ একটি সার্ভার তৈরি করুন এবং তারপরে সার্ভারের পক্ষ থেকে ক্লায়েন্টটি শুনুন এবং গ্রহণ করুন t এটি কাজ করবে।


1

আমি এই সমস্যায় পড়েছি এবং সকেটটি বন্ধ করার আগে ইনপুট এবং আউটপুট স্ট্রিমগুলি বন্ধ করে এটি ঠিক করেছি। এখন আমি সংযোগ বিচ্ছিন্ন করতে এবং কোনও সমস্যা ছাড়াই আবার সংযোগ করতে পারি।

https://stackoverflow.com/a/3039807/5688612

কোটলিনে:

fun disconnect() {
    bluetoothSocket.inputStream.close()
    bluetoothSocket.outputStream.close()
    bluetoothSocket.close()
}

1

যদি আপনার কোডের অন্য একটি অংশ ইতিমধ্যে একই সকেট এবং ইউইউডিটির সাথে সংযোগ তৈরি করে থাকে তবে আপনি এই ত্রুটিটি পান।


0

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


0

আমার এই সমস্যা হয়েছে এবং এর সমাধানটি ছিল বিশেষ যাদু জিইউইডি ব্যবহার করা।

            val id: UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB") // Any other GUID doesn't work.
            val device: BluetoothDevice = bta!!.bondedDevices.first { z -> z.name == deviceName }

            bts = device.createRfcommSocketToServiceRecord(id) // mPort is -1
            bts?.connect()
            // Start processing thread.

আমি সন্দেহ করি যে এটি ইউইউডিগুলি কাজ করে:

var did: Array<ParcelUuid?> = device.uuids

যাইহোক, আমি তাদের সব চেষ্টা করিনি।


এমনকি আমি একই ইউআইডি ব্যবহার করছি। তবে আমাকে সাহায্য করেনি। এটি কি কেবল ক্লাসিক ব্লুটুথ ডিভাইসগুলির সাথে সংযোগ স্থাপনের জন্য সমর্থন করে (বিএলই নয়)? Xamarin.forms ব্যবহার করে BLE ডিভাইসগুলির সাথে সংযোগ করতে আমার কী করতে হবে। এখানে পোস্ট করা হয়েছে [ স্ট্যাকওভারফ্লো.com
শৈলেশ ভট

আমি ক্লাসিক ব্লুটুথ ব্যবহার করছি; BLE আবর্জনা হয়।
রিচার্ড ব্যারাক্লফ

-1

ফিল্টার ক্রিয়া যুক্ত করে আমার সমস্যার সমাধান হয়েছে

 // Register for broadcasts when a device is discovered
    IntentFilter intentFilter = new IntentFilter();
    intentFilter.addAction(BluetoothDevice.ACTION_FOUND);
    intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
    intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
    registerReceiver(mReceiver, intentFilter);

-3

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

তাই আমি আমার প্রতিস্থাপন UUID.fromString("00001001-0000-1000-8000-00805F9B34FB")করতে UUID.fromString("8ce255c0-200a-11e0-ac64-0800200c9a66")এবং এটি সবচেয়ে দৃশ্য কাজ করেন, কেবল কখনও কখনও ব্লুটুথ ডিভাইস পুনরারম্ভ প্রয়োজন;

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.