廣告

2016年2月25日 星期四

Android Receive SMS Tutorial | android 取得sms內容


testReadSms.java
public class testReadSms extends BodyFragment{

    private SmsBroadcastReceiver receiver = new SmsBroadcastReceiver(new SmsBroadcastReceiver.UpdateSmsEvent() {
        @Override
        public void updateSms(String sms) {
            newMsg.setText(sms);
        }
    });

    private ArrayList smsMessagesList = new ArrayList();
    private ListView smsListView;
    private ArrayAdapter arrayAdapter;
    private TextView newMsg;

    @Override
    public void onStart() {
        super.onStart();

        //regist sms receiver
        Log. e("registerReceiver", "registerReceiver");
        receiver.registerSmsReceiver(activity);
    }

    @Override
    protected View fragmentLayout(LayoutInflater inflater, ViewGroup container) {
        return inflater.inflate(R.layout.test_body_sms, container, false);
    }

    @Override
    protected void setupComponents(View fragmentView) {
        newMsg = (TextView) fragmentView.findViewById(R.id. new_msg);
        smsListView = (ListView) fragmentView.findViewById(R.id. SMSList);
        arrayAdapter = new ArrayAdapter( activity, android.R.layout.simple_list_item_1 , smsMessagesList);
        smsListView.setAdapter(arrayAdapter);
        smsListView.setOnItemClickListener( this);

        refreshSmsInbox();

    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        //activity.unregisterReceiver(receiver);
    }

    public void refreshSmsInbox() {
        ContentResolver contentResolver = activity.getContentResolver();
        Cursor smsInboxCursor = contentResolver.query(Uri.parse("content://sms/inbox"), null, null , null, null);
        int indexBody = smsInboxCursor.getColumnIndex( "body");
        int indexAddress = smsInboxCursor.getColumnIndex( "address");
        if (indexBody < 0 || !smsInboxCursor.moveToFirst()) return;
        arrayAdapter.clear();
        do {
            String str = "SMS From: " + smsInboxCursor.getString(indexAddress) +
                    "\n" + smsInboxCursor.getString(indexBody) + "\n";
            arrayAdapter.add(str);
        } while (smsInboxCursor.moveToNext());
    }

    public void updateList(final String smsMessage) {
        arrayAdapter.insert(smsMessage, 0);
        arrayAdapter.notifyDataSetChanged();
    }

    public void updateNewMsg(final String msg) {
        newMsg.setText(msg);
    }

}


SmsBroadcastReceiver.java
public class SmsBroadcastReceiver extends BroadcastReceiver {

    public static final String SMS_BUNDLE = "pdus";
    public Activity activity;
    public UpdateSmsEvent updateSmsEvent;


    public interface UpdateSmsEvent{
        void updateSms(String sms);
    }

    public SmsBroadcastReceiver(UpdateSmsEvent inte){
        updateSmsEvent = inte;
    }


    public void onReceive(Context context, Intent intent) {
        Bundle intentExtras = intent.getExtras();
        if (intentExtras != null) {
            Object[] sms = (Object[]) intentExtras.get(SMS_BUNDLE);
            String smsMessageStr = "";
            String smsMessageBody= "";
            for (int i = 0; i < sms. length; ++i) {
                SmsMessage smsMessage = SmsMessage. createFromPdu((byte[]) sms[i]);

                String smsBody = smsMessage.getMessageBody().toString();
                String address = smsMessage.getOriginatingAddress();

                //smsMessage.getTimestampMillis() is current time
                smsMessageStr += "SMS From: " + address + "\n" ;
                smsMessageStr += smsBody + "\n" ;
                smsMessageBody = smsMessage.getMessageBody().toString();
            }
            Toast.makeText (context, smsMessageBody, Toast.LENGTH_SHORT).show();
            smsMessageBody = smsMessageBody.replaceAll("\\D+","" );
            //this will update the UI with message
            updateSmsEvent.updateSms(smsMessageBody);
            activity.unregisterReceiver(this);
        }
    }

    public void registerSmsReceiver(Activity activity){
        this.activity = activity;
        IntentFilter filter = new IntentFilter();
        filter.setPriority(999 );
        filter.addAction("android.provider.Telephony.SMS_RECEIVED");
        activity.registerReceiver(this, filter);
    }
}



main ref:

ref:

[android] sms emulator control in Android Studio | android模擬器 模擬簡訊寄送

Tools->Android->Android Device Monitor-> Click on the emulator name in devicess-> Emulator Controls

[android] phone call using intent in android


String phone = location.getPhoneNumber();
//Intent intent = new Intent(Intent.ACTION_DIAL, Uri.fromParts("tel", phone, null));
//need click call
Intent intent = new Intent(Intent. ACTION_CALL, Uri.fromParts( "tel", phone, null ));
//call directly
activity.startActivity(intent);


add permission in AndroidManifest.xml


[android] Send Email Intent

http://stackoverflow.com/questions/8701634/send-email-intent
Intent emailIntent = new Intent(Intent. ACTION_SENDTO, Uri.fromParts(
        "mailto", "lewisli.acer@gmail.com", null));
emailIntent.putExtra(Intent.EXTRA_EMAIL , "lewisli.acer@gmail.com");
emailIntent.putExtra(Intent.EXTRA_SUBJECT , "Pet");
emailIntent.putExtra(Intent.EXTRA_TEXT , "this is error page");
startActivity(Intent.createChooser(emailIntent, "Report error"));





but can't get result event
http://stackoverflow.com/questions/3778048/how-can-we-use-startactivityforresult-for-email-intent

You can't, this is not part of the API. It returns once you have pressed send button even if it is not sent

2016年1月11日 星期一

bootstrap disable navbar collapse

html


  

css

.disable-collapse {
    .navbar-collapse.collapse {
        display: block!important;
    }
    .navbar-nav>li,
    .navbar-nav {
        float: left !important;
    }
    .navbar-nav.navbar-right:last-child {
        margin-right: -15px !important;
    }
    .navbar-right {
        float: right!important;
    }
}


參考
 http://jsfiddle.net/t4ym3/

2016年1月7日 星期四

[android] 微信接入(登入,發動態) | weChat auth login,share



sample code
https://github.com/cihm/WeChatDemo

註冊
https://open.weixin.qq.com/cgi-bin/userinfo?lang=zh_CN&token=7a348e868afe006e18453eb53e825c65c231e870
教學
http://mobile.51cto.com/others-388965.htm
http://www.eoeandroid.com/thread-547012-1-1.html?_dsign=491583a0
============================
.程式裡的APP key 要使用開發者後台所提供的.
.要使用app_signatures.apk將包名編譯成md5並且填入開發者後台當中.
.或是直接cmd line跑出來,在自己轉小寫
willy key:7ae51e2d4ca6bb6c5df769148071bed6

登入功能需要開通

前提:
 要得到回傳訊息(不管發動態或是登入)
 一定要在自己於微信後台註冊的package(自己的專案)下面
 新增一個package 叫"wxapi"
 然後在此package下面新增
 "WXEntryActivity.java"並實作IWXAPIEventHandler則就可在onResp拿到回傳

 注意:
 package名稱(wxapi )跟java檔名稱(WXEntryActivity )一要要這樣叫

 androidmenifest:

    
        
        
        
    


===========
分享動態功能
WXEntryActivity => SendToWXActivity
 發送文字
 .將app註冊到APP
 .自訂TextView(EditText )
 .自訂dialog(MMAlert)
 .初始化一个 WXTextObject 对象(將要分享的文字放進去)
 .初始化WXMediaMessage(WXTextObject放進去 )
 .构造一个 Req(SendMessageToWX.Req)
 .调用api接口发送数据到微信(api .sendReq(req) )
 .WXEntryActivity 的onResp會顯示成功與否
其他發送訊息如程式sample所演示.

圖文同時的話目前找到用WXWebpageObject代替


package com.example.wechatsdk.party3control;

import android.app.Activity;
import android.app.Dialog;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;


import com.tencent.mm.sdk.openapi.BaseReq;
import com.tencent.mm.sdk.openapi.BaseResp;
import com.tencent.mm.sdk.openapi.ConstantsAPI;
import com.tencent.mm.sdk.openapi.IWXAPI;
import com.tencent.mm.sdk.openapi.IWXAPIEventHandler;
import com.tencent.mm.sdk.openapi.SendAuth;
import com.tencent.mm.sdk.openapi.SendMessageToWX;
import com.tencent.mm.sdk.openapi.ShowMessageFromWX;
import com.tencent.mm.sdk.openapi.WXAPIFactory;
import com.tencent.mm.sdk.openapi.WXAppExtendObject;
import com.tencent.mm.sdk.openapi.WXMediaMessage;
import com.tencent.mm.sdk.openapi.WXWebpageObject;

/**
* Created by 1409035  lewisli on 2015/11/17.
*/
public class WeChatControl {

    private static WeChatControl instance = new WeChatControl();

    private WeChatControl() {

    }

    public static WeChatControl getInstance() {
        return instance ;
    }

    private static final int THUMB_SIZE = 150 ;
    private IWXAPI iwaxaApi;
    private ApplicationInfo applicationInfo;
    private String appKey;
    private String TAG = "com.wechat.api.wechat_API_KEY";



    public void shareMessage(Activity activity, String text, Bitmap bitmap) {
        //ref:http://mobile.9sssd.com/android/art/1059
        // custom dialog


        String url = "http://test";// 收到分享的好友点击信息会跳转到这个地址去
        WXWebpageObject localWXWebpageObject = new WXWebpageObject();
        localWXWebpageObject.webpageUrl = url;

        WXMediaMessage msg = new WXMediaMessage(localWXWebpageObject);

        //msg.setThumbImage(BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher));
        //Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.send_img);

        Bitmap thumbBmp = Bitmap. createScaledBitmap(bitmap, THUMB_SIZE, THUMB_SIZE, true );

        msg.thumbData = Util.bmpToByteArrayFix(thumbBmp, true);  // 设置缩略图
        bitmap.recycle();

        msg.title = text;
        msg.description = text;

        SendMessageToWX.Req req = new SendMessageToWX.Req();
        req.transaction = System.currentTimeMillis() + "";
        req.message = msg;

        //send global or friend only
        //req.scene = isTimelineCb.isChecked() ? SendMessageToWX.Req.WXSceneTimeline : SendMessageToWX.Req.WXSceneSession;
        req. scene = SendMessageToWX.Req.WXSceneTimeline;
        getiIWXAPI(activity).sendReq(req);

        //finish();
    }


    public IWXAPI getiIWXAPI(Activity activity) {
        if (iwaxaApi == null) {
            setiIWXAPI(WXAPIFactory.createWXAPI (activity, getAppKey(activity), true));


            Log.e( "!!!!", "getiIWXAPI" );
            iwaxaApi.registerApp(getAppKey(activity));
            //iwaxaApi.handleIntent(activity.getIntent(), this);

        }
        return iwaxaApi ;
    }

    public void setiIWXAPI(IWXAPI iwaxAPI) {
        this.iwaxaApi = iwaxAPI;
    }


    private ApplicationInfo getApplicationInfo(Activity activity) {
        if (applicationInfo == null) {
            try {
                setApplicationInfo(activity.getPackageManager().getApplicationInfo(activity.getPackageName(), PackageManager.GET_META_DATA));
            } catch (PackageManager.NameNotFoundException e) {
                e.printStackTrace();
            }
        }
        return applicationInfo ;
    }

    private void setApplicationInfo(ApplicationInfo applicationInfo) {
        this.applicationInfo = applicationInfo;
    }

    public String getAppKey(Activity activity) {
        if (appKey == null) {
            setAppKey(getApplicationInfo(activity).metaData.getString( TAG));
        }
        return appKey ;
    }

    public void setAppKey(String appKey) {
        this.appKey = appKey;
    }


    public void login(Activity activity){
        final SendAuth.Req req = new SendAuth.Req();
        req.scope = "snsapi_userinfo";
        req.state = "wechat2chongba";
        getiIWXAPI(activity).sendReq(req);
    }



}
=============
登入功能:

文件
https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419317851&token=88a73255c4a18aa152113ef684fce5dfd2347719&lang=zh_CN

https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419317853&lang=zh_CN

  在onResp回傳 =>BaseResp resp
  做轉型
  SendAuth.Resp sendResp = (SendAuth.Resp) resp;
  取token
  sendResp.token
 // 官方文件寫錯(他寫code),但實際上是 token



STEP1:user token to get access_token and openid

https://api.weixin.qq.com/sns/oauth2/access_token?appid=wxbff6de7ebe6c9498&secret=a50b0b62ae77557b289c487308aa9faa&code=0112342663e805e50dd7fbe001075d0L&grant_type=authorization_code


STEP2: use refresh_token
=>第一次可跳過,又或者你只需要取得一次用戶資訊,那也可跳過此步驟

https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=wxbff6de7ebe6c9498&grant_type=refresh_token&refresh_token=OezXcEiiBSKSxW0eoylIeILPYvLIWkzXq-H0gG9o7k8Dt9ilr91flHHcPwl78kdLCCcgvEVqvNaksf3wpgyqlaIvgSqQwbgV9LnBvgafjJpdJa7R-XExsaMWDy_o7LpKMPkIGvnQsHpKY2_LP5z12g


STEP3: use access_token and openid get user info
https://api.weixin.qq.com/sns/userinfo?access_token=OezXcEiiBSKSxW0eoylIeILPYvLIWkzXq-H0gG9o7k8Dt9ilr91flHHcPwl78kdLXZNZvaTI5NyTOMl1klSSoTbRuXuzd52ZqVe5X9O6QGvd7wFUYOVubwRWhDGLcHzbKzPoZ_ukdukfBBgW1sL7tQ, unionid=oS9mHwNTZYvYeerdgwiGaEzqMBHc&openid=oibTCuAkkFgeUkJeV8bdp6wSgYJI




WXEntryActivity  code


package com.acer.wxapi;


import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.util.task.json.JsonGetTask;


import com.acer.R;
import com.acer.pet.util.ViewUtils;
import com.example.wechatsdk.party3control.WeChatControl;
import com.tencent.mm.sdk.openapi.BaseReq;
import com.tencent.mm.sdk.openapi.BaseResp;
import com.tencent.mm.sdk.openapi.ConstantsAPI;
import com.tencent.mm.sdk.openapi.IWXAPIEventHandler;
import com.tencent.mm.sdk.openapi.SendAuth;

import java.util.ArrayList;
import java.util.HashMap;

import static android.util.Constants.NETWORK_ERROR;
import static com.acer.pet.util.ViewUtils.loadingFinish;
import static com.acer.pet.util.ViewUtils.loadingStart;


public class WXEntryActivity extends Activity implements IWXAPIEventHandler {

    private static final int TIMELINE_SUPPORTED_VERSION = 0x21020001 ;
    private static final int RETURN_MSG_TYPE_LOGIN = 1 ;
    private static final int RETURN_MSG_TYPE_SHARE = 2 ;
    private String appId;
    private String secret;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        WeChatControl.getInstance().getiIWXAPI( this).handleIntent(getIntent(), this);


    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        Log.e( "onNewIntent", "!!!" + intent);
        setIntent(intent);
        WeChatControl.getInstance().getiIWXAPI( this).handleIntent(getIntent(), this);
    }

    // 微信发送请求到第三方应用时,会回调到该方法
    @Override
    public void onReq(BaseReq req) {
        Log.e( "onReq", "!!!" + req);
        switch (req.getType()) {
            case ConstantsAPI.COMMAND_GETMESSAGE_FROM_WX:
                //goToGetMsg();
                break;
            case ConstantsAPI.COMMAND_SHOWMESSAGE_FROM_WX:
                //goToShowMsg((ShowMessageFromWX.Req) req);
                break;
            default:
                break;
        }
    }

    // 第三方应用发送到微信的请求处理后的响应结果,会回调到该方法
    @Override
    public void onResp(BaseResp resp) {
        int result = 0;
        Log.e( "onResp", "!!!" + resp.getType());
        switch (resp.errCode) {
            case BaseResp.ErrCode.ERR_OK:

                switch (resp.getType()) {
                    case RETURN_MSG_TYPE_LOGIN:

                        SendAuth.Resp sendResp = (SendAuth.Resp) resp;
                        Log. e("resp.errCode", "!!!" + sendResp.errCode);
                        Log. e("resp.state", "!!!" + sendResp.state);
                        Log. e("resp.token", "!!!" + sendResp.token);

                        //loadingStart(this);
                        secret = getResources().getString(R.string.com_wechat_api_wechat_API_SECRET );
                        appId = WeChatControl.getInstance().getAppKey( this);
                        getAccessToken(sendResp. token);

                        //官方文件寫錯,是token,不是 code
                        // 拿到了微信返回的 code,立马再去请求access_token
                        //String code = ((SendAuth.Resp) resp).code;

                        // 就在这个地方,用网络库什么的或者自己封的网络 api,发请求去咯,注意是 get请求

                        break;

                    case RETURN_MSG_TYPE_SHARE:
                        //"微信分享成功";
                        finish();
                        break;
                }

                break;
            case BaseResp.ErrCode.ERR_USER_CANCEL:
                result = com.example.wechatsdk.party3control.R.string.errcode_cancel;
                break;
            case BaseResp.ErrCode.ERR_AUTH_DENIED:
                result = com.example.wechatsdk.party3control.R.string.errcode_deny;
                break;
            default:
                result = com.example.wechatsdk.party3control.R.string.errcode_unknown;
                break;
        }

    }

    //stpe1
    public void getAccessToken(String toekn) {

        String apiUrl = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + appId + "&secret=" + secret + "&code=" + toekn + "&grant_type=authorization_code" ;

        (new JsonGetTask(apiUrl) {
            @Override
            protected void onPostExecute(ArrayList> arrayList) {
                if ((arrayList.size() == 1 && null != arrayList.get(0).get(NETWORK_ERROR ))) {

                    Log.e("getAccessToken", "NETWORK_ERROR");

                } else {

                    //我要做的事情
                    Log.e( "getAccessToken", arrayList.toString());

                    if (!arrayList.get( 0).containsKey( "errcode")) {

                        String refreshToken = (String) arrayList.get(0).get("refresh_token" );
                        String accessToken = (String) arrayList.get(0).get("access_token" );
                        String openid = (String) arrayList.get( 0).get( "openid");
                        getUserInfo(refreshToken, accessToken, openid);

                    } else {
                        Log. e("error", arrayList.toString());
                    }

                }

                //loadingFinish();

            }
        }).execute();
    }


    //stpe2
    public void getUserInfo(String refreshToken, String accessToken, String openid) {

        String apiUrl = "https://api.weixin.qq.com/sns/userinfo?access_token=" + accessToken + "&openid=" + openid;

        (new JsonGetTask(apiUrl) {
            @Override
            protected void onPostExecute(ArrayList> arrayList) {
                if ((arrayList.size() == 1 && null != arrayList.get(0).get(NETWORK_ERROR ))) {
                    Log.e("getUserInfo", "NETWORK_ERROR");
                } else {

                    Log.e("getAccessToken", arrayList.toString());

                    if (!arrayList.get( 0).containsKey( "errcode")) {

                        String nickname = (String) arrayList.get(0).get("nickname" );
                        String unionid = (String) arrayList.get( 0).get( "unionid");
                        String headimgurl = (String) arrayList.get(0).get("headimgurl" );

                        Log.e("userinfo", "nickname:"+nickname+"===unionid:"+unionid+"===headimgurl"+headimgurl);

                    } else {
                        Log. e("error", arrayList.toString());
                    }


                }

                //loadingFinish();
                finish();
            }
        }).execute();
    }


}


[android] 解決list item事件,與該list item裡面的"元件" 造成的事件衝突


1.將事件寫在BaseAdapter的 getView裡面
ref:https://tausiq.wordpress.com/2012/08/22/android-listview-example-with-custom-adapter/
    public View getView(int index, View view, final ViewGroup parent) {
     
     view.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
              //do things here
            }
        });
     
     button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
              //do things here
            }
        });
  }

2.設定list item裡面的"元件"
ref:http://stackoverflow.com/questions/6703390/listview-setonitemclicklistener-not-working-by-adding-button

Try seting your buttons(or any other views you want to handle click inside a list item) like this:

android:focusable="false"
android:focusableInTouchMode="false"