Android跨應用間的數據傳輸

在有些項目中,會有多個應用出現,這樣應用間的數據傳輸就成瞭必然。那應用間的數據傳輸要怎麼實現呢?我們知道,在跨Activity之間的數據傳輸可以通過Bundle和Intent結合來實現,那應用間的數據傳輸是否也可以使用這種方式呢?答案是可以的!

在使用Bundle來傳輸數據時,又有多種途徑,比如直接數據傳輸、序列化數據傳輸、打包數據傳輸等。下面是從TransDataA應用傳輸到TransDataB應用的效果圖。

在直接傳輸數據時,我們傳輸的是圖片數據,序列化傳輸和打包傳輸時傳輸的是相應的結構信息,下面是實現的代碼:vcD4KPHA+PHN0cm9uZz5UcmFuc0RhdGFBz+7Ev7XETWFpbkFjdGl2aXR5LmphdmE8L3N0cm9uZz48YnI+CjwvcD4KPHA+PC9wPgo8cHJlIGNsYXNzPQ==”brush:java;”>package com.example.transdataa;

import com.example.data.DirectData;
import com.example.data.SerialData;
import com.example.data.ParcelData;

import com.kitsp.contentsp.IntentSp;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class MainActivity extends Activity {

private Button _directTrans_button = null;
private Button _serialTrans_button = null;
private Button _pracelTrans_button = null;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Init();
}

private void Init() {
FetchUIControls();
BindingEvents();
}

private void FetchUIControls() {
_directTrans_button = (Button) findViewById(R.id.activity_main_directTrans);
_serialTrans_button = (Button) findViewById(R.id.activity_main_serialTrans);
_pracelTrans_button = (Button) findViewById(R.id.activity_main_ParcelTrans);
}

private void BindingEvents() {
if(_directTrans_button!=null)
{
_directTrans_button.setOnClickListener(new OnClickListenerEx());
}

if (_serialTrans_button != null) {
_serialTrans_button.setOnClickListener(new OnClickListenerEx());
}

if (_pracelTrans_button != null) {
_pracelTrans_button.setOnClickListener(new OnClickListenerEx());
}
}

private class OnClickListenerEx implements OnClickListener {

@Override
public void onClick(View v) {
Bundle bundle = null;
switch (v.getId()) {
case R.id.activity_main_directTrans:
{
bundle=DirectGenerateData();
break;
}
case R.id.activity_main_serialTrans: {
bundle = SerializeData();
break;
}
case R.id.activity_main_ParcelTrans: {
bundle = ParcelableData();
break;
}
default: {
break;
}
}
TransData(bundle);
}

private Bundle DirectGenerateData()
{
Bundle bundle = new Bundle();
Bitmap bitmap=BitmapFactory.decodeResource(getResources(), R.drawable.test);
bundle.putParcelable(DirectData.KEY, bitmap);
return bundle;
}

private Bundle SerializeData() {
SerialData serialData = new SerialData();
serialData.SetSerialNo(“123456789”);
serialData.SetWeight(180.82);
Bundle bundle = new Bundle();
bundle.putSerializable(SerialData.KEY, serialData);
return bundle;
}

private Bundle ParcelableData() {
ParcelData parcelData = new ParcelData();
parcelData.SetAccount(“Test”);
parcelData.SetPassword(“ABCDEFG”);
parcelData.SetAge(25);
Bundle bundle = new Bundle();
bundle.putParcelable(ParcelData.KEY, parcelData);
return bundle;
}

private void TransData(Bundle bundle) {
if (bundle == null) {
return;
}
Intent intent = new Intent();
ComponentName cn = new ComponentName(“com.example.transdatab”,
“com.example.transdatab.MainActivity”);
if (cn != null) {
intent.setComponent(cn);
intent.putExtras(bundle);
startActivity(intent);
}

}
}
}
註:

1、數據都是以Bundle的形式添加到Intent中的。一定要記得在Intent中putExtras(bundle)。這是將數據添加到Intent的必須步驟,有時可能會遺忘。

2、在跨應用時,使用Intent來啟動另一個應用。這裡采用ComponentName的形式來啟動另一個應用。\

3、在使用Intent傳輸數據時有上限的限制,不然會導致應用卡死或黑屏。具體上限是多少,網上有很多說法,有說40kb的、有說100kb的,有說1M的,我實際測試的結果是200kb左右。我的結論是可能與具體的設備有關。

TransDataB項目的MainActivity.java

package com.example.transdatab;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.widget.TextView;

import com.example.data.DirectData;
import com.example.data.SerialData;
import com.example.data.ParcelData;

public class MainActivity extends Activity {

	private SerialData _serialData = null;
	private ParcelData _parcelData = null;
	private Bitmap _bitmap=null;
	private TextView _info_textView = null;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		Init();
	}

	private void Init() {
		FetchUIControls();
		InitParams();
		InitUI();
	}

	private void InitParams() {
		try {
			Intent intent = getIntent();
			if (intent == null) {
				_info_textView.setText("Intent is null");
				return;
			}

			if(intent.hasExtra(DirectData.KEY))
			{
				_bitmap=intent.getParcelableExtra(DirectData.KEY);
			}
			
			if (intent.hasExtra(SerialData.KEY)) {
				_serialData = (SerialData) intent
						.getSerializableExtra(SerialData.KEY);
				_info_textView.setText("MachineData");
			}

			if (intent.hasExtra(ParcelData.KEY)) {
				_info_textView.setText("RegisterData");
				_parcelData = (ParcelData) intent
						.getParcelableExtra(ParcelData.KEY);
			}

		} catch (Exception e) {
			_info_textView.setText("Exception");
		}
	}

	private void FetchUIControls() {
		_info_textView = (TextView) findViewById(R.id.activity_main_info);
	}

	private void InitUI() {

		if (_info_textView == null) {

			return;
		}
				
		String info = "";

		if(_bitmap!=null)
		{
			BitmapDrawable bitmapDrawble= new BitmapDrawable(MainActivity.this.getResources(), _bitmap); 
			bitmapDrawble.setBounds(0, 0, _bitmap.getWidth(),_bitmap.getHeight());
			_info_textView.setCompoundDrawables(null, bitmapDrawble, null, null);
		}
		
		if (_serialData != null) {
			info = "SerialData\nSerialNo=" + _serialData.GetSerialNo() + "\nWeight="
					+ _serialData.GetWeight() + "\n";
		}

		if (_parcelData != null) {
			info = "ParcelData\nAccount=" + _parcelData.GetAccount() + "\n" + "Password="
					+ _parcelData.GetPassword() + "\n" + "Age="
					+ _parcelData.GetAge() + "\n";
		}
		_info_textView.setText(info);
	}
}

註:

1、在接收數據的一端,先獲取Intent,再判斷是否有相應的KEY,然後再解開數據。

2、在獲取直接傳輸過來的數據時,采用intent.getParcelableExtra來獲取數據。

在TransDataA和TransDataB中傳輸序列化和打包的數據時,一定要用同樣的KEY和同樣的類,不然數據會解不開。這裡,他們共用的是TransData項目中的類,下面是代碼。

TransData項目的DirectData.java

package com.example.data;

public class DirectData {
	public final static String KEY="{56896229-BFCD-4630-B1EF-4D8FA6CA90FE}";
}

註:直接傳輸數據,隻需要一個唯一的KEY就可能 瞭。KEY采用GUID以確保唯一性,也可以自己命名,隻要能確保唯一性就可以。

TransData項目的SerialData.java

package com.example.data;

import java.io.Serializable;

public class SerialData implements Serializable {

	public static final String KEY="{1D7D9EF2-06F6-4A55-9DF6-293471209D15}";
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 1464294135398038125L;

	private String _serialNo="";
	private double _weight_kg=0;
	
	public void SetSerialNo(String serialNo)
	{
		_serialNo=serialNo;
	}
	
	public String GetSerialNo()
	{
		return _serialNo;
	}
	
	public void SetWeight(double weight_kg)
	{
		_weight_kg=weight_kg;
	}
	
	public double GetWeight()
	{
		return _weight_kg;
	}
	
}

註:

1、需實現Serializable。

2、每一個變量都必須要有對應的Set和Get方法。

TransData項目的ParcelData.java

package com.example.data;

import android.os.Parcel;
import android.os.Parcelable;

public class ParcelData implements Parcelable {

	public final static String KEY="{00D2DF54-B448-415F-AB7C-E0C6B6D3E608}";
	
	private String _account="";
	private String _password="";
	private int _age=0;
	
	public void SetAccount(String account)
	{
		_account=account;
	}
	
	public String GetAccount()
	{
		return _account;
	}
	
	public void SetPassword(String password)
	{
		_password=password;
	}
	
	public String GetPassword()
	{
		return _password;
	}
	
	public void SetAge(int age)
	{
		_age=age;
	}
	
	public int GetAge()
	{
		return _age;
	}
	
	
	@Override
	public int describeContents() {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public void writeToParcel(Parcel dest, int flags) {
		// TODO Auto-generated method stub
		dest.writeString(_account);
		dest.writeString(_password);
		dest.writeInt(_age);
	}

	public static final Parcelable.Creator CREATOR=new Creator() {

		@Override
		public ParcelData createFromParcel(Parcel source) {
			ParcelData registerData=new ParcelData();
			registerData._account=source.readString();
			registerData._password=source.readString();
			registerData._age=source.readInt();
			return registerData;
		}

		@Override
		public ParcelData[] newArray(int size) {
			
			return new ParcelData[size];
		}
		
	};
}

註:

1、需實現Parcelable。

2、每一個變量都必須要有對應的Set和Get方法。

3、需重載writeToParcel寫入數據。

4、必須實現Parcelable.Creator CREATOR,而且必須為public靜態。在實現時還要重載createFromParcel來讀取數據。

5、TransData需要被TransDataA和TransDataB共同引用,為瞭確保正確,可以將TransData設置為Library,然後在TransDataA和TransDataB中引用。可參看下圖

Android跨應用間的數據傳輸

發佈留言