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;
|
}
|
}
|
}
|
}
|
}
|