當前位置:首頁 » 安卓系統 » androidxstream

androidxstream

發布時間: 2023-01-24 08:42:13

Ⅰ 如何獲取 Android 設備的CPU核數,時鍾頻率以及內存大小

獲取 CPU 核數
linux 中的設備都是以文件的形式存在,CPU 也不例外,因此 CPU 的文件個數就等價與核數。
Android 的 CPU 設備文件位於/sys/devices/system/cpu/目錄,文件名的的格式為cpu\d+。
root@generic_x86_64:/sys/devices/system/cpu # ls cpu0 cpufreq
cpuidle
kernel_max
modalias
offline
online
possible
power
present
uevent
統計一下文件個數便可以獲得 CPU 核數。
public static int getNumberOfCPUCores() {
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.GINGERBREAD_MR1) {
// Gingerbread doesn't support giving a single application access to both cores, but a
// handful of devices (Atrix 4G and Droid X2 for example) were released with a al-core
// chipset and Gingerbread; that can let an app in the background run without impacting
// the foreground application. But for our purposes, it makes them single core.
return 1;
}
int cores;
try {
cores = new File(「/sys/devices/system/cpu/」)。listFiles(CPU_FILTER)。length;
} catch (SecurityException e) {
cores = DEVICEINFO_UNKNOWN;
} catch (NullPointerException e) {
cores = DEVICEINFO_UNKNOWN;
}
return cores;
}
private static final FileFilter CPU_FILTER = new FileFilter() {
@Override
public boolean accept(File pathname) {
String path = pathname.getName();
//regex is slow, so checking char by char.
if (path.startsWith(「cpu」)) {
for (int i = 3; i < path.length(); i++) {
if (path.charAt(i) < '0' path.charAt(i) > '9『) {
return false;
}
}
return true;
}
return false;
}
};
獲取時鍾頻率
獲取時鍾頻率需要讀取系統文件 -/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq或者/proc/cpuinfo。
Android 模擬器中並沒有cpuinfo_max_freq文件,因此只能讀取/proc/cpuinfo。
/proc/cpuinfo包含了很多 cpu 數據。
processor : 0
vendor_id : GenuineIntel
cpu family : 6
model : 70
model name : Intel(R) Core(TM) i7-4770HQ CPU @ 2.20GHz
stepping : 1
cpu MHz : 0.000
cache size : 1024 KB
fdiv_bug : no
hlt_bug : no
f00f_bug : no
coma_bug : no
fpu : yes
fpu_exception : yes
cpuid level : 4
wp : yes
代碼如下:
public static int getCPUMaxFreqKHz() {
int maxFreq = DEVICEINFO_UNKNOWN;
try {
for (int i = 0; i < getNumberOfCPUCores(); i++) {
String filename =
「/sys/devices/system/cpu/cpu」 + i + 「/cpufreq/cpuinfo_max_freq」;
File cpuInfoMaxFreqFile = new File(filename);
if (cpuInfoMaxFreqFile.exists()) {
byte[] buffer = new byte[128];
FileInputStream stream = new FileInputStream(cpuInfoMaxFreqFile);
try {
stream.read(buffer);
int endIndex = 0;
//Trim the first number out of the byte buffer.
while (buffer[endIndex] >= '0' && buffer[endIndex] <= '9'
&& endIndex < buffer.length) endIndex++;
String str = new String(buffer, 0, endIndex);
Integer freqBound = Integer.parseInt(str);
if (freqBound > maxFreq) maxFreq = freqBound;
} catch (NumberFormatException e) {
//Fall through and use /proc/cpuinfo.
} finally {
stream.close();
}
}
}
if (maxFreq == DEVICEINFO_UNKNOWN) {
FileInputStream stream = new FileInputStream(「/proc/cpuinfo」);
try {
int freqBound = parseFileForValue(「cpu MHz」, stream);
freqBound *= 1000; //MHz -> kHz
if (freqBound > maxFreq) maxFreq = freqBound;
} finally {
stream.close();
}
}
} catch (IOException e) {
maxFreq = DEVICEINFO_UNKNOWN; //Fall through and return unknown.
}
return maxFreq;
}
獲取內存大小
如果 SDK 版本大於等於JELLY_BEAN,可以通過ActivityManager來獲取內從大小。
ActivityManager.MemoryInfo memInfo = new ActivityManager.MemoryInfo();
ActivityManager am = (ActivityManager) c.getSystemService(Context.ACTIVITY_SERVICE);
am.getMemoryInfo(memInfo);
如果版本低於JELLY_BEAN,則只能讀取系統文件了。
FileInputStream stream = new FileInputStream(「/proc/meminfo」);
totalMem = parseFileForValue(「MemTotal」, stream);
完整代碼如下:
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
public static long getTotalMemory(Context c) {
// memInfo.totalMem not supported in pre-Jelly Bean APIs.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
ActivityManager.MemoryInfo memInfo = new ActivityManager.MemoryInfo();
ActivityManager am = (ActivityManager) c.getSystemService(Context.ACTIVITY_SERVICE);
am.getMemoryInfo(memInfo);
if (memInfo != null) {
return memInfo.totalMem;
} else {
return DEVICEINFO_UNKNOWN;
}
} else {
long totalMem = DEVICEINFO_UNKNOWN;
try {
FileInputStream stream = new FileInputStream(「/proc/meminfo」);
try {
totalMem = parseFileForValue(「MemTotal」, stream);
totalMem *= 1024;
} finally {
stream.close();
}
} catch (IOException e) {
}
return totalMem;
}
}

Ⅱ Android 10(29)適配方案簡要說明

Android 10(29)適配方案簡要說明

1、根據Google官方文檔說明,Android10引入了大量變更

官方文檔: https://developer.android.google.cn/about/versions/10/highlights?hl=zh_cn

1.1、Android 10 中的隱私權變更

1.1.1重大隱私權變更

分區存儲

針對外部存儲的過濾視圖,可提供對特定於應用的文件和媒體集合的訪問許可權 訪問和共享外部存儲中的文件的應用 使用特定於應用的目錄和媒體集合目錄

增強了用戶對位置許可權的控制力

僅限前台許可權,可讓用戶更好地控制應用對設備位置信息的訪問許可權 在後台時請求訪問用戶位置信息的應用 確保在沒有後台位置信息更新的情況下優雅降級

使用 Android 10 中引入的許可權在後台獲取位置信息

系統執行後台 Activity

針對從後台啟動 Activity 實施了限制 不需要用戶互動就啟動 Activity 的應用 使用通知觸發的 Activity

不可重置的硬體標識符

針對訪問設備序列號和 IMEI 實施了限制 訪問設備序列號或 IMEI 的應用 使用用戶可以重置的標識符

無線掃描許可權

訪問某些 WLAN、WLAN 感知和藍牙掃描方法需要獲得精確位置許可權 使用 WLAN API 和藍牙 API 的應用 針對相關使用場景請求 ACCESS_FINE_LOCATION 許可權

1.1.2更多隱私權變更

標識符和數據: 針對硬體標識符(如 IMEI、序列號、MAC 和類似數據)實施了新限制。

移除了聯系人親密程度信息

隨機分配 MAC 地址

對 /proc/net 文件系統的訪問許可權實施了限制

對不可重置的設備標識符實施了限制

限制了對剪貼板數據的訪問許可權

保護 USB 設備序列號

攝像頭和連接性: 針對攝像頭元數據和連接 API 提供了更強大的保護措施。 對訪問攝像頭詳情和元數據的許可權實施了限制

對啟用和停用 WLAN 實施了限制

對直接訪問已配置的 WLAN 網路實施了限制

一些電話 API、藍牙 API 和 WLAN API 需要精確位置許可權

許可權 : 針對許可權模型和要求的一些變更。

限制對屏幕內容的訪問

面向用戶的許可權檢查(針對舊版應用)

身體活動識別

從界面中移除了許可權組

1.2影響應用的行為變更

文檔: https://developer.android.google.cn/about/versions/10/behavior-changes-all?hl=zh_cn

限制非 SDK 介面: 為了幫助確保應用的穩定性和兼容性,Android 平台開始限制應用在 Android 9(API 級別 28)中使用非 SDK 介面。Android 10 包含更新後的受限制非 SDK 介面列表(基於與 Android 開發者之間的協作以及最新的內部測試)。我們的目標是在限制使用非 SDK 介面之前確保有可用的公開替代方案。

手勢導航: 從 Android 10 開始,用戶可以在設備中啟用手勢導航。用戶啟用後,手勢導航會影響設備上的所有應用,無論應用是否以 API 級別 29 為目標平台。例如,如果用戶從屏幕邊緣向內滑動,系統會將該手勢解讀為「返回」導航,除非應用針對屏幕的相應部分明確替換該手勢。

NDK 方面的變更

共享對象不得包含文本重定位

Bionic 庫和動態鏈接器路徑變更

系統二進制文件/庫會映射到只執行內存

安全方面的變更

 TLS 1.3 默認處於啟用狀態

TLS 不信任使用 SHA-1 簽名的證書

KeyChain 行為變更和改進

其他 TLS 和加密更改

WLAN 直連廣播

在 Android 10 中,以下與 WLAN 直連相關的廣播不具有粘性:

WIFI_P2P_CONNECTION_CHANGED_ACTION

WIFI_P2P_THIS_DEVICE_CHANGED_ACTION

如果的應用依賴於在注冊時接收這些廣播(因為其之前一直具有粘性),請在初始化時使用適當的 get() 方法獲取信息。

WLAN 感知功能  

Android 10 擴大了支持范圍,現在可以使用 WLAN 感知數據路徑輕松創建 TCP/UDP 套接字。要創建連接到 ServerSocket 的 TCP/UDP 套接字,客戶端設備需要知道伺服器的 IPv6 地址和埠。這在之前需要通過頻外方式進行通信(例如使用 BT 或 WLAN 感知第 2 層消息傳遞),或者使用其他協議(例如 mDNS)通過頻內方式發現。而藉助 Android 10,可以將此類消息作為網路設置的一部分進行傳遞。

Go 設備上的 SYSTEM_ALERT_WINDOW

在 Android 10(Go 版本)設備上運行的應用無法獲得 SYSTEM_ALERT_WINDOW 許可權。這是因為繪制疊加層窗口會使用過多的內存,這對低內存 Android 設備的性能十分有害。

如果在搭載 Android 9 或更低版本的 Go 版設備上運行的應用獲得了 SYSTEM_ALERT_WINDOW 許可權,則即使設備升級到 Android 10,也會保留此許可權。不過,尚不具有此許可權的應用在設備升級後便無法獲得此許可權了。

如果 Go 設備上的應用發送具有 ACTION_MANAGE_OVERLAY_PERMISSION 操作的 intent,則系統會自動拒絕此請求,並將用戶轉到設置屏幕,上面會顯示不允許授予此許可權,原因是它會減慢設備的運行速度。如果 Go 設備上的應用調用 Settings.canDrawOverlays(),則此方法始終返回 false。同樣,這些限制不適用於在設備升級到 Android 10 之前便已收到 SYSTEM_ALERT_WINDOW 許可權的應用。

關於以舊版 Android 系統為目標平台的應用的警告

在搭載 Android 10 或更高版本的設備上,如果用戶首次運行以 Android 5.1(API 級別 22)或更低版本為目標平台的應用,則會看到警告。如果此應用要求用戶授予許可權,則系統會先向用戶提供調整應用許可權的機會,然後才會允許此應用首次運行。

由於 Google Play 的目標 API 方面的要求,用戶只有在運行最近未更新的應用時才會看到這些警告。對於通過其他商店分發的應用,我們也將於 2019 年引入類似的目標 API 方面的要求。如需詳細了解這些要求,請參閱在 2019 年擴展目標 API 級別方面的要求。

移除了 SHA-2 CBC 加密套件

以下 SHA-2 CBC 加密套件已從平台中移除:

TLS_RSA_WITH_AES_128_CBC_SHA256

TLS_RSA_WITH_AES_256_CBC_SHA256

TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256

TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384

TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256

TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384

這些加密套件不如使用 GCM 的類似加密套件安全,並且大多數伺服器要麼同時支持這些加密套件的 GCM 變體和 CBC 變體,要麼二者均不支持。

應用使用情況的變更

UsageStats 應用使用情況方面的改進 - 當在分屏或畫中畫模式下使用應用時,Android 10 現在能夠使用 UsageStats 准確地跟蹤應用使用情況。此外,Android 10 可以正確地跟蹤免安裝應用的使用情況。

按應用開啟灰度模式 - Android 10 可針對各個應用設置灰度顯示模式。

按應用開啟干擾模式 - Android 10 可以選擇性地將應用設置為「干擾模式」,此時系統會禁止顯示其通知,並且不會將其顯示為推薦的應用。

暫停和播放 - 在 Android 10 中,暫停的應用無法播放音頻。

HTTPS 連接變更

如果在 Android 10 上運行的應用將 null 傳遞給 setSSLSocketFactory(),則會出現 IllegalArgumentException。在以前的版本中,將 null 傳遞給 setSSLSocketFactory() 與傳入當前的默認 SSL 套接字工廠效果相同。

android.preference 庫已棄用

從 Android 10 開始,將棄用 android.preference 庫。開發者應該改為使用 AndroidX preference 庫,這是 Android Jetpack 的一部分。如需獲取其他有助於遷移和開發的資源,請查看經過更新的設置指南以及我們的公開示例應用和參考文檔。

ZIP 文件實用程序庫變更

Android 10 對 java.util.zip 軟體包(用於處理 ZIP 文件)中的類進行了以下變更。這些變更會讓庫的行為在 Android 和使用 java.util.zip 的其他平台之間更加一致。

Inflater

在以前的版本中,如果在調用 end() 之後調用 Inflater 類中的某些方法,這些方法會拋出 IllegalStateException。在 Android 10 中,這些方法會改為拋出 NullPointerException。

ZipFile

在 Android 10 及更高版本中,如果所提供的 ZIP 文件不包含任何文件,則 ZipFile 的構造函數(採用的參數類型為 File、int 和 Charset)不會拋出 ZipException。

ZipOutputStream

在 Android 10 及更高版本中,如果 ZipOutputStream 中的 finish() 方法嘗試為不包含任何文件的 ZIP 文件寫入輸出流,則此方法不會拋出 ZipException。

攝像頭變更

很多使用攝像頭的應用都會假定如果設備採用縱向配置,則物理設備也會處於縱向,正如攝像頭方向中所述。在過去可以做出這樣的假定,但隨著可用的設備類型(例如可折疊設備)的擴展,這一情況發生了變化。針對這些設備做出這樣的假定可能導致相機取景器的顯示產生錯誤的旋轉和/或縮放。

以 API 級別 24 或更高級別為目標平台的應用應該明確設置 android:resizeableActivity,並提供必要的功能來處理多窗口操作。

電池用量跟蹤

從 Android 10 開始,只要在發生重大充電事件之後拔下設備電源插頭,SystemHealthManager 就會重置其電池用量統計信息。一般來說,重大充電事件指的是設備電池已充滿,或者設備電量從幾乎耗盡變為即將充滿。

在 Android 10 之前,無論何時拔下設備電源插頭,無論電池電量有多微小的變化,電池用量統計信息都會重置。

Android Beam 已棄用

在 Android 10 中,我們正式棄用了 Android Beam,這是一項舊版功能,可通過近距離無線通信 (NFC) 在多個設備之間啟動數據共享。我們還棄用了一些相關的 NFC API。Android Beam 仍可供需要的設備製造商合作夥伴使用,但它已不再處於積極的開發階段。不過,Android 仍將繼續支持其他的 NFC 功能和 API,並且從標簽和付款中讀取數據等使用場景仍將繼續按預期執行。

Ⅲ 如何搭建 android 開發環境

一.認識android的架構
Android其本質就是在標準的Linux系統上增加了Java虛擬機Dalvik,並在Dalvik虛擬機上搭建了一個JAVA的application framework,所有的應用程序都是基於JAVA的application framework之上。
android分為四個層,從高層到低層分別是應用程序層、應用程序框架層、系統運行庫層和linux核心層。
二.搭建環境
搭建開發環境
對國內的開發者來說最痛苦的是無法去訪問android開發網站。為了更好的認識世界,對程序員來說,會翻牆也是的一門技術,帶你去領略牆外的世界,好了,不廢話了, 國內開發者訪問(androiddevtools) 上面已經有了所有你要的資源,同時可以下載到我們的主角framework
但是這樣的搭建只能去閱讀源代碼,我們無法去更進一步去實現自己的rom,我們看到錘子的系統在早期的開放rom是自己從新實現了framework的代碼,現在看起來他成功了,所以我們還要去搭建android系統的源碼編譯環境。
搭建源碼編譯環境

三.開始主題
在一開始寫c程序的時候都有一個運行的入口,比如
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
//這里的main就是應用的入口
int main(int argc, const char * argv[]){
return 0;
}
在計算機網路原理中我們用socket實現一個伺服器端,不斷的接聽客戶端的訪問,而且他的代碼是這樣實現的:
#include <winsock2.h>
#pragma comment(lib, "WS2_32.lib")
#include <stdio.h>
void main()
{
WORD wVersionRequested;//版本號
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD(2, 2);//2.2版本的套接字
//載入套接字型檔,如果失敗返回
err = WSAStartup(wVersionRequested, &wsaData);
if (err != 0)
{
return;
}
//判斷高低位元組是不是2,如果不是2.2的版本則退出
if (LOBYTE(wsaData.wVersion) != 2 ||
HIBYTE(wsaData.wVersion) != 2)
{
return;
}
//創建流式套接字,基於TCP(SOCK_STREAM)
SOCKET socSrv = socket(AF_INET, SOCK_STREAM, 0);
//Socket地址結構體的創建
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);//轉換Unsigned long型為網路位元組序格
addrSrv.sin_family = AF_INET;//指定地址簇
addrSrv.sin_port = htons(6000);
//指定埠號,除sin_family參數外,其它參數都是網路位元組序,因此需要轉換
//將套接字綁定到一個埠號和本地地址上
bind(socSrv, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));//必須用sizeof,strlen不行
listen(socSrv, 5);
SOCKADDR_IN addrClient;//字義用來接收客戶端Socket的結構體
int len = sizeof(SOCKADDR);//初始化參數,這個參數必須進行初始化,sizeof
//循環等待接受客戶端發送請求
while (1)
{
//等待客戶請求到來;當請求到來後,接受連接請求,
//返回一個新的對應於此次連接的套接字(accept)。
//此時程序在此發生阻塞
SOCKET sockConn = accept(socSrv, (SOCKADDR*)&addrClient, &len);
char sendBuf[100];
sprintf(sendBuf, "Welcome %s to JoyChou",
inet_ntoa(addrClient.sin_addr));//格式化輸出
//用返回的套接字和客戶端進行通信
send(sockConn, sendBuf, strlen(sendBuf)+1, 0);//多發送一個位元組
//接收數據
char recvBuf[100];
recv(sockConn, recvBuf, 100, 0);
printf("%s\\n", recvBuf);
closesocket(sockConn);
}
}
他採用了一個while死循環去監聽客戶端的請求。

先上源代碼
public final class ActivityThread {
public static void main(String[] args) {
SamplingProfilerIntegration.start();
CloseGuard.setEnabled(false);
Environment.initForCurrentUser();
EventLogger.setReporter(new EventLoggingReporter());
Security.addProvider(new AndroidKeyStoreProvider());
final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
TrustedCertificateStore.setDefaultUserDirectory(configDir);
Process.setArgV0("<pre-initialized>");
Looper.prepareMainLooper();
//從中可以看到為app開辟了一個線程進入了looper之中
ActivityThread thread = new ActivityThread();
thread.attach(false);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
AsyncTask.init();
if (false) {
Looper.myLooper().setMessageLogging(new
LogPrinter(Log.DEBUG, "ActivityThread"));
}
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
}
看到源碼失望了,沒有一個while循環啊,其實用了他方法實現
//用一個looper的機制循環監聽響應
Looper.prepareMainLooper();
Looper.loop();
進一步深入代碼
public static void loop() {
final Looper me = myLooper();
if (me == null) {
throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
}
final MessageQueue queue = me.mQueue;
Binder.clearCallingIdentity();
final long ident = Binder.clearCallingIdentity();
// 在這里看到了一個循環監聽消息
for (;;) {
Message msg = queue.next(); // might block
if (msg == null) {
// No message indicates that the message queue is quitting.
return;
}
Printer logging = me.mLogging;
if (logging != null) {
logging.println(">>>>> Dispatching to " + msg.target + " " +
msg.callback + ": " + msg.what);
}
msg.target.dispatchMessage(msg);
if (logging != null) {
logging.println("<<<<< Finished to " + msg.target + " " + msg.callback);
}
// Make sure that ring the course of dispatching the
// identity of the thread wasn't corrupted.
final long newIdent = Binder.clearCallingIdentity();
if (ident != newIdent) {
Log.wtf(TAG, "Thread identity changed from 0x"
+ Long.toHexString(ident) + " to 0x"
+ Long.toHexString(newIdent) + " while dispatching to "
+ msg.target.getClass().getName() + " "
+ msg.callback + " what=" + msg.what);
}
msg.recycleUnchecked();
}
}

Ⅳ android如何實現圖片批量上傳

首先,以下架構下的批量文件上傳可能會失敗或者不會成功:
1.android客戶端+springMVC服務端:服務端採用org.springframework.web.multipart.MultipartHttpServletRequest作為批量上傳接收類,這種搭配下的批量文件上傳會失敗,最終服務端只會接受到一個文件,即只會接受到第一個文件。可能因為MultipartHttpServletRequest對servlet原本的HttpServletRequest類進行封裝,導致批量上傳有問題。
2.android客戶端+strutsMVC服務端:
上傳成功的方案:
採用android客戶端+Servlet(HttpServletRequest)進行文件上傳。
Servlet端代碼如下:

[java] view plainprint?
DiskFileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
try
{
List items = upload.parseRequest(request);
Iterator itr = items.iterator();
while (itr.hasNext())
{
FileItem item = (FileItem) itr.next();
if (item.isFormField())
{
System.out.println("表單參數名:" + item.getFieldName() + ",表單參數值:" + item.getString("UTF-8"));
}
else
{
if (item.getName() != null && !item.getName().equals(""))
{
System.out.println("上傳文件的大小:" + item.getSize());
System.out.println("上傳文件的類型:" + item.getContentType());
// item.getName()返回上傳文件在客戶端的完整路徑名稱
System.out.println("上傳文件的名稱:" + item.getName());

File tempFile = new File(item.getName());
// 上傳文件的保存路徑
File file = new File(sc.getRealPath("/") + savePath, tempFile.getName());
item.write(file);
request.setAttribute("upload.message", "上傳文件成功!");
} else
{
request.setAttribute("upload.message", "沒有選擇上傳文件!");
}
}
}
}
catch (FileUploadException e)
{
e.printStackTrace();
}
catch (Exception e)
{
e.printStackTrace();
request.setAttribute("upload.message", "上傳文件失敗!");
}
request.getRequestDispatcher("/uploadResult.jsp").forward(request, response);

android端代碼如下:

[java] view plainprint?
public class SocketHttpRequester {
/**
*多文件上傳
* 直接通過HTTP協議提交數據到伺服器,實現如下面表單提交功能:
* <FORM METHOD=POST ACTION="http://192.168.1.101:8083/upload/servlet/UploadServlet" enctype="multipart/form-data">
<INPUT TYPE="text" NAME="name">
<INPUT TYPE="text" NAME="id">
<input type="file" name="imagefile"/>
<input type="file" name="zip"/>
</FORM>
* @param path 上傳路徑(註:避免使用localhost或127.0.0.1這樣的路徑測試,因為它會指向手機模擬器,你可以使用http://www.iteye.cn或http://192.168.1.101:8083這樣的路徑測試)
* @param params 請求參數 key為參數名,value為參數值
* @param file 上傳文件
*/
public static boolean post(String path, Map<String, String> params, FormFile[] files) throws Exception{
final String BOUNDARY = "---------------------------7da2137580612"; //數據分隔線
final String endline = "--" + BOUNDARY + "--\r\n";//數據結束標志

int fileDataLength = 0;
for(FormFile uploadFile : files){//得到文件類型數據的總長度
StringBuilder fileExplain = new StringBuilder();
fileExplain.append("--");
fileExplain.append(BOUNDARY);
fileExplain.append("\r\n");
fileExplain.append("Content-Disposition: form-data;name=\""+ uploadFile.getParameterName()+"\";filename=\""+ uploadFile.getFilname() + "\"\r\n");
fileExplain.append("Content-Type: "+ uploadFile.getContentType()+"\r\n\r\n");
fileExplain.append("\r\n");
fileDataLength += fileExplain.length();
if(uploadFile.getInStream()!=null){
fileDataLength += uploadFile.getFile().length();
}else{
fileDataLength += uploadFile.getData().length;
}
}
StringBuilder textEntity = new StringBuilder();
for (Map.Entry<String, String> entry : params.entrySet()) {//構造文本類型參數的實體數據
textEntity.append("--");
textEntity.append(BOUNDARY);
textEntity.append("\r\n");
textEntity.append("Content-Disposition: form-data; name=\""+ entry.getKey() + "\"\r\n\r\n");
textEntity.append(entry.getValue());
textEntity.append("\r\n");
}
//計算傳輸給伺服器的實體數據總長度
int dataLength = textEntity.toString().getBytes().length + fileDataLength + endline.getBytes().length;

URL url = new URL(path);
int port = url.getPort()==-1 ? 80 : url.getPort();
Socket socket = new Socket(InetAddress.getByName(url.getHost()), port);
OutputStream outStream = socket.getOutputStream();
//下面完成HTTP請求頭的發送
String requestmethod = "POST "+ url.getPath()+" HTTP/1.1\r\n";
outStream.write(requestmethod.getBytes());
String accept = "Accept: image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-shockwave-flash, application/xaml+xml, application/vnd.ms-xpsdocument, application/x-ms-xbap, application/x-ms-application, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*\r\n";
outStream.write(accept.getBytes());
String language = "Accept-Language: zh-CN\r\n";
outStream.write(language.getBytes());
String contenttype = "Content-Type: multipart/form-data; boundary="+ BOUNDARY+ "\r\n";
outStream.write(contenttype.getBytes());
String contentlength = "Content-Length: "+ dataLength + "\r\n";
outStream.write(contentlength.getBytes());
String alive = "Connection: Keep-Alive\r\n";
outStream.write(alive.getBytes());
String host = "Host: "+ url.getHost() +":"+ port +"\r\n";
outStream.write(host.getBytes());
//寫完HTTP請求頭後根據HTTP協議再寫一個回車換行
outStream.write("\r\n".getBytes());
//把所有文本類型的實體數據發送出來
outStream.write(textEntity.toString().getBytes());
//把所有文件類型的實體數據發送出來
for(FormFile uploadFile : files){
StringBuilder fileEntity = new StringBuilder();
fileEntity.append("--");
fileEntity.append(BOUNDARY);
fileEntity.append("\r\n");
fileEntity.append("Content-Disposition: form-data;name=\""+ uploadFile.getParameterName()+"\";filename=\""+ uploadFile.getFilname() + "\"\r\n");
fileEntity.append("Content-Type: "+ uploadFile.getContentType()+"\r\n\r\n");
outStream.write(fileEntity.toString().getBytes());
if(uploadFile.getInStream()!=null){
byte[] buffer = new byte[1024];
int len = 0;
while((len = uploadFile.getInStream().read(buffer, 0, 1024))!=-1){
outStream.write(buffer, 0, len);
}
uploadFile.getInStream().close();
}else{
outStream.write(uploadFile.getData(), 0, uploadFile.getData().length);
}
outStream.write("\r\n".getBytes());
}
//下面發送數據結束標志,表示數據已經結束
outStream.write(endline.getBytes());

BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
if(reader.readLine().indexOf("200")==-1){//讀取web伺服器返回的數據,判斷請求碼是否為200,如果不是200,代表請求失敗
return false;
}
outStream.flush();
outStream.close();
reader.close();
socket.close();
return true;
}

/**
*單文件上傳
* 提交數據到伺服器
* @param path 上傳路徑(註:避免使用localhost或127.0.0.1這樣的路徑測試,因為它會指向手機模擬器,你可以使用http://www.itcast.cn或http://192.168.1.10:8080這樣的路徑測試)
* @param params 請求參數 key為參數名,value為參數值
* @param file 上傳文件
*/
public static boolean post(String path, Map<String, String> params, FormFile file) throws Exception{
return post(path, params, new FormFile[]{file});
}
}

Ⅳ android 開發框架有哪些

主要總結了7個好用的android 開發框架推薦給你:
一、 Afinal

Afinal是一個Android的ioc,orm框架,內置了四大模塊功能:FinalAcitivity,FinalBitmap,FinalDb,FinalHttp。通過finalActivity,我們可以通過註解的方式進行綁定ui和事件。通過finalBitmap,我們可以方便的載入bitmap圖片,而無需考慮oom等問題。通過finalDB模塊,我們一行代碼就可以對android的sqlite資料庫進行增刪改查。通過FinalHttp模塊,我們可以以ajax形式請求http數據。

功能:

一個android的ioc,orm框架,內置了四大模塊功能:FinalAcitivity,FinalBitmap,FinalDb,FinalHttp。通過finalActivity,我們可以通過註解的方式進行綁定ui和事件。通過finalBitmap,我們可以方便的載入bitmap圖片,而無需考慮oom等問題。通過finalDB模塊,我們一行代碼就可以對android的sqlite資料庫進行增刪改查。通過FinalHttp模塊,我們可以以ajax形式請求http數據。

優點:功能比較全面,文檔完善,代碼效率比較高。

缺點:沒有項目demo,框架的時間比較久,代碼冗餘比較多(這也是無可避免的),文檔比較老跟不上代碼更新進度。

二、 xUtils

xUtils:可以說是Afinal的升級版。

xUtils 包含了很多實用的android工具。

xUtils 支持大文件上傳,更全面的http請求協議支持(10種謂詞),擁有更加靈活的ORM,更多的事件註解支持且不受混淆影響...

xUitls 最低兼容android 2.2 (api level 8)

三、 ThinkAndroid

ThinkAndroid是一個免費的開源的、簡易的、遵循Apache2開源協議發布的Android開發框架,其開發宗旨是簡單、快速的進行Android應用程序的開發,包含Android
mvc、簡易sqlite orm、ioc模塊、封裝Android
httpclitent的http模塊,具有快速構建文件緩存功能,無需考慮緩存文件的格式,都可以非常輕松的實現緩存,它還基於文件緩存模塊實現了圖片緩存功能,在android中載入的圖片的時候,對oom的問題,和對載入圖片錯位的問題都輕易解決。他還包括了一個手機開發中經常應用的實用工具類,如日誌管理,配置文件管理,android下載器模塊,網路切換檢測等等工具

四、 LoonAndroid

如果你想看ui方面的東西,這里沒有,想要看牛逼的效果這里也沒有。這只是純實現功能的框架,它的目標是節省代碼量,降低耦合,讓代碼層次看起來更清晰。整個框架一部分是網上的,一部分是我改的,為了適應我的編碼習慣,還有一部分像orm完全是網上的組件。在此感謝那些朋友們。
整個框架式的初衷是為了偷懶,之前都是一個功能一個jar,做項目的時候拉進去,這樣對於我來說依然還是比較麻煩。最後就導致我把所有的jar做成了一個工具集合包。
有很多框架都含有這個工具集合里的功能,這些不一定都好用,因為這是根據我個人使用喜歡來實現的,如果你們有自己的想法,可以自己把架包解壓了以後,源碼拉出來改動下。
目前很多框架都用到了註解,除了androidannotations沒有入侵我們應用的代碼以外,其他的基本上都有,要麼是必須繼承框架裡面的activity,要麼是必須在activity的oncreat裡面調用某個方法。
整個框架式不同於androidannotations,Roboguice等ioc框架,這是一個類似spring的實現方式。在整應用的生命周期中找到切入點,然後對activity的生命周期進行攔截,然後插入自己的功能。

五、 KJFrameForAndroid

KJFrameForAndroid 又叫KJLibrary,是一個android的orm 和 ioc
框架。同時封裝了android中的Bitmap與Http操作的框架,使其更加簡單易用;

KJFrameForAndroid的設計思想是通過封裝Android原生SDK中復雜的復雜操作而達到簡化Android應用級開發,最終實現快速而又安全的開發APP。我們提倡用最少的代碼,完成最多的操作,用最高的效率,完成最復雜的功能。

功能:

一個android的orm 和 ioc 框架。同時封裝了android中的Bitmap與Http操作的框架,使其更加簡單易用;
KJFrameForAndroid開發框架的設計思想是通過封裝Android原生SDK中復雜的復雜操作而達到簡化Android應用級開發,最終實現快速而又安全的開發APP。總共分為五大模塊:UILibrary,UtilsLibrary,HttpLibrary,BitmapLibrary,DBLibrary。

六、 dhroid

dhroid 是基於android 平台,
極速開發框架,其核心設計目標是開發迅速、代碼量少、學習簡單、功能強大、輕量級、易擴展.使你更快,更好的開發商業級別應用

功能:

1.Ioc容器: (用過spring的都知道)視圖注入,對象注入,介面注入,解決類依賴關系

2.Eventbus: android平台事件匯流排框架,獨創延時事件,事件管理輕松

3.Dhnet: 網路http請求的解決方案,使用簡單,減少代碼,自帶多種網路訪問緩存策略

4.adapter模塊: 數據綁定輕松,不用寫多餘的adapter,天生網路支持(一行代碼搞定載入,刷新問題)

5.DhDb: android中sqlite的最輕量orm框架(增刪改查輕松搞定)

6.Perference: android自帶Perference 升級版,讓你的Perference更強大,更方便

工具集合 JSONUtil(安全處理json),ViewUtil(數據綁定更快) ThreadWorker(非同步任務工具)...

七、 SmartAndroid

SmartAndroid是一套給
Android開發者使用的應用程序開發框架和工具包。它提供一套豐富的標准庫以及簡單的介面和邏輯結構,其目的是使開發人員更快速地進行項目開發。使用
SmartAndroid可以減少代碼的編寫量,並將你的精力投入到項目的創造性開發上。

功能:

SmartAndroid 擁有全范圍的類庫,可以完成大多數通常需要的APP開發任務,包括:
非同步網路操作相關所有功能、強大的圖片處理操作、輕量級ORM資料庫Sqlite庫、zip操作
、動畫特效、Html等解析採集、事件匯流排EventBus/Otto、Gson(Json)、AQuery、主流所有UI控制項(例如:ActionbarSherlock,SlidingMenu,BottomView,Actionbar,DragListView等10多種UI庫)等。

Ⅵ 後端伺服器返回給android應用程序的數據格式通常是

通常是以下幾種:
1、json。
2、arraybuffer。
3、blob。
4、document。
5、text。
6、stream。

Ⅶ android 網路請求數據一般寫在哪

在iOS開發中有大名鼎鼎的ASIHttpRequest庫,用來處理網路請求操作,今天要介紹的是一個在Android上同樣強大的網路請求庫android-async-http,目前非常火的應用Instagram和Pinterest的Android版就是用的這個網路請求庫。這個網路請求庫是基於Apache HttpClient庫之上的一個非同步網路請求處理庫,網路處理均基於Android的非UI線程,通過回調方法處理請求結果。

其主要特徵如下:

■處理非同步Http請求,並通過匿名內部類處理回調結果
■Http請求均位於非UI線程,不會阻塞UI操作
■通過線程池處理並發請求
■處理文件上傳、下載
■響應結果自動打包JSON格式
■自動處理連接斷開時請求重連
使用android-async-http也非常簡單,到官網下載依賴jar包,導入工程中libs文件夾下並添加到工程路徑即可。

Ⅷ 安卓如何擴展輸出

選擇設備的工作基本就做完了,但是前提是需要j從ava層到framework層為該音頻類型打通過程。實際上這個參照一種音頻類型的實現就很容易解決。基本上理清一個audiotrack從java層到native層的調用過程即可,在java層audiomanger與audiosystem中添加我們自定義的音頻類型之後來看audiotrack的構造函數,5.1之於4.4多了一個AudioAttributes,這對上層傳下來的streamType做了一層封裝,看上去是更方便了我們的擴展,通過上層stream_type轉化得到 private int mUsage = USAGE_UNKNOWN;

和 private int mContentType = CONTENT_TYPE_UNKNOWN兩種類型,到了native層AudioTrack.cpp的set函數中:

status_t AudioTrack::set(

audio_stream_type_t streamType,

uint32_t sampleRate,

audio_format_t format,

audio_channel_mask_t channelMask,

size_t frameCount,

audio_output_flags_t flags,

callback_t cbf,

void* user,

uint32_t notificationFrames,

const sp& sharedBuffer,

bool threadCanCallJava,

int sessionId,

transfer_type transferType,

const audio_offload_info_t *offloadInfo,

int uid,

pid_t pid,

const audio_attributes_t* pAttributes)

{

ALOGI("set(): %p streamType %d, sampleRate %u, format %#x, channelMask %#x, frameCount %zu, "

"flags #%x, notificationFrames %u, sessionId %d, transferType %d",

this,streamType, sampleRate, format, channelMask, frameCount, flags, notificationFrames,

sessionId, transferType);

switch (transferType) {

case TRANSFER_DEFAULT:

if (sharedBuffer != 0) {

transferType = TRANSFER_SHARED;

} else if (cbf == NULL || threadCanCallJava) {

transferType = TRANSFER_SYNC;

} else {

transferType = TRANSFER_CALLBACK;

}

break;

case TRANSFER_CALLBACK:

if (cbf == NULL || sharedBuffer != 0) {

ALOGE("Transfer type TRANSFER_CALLBACK but cbf == NULL || sharedBuffer != 0");

return BAD_VALUE;

}

break;

case TRANSFER_OBTAIN:

case TRANSFER_SYNC:

if (sharedBuffer != 0) {

ALOGE("Transfer type TRANSFER_OBTAIN but sharedBuffer != 0");

return BAD_VALUE;

}

break;

case TRANSFER_SHARED:

if (sharedBuffer == 0) {

ALOGE("Transfer type TRANSFER_SHARED but sharedBuffer == 0");

return BAD_VALUE;

}

break;

default:

ALOGE("Invalid transfer type %d", transferType);

return BAD_VALUE;

}

mSharedBuffer = sharedBuffer;

mTransfer = transferType;

ALOGV_IF(sharedBuffer != 0, "sharedBuffer: %p, size: %d", sharedBuffer->pointer(),

sharedBuffer->size());

ALOGV("set() streamType %d frameCount %zu flags %04x", streamType, frameCount, flags);

AutoMutex lock(mLock);

// invariant that mAudioTrack != 0 is true only after set() returns successfully

if (mAudioTrack != 0) {

ALOGE("Track already in use");

return INVALID_OPERATION;

}

// handle default values first.

if (streamType == AUDIO_STREAM_DEFAULT) {

streamType = AUDIO_STREAM_MUSIC;

}

if (pAttributes == NULL) {

if (uint32_t(streamType) >= AUDIO_STREAM_PUBLIC_CNT) {

ALOGE("Invalid stream type %d", streamType);

return BAD_VALUE;

}

mStreamType = streamType;

} else {

// stream type shouldn't be looked at, this track has audio attributes

memcpy(&mAttributes, pAttributes, sizeof(audio_attributes_t));

ALOGV("Building AudioTrack with attributes: usage=%d content=%d flags=0x%x tags=[%s]",

mAttributes.usage, mAttributes.content_type, mAttributes.flags, mAttributes.tags);

mStreamType = AUDIO_STREAM_DEFAULT;

}

// these below should probably come from the audioFlinger too...

if (format == AUDIO_FORMAT_DEFAULT) {

format = AUDIO_FORMAT_PCM_16_BIT;

}

......看到 mStreamType = AUDIO_STREAM_DEFAULT; stream_type已經被設為-1,後面獲取設備時不再關心stream_type,而是由audio_attributes_t這個結構體來選擇,再來看看這個結構體的定義:

typedef struct {

audio_content_type_t content_type;

audio_usage_t usage;

audio_source_t source;

audio_flags_mask_t flags;

char tags[AUDIO_ATTRIBUTES_TAGS_MAX_SIZE]; /* UTF8 */

} audio_attributes_t;

正是前面提到的mUsage 和mContentType 。

再回到AudioPolicyManager,看看getOutputForAttr介面,改介面調用了我們之前修改過的getDeviceForStrategy來獲取設備:

......

ALOGV("getOutputForAttr() usage=%d, content=%d, tag=%s flags=%08x",

attributes.usage, attributes.content_type, attributes.tags, attributes.flags);

routing_strategy strategy = (routing_strategy) getStrategyForAttr(&attributes);

audio_devices_t device = getDeviceForStrategy(strategy, false /*fromCache*/);

...... 所以在上層將stream_type 與AudioAttributes的轉換做好,這條路就基本打通了,雙音頻輸出的功能就實現了。

Ⅸ Android 如何觸發打開文件

<activity android:name=".EasyNote" android:label="@string/app_name" android:launchMode="singleTask" android:screenOrientation="portrait">
< intent-filter>
< action android:name="android.intent.action.MAIN" />
< category android:name="android.intent.category.LAUNCHER" />
< /intent-filter>
<intent-filter>
< action android:name="android.intent.action.VIEW"></action>
< category android:name="android.intent.category.DEFAULT"></category>
< data android:mimeType="text/plain"></data>
< /intent-filter>
< /activity>
第一個<intent-filter>標簽是每個程序都有的,關鍵是要添加第二個!這樣你的應用程序就會出現在默認打開列表了。。。

注意需要將mimeType修改成你需要的類型,文本文件當然就是:text/plain

還有其它常用的如:

text/plain(純文本)

text/html(HTML文檔)

application/xhtml+xml(XHTML文檔)

image/gif(GIF圖像)

image/jpeg(JPEG圖像)【PHP中為:image/pjpeg】

image/png(PNG圖像)【PHP中為:image/x-png】

video/mpeg(MPEG動畫)

application/octet-stream(任意的二進制數據)

application/pdf(PDF文檔)

application/msword(Microsoft Word文件)

message/rfc822(RFC 822形式)

multipart/alternative(HTML郵件的HTML形式和純文本形式,相同內容使用不同形式表示)

application/x-www-form-urlencoded(使用HTTP的POST方法提交的表單)

multipart/form-data(同上,但主要用於表單提交時伴隨文件上傳的場合)

熱點內容
cbs加密 發布:2024-05-19 06:29:56 瀏覽:200
ssis存儲過程 發布:2024-05-19 06:21:31 瀏覽:630
怎樣刪除小視頻文件夾 發布:2024-05-19 05:49:29 瀏覽:589
開啟php短標簽 發布:2024-05-19 05:44:12 瀏覽:473
android各國語言 發布:2024-05-19 05:42:54 瀏覽:247
微信什麼資料都沒怎麼找回密碼 發布:2024-05-19 05:35:34 瀏覽:907
填志願密碼是什麼 發布:2024-05-19 05:30:23 瀏覽:318
城堡爭霸自動掠奪腳本 發布:2024-05-19 05:22:06 瀏覽:204
asp編程工具 發布:2024-05-19 05:20:36 瀏覽:143
insertpython 發布:2024-05-19 05:12:26 瀏覽:244