0%

默认情况下,Activity中的EditText会自动获取焦点,导致打开Activity时自动弹出软键盘.解决方法,声明Activity时加上:android:windowSoftInputMode=”stateHidden” 如:

        <activity
            android:name=".Login_"
            android:windowSoftInputMode="stateHidden"
            android:label="@string/title_activity_login"
            android:screenOrientation="unspecified" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

这里没有用CursorAdapter,而是自己继承BaseAdapter写了个适配器. 与ListView不同,AutoCompleteTextView的适配器除了继承BaseAdapter外,还要实现Filterable接口。Filterable接口中有个getFilter方法,用于获取过滤器,我们需要自己写个继承Filter的过滤器,实现数据库查询。 代码使用了androidannotations.

import java.util.ArrayList;
import java.util.List;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.ImageView;
import android.widget.TextView;
import cn.jtang.discussion.R;
import cn.jtang.discussion.db.UserDB;
import cn.jtang.discussion.mode.User;

import com.googlecode.androidannotations.annotations.Bean;
import com.googlecode.androidannotations.annotations.EBean;
import com.googlecode.androidannotations.annotations.RootContext;

@EBean
public class LoginUsernameAdapter extends BaseAdapter implements Filterable {
    LayoutInflater mInflater;
    ArrayList users;
    String key;
    @RootContext
    Context context;
    @Bean
    UserDB userDb;
    DBFilter filter;
    @Override
    public int getCount() {
        // TODO Auto-generated method stub
        if (users != null && users.size() > 0) {
            return users.size();
        }
        return 0;
    }

    @Override
    public Object getItem(int position) {
        // TODO Auto-generated method stub
        return users.get(position);
    }

    @Override
    public long getItemId(int position) {
        // TODO Auto-generated method stub
        return position;
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        // TODO Auto-generated method stub
        if (mInflater == null) {
            mInflater = LayoutInflater.from(context);
        }
        
        final User user = users.get(position);

        View view = mInflater.inflate(R.layout.item_actv_username, null);
        TextView tv_username = (TextView) view.findViewById(R.id.tv_username);
        tv_username.setText(user.getUsername());
        ImageView iv_delete = (ImageView) view.findViewById(R.id.iv_delete);
        //添加点击事件
        iv_delete.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                //点击后删除用户
                userDb.deleteUser(user);
                users.remove(position);
                notifyDataSetChanged();
            }
        });
        return view;
    }
    /**
     * 获取过滤器
     */
    @Override
    public Filter getFilter() {
        // TODO Auto-generated method stub
        if (filter == null) {
            filter = new DBFilter();
        }
        return filter;
    }

    /**
     * 数据库查询过滤器
     * 
     * @author Administrator
     * 
     */
    private class DBFilter extends Filter {
        /**
         * 查询数据库
         */
        @Override
        protected FilterResults performFiltering(CharSequence prefix) {
            // TODO Auto-generated method stub
            //查询结果保存到FilterResults对象里
            FilterResults results = new FilterResults();
            List queryUsers = userDb.query(prefix.toString());
            results.values = queryUsers;
            results.count = queryUsers.size();
            return results;
        }

        /**
         * 更新UI
         */
        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {
            // TODO Auto-generated method stub
            List queryUsers = (List) results.values;
            //把结果读取出复制到users里
            if (users == null) {
                users = new ArrayList();
            }
            if (users.size() > 0) {
                users.clear();
            }

            if (queryUsers != null && queryUsers.size() > 0)
                for (User user : queryUsers) {
                    users.add(user);
                    notifyDataSetChanged();
                }
        }

    }
}

与Wifi开关状态无关,以前看到一篇文章,说是关了WIFI获取不到MAC地址,也没试,被误导。这个应该是目前识别机器最好的方法了,Android ID在重置后会改变。

        textview=(TextView)findViewById(R.id.textview);
        WifiManager wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);
        WifiInfo info = wifi.getConnectionInfo();
        textview.setText(info.getMacAddress());

需要权限:

 <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />

来自:http://stackoverflow.com/questions/5910219/problem-using-usersearch-in-xmpp-with-asmack 原因是Android读不到/META-INF下的配置文件,需要手工配置。

    public static void configure(ProviderManager pm) {

        // Private Data Storage
        pm.addIQProvider("query", "jabber:iq:private", new PrivateDataManager.PrivateDataIQProvider());

        // Time
        try {
            pm.addIQProvider("query", "jabber:iq:time", Class.forName("org.jivesoftware.smackx.packet.Time"));
        } catch (ClassNotFoundException e) {
            Log.w("TestClient", "Can't load class for org.jivesoftware.smackx.packet.Time");
        }

        // Roster Exchange
        pm.addExtensionProvider("x", "jabber:x:roster", new RosterExchangeProvider());

        // Message Events
        pm.addExtensionProvider("x", "jabber:x:event", new MessageEventProvider());

        // Chat State
        pm.addExtensionProvider("active", "http://jabber.org/protocol/chatstates", new ChatStateExtension.Provider());
        pm.addExtensionProvider("composing", "http://jabber.org/protocol/chatstates", new ChatStateExtension.Provider());
        pm.addExtensionProvider("paused", "http://jabber.org/protocol/chatstates", new ChatStateExtension.Provider());
        pm.addExtensionProvider("inactive", "http://jabber.org/protocol/chatstates", new ChatStateExtension.Provider());
        pm.addExtensionProvider("gone", "http://jabber.org/protocol/chatstates", new ChatStateExtension.Provider());

        // XHTML
        pm.addExtensionProvider("html", "http://jabber.org/protocol/xhtml-im", new XHTMLExtensionProvider());

        // Group Chat Invitations
        pm.addExtensionProvider("x", "jabber:x:conference", new GroupChatInvitation.Provider());

        // Service Discovery # Items
        pm.addIQProvider("query", "http://jabber.org/protocol/disco#items", new DiscoverItemsProvider());

        // Service Discovery # Info
        pm.addIQProvider("query", "http://jabber.org/protocol/disco#info", new DiscoverInfoProvider());

        // Data Forms
        pm.addExtensionProvider("x", "jabber:x:data", new DataFormProvider());

        // MUC User
        pm.addExtensionProvider("x", "http://jabber.org/protocol/muc#user", new MUCUserProvider());

        // MUC Admin
        pm.addIQProvider("query", "http://jabber.org/protocol/muc#admin", new MUCAdminProvider());

        // MUC Owner
        pm.addIQProvider("query", "http://jabber.org/protocol/muc#owner", new MUCOwnerProvider());

        // Delayed Delivery
        pm.addExtensionProvider("x", "jabber:x:delay", new DelayInformationProvider());

        // Version
        try {
            pm.addIQProvider("query", "jabber:iq:version", Class.forName("org.jivesoftware.smackx.packet.Version"));
        } catch (ClassNotFoundException e) {
            // Not sure what's happening here.
        }

        // VCard
        pm.addIQProvider("vCard", "vcard-temp", new VCardProvider());

        // Offline Message Requests
        pm.addIQProvider("offline", "http://jabber.org/protocol/offline", new OfflineMessageRequest.Provider());

        // Offline Message Indicator
        pm.addExtensionProvider("offline", "http://jabber.org/protocol/offline", new OfflineMessageInfo.Provider());

        // Last Activity
        pm.addIQProvider("query", "jabber:iq:last", new LastActivity.Provider());

        // User Search
        pm.addIQProvider("query", "jabber:iq:search", new UserSearch.Provider());

        // SharedGroupsInfo
        pm.addIQProvider("sharedgroup", "http://www.jivesoftware.org/protocol/sharedgroup", new SharedGroupsInfo.Provider());

        // JEP-33: Extended Stanza Addressing
        pm.addExtensionProvider("addresses", "http://jabber.org/protocol/address", new MultipleAddressesProvider());

        // FileTransfer
        pm.addIQProvider("si", "http://jabber.org/protocol/si", new StreamInitiationProvider());

        pm.addIQProvider("query", "http://jabber.org/protocol/bytestreams", new BytestreamsProvider());

        // Privacy
        pm.addIQProvider("query", "jabber:iq:privacy", new PrivacyProvider());
        pm.addIQProvider("command", "http://jabber.org/protocol/commands", new AdHocCommandDataProvider());
        pm.addExtensionProvider("malformed-action", "http://jabber.org/protocol/commands", new AdHocCommandDataProvider.MalformedActionError());
        pm.addExtensionProvider("bad-locale", "http://jabber.org/protocol/commands", new AdHocCommandDataProvider.BadLocaleError());
        pm.addExtensionProvider("bad-payload", "http://jabber.org/protocol/commands", new AdHocCommandDataProvider.BadPayloadError());
        pm.addExtensionProvider("bad-sessionid", "http://jabber.org/protocol/commands", new AdHocCommandDataProvider.BadSessionIDError());
        pm.addExtensionProvider("session-expired", "http://jabber.org/protocol/commands", new AdHocCommandDataProvider.SessionExpiredError());
    }

在new XMPPConnection前,调用:

configure(ProviderManager.getInstance());

搜索好友:

try {
            UserSearchManager search = new UserSearchManager(XmppTool.getConnection());
            Form searchForm = search.getSearchForm("search.fhp");
            Form answerForm = searchForm.createAnswerForm();
            answerForm.setAnswer("Username", true);
            answerForm.setAnswer("search", et_username.getText().toString());
            org.jivesoftware.smackx.ReportedData data = search.getSearchResults(answerForm, "search.fhp");

            Iterator it = data.getRows();
            Row row = null;
            String ansS = "";
            while (it.hasNext()) {
                row = it.next();
                ansS += row.getValues("Username").next().toString() + "\n";
                System.out.println(ansS);
                // Log.i("Username",row.getValues("Username").next().toString());
            }
//			Toast.makeText(this, ansS, Toast.LENGTH_SHORT).show();
        } catch (Exception e) {
            e.printStackTrace();
//			Toast.makeText(this, e.getMessage() + " " + e.getClass().toString(), Toast.LENGTH_SHORT).show();
        }

searchService要与openfire服务器设置一致

默认情况下,如果图片的宽度大于xml中设定的宽度,高度设为wrap_content,view中显示的图片会以xml中设定的宽度显示,但是却占据了图片真实高度的空间(只是占着空间,图片没有被拉伸)。可以设置adjustViewBounds属性解决。

         <ImageView
                android:layout_width="0dp"
                android:layout_weight="4.33"
                android:src="@drawable/bg_weather"
                android:adjustViewBounds="true"
                android:layout_height="wrap_content" />

四个参数:

            android:shadowColor="@color/white"
            android:shadowDx="0"
            android:shadowDy="1"
            android:shadowRadius="1"

分别是阴影的颜色,水平位移,垂直位移,模糊半径。 模糊半径越大越模糊。 使用Java代码:

mTextView.setShadowLayer(10F, 11F,5F, Color.YELLOW);

每次到网上搜,经常搜到一些不正确的方法,所以还是自己记录一下 在 /etc/bash.bashrc未尾添加 JAVA_HOME=/home/fhp/Documents/jdk1.6.0_37 export JRE_HOME=/home/fhp/Documents/jdk1.6.0_37/jre export CLASSPATH=.:$JAVA_HOME/lib:$JRE_HOME/lib:$CLASSPATH export PATH=$JAVA_HOME/bin:$JRE_HOME/bin:$PATH

静默安装需要系统权限,我这里通过 platform.x509.pem platform.pk8给应用签名获得。另外,加上android.permission.INSTALL_PACKAGES权限。

package com.example.lianxiren;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

import android.app.Activity;
import android.os.Bundle;
import android.os.Environment;

public class MainActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        try {
            if(slientInstall(Environment.getExternalStorageDirectory()+"/a.apk"))
            {
                System.out.println("安装成功");
            }else{
                System.out.println("安装失败");
            }
            
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    public boolean slientInstall(String apkPath) throws IOException {
        Runtime runtime = Runtime.getRuntime();
        Process proc = runtime.exec("pm install -r "+apkPath); // 这句话就是shell与高级语言间的调用
        // 如果有参数的话可以用另外一个被重载的exec方法
        // 实际上这样执行时启动了一个子进程,它没有父进程的控制台
        // 也就看不到输出,所以我们需要用输出流来得到shell执行后的输出
        InputStream inputstream = proc.getInputStream();
        InputStreamReader inputstreamreader = new InputStreamReader(inputstream);
        BufferedReader bufferedreader = new BufferedReader(inputstreamreader);
        String line = "";
        StringBuilder sb = new StringBuilder(line);
        while ((line = bufferedreader.readLine()) != null) {
            sb.append(line);
        }
        // 使用exec执行不会等执行成功以后才返回,它会立即返回
        // 所以在某些情况下是很要命的(比如复制文件的时候)
        // 使用wairFor()可以等待命令执行完成以后才返回
        try {
            if (proc.waitFor() != 0) {
                System.err.println("exit value = " + proc.exitValue());
            }
        } catch (InterruptedException e) {
            System.err.println(e);
        }
        
        String result=sb.toString();
        if(result.equals("Success"))
        {
            return true;
        }
        return false;
    }

}

导出无签名的apk,再用platform.x509.pem platform.pk8签名,即可实现静默安装。所以必须拿到root权限,或者能拿到两个签名文件。

代码转自:http://my.oschina.net/eclipse88/blog/80210

package com.example.videocapture;

import android.app.Activity;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.provider.MediaStore.Video.Thumbnails;
import android.provider.MediaStore.Video.VideoColumns;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;

public class MainActivity extends Activity {

    private static final int VIDEO_CAPTURE = 0;
    private ImageView imageView;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        imageView = (ImageView) findViewById(R.id.imageView);
        Button button = (Button) findViewById(R.id.button);
        button.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
                intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);
                startActivityForResult(intent, VIDEO_CAPTURE);
            }
        });
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == Activity.RESULT_OK && requestCode == VIDEO_CAPTURE) {
            Uri uri = data.getData();
            Cursor cursor = this.getContentResolver().query(uri, null, null,
                    null, null);
            if (cursor != null && cursor.moveToNext()) {
                int id = cursor.getInt(cursor.getColumnIndex(VideoColumns._ID));
                String filePath = cursor.getString(cursor.getColumnIndex(VideoColumns.DATA));
                Bitmap bitmap = Thumbnails.getThumbnail(getContentResolver(),
                        id, Thumbnails.MICRO_KIND, null);
                //ThumbnailUtils类2.2以上可用
//				Bitmap bitmap = ThumbnailUtils.createVideoThumbnail(filePath, Thumbnails.MICRO_KIND);
                imageView.setImageBitmap(bitmap);
                cursor.close();
            }
        }
    }
}