最近公司需要一個android拍照上傳和定位功能的的單一功能頁面,一開始選擇ionic cordova angular的一套H5框架,但是遇到和上傳文件報錯的問題,bug找了一天沒找到原因,懷疑是ionic版本問題,但是不重要了,不過有想繼續研究問題的代碼給你們,加油呀
git@github.com:tsxylhs/ionic-image-upload.git
因為趕的急臨時抱佛腳,一天的時間將android入門然后寫了這個Demo 希望大家共同學習,全棧就得有個全棧的樣子你說對不,現在說正事
首先是定位, gps定位和網絡定位,動態獲取權限卡了一會,貼代碼瞧瞧吧,寫慣了golang 再寫java感覺太臃腫了。。太臃腫了。。。。。臃腫。。。。了
System.out.println("獲取經緯度");
showGPSContacts();
哈哈哈是是不是覺得我在逗你們,這個就是click里的方法了。實現showGpsContacts,根據多年菜逼的經驗代碼不要亂寫,會更亂,放在類里調用就好了,上核心代碼
public void showGPSContacts() { LocationManager lm = (LocationManager) MainActivity.this.getSystemService(Context.LOCATION_SERVICE); boolean ok = lm.isProviderEnabled(LocationManager.GPS_PROVIDER); if (ok) {//開了定位服務 if (Build.VERSION.SDK_INT >= 23) { //判斷是否為android6.0系統版本,如果是,需要動態添加權限 if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {// 沒有權限,申請權限。 ActivityCompat.requestPermissions(MainActivity.this, LOCATIONGPS, BAIDU_READ_PHONE_STATE); } else { getLocation();//getLocation為定位方法 } } else { getLocation();//getLocation為定位方法 } } else { Toast.makeText(MainActivity.this, "系統檢測到未開啟GPS定位服務,請開啟", Toast.LENGTH_SHORT).show(); Intent intent = new Intent(); intent.setAction(Settings.ACTION_LOCATION_SOURCE_SETTINGS); startActivityForResult(intent, PRIVATE_CODE); } } /** * 獲取具體位置的經緯度 */ private void getLocation() { // 獲取位置管理服務 LocationManager locationManager; String serviceName = Context.LOCATION_SERVICE; locationManager = (LocationManager) MainActivity.this.getSystemService(serviceName); // 查找到服務信息 Criteria criteria = new Criteria(); criteria.setAccuracy(Criteria.ACCURACY_FINE); // 高精度 criteria.setAltitudeRequired(false); criteria.setBearingRequired(false); criteria.setCostAllowed(true); criteria.setPowerRequirement(Criteria.POWER_LOW); // 低功耗 String provider = locationManager.getBestProvider(criteria, true); // 獲取GPS信息 /**這段代碼不需要深究,是locationManager.getLastKnownLocation(provider)自動生成的,不加會出錯**/ if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { return; } Location location = locationManager.getLastKnownLocation(provider); // 通過GPS獲取位置 updateLocation(location); } /** * 獲取到當前位置的經緯度 * * @param location */ private void updateLocation(Location location) { if (location != null) { lat = location.getLatitude(); lng= location.getLongitude(); locationSuccess = new AlertDialog.Builder(MainActivity.this) .setTitle("提示信息")//標題 .setMessage("獲取定位成功!")//內容 .setPositiveButton("確定", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { Toast.makeText(MainActivity.this, "獲取定位成功", Toast.LENGTH_SHORT).show(); dialog.dismiss(); } }).setIcon(R.mipmap.ic_launcher).create();//圖標 locationSuccess.show(); System.out.println("lat"+lat+":"+"location"+lng); } else { System.out.println("獲取失敗"); locationError = new AlertDialog.Builder(MainActivity.this) .setTitle("定位失敗")//標題 .setMessage("獲取定位失敗聯系開發者:17615855621!")//內容 .setPositiveButton("確定", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { Toast.makeText(MainActivity.this, "獲取定位失敗", Toast.LENGTH_SHORT).show(); dialog.dismiss(); } }).setIcon(R.mipmap.ic_launcher).create();//圖標 locationError.show(); } } }
其實我也是從網上找的例子,讀一讀,看一看 control c v 拿過來,這個就是拿來主義
AndroidManifest.xml 引入權限
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
沒有什么大毛病的話定位就走起了
接下來就是要拍照上傳了這個說實話真耽誤了一些功夫,沒辦法有拿來主義,就要有分享精神(哈哈)自吹自擂的話就不說了上代碼
//設置圖片的保存路徑,作為全局變量 System.out.println("打開攝像頭拍照"); intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE); startActivityForResult(intent, PICK);
套路一樣,邏輯分類些,就像是上海的垃圾分類,博主每天接收大媽的審問,我是什么垃圾,代碼也一樣,代碼不分類也是和垃圾一樣(丑呀)
重寫
onActivityResult此方法
然后將
Bitmap 轉換為文件 初步工作完成
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) { case PICK: if (resultCode == RESULT_OK) { //將拍攝的照片顯示出來 Bundle bundle = data.getExtras(); Bitmap bitmap = (Bitmap) bundle.get("data"); base64ImageData = bitmapToBase64(bitmap); imageView.setImageBitmap(bitmap); file= compressImage(bitmap); // 拍照完成並且顯示完成 // todo 上傳圖片和位置信息 } break; default: break; } } //轉換文件 public File compressImage(Bitmap bitmap) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);//質量壓縮方法,這里100表示不壓縮,把壓縮后的數據存放到baos中 int options = 100; SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss"); Date date = new Date(System.currentTimeMillis()); String filename = format.format(date); File file = new File(Environment.getExternalStorageDirectory(), filename + ".png"); try { FileOutputStream fos = new FileOutputStream(file); try { fos.write(baos.toByteArray()); fos.flush(); fos.close(); } catch (IOException e) { e.printStackTrace(); } } catch (FileNotFoundException e) { e.printStackTrace(); } return file; }
上傳有點亂將就吧,天不早該睡覺了,有些業務上的邏輯請忽略
System.out.println("上傳圖片"); address = editTextAddress.getText().toString(); deviceId = editTextDeviceId.getText().toString(); System.out.println("address:" + address); if (address==""||deviceId==""||lng==0.0||lat==0.0) { alertDialog1 = new AlertDialog.Builder(MainActivity.this) .setTitle("錯誤")//標題 .setMessage("內容未完善!")//內容 .setPositiveButton("重新完善內容", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { Toast.makeText(MainActivity.this, "重新完善內容", Toast.LENGTH_SHORT).show(); dialog.dismiss(); } }).setIcon(R.mipmap.ic_launcher).create();//圖標 alertDialog1.show(); } else { new Thread(new Runnable() { @Override public void run() { OkHttpClient okHttpClient = new OkHttpClient.Builder().build(); RequestBody fileBody = RequestBody.create(MediaType.parse("image/png"), file); RequestBody requestBody = new MultipartBody.Builder().setType(MultipartBody.FORM) .addFormDataPart("file", deviceId, fileBody) .addFormDataPart("address", address) .addFormDataPart("deviceId", deviceId) .addFormDataPart("latlong", lat + ":" + lng).build(); Request request = new Request.Builder().url(url).post(requestBody).build(); okHttpClient.newCall(request).enqueue(new Callback() { @Override public void onFailure(@NotNull Call call, @NotNull IOException e) { Log.i("response:", e.toString()); Looper.prepare(); AlertFailure= new AlertDialog.Builder(MainActivity.this) .setTitle("上傳失敗")//標題 .setMessage("上傳失敗請聯系開發者:17615855621!")//內容 .setPositiveButton("確定", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { Toast.makeText(MainActivity.this, "上傳失敗", Toast.LENGTH_SHORT).show(); dialog.dismiss(); } }).setIcon(R.mipmap.ic_launcher).create();//圖標 AlertFailure.show(); Looper.loop(); System.out.println(e.getMessage()); } @Override public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException { Log.i("response:", response.toString()); Looper.prepare(); AlerDialogsuccess= new AlertDialog.Builder(MainActivity.this) .setTitle("上傳成功")//標題 .setMessage("上傳成功!")//內容 .setPositiveButton("確定", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { Toast.makeText(MainActivity.this, "上傳成功", Toast.LENGTH_SHORT).show(); dialog.dismiss(); } }).setIcon(R.mipmap.ic_launcher).create();//圖標 AlerDialogsuccess.show(); Looper.loop(); System.out.println("上傳成功"); } }); } }).start(); }
AndroidManifest.xml 引入權限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
至此便大獲全勝。本教程只適合1天android工齡人查看,大神請繞路行駛,以免發生車禍
頁面要不要貼。。。。。不貼了吧都是拖出來的毫無美感可言
最后源代碼來啦請注意查收:
https://github.com/tsxylhs/android-image-upload
謝謝,歡迎留言交流