package android.serialport.api.sample; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import android.annotation.SuppressLint; import android.app.Activity; import android.app.AlertDialog; import android.content.ContentUris; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.database.Cursor; import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.os.Environment; import android.os.Handler; import android.os.Message; import android.provider.DocumentsContract; import android.provider.MediaStore; import android.support.v4.app.Fragment; import android.util.DisplayMetrics; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.view.WindowManager; import android.widget.Button; import android.widget.EditText; import android.widget.ProgressBar; import android.widget.TextView; import android.widget.Toast; import sendData.Commands; import sendData.SendDatas; public class Fragment_Update extends Fragment implements OnClickListener { public static Fragment_Update mFragment_Update; private byte[] mBuffer; private UpgradeThread mThread; private static boolean mFlag = false; private View mView; private Button Btn_Path; private Button Btn_Upgrade; private EditText EditText_Path; private AlertDialog ProDialog; private ProgressBar Pro; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { mView = inflater.inflate(R.layout.fragment_upgrade, container, false); iniView(); iniData(); return mView; } @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { String mPath = ""; if (resultCode == Activity.RESULT_OK) { Uri uri = data.getData(); if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT) { // 大于 android 4.4 mPath = getPath(getActivity(), uri); } else { // 小于 android 4.4 mPath = getRealPathFromURI(uri); } } EditText_Path.setText(mPath + ""); } private String getRealPathFromURI(Uri contentUri) { String res = null; String[] proj = { MediaStore.Images.Media.DATA }; Cursor cursor = getActivity().getContentResolver().query(contentUri, proj, null, null, null); if (null != cursor && cursor.moveToFirst()) { ; int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); res = cursor.getString(column_index); cursor.close(); } return res; } /** * 专为Android4.4设计的从Uri获取文件绝对路径,以前的方法已不好使 */ @SuppressLint("NewApi") private String getPath(final Context context, final Uri uri) { final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT; // DocumentProvider if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) { // ExternalStorageProvider if (isExternalStorageDocument(uri)) { final String docId = DocumentsContract.getDocumentId(uri); final String[] split = docId.split(":"); final String type = split[0]; if ("primary".equalsIgnoreCase(type)) { return Environment.getExternalStorageDirectory() + "/" + split[1]; } } // DownloadsProvider else if (isDownloadsDocument(uri)) { final String id = DocumentsContract.getDocumentId(uri); final Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(id)); return getDataColumn(context, contentUri, null, null); } // MediaProvider else if (isMediaDocument(uri)) { final String docId = DocumentsContract.getDocumentId(uri); final String[] split = docId.split(":"); final String type = split[0]; Uri contentUri = null; if ("image".equals(type)) { contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; } else if ("video".equals(type)) { contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI; } else if ("audio".equals(type)) { contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; } final String selection = "_id=?"; final String[] selectionArgs = new String[] { split[1] }; return getDataColumn(context, contentUri, selection, selectionArgs); } } // MediaStore (and general) else if ("content".equalsIgnoreCase(uri.getScheme())) { return getDataColumn(context, uri, null, null); } // File else if ("file".equalsIgnoreCase(uri.getScheme())) { return uri.getPath(); } return null; } /** * Get the value of the data column for this Uri. This is useful for * MediaStore Uris, and other file-based ContentProviders. * * @param context * The context. * @param uri * The Uri to query. * @param selection * (Optional) Filter used in the query. * @param selectionArgs * (Optional) Selection arguments used in the query. * @return The value of the _data column, which is typically a file path. */ private String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) { Cursor cursor = null; final String column = "_data"; final String[] projection = { column }; try { cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null); if (cursor != null && cursor.moveToFirst()) { final int column_index = cursor.getColumnIndexOrThrow(column); return cursor.getString(column_index); } } finally { if (cursor != null) cursor.close(); } return null; } /** * @param uri * The Uri to check. * @return Whether the Uri authority is ExternalStorageProvider. */ private boolean isExternalStorageDocument(Uri uri) { return "com.android.externalstorage.documents".equals(uri.getAuthority()); } /** * @param uri * The Uri to check. * @return Whether the Uri authority is DownloadsProvider. */ private boolean isDownloadsDocument(Uri uri) { return "com.android.providers.downloads.documents".equals(uri.getAuthority()); } /** * @param uri * The Uri to check. * @return Whether the Uri authority is MediaProvider. */ private boolean isMediaDocument(Uri uri) { return "com.android.providers.media.documents".equals(uri.getAuthority()); } private void iniView() { // Btn_Path = (Button) mView.findViewById(R.id.Btn_path); Btn_Path.setOnClickListener(this); Btn_Upgrade = (Button) mView.findViewById(R.id.Btn_Upgrade); Btn_Upgrade.setOnClickListener(this); EditText_Path = (EditText) mView.findViewById(R.id.EditText_Path); ProDialog = new AlertDialog.Builder(getActivity(), R.style.Theme_Transparent).create(); LayoutInflater inflater = LayoutInflater.from(getActivity()); final View tmpickerview = inflater.inflate(R.layout.dialog_pro, null); ProDialog.setView(tmpickerview); Pro = (ProgressBar) tmpickerview.findViewById(R.id.pro); } private void iniData() { mFlag = false; mFragment_Update = this; } private void showPro() { Pro.setProgress(0); ProDialog.show(); ProDialog.setTitle("upgrading, please do not operate it."); WindowManager.LayoutParams lp = ProDialog.getWindow().getAttributes(); lp.width = 700; lp.height = 80; ProDialog.getWindow().setAttributes(lp); } private void hidePro() { ProDialog.dismiss(); } private void NoticeDialog(String str) { // new AlertDialog.Builder(getActivity(), R.style.Theme_Transparent_NoTitle).setMessage(str) .setPositiveButton("OK", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); } }).create().show(); } private byte[] getBytes(int index) { // try { int count = mBuffer.length / 64; int b = mBuffer.length % 64; if (b != 0) { count = count + 1; } // // int count = (mBuffer.length / 64) + (mBuffer.length % 64 == 0 ? 0 // : 1); byte[] _bytes; if (index > count) { // 当index大于count的时候,代表升级成功 mFragment_Update.mUpdataHandler.sendEmptyMessage(2); return null; } if (index == count) { // 最后一条 _bytes = new byte[(mBuffer.length - (index - 1) * 64) + 2]; } else { _bytes = new byte[64 + 2]; } _bytes[0] = (byte) (index / 256); _bytes[1] = (byte) (index % 256); System.arraycopy(mBuffer, (index - 1) * 64, _bytes, 2, _bytes.length - 2); Message msg = new Message(); msg.arg1 = (index * 100) / count; msg.what = 0; mFragment_Update.mUpdataHandler.sendMessage(msg); return _bytes; // } catch (Exception e) { // mFragment_Update.mUpdataHandler.sendEmptyMessage(1); // Log.e("asdf", e.getMessage().toString()); // return null; // } } private void SendUpgradeData(final int index) { new Thread(new Runnable() { @Override public void run() { try { byte[] _bytes = getBytes(index); if (_bytes == null) { // return; } byte[] sendBytes = SendDatas.AddSendData(Commands.DataRequest_ACK.getCommand(), Global.SubNet_Id, Global.Device_Id, _bytes); ReceiveAndSend.SendDatasList.add(sendBytes); Log.i("asd", "发送第" + index + "条数据包" + _bytes.length); } catch (Exception e) { mFragment_Update.mUpdataHandler.sendEmptyMessage(1); e.getMessage(); } } }).start(); } private void SendUpgradeDataLength() { try { int count = (mBuffer.length / 64) + (mBuffer.length % 64 == 0 ? 0 : 1); byte[] _byte = new byte[4]; _byte[0] = 0; _byte[1] = 0; _byte[2] = (byte) (count / 256); _byte[3] = (byte) (count % 256); byte[] sendBytes = SendDatas.AddSendData(Commands.DataRequest_ACK.getCommand(), Global.SubNet_Id, Global.Device_Id, _byte); Global.mOutputStream.flush(); Global.mOutputStream.write(sendBytes); } catch (Exception e) { e.getMessage(); } } @Override public void onClick(View v) { if (v.equals(Btn_Path)) { // 查找文件路径 Intent intent = new Intent(Intent.ACTION_GET_CONTENT); intent.setType("*/*"); intent.addCategory(Intent.CATEGORY_OPENABLE); startActivityForResult(intent, 1); } else if (v.equals(Btn_Upgrade)) { // 升级 if (EditText_Path.getText().toString().equals("")) { NoticeDialog("The path cannot be empty."); return; } File file = new File(EditText_Path.getText().toString()); String name = file.getName(); String prefix = name.substring(name.lastIndexOf(".") + 1).toUpperCase(); if (!prefix.equals("BIN")) { new AlertDialog.Builder(getActivity()).setMessage("File type error !").create().show(); return; } // 读取文件 try { FileInputStream fis = new FileInputStream(file); int length = fis.available(); mBuffer = new byte[length]; fis.read(mBuffer); if (mBuffer.length > 256 * 1024) { new AlertDialog.Builder(getActivity()).setMessage("File Error !").create().show(); return; } mFlag = true; mThread = new UpgradeThread(); mThread.start(); showPro(); } catch (IOException e) { mFlag = false; e.printStackTrace(); } } } public Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { if (mBuffer == null) return; if (msg.what == 0) { // 接收到的是备注,回复数据包长度 Log.i("asd", "接收到的是备注,回复数据包长度"); SendUpgradeDataLength(); } else { // 发送对应的数据 Log.i("asd", "发送对应的数据"); SendUpgradeData(msg.what); } } }; private Handler mUpdataHandler = new Handler() { @Override public void handleMessage(Message msg) { switch (msg.what) { case 0: Pro.setProgress(msg.arg1); break; case 1: hidePro(); NoticeDialog("Upgrade Failed !"); break; case 2: hidePro(); NoticeDialog("Upgrade Succeed !"); break; default: break; } } }; @Override public void onStart() { super.onStart(); } @Override public void onStop() { super.onStop(); } @Override public void onDestroy() { super.onDestroy(); } private class UpgradeThread extends Thread { @Override public void run() { super.run(); int i = 0; while (mFlag) { try { if (i > 20) { // 发送20次没有成功就直接退出了 mFlag = false; Log.i("asdf", "发送wan了读取备注命令"); return; } i++; byte[] sendBytes = SendDatas.AddSendData(Commands.readRemark.getCommand(), Global.SubNet_Id, Global.Device_Id, new byte[] {}); Global.mOutputStream.flush(); Global.mOutputStream.write(sendBytes); Log.i("asdf", "发送了读取备注命令"); sleep(30); } catch (Exception e) { e.getMessage(); continue; } } } } }