【问题标题】:How to print a text file using WiFi Direct如何使用 WiFi Direct 打印文本文件
【发布时间】:2017-10-06 14:06:05
【问题描述】:

我有一个可以显示用户统计信息的 Android 应用。我想将纯文本格式 (.txt) 的小报告发送到 WiFi Direct 打印机。我已经从 Android 下载了示例 demo 应用程序。我进行了适当的修改以查找 .txt 文件。但我不明白为什么我的代码不起作用。选择我要打印的文件后,没有任何反应。

下面是我的 EPSON 打印机的当前配置。

  • Wi-Fi 直连模式:开启

  • 通讯模式:AP

  • 工作模式:IEEE802.11g/n

  • 通讯速度:自动

  • SSID:DIRECT-D3A36C54
  • 频道:7
  • 安全级别:WPA2-PSK(AES)

  • 链接状态:未知

这是 DeviceDetailFragment 类

public class DeviceDetailFragment extends Fragment implements WifiP2pManager.ConnectionInfoListener {
    protected static final int CHOOSE_FILE_RESULT_CODE = 20;
    private View mContentView = null;
    private WifiP2pDevice device;
    private WifiP2pInfo info;
    ProgressDialog progressDialog = null;
    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
    }
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        mContentView = inflater.inflate(R.layout.device_detail, null);
        mContentView.findViewById(R.id.btn_connect).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                WifiP2pConfig config = new WifiP2pConfig();
                config.deviceAddress = device.deviceAddress;
                config.wps.setup = WpsInfo.LABEL;
                config.wps.pin = "12345677";
//                config.groupOwnerIntent = 15;
                if (progressDialog != null && progressDialog.isShowing()) {
                    progressDialog.dismiss();
                }
                progressDialog = ProgressDialog.show(getActivity(), "Press back to cancel",
                        "Connecting to :" + device.deviceAddress, true, true
//                        new DialogInterface.OnCancelListener() {
//
//                            @Override
//                            public void onCancel(DialogInterface dialog) {
//                                ((DeviceActionListener) getActivity()).cancelDisconnect();
//                            }
//                        }
                );
                ((DeviceListFragment.DeviceActionListener) getActivity()).connect(config);
            }
        });
        mContentView.findViewById(R.id.btn_disconnect).setOnClickListener(
                new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        ((DeviceListFragment.DeviceActionListener) getActivity()).disconnect();
                    }
                });
        mContentView.findViewById(R.id.btn_start_client).setOnClickListener(
                new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        // Allow user to pick a text file from storage or other
                        // registered apps
                        Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
                        intent.setType("text/*");
//                        intent.setType("image/*");
                        startActivityForResult(intent, CHOOSE_FILE_RESULT_CODE);
                    }
                });
        return mContentView;
    }
    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        // User has picked a text file. Transfer it to group owner i.e peer using
        // FileTransferService.
        Uri uri = data.getData();
        TextView statusText = (TextView) mContentView.findViewById(R.id.status_text);
        statusText.setText("Sending: " + uri);
        Log.d(WiFiDirectActivity.TAG, "Intent----------- " + uri);
        Intent serviceIntent = new Intent(getActivity(), FileTransferService.class);
        serviceIntent.setAction(FileTransferService.ACTION_SEND_FILE);
        serviceIntent.putExtra(FileTransferService.EXTRAS_FILE_PATH, uri.toString());
        serviceIntent.putExtra(FileTransferService.EXTRAS_GROUP_OWNER_ADDRESS,
                info.groupOwnerAddress.getHostAddress());
        serviceIntent.putExtra(FileTransferService.EXTRAS_GROUP_OWNER_PORT, 8315); //631
        getActivity().startService(serviceIntent);
    }
    @Override
    public void onConnectionInfoAvailable(final WifiP2pInfo info) {
        if (progressDialog != null && progressDialog.isShowing()) {
            progressDialog.dismiss();
        }
        this.info = info;
        this.getView().setVisibility(View.VISIBLE);
        // The owner IP is now known.
        TextView view = (TextView) mContentView.findViewById(R.id.group_owner);
        view.setText(getResources().getString(R.string.group_owner_text)
                + ((info.isGroupOwner == true) ? getResources().getString(R.string.yes)
                : getResources().getString(R.string.no)));
        // InetAddress from WifiP2pInfo struct.
        view = (TextView) mContentView.findViewById(R.id.device_info);
        view.setText("Group Owner IP - " + info.groupOwnerAddress.getHostAddress());
        // After the group negotiation, we assign the group owner as the file
        // server. The file server is single threaded, single connection server
        // socket.
        if (info.groupFormed && info.isGroupOwner) {
            new FileServerAsyncTask(getActivity(), mContentView.findViewById(R.id.status_text))
                    .execute();
        } else if (info.groupFormed) {
            // The other device acts as the client. In this case, we enable the
            // get file button.
            mContentView.findViewById(R.id.btn_start_client).setVisibility(View.VISIBLE);
            ((TextView) mContentView.findViewById(R.id.status_text)).setText(getResources()
                    .getString(R.string.client_text));
        }
        // hide the connect button
        mContentView.findViewById(R.id.btn_connect).setVisibility(View.GONE);
    }
    /**
     * Updates the UI with device data
     *
     * @param device the device to be displayed
     */
    public void showDetails(WifiP2pDevice device) {
        this.device = device;
        this.getView().setVisibility(View.VISIBLE);
        TextView view = (TextView) mContentView.findViewById(R.id.device_address);
        view.setText(device.deviceAddress);
        view = (TextView) mContentView.findViewById(R.id.device_info);
        view.setText(device.toString());
    }
    /**
     * Clears the UI fields after a disconnect or direct mode disable operation.
     */
    public void resetViews() {
        mContentView.findViewById(R.id.btn_connect).setVisibility(View.VISIBLE);
        TextView view = (TextView) mContentView.findViewById(R.id.device_address);
        view.setText(R.string.empty);
        view = (TextView) mContentView.findViewById(R.id.device_info);
        view.setText(R.string.empty);
        view = (TextView) mContentView.findViewById(R.id.group_owner);
        view.setText(R.string.empty);
        view = (TextView) mContentView.findViewById(R.id.status_text);
        view.setText(R.string.empty);
        mContentView.findViewById(R.id.btn_start_client).setVisibility(View.GONE);
        this.getView().setVisibility(View.GONE);
    }
    /**
     * A simple server socket that accepts connection and writes some data on
     * the stream.
     */
    public static class FileServerAsyncTask extends AsyncTask<Void, Void, String> {
        private Context context;
        private TextView statusText;
        /**
         * @param context
         * @param statusText
         */
        public FileServerAsyncTask(Context context, View statusText) {
            this.context = context;
            this.statusText = (TextView) statusText;
        }
        @Override
        protected String doInBackground(Void... params) {
            try {
                ServerSocket serverSocket = new ServerSocket(8315); //631
                Log.d(WiFiDirectActivity.TAG, "Server: Socket opened");
                Socket client = serverSocket.accept();

                Log.d(WiFiDirectActivity.TAG, "Server: connection done");
//                final File f = new File(Environment.getExternalStorageDirectory() + "/"
//                        + context.getPackageName() + "/wifip2pshared-" + System.currentTimeMillis()
//                        + ".txt");


                final File f = new File(Environment.getExternalStorageDirectory() + "/"
                        + context.getPackageName() + "/wifip2pshared-" + ".txt");
                File dirs = new File(f.getParent());
                if (!dirs.exists())
                    dirs.mkdirs();
                f.createNewFile();
                Log.d(WiFiDirectActivity.TAG, "server: copying files " + f.toString());
                InputStream inputstream = client.getInputStream();
                copyFile(inputstream, new FileOutputStream(f));
                serverSocket.close();
                return f.getAbsolutePath();
            } catch (IOException e) {
                Log.e(WiFiDirectActivity.TAG, e.getMessage());
                return null;
            }
        }
        /*
         * (non-Javadoc)
         * @see android.os.AsyncTask#onPostExecute(java.lang.Object)
         */
        @Override
        protected void onPostExecute(String result) {
            if (result != null) {
                statusText.setText("File copied - " + result);
//                Log.e("...File copied - ", result);
                Intent intent = new Intent();
                intent.setAction(android.content.Intent.ACTION_VIEW);
                intent.setDataAndType(Uri.parse("file://" + result), "text/*");
                context.startActivity(intent);
            } else {
                Log.e("File copied is NULL- ", result);
            }
        }
        /*
         * (non-Javadoc)
         * @see android.os.AsyncTask#onPreExecute()
         */
        @Override
        protected void onPreExecute() {
            statusText.setText("Opening a server socket");
        }
    }
    public static boolean copyFile(InputStream inputStream, OutputStream out) {
        byte buf[] = new byte[1024];
        int len;
        try {
            while ((len = inputStream.read(buf)) != -1) {
                out.write(buf, 0, len);
            }
            out.close();
            inputStream.close();
        } catch (IOException e) {
            Log.d(WiFiDirectActivity.TAG, e.toString());
            return false;
        }
        return true;
    }
}

编辑 #1 这是我的权限设置

<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.BIND_PRINT_SERVICE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

连接打印机后,我得到了选择文件的 UI,选择后,没有任何反应,我只是得到以下控制台输出(我正在拾取的文件位于 SD 卡中)

  • 05-17 10:39:50.994 28659-28659/com.example.ccano.wifidirect E/ViewRootImpl: sendUserActionEvent() mView == null

  • 05-17 10:39:52.314 28659-28659/com.example.ccano.wifidirect D/ViewRootImpl: ViewPostImeInputStage processPointer 0

  • 05-17 10:39:52.384 28659-28659/com.example.ccano.wifidirect D/ViewRootImpl: ViewPostImeInputStage processPointer 1

  • 05-17 10:39:56.484 28659-28659/com.example.ccano.wifidirect D/wifidirectdemo: Intent-----------
    content://com.android.externalstorage.documents/document/9C33-6BBD%3Asample_file.txt

  • 05-17 10:39:56.514 28659-28659/com.example.ccano.wifidirect D/wifidirectdemo:P2P 状态已更改 - 2

  • 05-17 10:39:56.514 28659-29309/com.example.ccano.wifidirect D/wifidirectdemo:打开客户端套接字 -

  • 05-17 10:39:56.514 28659-28659/com.example.ccano.wifidirect D/wifidirectdemo:对等状态:0

  • 05-17 10:39:56.524 28659-29309/com.example.ccano.wifidirect D/wifidirectdemo:客户端套接字 - 真
  • 05-17 10:39:56.524 28659-29309/com.example.ccano.wifidirect E/ccano..copyfile: true

  • 05-17 10:39:56.524 28659-29309/com.example.ccano.wifidirect D/wifidirectdemo:客户端:数据写入

  • 05-17 10:39:56.534 28659-28659/com.example.ccano.wifidirect I/时间线:时间线:Activity_idle id:
    android.os.BinderProxy@75dd5e 时间:4602644
  • 05-17 10:41:01.714 28659-28659/com.example.ccano.wifidirect D/ViewRootImpl: ViewPostImeInputStage processPointer 0
  • 05-17 10:41:01.774 28659-28659/com.example.ccano.wifidirect D/ViewRootImpl: ViewPostImeInputStage processPointer 1
  • 05-17 10:41:02.564 28659-28659/com.example.ccano.wifidirect D/wifidirectdemo:P2P 对等点已更改
  • 05-17 10:41:02.574 28659-28659/com.example.ccano.wifidirect D/wifidirectdemo:对等状态:3
  • 05-17 10:41:02.594 28659-28659/com.example.ccano.wifidirect D/wifidirectdemo:未找到设备

编辑#2

在我的清单中添加以下行后,我仍然得到相同的结果,没有任何反应。

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

编辑#3

现在将 WpsInfo.Label 更改为 WpsInfo.PBC 后,我在调试器控制台上得到了不同的输出。 (见下面的屏幕截图)。但是,打印机仍然没有发送打印作业。

【问题讨论】:

  • Android 操作系统版本?
  • 您能否提供更多关于“没有发生任何事情”的详细信息,WiFi Direct 连接是否已建立?输出日志中的哪一点失败?
  • 该项目使用的是 Android 6.0 API 级别 23。日志显示文件已发送并建立了正确的握手。
  • 你是否添加了存储所需的权限:''' '''
  • 一开始就设置的那些权限,因为我在我的描述中克隆了上面描述的 Android 演示。请参阅我的重新编辑帖子。

标签: java android printing wifi-direct


【解决方案1】:

原来我的代码没问题,经过几天的测试和研究,我发现问题是套接字类,我使用的是谷歌在演示代码中提供的默认类(这是我正在使用)但是,在阅读了来自Wi-Fi.org 的官方文档后,我可以理解端口号很重要,并且为了使其与 WiFi Direct 一起使用,您只需定位端口 #631,打印机会询问您有关 PIN 的信息密码,以防启用。现在,如果你想使用 P2P 并绕过密码,你必须使用端口#9100。

所以,我同时使用了 9100 和 631 端口,现在我正在打印 txt 文件。

现在,如果你想打印 PDF,你只需要添加:

intent.setType("application/pdf"); 

intent.setDataAndType(Uri.parse("file://" + result), "application/pdf");

到 DeviceDetailFragment 类(上面发布的那个)。

我希望这篇文章能提供一个很好的理解和深入了解 Android 打印与 P2P 通信。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-05
    • 2016-03-10
    • 2017-02-03
    相关资源
    最近更新 更多