編輯:中級開發
431.* 判斷存儲卡是否存在
432.*
433.* @return
434.*/
435.public boolean existSDcard() {
436.if (android.os.Environment.getExternalStorageState().equals(
437.android.os.Environment.MEDIA_MOUNTED)) {
438.return true;
439.} else
440.return false;
441.}
442./**
443.* 相機自動對焦函數
444.*/
445.AutoFocusCallback autoFocusCallback = new AutoFocusCallback() {
446.public void onAutoFocus(boolean success, Camera camera) {
447.}
448.};
449.@Override
450.protected Dialog onCreateDialog(int id) {
451.switch (id) {
452.case 1: {
453.return new AlertDialog.Builder(MainPage.this)
454..setIcon(R.drawable.ic_menu_info_details)
455..setTitle("關於拍照上傳軟件")
456..setMessage(
457.Html.fromHtml("<font color=#E43E07 >程序功能介紹:</font><p>本程序用於圖片拍攝及上傳圖片等功能</p>"
458.+ "<font color=#E43E07 >注意:</font><p>使用本程序前,請先開啟用戶手機的GPS及無線網絡。(拍照界面中點擊 menu鍵->設置->安全與位置/無限網絡 開啟GPS及無限網絡)</p>"
459.+ "<p align=center color=#767676 size=12px>PETER制作 版權所有</p>"))
460..setPositiveButton("確定",
461.new DialogInterface.OnClickListener() {
462.public void onClick(DialogInterface dialog,
463.int whichButton) {
464.removeDialog(1);
465.}
466.}).create();
467.}
468.case 0: {
469.ProgressDialog dialog = new ProgressDialog(this);
470.dialog.setMessage("處理中,請稍後...");
471.dialog.setIndeterminate(true);
472.dialog.setCancelable(true);
473.return dialog;
474.}
475.}
476.return null;
477.}
478.Handler myHandler = new Handler() {
479. public void handleMessage(Message msg) {
480. switch (msg.what) {
481. case 0:
482. Bundle bundle = msg.getData();
483.// Log.d("Thread Test", "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<handler get message"+msg.what);
484. lat = bundle.getString("lat");
485. lng = bundle.getString("lng");
486. latLongString = bundle.getString("latLongString");
487.// Log.d("handler Text", "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"+latLongString+" lat:"+lat+" lng:"+lng);
488. nowLocality.setText(System.currentTimeMillis() + ":\n" + latLongString);
489. break;
490. case 1:
491. AlertDialog dialog1 = new AlertDialog.Builder(MainPage.this)
492..setTitle("提示").setMessage(
493."檢測到GPS/A-GPS沒有開啟 \n 點擊 確定 進入系統設置,點擊 取消 結束").setPositiveButton("Ok",
494.new DialogInterface.OnClickListener() {
495.public void onClick(DialogInterface dialog,
496.int whichButton) {
497./*
498.* 轉到設置界面
499.*/
500.Intent fireAlarm = new Intent(
501."android.settings.LOCATION_SOURCE_SETTINGS");
502.fireAlarm
503..addCategory(Intent.CATEGORY_DEFAULT);
504.startActivity(fireAlarm);
505.}
506.}).setNegativeButton("取消",
507.new DialogInterface.OnClickListener() {
508.public void onClick(DialogInterface dialog,
509.int whichButton) {
510.if(!gpsThread.isInterrupted()){
511.gpsThread.stopGspListener();
512.gpsThread.interrupt();
513.}
514.finish();
515.}
516.}).create();
517.dialog1.show();
518.break;
519. case 2:
520. AlertDialog dialog2 = new AlertDialog.Builder(MainPage.this)
521..setTitle("提示").setMessage("無法獲得當前位置,稍後將會重試")
522..setPositiveButton("Ok",
523.new DialogInterface.OnClickListener() {
524.public void onClick(DialogInterface dialog,
525.int whichButton) {
526.// finish();
527.}
528.}).create();
529.dialog2.show();
530.break;
531. }
532. super.handleMessage(msg);
533. }
534.};
535./**
536.* 手機的GPS線程
537.* @author peter
538.*/
539.class GpsThread extends Thread implements Runnable {
540. private Looper mLooper;
541.private LocationManager mLocationManager;
542.private Location location;
543.private Message message;
544.private long preTime;
545.String latLongStr = "",latitude = "",longitude = "";
546.public Looper getLooper() {
547. return mLooper;
548. }
549.public void quit() {
550. mLooper.quit();
551. }
552.private void updateWithNewLocation(Location slocation) {
553. if (slocation != null) {
554. latitude = Double.toString(slocation.getLatitude());
555. longitude = Double.toString(slocation.getLongitude());
556. long subTime = (System.currentTimeMillis() - preTime) / 1000;
557. float v = (subTime == 0 || location == null) ? 0 : (location
558. .distanceTo(slocation) / subTime);
559. latLongStr = "緯度:" + latitude + "\n經度:" + longitude + "\n速度:" + v
560. + " m/s , " + v * 3.6 + " km/h";
561. location = slocation;
562. preTime = System.currentTimeMillis();
563. } else {
564. latLongStr = "無法獲取地理信息";
565. }
566. }
567.private LocationListener locationListener = new LocationListener() {
568.// 底層獲得的位置會通過這個接口上報給應用
569.public void onLocationChanged(Location location) {
570.message.what = 0;
571.updateWithNewLocation(location);
572.// Log.d("Thread Test", "*************************GPS IS OPEN!");
573.}
574.// Provider被disable時觸發此函數,比如GPS被關閉
575.public void onProviderDisabled(String provider) {
576.message.what = 1;
577.// Log.d("Thread Test", "*************************GPS IS CLOSED!");
578.}
579.// Provider被enable時觸發此函數,比如GPS被打開
580.public void onProviderEnabled(String provider) {
581.}
582./*
583.* 位置服務狀態的變化通過這個接口上報
584.* Provider的轉態在可用、暫時不可用和無服務三個狀態直接切換時觸發此函數
585.*/
586.public void onStatusChanged(String provider, int status, Bundle extras) {
587.message.what = 2;
588.}
589.};
590.@SuppressWarnings("static-Access")
591.public void run(){
592.Looper.prepare();
593.mLooper = Looper.myLooper();
594.// 此處實例化了 手機的本地位置服務 的一個對象
595.mLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
596.Criteria criteria = new Criteria();
597. criteria.setAccuracy(Criteria.ACCURACY_FINE);// 設置為最大精度
598. criteria.setAltitudeRequired(false);// 不要求海拔信息
599. criteria.setBearingRequired(false);// 不要求方位信息
600. criteria.setCostAllowed(true);// 是否允許付費
601. criteria.setPowerRequirement(Criteria.POWER_LOW);// 對電量的要求
602. String provider = mLocationManager.getBestProvider(criteria, true);
603. while (!Thread.currentThread().isInterrupted()) {
604. mLocationManager.requestLocationUpdates(provider, 1000, 1, locationListener);
605. location = mLocationManager.getLastKnownLocation(provider);
606.// updateWithNewLocation(location); // 更新位置
607. while(location == null){
608. preTime = System.currentTimeMillis();
609. //刷新Provider信息
610. mLocationManager.requestLocationUpdates(provider, 1000, 1, locationListener);
611. //獲得最新的位置數據
612. location = mLocationManager.getLastKnownLocation(provider);
613. updateWithNewLocation(location); // 更新位置
614. try {
615. Thread.sleep(1000);
616. } catch (InterruptedException e) {
617. e.printStackTrace();
618. }
619. }
620.try {
621.message = new Message();
622.updateWithNewLocation(location); // 更新位置
623.Thread.sleep(4000);
624.} catch (InterruptedException e) {
625.e.printStackTrace();
626.}
627.// Log.d("Thread Test", "*************************Message.what's Value is:"+message.what);
628. Bundle data = new Bundle();
629. data.putString("latLongString", latLongStr);
630. data.putString("lat", latitude);
631. data.putString("lng", longitude);
632. message.setData(data);
633. myHandler.sendMessage(message);
634. }
635. Looper.loop();
636.}
637.public void stopGspListener(){
638.if(mLocationManager!=null){
639.mLocationManager.removeUpdates(locationListener);
640.}
641.}
642.};
643.}
package com.bjwmt.camera;
import Java.io.BufferedOutputStream;
import Java.io.File;
import Java.io.FileNotFoundException;
import Java.io.FileOutputStream;
import Java.io.IOException;
import Java.text.SimpleDateFormat;
import Java.util.Date;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.hardware.Camera.AutoFocusCallback;
import android.hardware.Camera.PictureCallback;
import android.hardware.Camera.ShutterCallback;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.Net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.telephony.TelephonyManager;
import android.text.Html;
import android.util.Log;
import android.vIEw.KeyEvent;
import android.vIEw.Menu;
import android.vIEw.MenuItem;
import android.vIEw.SurfaceHolder;
import android.view.SurfaceVIEw;
import android.view.VIEw;
import android.view.VIEw.OnClickListener;
import android.widget.Button;
import android.widget.TextVIEw;
public class MainPage extends Activity implements SurfaceHolder.Callback,
OnClickListener {
/**
* 程序存放的圖片路徑是在/sdcard/fatalityUpload這個文件夾
*/
private SurfaceView mSurfaceVIEw;
private Camera mCamera;
private SurfaceHolder mSurfaceHolder;
private boolean mPrevIEwRunning;
private TextVIEw nowLocality;
private Button exitButton;
private Button uploadButton;
private Button paizhaoButton;
// 實例化一個TelephonyManager 創建android的電話管理
private TelephonyManager tm;
private Date today;
private SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddhhmmss");
private String fileName;
private String lat = "", lng = "";// 經度和緯度
private String latLongString;
private GpsThread gpsThread;
private DBHelper dbHelper;
private Cursor cursor;
/**
* 本界面的主函數
*/
@Override
public void onCreate(Bundle savedInstanceState) {
checkMysoftStage();
super.onCreate(savedInstanceState);
setContentVIEw(R.layout.camera_surface);
// 攝像頭界面將通過全屏顯示,沒有"標題(title)";
getWindow().setFormat(PixelFormat.TRANSLUCENT);
// getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
// WindowManager.LayoutParams.FLAG_FULLSCREEN);// 全屏
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);// 橫屏
this.initMyCamera();
}
/**
* 檢查一下手機設備各項硬件的開啟狀態
*/
public void checkMysoftStage(){
/*
* 先看手機是否已插入sd卡 然後判斷sd卡裡是不是已經創建了fatalityUpload文件夾用來存儲本程序拍下來的照片
* 如果沒有創建的話就重新在sdcard裡創建fatalityUpload文件夾
*/
if (existSDcard()) { //判斷手機SD卡是否存在
if (new File("/sdcard").canRead()) {
File file = new File("sdcard/fatalityUpload");
if (!file.exists()) {
file.mkdir();
file = new File("sdcard/fatalityUpload/Thumbnail_fatality");
file.mkdir();
file = new File("sdcard/fatalityUpload/fatality");
file.mkdir();
}
}
} else {
new AlertDialog.Builder(this).setMessage("檢查到沒有存儲卡,請插入手機存儲卡再開啟本應用")
.setPositiveButton("確定",
new DialogInterface.OnClickListener() {
public void onClick(
DialogInterface dialoginterface, int i) {
finish();
}
}).show();
}
/*
* 此處開始初始化數據庫
try {
dbHelper = new DBHelper(this);
dbHelper.open(this);
cursor = dbHelper.loadAll();
if(!(cursor!=null && cursor.getCount()>0)){
dbHelper.initData();
}
cursor.close();
dbHelper.close();
} catch (Exception e) {
Log.d("save data", "save data fail");
} finally {
this.dbHelper.close();
}
*/
ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
NetworkInfo networkinfo = connectivityManager.getActiveNetworkInfo();
if (networkinfo == null || !networkinfo.isAvailable()) { // 當前網絡不可用
new AlertDialog.Builder(MainPage.this)
.setMessage("檢查到沒有可用的網絡連接,請打開網絡連接")
.setPositiveButton("確定",
new DialogInterface.OnClickListener(){
public void onClick(DialogInterface dialoginterface, int i){
ComponentName cn = new ComponentName("com.android.settings","com.android.settings.Settings");
Intent intent = new Intent();
intent.setComponent(cn);
intent.setAction("android.intent.action.VIEW");
startActivity(intent);
// finish();
}
}
).show();
}
}
/**
* 初始化組件
*/
public void initMyCamera() {
setListensers();
// TelephonyManager是android的電源通訊的幫助類,通過實例化TelephonyManager來實現操作類似獲取本機
// IME碼,手機號等信息
tm = (TelephonyManager) this
.getSystemService(Context.TELEPHONY_SERVICE);
// 初始化拍攝模塊
mSurfaceView = (SurfaceView) findVIEwById(R.id.surface_camera);
// mSurfaceVIEw.setOnClickListener(this);
mSurfaceHolder = mSurfaceVIEw.getHolder();
mSurfaceHolder.addCallback(MainPage.this);
mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
gpsThread = new GpsThread();
gpsThread.start();
// 設置監聽器,自動更新的最小時間為間隔1秒,最小位移變化超過3米
// mLocationManager.requestLocationUpdates(provider, 1000, 3,
// locationListener);
}
/**
* 此函數負責兩個工作 1.實例化屏幕上的按鈕 2.為按鈕添加Listener
*/
private void setListensers() {
nowLocality = (TextView) findVIEwById(R.id.nowLocality);
exitButton = (Button) findVIEwById(R.id.exitPro);
uploadButton = (Button) findVIEwById(R.id.uploadPhoto);
paizhaoButton = (Button) findVIEwById(R.id.paizhao);
exitButton.setOnClickListener(clickExitButton);
uploadButton.setOnClickListener(clickUploadButton);
paizhaoButton.setOnClickListener(clickShootButton);
}
/**
* 當預覽界面的格式和大小發生改變時,該方法被調用
*/
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
if (mPrevIEwRunning) {
mCamera.stopPrevIEw();
}
Camera.Parameters p = mCamera.getParameters();
p.setPrevIEwSize(w, h);
mCamera.setParameters(p);
try {
mCamera.setPrevIEwDisplay(holder);
} catch (IOException e) {
e.printStackTrace();
}
mCamera.startPrevIEw();
mPrevIEwRunning = true;
}
/**
* 重點函數 此處實例化了本界面的PictureCallback
* 當用戶拍完一張照片的時候觸發onPictureTaken,這時候對拍下的照片進行相應的處理操作
*/
PictureCallback mPictureCallback = new PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
if (data != null) {
try {
today = new Date();
// 定義fileName 用來設定拍照後的文件名
// 結構: IMSI號 + 經度+ & + 緯度+ 格式化後的當前時間 (本來結構應該是 手機號 + 精度&緯度 + 格式化後的當前時間)但是因為手機號有獲取不到的情況,所以換為了IMSI號
fileName = tm.getDeviceId() + "-" + lat + "-" + lng
+ "-" + sdf.format(today); //tm.getLine1Number()獲取手機號,這裡直接是獲取不到的,需要運營商的API解析
Bitmap bm = BitmapFactory.decodeByteArray(data, 0,
data.length);
BufferedOutputStream bos = new BufferedOutputStream(
new FileOutputStream(String.format(
"sdcard/fatalityUpload/fatality/"
+ fileName + ".jpg", System
.currentTimeMillis())));
bm.compress(Bitmap.CompressFormat.JPEG, 60, bos);
bos.flush();
bos.close();
BufferedOutputStream bos1 = new BufferedOutputStream(
new FileOutputStream(String.format(
"sdcard/fatalityUpload/Thumbnail_fatality/"
+ fileName + ".jpg", System
.currentTimeMillis())));
Bitmap bm1 = Bitmap.createScaledBitmap(bm, 100, 100, false);
bm1.compress(Bitmap.CompressFormat.JPEG, 100, bos1);
bos1.flush();
bos1.close();
removeDialog(0);
// ByteArrayOutputStream baos = new ByteArrayOutputStream();
// bm.compress(Bitmap.CompressFormat.PNG, 30, baos);
// byte[] newData = baos.toByteArray();
// 然後傳遞圖片信息到 圖像預覽界面
Intent intent = new Intent();
Bundle bundle = new Bundle();
// bundle.putByteArray("picPre", newData);
bundle.putString("picPath",
"/sdcard/fatalityUpload/fatality/" + fileName
+ ".jpg");
// intent.putExtra("picPre", data);
intent.putExtras(bundle);
intent.setClass(MainPage.this, PhotoPrevIEw.class);
// if (mLocationManager != null) {
// mLocationManager.removeUpdates(locationListener);
// }
if(!gpsThread.isInterrupted()){
gpsThread.stopGspListener();
gpsThread.interrupt();
}
finish();
startActivity(intent);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
};
/**
* 創建Camera對象函數 初次實例化,界面打開時該方法自動調用
*/
public void surfaceCreated(SurfaceHolder holder) {
// Thread openCameraThread = new Thread(
// new Runnable() {
// public void run() {
// mCamera = Camera.open();
// }
// }
// ).start();
mCamera = Camera.open();// “打開”攝像頭
}
/**
* 當用戶進行 點擊 操作的時候觸發此事件,不過貌似沒有起作用,有待測試
*/
public void onClick(VIEw v) {
mCamera.takePicture(mShutterCallback, null, mPictureCallback);
}
/**
* 在相機快門關閉時候的回調接口,通過這個接口來通知用戶快門關閉的事件,
* 普通相機在快門關閉的時候都會發出響聲,根據需要可以在該回調接口中定義各種動作, 例如:使設備震動
*/
ShutterCallback mShutterCallback = new ShutterCallback() {
public void onShutter() {
// just log ,do nothing
Log.d("ShutterCallback", "...onShutter...");
}
};
// PictureCallback rowCallback = new PictureCallback(){
// public void onPictureTaken(byte[] data, Camera camera) {
//
// }
// };
/**
* 銷毀函數 當預覽界面被關閉時,該方法被調用
*/
public void surfaceDestroyed(SurfaceHolder holder) {
mCamera.stopPrevIEw();
mPrevIEwRunning = false;
mCamera.release();
mCamera = null;
}
/*
* 點擊屏幕上的"退出"鍵時觸發該Listener監聽此按鈕的動作
*/
private OnClickListener clickExitButton = new OnClickListener() {
public void onClick(VIEw v) {
new AlertDialog.Builder(MainPage.this).setTitle("提示").setMessage(
"確定退出?").setPositiveButton("確定",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int whichButton) {
// if (mLocationManager != null) {
// mLocationManager
// .removeUpdates(locationListener);
// }
if(!gpsThread.isInterrupted()){
gpsThread.stopGspListener();
gpsThread.interrupt();
}
finish();
}
}).setNegativeButton("取消",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int whichButton) {
// 取消按鈕事件
}
}).show();
}
};
/*
* 點擊屏幕上的"上傳"鍵時觸發該Listener監聽此按鈕的動作
*/
private OnClickListener clickUploadButton = new OnClickListener() {
public void onClick(VIEw v) {
Intent intent = new Intent();
intent.setClass(MainPage.this, PictrueView.class);// PhotoVIEw
// if (mLocationManager != null) {
// mLocationManager.removeUpdates(locationListener);
// }
if(!gpsThread.isInterrupted()){
gpsThread.stopGspListener();
gpsThread.interrupt();
}
finish();
startActivity(intent);
}
};
<?XML version=1.0 encoding=utf-8?> 然後是主布局,一個水平滾動條,放入menu
本文為個人總結,不代表官方觀點。 分為幾個階段: 1、整個android的多媒體框架OpenCore 2、Player和Author的詳細介紹 2、OpenCo
簡介: BFS 是一款專門為 Linux 桌面環境所設計的內核調度器,它基於 Staircase Deadline 和 EEVDF 算法,支持 Linux 2
有關android SDK自帶的性能分析調試工具TraceVIEw使用方法,我們在android.os.Debug調試工具使用方法 簡單的說過,有關實際使用如