[android] 影片邊播放邊下載須知

想邊播放邊下載,第一件事要確認影片檔案的moov atom檔案是否在影片的開頭
參考:http://blog.sina.com.cn/s/blog_6c762bb301016swe.html
1.先下載isoViewer來查看影片資訊
https://code.google.com/archive/p/mp4parser/downloads
選擇isoviewer-1.0-RC-35.jar下載
2.使用cmd開啟
在cmd下輸入指令 java -jar isoviewer-1.0-RC-35.jar
3.確認是否moov檔在前面

1458727193845

像這樣就是沒有在前面,需要一些動作來做到移動

4.下載qt-faststart
網路收尋或者從參考網站下載

5.接著在cmd下指令
指令 原檔名 輸出檔名
qt-faststart xxx.mp4 xxx1.mp4

6.再用isoviewer確認一下

1458727840417

[Android]抓取相簿圖片並且裁切

1.如果只需要抓取相簿圖片,不裁切的方法

onActivityResult加入
(android版本低於KITKAT使用selectImage(),以上的用getPath(), 網路查到的,功能可以正常執行,但未查明實際程序如何跑的)

            if (requestCode == IMAGE_TAKE && data != null) {
                userIconUri = data.getData();
                LogUtils.d(TAG, userIconUri.toString());
                userIconPath = selectImage(getActivity(), userIconUri);
//                userIconPath = getPath(getActivity(), userIconUri);
                LogUtils.d(TAG, userIconPath);
                ImageLoader.getInstance().displayImage(userIconPath, userIcon, mOptions);
                isImageChange = true;
            }
                Intent intent=new Intent(Intent.ACTION_GET_CONTENT);//ACTION_OPEN_DOCUMENT
                intent.addCategory(Intent.CATEGORY_OPENABLE);
                intent.setType("image/jpeg");
                if(android.os.Build.VERSION.SDK_INT>=android.os.Build.VERSION_CODES.KITKAT){
                    startActivityForResult(intent, IMAGE_TAKE_KITKAT);
                }else{
                    startActivityForResult(intent, IMAGE_TAKE);
                }

getPath()

    /**
     * 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.
     */
    public static 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 index = cursor.getColumnIndexOrThrow(column);
                return cursor.getString(index);
            }
        } finally {
            if (cursor != null)
                cursor.close();
        }
        return null;
    }


    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is ExternalStorageProvider.
     */
    public static 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.
     */
    public static 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.
     */
    public static boolean isMediaDocument(Uri uri) {
        return "com.android.providers.media.documents".equals(uri.getAuthority());
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is Google Photos.
     */
    public static boolean isGooglePhotosUri(Uri uri) {
        return "com.google.android.apps.photos.content".equals(uri.getAuthority());
    }

    public static boolean isNewGooglePhotoUri(Uri uri) {
        return "com.google.android.apps.photos.contentprovider".equals(uri.getAuthority());
    }

    public static String getImageUrlWithAuthority(Context context, Uri uri) {
        InputStream is = null;
        if (uri.getAuthority() != null) {
            LogUtils.d(TAG, "getImageUrlWithAuthority");
            try {
                is = context.getContentResolver().openInputStream(uri);
                Bitmap bmp = BitmapFactory.decodeStream(is);
                return writeToTempImageAndGetPathUri(context, bmp).toString();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }finally {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }

    public static Uri writeToTempImageAndGetPathUri(Context inContext, Bitmap inImage) {
        ByteArrayOutputStream bytes = new ByteArrayOutputStream();
        inImage.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
        String path = MediaStore.Images.Media.insertImage(inContext.getContentResolver(), inImage, "Title", null);
        return Uri.parse(path);
    }

selectImage()

    public static String selectImage(Context context,Uri data){
        Uri selectedImage = data;
//      Log.e(TAG, selectedImage.toString());
        if(selectedImage!=null){
            String uriStr=selectedImage.toString();
            String path=uriStr.substring(10,uriStr.length());
            if(path.startsWith("com.sec.android.gallery3d")){
                LogUtils.e(TAG, "It's auto backup pic path:"+selectedImage.toString());
                return null;
            }
        }
        String[] filePathColumn = { MediaStore.Images.Media.DATA };
        Cursor cursor = context.getContentResolver().query(selectedImage,filePathColumn, null, null, null);
        cursor.moveToFirst();
        int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
        String picturePath = cursor.getString(columnIndex);
        cursor.close();
        return picturePath;
    }

我原本使用的方法

    private String getPathFromURI(Uri selectedImage) {
        final String[] filePathColumn = { MediaStore.MediaColumns.DATA, MediaStore.MediaColumns.DISPLAY_NAME };
        Cursor cursor = getActivity().getContentResolver().query(selectedImage, filePathColumn, null, null, null);
        String filePath = "";
        // some devices (OS versions return an URI of com.android instead of com.google.android
        if (selectedImage.toString().startsWith("content://com.android.gallery3d.provider"))  {
            // use the com.google provider, not the com.android provider.
            selectedImage = Uri.parse(selectedImage.toString().replace("com.android.gallery3d","com.google.android.gallery3d"));
            filePath = selectedImage.getPath();
        } else if (selectedImage.toString().startsWith("content://com.google.android.apps.photos.content/"))  {
            // use the com.google provider, not the com.android provider.
            filePath = selectedImage.getLastPathSegment();
        } else if (selectedImage.toString().startsWith("content://com.google.android.apps.photos.contentprovider"))  {
            // use the com.google provider, not the com.android provider.
            filePath = getImageUrlWithAuthority(getActivity(), selectedImage);
        } else {
            filePath = Uri.decode(userIconUri.toString());
        }
        return filePath;
    }

    public static String getImageUrlWithAuthority(Context context, Uri uri) {
        InputStream is = null;
        if (uri.getAuthority() != null) {
            LogUtils.d(TAG, "getImageUrlWithAuthority");
            try {
                is = context.getContentResolver().openInputStream(uri);
                Bitmap bmp = BitmapFactory.decodeStream(is);
                return writeToTempImageAndGetPathUri(context, bmp).toString();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }finally {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }

    public static Uri writeToTempImageAndGetPathUri(Context inContext, Bitmap inImage) {
        ByteArrayOutputStream bytes = new ByteArrayOutputStream();
        inImage.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
        String path = MediaStore.Images.Media.insertImage(inContext.getContentResolver(), inImage, "Title", null);
        return Uri.parse(path);
    }

上面的程式執行完,會發現圖片可能會有翻轉角度不正常的,還需要另外判斷角度的數據
(這是網路上查到的資料,還未執行過,等以後要使用再來了解程序如何執行的)

    public static int getExifOrientation(String filepath) {// YOUR MEDIA PATH AS STRING
        int degree = 0;
        ExifInterface exif = null;
        try {
            exif = new ExifInterface(filepath);
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        if (exif != null) {
            int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, -1);
            if (orientation != -1) {
                switch (orientation) {
                    case ExifInterface.ORIENTATION_ROTATE_90:
                        degree = 90;
                        break;
                    case ExifInterface.ORIENTATION_ROTATE_180:
                        degree = 180;
                        break;
                    case ExifInterface.ORIENTATION_ROTATE_270:
                        degree = 270;
                        break;
                }

            }
        }
        return degree;
    }

2.抓取相簿圖片,並裁切的方法
先執行Intent.ACTION_GET_CONTENT去圖庫抓圖,返回時再Intent com.android.camera.action.CROP 裁切圖片

                Intent photoPickerIntent = new Intent(Intent.ACTION_GET_CONTENT);
                photoPickerIntent.setType("image/*");
                startActivityForResult(photoPickerIntent, RESULT_LOAD_IMAGE);

onActivityResult()

            if (requestCode == RESULT_LOAD_IMAGE) {
                final String CROP_ACTION = "com.android.camera.action.CROP";
                Intent photoCropIntent = new Intent(CROP_ACTION);
                photoCropIntent.putExtra("crop", "true");
                photoCropIntent.putExtra("aspectX", 1);
                photoCropIntent.putExtra("aspectY", 1);
                photoCropIntent.putExtra("outputX", 300);
                photoCropIntent.putExtra("outputY", 300);
                photoCropIntent.putExtra("scale", true);
                photoCropIntent.putExtra("return-data", false);
                photoCropIntent.putExtra(MediaStore.EXTRA_OUTPUT, getTempUri(getActivity()));
                photoCropIntent.putExtra("outputFormat",
                        Bitmap.CompressFormat.JPEG.toString());
                photoCropIntent.setDataAndType(data.getData(), "image/*");

                startActivityForResult(photoCropIntent, RESULT_CROP_IMAGE);
            }

            if (requestCode == RESULT_CROP_IMAGE) {
                String uriString = null;
                if (data.getAction() != null) {
                    LogUtils.d(TAG, "action");
                    uriString = data.getAction();
                } else if (data.getData() != null) {
                    LogUtils.d(TAG, "data");
                    uriString = data.getDataString();
                }
                LogUtils.d(TAG, "userIconPath:" + uriString);
                if (uriString.startsWith("/")) {
                    ImageLoader.getInstance().displayImage("file://" + uriString, userIcon, mOptions);
                } else {
                    ImageLoader.getInstance().displayImage(uriString, userIcon, mOptions);
                }
            }

建立一個Uri給裁切的圖片使用(Uri如同一個檔案位置)

    private static Uri getTempUri(Context context) {
        return context.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, new ContentValues());
    }

參考網址:
http://my.oschina.net/ryanhoo/blog/86853
http://my.oschina.net/ryanhoo/blog/86842
http://androidbiancheng.blogspot.tw/2011/01/extraoutput.html
http://www.eoeandroid.com/home.php?mod=space&uid=1289462&do=blog&id=49568
http://stackoverflow.com/questions/23236392/failure-delivering-resultinfo

[Android]使用attrs新增物件的屬性並對應selector

功能描述:android的原生物件擁有自己的屬性,例如在layout.xml中設定一個TextView,便有text、enable之類的屬性,若自己想要設定android沒有提供的屬性,就需要在attrs裡面設定。

res/values/attrs.xml

  <declare-styleable name="CalendarPickerView">
    <attr name="android:background"/>
    <attr name="dividerColor" format="color"/>
    <attr name="dayBackground" format="reference"/>
    <attr name="dayTextColor" format="color"/>
    <attr name="titleTextColor" format="color"/>
    <attr name="displayHeader" format="boolean"/>
    <attr name="headerTextColor" format="color"/>
  </declare-styleable>
  <declare-styleable name="calendar_cell">
    <attr name="state_is_can_reserve" format="boolean" />
  </declare-styleable>

format的類別很多color、reference、boolean…
這邊要講的是boolean的控制對應selector

建立一個CustomeView 繼承 TextView

public class CustomeView extends TextView {
    private static final int[] STATE_CAN_RESERVE = {
          R.attr.state_is_can_reserve
      };
    private boolean isReserve = false;
    public void setReserve(boolean isReserve) {
        this.isReserve = isReserve;
        refreshDrawableState();
    }
    @Override protected int[] onCreateDrawableState(int extraSpace) {
        final int[] drawableState = super.onCreateDrawableState(extraSpace + 1);
        if (isReserve) {
            mergeDrawableStates(drawableState, STATE_CAN_RESERVE);
        }
    }
}

super.onCreateDrawableState(extraSpace + 1)
extraSpace是指android的屬性數量,因為有新增一項自定義的,所以加1
mergeDrawableStates(drawableState, STATE_CAN_RESERVE)將自定義的屬性merge進原本的
refreshDrawableState()在setReserve時就會做狀態及畫面的refresh
這樣便完成屬性的設定

再來是selector

    public CalendarPickerView(Context context, AttributeSet attrs) {
        super(context, attrs);

        Resources res = context.getResources();
        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CalendarPickerView);
        final int bg = a.getColor(R.styleable.CalendarPickerView_android_background,
        res.getColor(R.color.calendar_bg));
        dividerColor = a.getColor(R.styleable.CalendarPickerView_dividerColor,
        res.getColor(R.color.calendar_divider));
        dayBackgroundResId = a.getResourceId(R.styleable.CalendarPickerView_dayBackground,
        R.drawable.calendar_bg_selector);
        dayTextColorResId = a.getResourceId(R.styleable.CalendarPickerView_dayTextColor,
        R.color.calendar_text_selector);
        titleTextColor = a.getColor(R.styleable.CalendarPickerView_titleTextColor,
        res.getColor(R.color.calendar_text_active));
        displayHeader = a.getBoolean(R.styleable.CalendarPickerView_displayHeader, true);
        headerTextColor = a.getColor(R.styleable.CalendarPickerView_headerTextColor,
        res.getColor(R.color.calendar_text_active));
    a.recycle();
    }

context.objainStyledAttributes(attrs, R.styleable.CalendarPickerView)
將attrs用TypeArray帶入程式,R.styleable.CalendarPickerView和attrs中的name要相同
dayTextColorResId = a.getResourceId(R.styleable.CalendarPickerView_dayTextColor,
R.color.calendar_text_selector);
將calendar_text_selector帶入

再來是selector

<selector xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <item android:state_selected="true" android:color="@color/custom_text_selected"/>
    <item android:state_pressed="true" android:color="@color/custom_text_selected"/>
    <item app:state_current_month="false" android:color="@color/custom_text_inactive"/>
    <item app:state_today="true" android:color="@color/custom_text_selected"/>
    <item app:state_selectable="false" android:color="@color/custom_text_inactive" />
    <item
        app:state_current_month="true"
        app:state_is_can_reserve="true"
        android:color="@color/custom_background_today" />
    <item
        app:state_current_month="true"
        app:state_is_can_reserve="false"
        android:color="@color/custom_text_inactive" />
    <item android:color="@color/custom_background_today"/>
</selector>

此時,須先加入一行
xmlns:app="http://schemas.android.com/apk/res-auto"
這樣才能找到自定義的屬性
item 中的判斷很像if else 的判斷,如上,當兩個都true時才設定color

[Android]PinnedSectionListView應用

1.宣告 PinnedSectionListView

private PinnedSectionListView mPinnedListView;

2.onCreat的時候,建立 PinnedSectionListView物件,再設定Adapter

mPinnedListView = (PinnedSectionListView) findViewById(R.id.pinned_listview);
mPinnedListView.setAdapter(new SimpleAdapter(this, R.layout.listitem_productlist_content_pinned, getPinnedProductList()));

3.要放入Adapter的物件,要設定兩種狀態

public class Product {
	public static final int ITEM = 0;
	public static final int SECTION = 1;
}

4.建立一個Adapter class繼承ArrayAdapter並實作PinnedSectionListAdapter
因為View有兩準狀態ITEM或SECTION,所以getViewTypeCount()要return 2
isItemViewTypePinned()設定返回要釘住的是哪一個狀態的view

	class SimpleAdapter extends ArrayAdapter<Product> implements PinnedSectionListAdapter {

		int mItemResource;
		List<Product> products;
		public SimpleAdapter(Context context, int resource,	List<Product> products) {
			super(context, resource, products);
			mItemResource = resource;
			this.products = products;
		}

		class ViewHolder{
			TextView name;
			TextView amount;
			TextView price;
			TextView tital;
			LinearLayout contentTital;
			LinearLayout content;
			TextView nameTital;
			TextView amountTital;
			TextView priceTital;
		}
		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			ViewHolder holder;
			if (convertView == null) {
				LayoutInflater inflater = LayoutInflater.from(mContext);
				convertView = inflater.inflate(mItemResource, null);
				holder = new ViewHolder();
				holder.name = (TextView) convertView
						.findViewById(R.id.product_listitem_name_cont);
				holder.amount = (TextView) convertView
						.findViewById(R.id.product_listitem_amount_cont);
				holder.price = (TextView) convertView
						.findViewById(R.id.product_listitem_price_cont);
				holder.tital = (TextView) convertView
						.findViewById(R.id.additional_tital);
				holder.contentTital = (LinearLayout) convertView
						.findViewById(R.id.listview_tital);
				holder.content = (LinearLayout) convertView
						.findViewById(R.id.additional_content);
				holder.nameTital = (TextView) convertView
						.findViewById(R.id.product_listitem_name_content);
				holder.amountTital = (TextView) convertView
						.findViewById(R.id.product_listitem_amount_content);
				holder.priceTital = (TextView) convertView
						.findViewById(R.id.product_listitem_price_content);
				convertView.setTag(holder);
			} else {
				holder = (ViewHolder) convertView.getTag();
			}
			convertView.setOnClickListener(new Item_Click(position));
			if (products.get(position).getListType() == Product.SECTION) {
				holder.tital.setVisibility(View.VISIBLE);
				holder.contentTital.setVisibility(View.VISIBLE);
				holder.content.setVisibility(View.GONE);
				holder.tital.setText(products.get(position).getName());
				if (products.get(position).isAdditionalBuySelected()){
					holder.priceTital.setText(mContext.getResources().getString(R.string.additiional_price_tital));
				} else {
					holder.priceTital.setText(mContext.getResources().getString(R.string.price_tital));					
				}
			} else {
				holder.tital.setVisibility(View.GONE);
				holder.contentTital.setVisibility(View.GONE);
				holder.name.setText(products.get(position).getName());
				if (products.get(position).isAdditionalBuySelected())
					holder.amount.setText((products.get(position).getAdditionalBuySelectedIndex() + 1) + "");
				else
					holder.amount.setText("1");
				holder.price.setText(String.format(mContext
						.getString(R.string.currency_s),
						(Long.valueOf(products.get(position)
								.getPromotePrice()) * (products.get(position).getAdditionalBuySelectedIndex() + 1))));
			}
			
			return convertView;
		}
		
        @Override public int getItemViewType(int position) {
            return getItem(position).getListType();
        }

        @Override 
        public int getViewTypeCount() {
            return 2;
        }
		
        @Override
	public boolean isItemViewTypePinned(int viewType) {
		// TODO Auto-generated method stub
		return viewType == Product.SECTION;
	}
}

PinnedSectionListView下載

原始參考範例

Android在待機狀態下顯示Activity

問題描述:要做到像Line一樣,待機時跳出通知畫面,需要做一些設定才有辦法達到效果,因為在非待機模式下直接Intent就可顯示,但是在待機鎖屏的情況下Intent是無法顯示的

解決辦法:

在需要顯示的Activity的onCreate()中加入下列程式

	this.getWindow().setFlags(
			WindowManager.LayoutParams.FLAG_FULLSCREEN
					| WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
					| WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
					| WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON,
			WindowManager.LayoutParams.FLAG_FULLSCREEN
					| WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
					| WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
					| WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
					| WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
	requestWindowFeature(Window.FEATURE_NO_TITLE);
	setContentView(R.layout.activity_alarm);

參考網址:http://blog.csdn.net/lovekiss2012/article/details/8541548

Android : Swipe View With Tabs

分成三個步驟


1.在onCreate時候建立ActionBar,ActionBar.addTab增加Tab的頁面,並且在FragmentActivity實作TabListener


2.建立一個class繼承FragmentStatePagerAdapter用來狀載Fragment頁面


3.實作TabListener後要orverride OnTabSelected

public class PaymentInfoActivity extends FragmentActivity implements
  TabListener {

 CollectionPagerAdapter mPagerAdapter;
 ViewPager mViewPager;

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

 final ActionBar mActionBar = getActionBar();
 mActionBar.setHomeButtonEnabled(true);
 mActionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
 mViewPager = (ViewPager) findViewById(R.id.pager);
 if (mViewPager != null) {
         mPagerAdapter = new CollectionPagerAdapter(
  getSupportFragmentManager());
  mViewPager.setAdapter(mPagerAdapter);
  mViewPager.setOnPageChangeListener(new ViewPager
                                        .SimpleOnPageChangeListener() {

     @Override
     public void onPageSelected(int position) {
  mActionBar.setSelectedNavigationItem(position);
     }
  });
 }
 TextView view1 = (TextView) getLayoutInflater().inflate(
   R.layout.view_custom_tab, null);
 view1.setText(mPagerAdapter.getPageTitle(0));
 mActionBar.addTab(mActionBar.newTab().setCustomView(view1)
   .setTabListener(this));
 TextView view2 = (TextView) getLayoutInflater().inflate(
   R.layout.view_custom_tab, null);
 view2.setText(mPagerAdapter.getPageTitle(1));
 mActionBar.addTab(mActionBar.newTab().setCustomView(view2)
   .setTabListener(this));
    }
}
  
 class CollectionPagerAdapter extends FragmentStatePagerAdapter {

  public CollectionPagerAdapter(FragmentManager fm) {
   super(fm);
  }

  @Override
  public Fragment getItem(int position) {
   switch (position) {
   case 0:
    return new PaymentPickupFragment();
   case 1:
    return new PaymentSearchFragment();
   }
   return null;
  }

   String[] title = new String[] {getResources().getString(R.string.web_payment),
     getResources().getString(R.string.search_payment) };

  @Override
  public CharSequence getPageTitle(int position) {

   return title[position];
  }

  @Override
  public int getCount() {
   // TODO Auto-generated method stub
   return 2;
  }

 }
 @Override
 public void onTabSelected(Tab tab, FragmentTransaction ft) {
  mViewPager.setCurrentItem(tab.getPosition());
 }


FragmentActivity的xml

     
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

<android.support.v4.view.ViewPager
    android:id="@+id/pager"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
</RelativeLayout>

最後要記得建立多個Fragment頁面加入Tab

在Android的TextView上面加上html的連結語法

如果只是想要在Android的view上面連結,不需要使用到WebView,只要使用TexView就可以完成。

網路上很多資料都說要在layout.xml的TextView裡加上

android:linksClickable="true"

或是

android:autoLink="web"

其實實際側試過後,這兩行都不需要設定,只要加上MovementMethod就可以,而內容文字則是透過Html.fromHtml(html)來做轉換,參考範例如下:

TextView tvLinks = (TextView)findViewById(R.id.my_links);
tvLinks.setMovementMethod(LinkMovementMethod.getInstance());
tvLinks.setText(Html.fromHtml("<a href='http://blog.examtw.net'>璟程資訊部落格</a>"));