2012-03-29

ComponentName

Android软件时,常常需要打开系统设置或信息界面,来设置相关系统项或查看系统的相关信息,这时我们就可以使用以下语句来实现:(如打开“无线和网络设置”界面)

  Intent intent = new Intent("/");
  ComponentName cm = new ComponentName("com.android.settings","com.android.settings.WirelessSettings");
  intent.setComponent(cm);
  intent.setAction("android.intent.action.VIEW");
  activity.startActivityForResult( intent , 0);
  经过测试,使用下面字段可以在软件中直接打开相应的系统界面
  com.android.settings.AccessibilitySettings 辅助功能设置
  com.android.settings.ActivityPicker 选择活动
  com.android.settings.ApnSettings APN设置
  com.android.settings.ApplicationSettings 应用程序设置
  com.android.settings.BandMode 设置GSM/UMTS波段
  com.android.settings.BatteryInfo 电池信息
  com.android.settings.DateTimeSettings 日期和坝上旅游网时间设置
  com.android.settings.DateTimeSettingsSetupWizard 日期和时间设置
  com.android.settings.DevelopmentSettings 应用程序设置=》开发设置
  com.android.settings.DeviceAdminSettings 设备管理器
  com.android.settings.DeviceInfoSettings 关于手机
  com.android.settings.Display 显示——设置显示字体大小及预览
  com.android.settings.DisplaySettings 显示设置
  com.android.settings.DockSettings 底座设置
  com.android.settings.IccLockSettings SIM卡锁定设置
  com.android.settings.InstalledAppDetails 语言和键盘设置
  com.android.settings.LanguageSettings 语言和键盘设置
  com.android.settings.LocalePicker 选择手机语言
  com.android.settings.LocalePickerInSetupWizard 选择手机语言
  com.android.settings.ManageApplications 已下载(安装)软件列表
  com.android.settings.MasterClear 恢复出厂设置
  com.android.settings.MediaFormat 格式化手机闪存
  com.android.settings.PhysicalKeyboardSettings 设置键盘
  com.android.settings.PrivacySettings 隐私设置
  com.android.settings.ProxySelector 代理设置
  com.android.settings.RadioInfo 手机信息
  com.android.settings.RunningServices 正在运行的程序(服务)
  com.android.settings.SecuritySettings 位置和安全设置
  com.android.settings.Settings 系统设置
  com.android.settings.SettingsSafetyLegalActivity 安全信息
  com.android.settings.SoundSettings 声音设置
  com.android.settings.TestingSettings 测试——显示手机信息、电池信息、使用情况统计、Wifi information、服务信息
  com.android.settings.TetherSettings 绑定与便携式热点
  com.android.settings.TextToSpeechSettings 文字转语音设置
  com.android.settings.UsageStats 使用情况统计
  com.android.settings.UserDictionarySettings 用户词典
  com.android.settings.VoiceInputOutputSettings 语音输入与输出设置
  com.android.settings.WirelessSettings 无线和网络设置

2012-03-28

[android] java.lang.reflect.Method.invoke()

Ex: Class A

public   Class   A
{
        public   void   setName(String   name)
       {

        }
}

A   a   =   new   A();
Class   c   =   Class.forName( "A ");
Method   method   =   c.getMethod( "setName ",   new   Class[]{String.class});
//從Class c中找到名為setName, 帶一個String參數的methid
method.invoke(a,   new   Object[]{ "name "});
//調用a的該方法, 參數為"name"的String


以上相當於a.setName( "name ");

[Android] Wifi hotspot API -- JAVA Reflection

There is no official API, but you can use reflection to handle it. I know some say, it's not recommended, however imho I say, screw it if Google doesn't want to provide an API for whatever reason.
Below is the code of an activity I used in my application, where the user can enable/disable the Wifi AP. When you enable Wifi AP, usually the regular Wifi will be turned off, so after the user disables the Wifi AP again, we'll be activating regular wifi again.
The code sample below is taken from one of my projects, hope you can get the logic there easily. Let me know if you have further questions.
Code is tested on Nexus One 2.2 (and I think also 2.3) as well as on Samsung Galaxy S (2.2).


package com.myapp.android.activity.wifi;
 
import android.app.ProgressDialog; import android.content.Context; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiManager; import android.os.AsyncTask; import android.os.Bundle; import android.view.View; import android.view.WindowManager; import android.widget.Button;
 
import java.lang.reflect.Method;
 
public class WifiAP extends BaseActivity {

   
// boolean mIsWifiEnabled = false;
   
private static final int WIFI_AP_STATE_UNKNOWN = -1;
   
private static final int WIFI_AP_STATE_DISABLING = 0;
   
private static final int WIFI_AP_STATE_DISABLED = 1;
   
private static final int WIFI_AP_STATE_ENABLING = 2;
   
private static final int WIFI_AP_STATE_ENABLED = 3;
   
private static final int WIFI_AP_STATE_FAILED = 4;

   
private final String[] WIFI_STATE_TEXTSTATE = new String[] {
       
"DISABLING","DISABLED","ENABLING","ENABLED","FAILED"
   
};

   
private WifiManager wifi;

   
@Override
   
protected void onCreate(Bundle icicle) {
       
super.onCreate(icicle);
        setContentView
(R.layout.wifi);
        getWindow
().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
               
|WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
               
|WindowManager.LayoutParams.FLAG_DIM_BEHIND
       
);

        wifi
= (WifiManager) getSystemService(Context.WIFI_SERVICE);
   
}

   
@Override
   
public void onResume() {
       
super.onResume();
        updateStatusDisplay
();
   
}

   
public void toggleWifi(View v) {
       
boolean wifiApIsOn = getWifiAPState()==WIFI_AP_STATE_ENABLED || getWifiAPState()==WIFI_AP_STATE_ENABLING;
       
new SetWifiAPTask(!wifiApIsOn,false).execute();
   
}

   
public void close(View v) {
       
boolean wifiApIsOn = getWifiAPState()==WIFI_AP_STATE_ENABLED || getWifiAPState()==WIFI_AP_STATE_ENABLING;
       
if (wifiApIsOn) {
           
new SetWifiAPTask(false,true).execute();
       
} else {
            finish
();
       
}
   
}


   
/**
     * Endable/disable wifi
     * @param enabled
     * @return WifiAP state
     */

   
private int setWifiApEnabled(boolean enabled) {
       
Log.d("WifiAP", "*** setWifiApEnabled CALLED **** " + enabled);
       
if (enabled && wifi.getConnectionInfo() !=null) {
            wifi
.setWifiEnabled(false);
           
try {Thread.sleep(1500);} catch (Exception e) {}
       
}

       
//int duration = Toast.LENGTH_LONG;
       
//String toastText = "MobileAP status: ";
       
int state = WIFI_AP_STATE_UNKNOWN;
       
try {
            wifi
.setWifiEnabled(false);
           
Method method1 = wifi.getClass().getMethod("setWifiApEnabled",
               
WifiConfiguration.class, boolean.class);
            method1
.invoke(wifi, null, enabled); // true
           
Method method2 = wifi.getClass().getMethod("getWifiApState");
            state
= (Integer) method2.invoke(wifi);
       
} catch (Exception e) {
           
Log.e(WIFI_SERVICE, e.getMessage());
           
// toastText += "ERROR " + e.getMessage();
       
}

       
if (!enabled) {
           
int loopMax = 10;
           
while (loopMax>0 && (getWifiAPState()==WIFI_AP_STATE_DISABLING
                   
|| getWifiAPState()==WIFI_AP_STATE_ENABLED
                   
|| getWifiAPState()==WIFI_AP_STATE_FAILED)) {
               
try {Thread.sleep(500);loopMax--;} catch (Exception e) {}
           
}
            wifi
.setWifiEnabled(true);
       
} else if (enabled) {
           
int loopMax = 10;
           
while (loopMax>0 && (getWifiAPState()==WIFI_AP_STATE_ENABLING
                   
|| getWifiAPState()==WIFI_AP_STATE_DISABLED
                   
|| getWifiAPState()==WIFI_AP_STATE_FAILED)) {
               
try {Thread.sleep(500);loopMax--;} catch (Exception e) {}
           
}
       
}

       
return state;
   
}


   
private int getWifiAPState() {
       
int state = WIFI_AP_STATE_UNKNOWN;
       
try {
           
Method method2 = wifi.getClass().getMethod("getWifiApState");
            state
= (Integer) method2.invoke(wifi);
       
} catch (Exception e) {}
       
Log.d("WifiAP", "getWifiAPState.state " + (state==-1?"UNKNOWN":WIFI_STATE_TEXTSTATE[state]));
       
return state;
   
}

   
private void updateStatusDisplay() {

       
if (getWifiAPState()==WIFI_AP_STATE_ENABLED || getWifiAPState()==WIFI_AP_STATE_ENABLING) {
           
((Button)findViewById(R.id.btnWifiToggle)).setText("Turn off");
            findViewById
(R.id.bg).setBackgroundResource(R.drawable.bg_wifi_on);
       
} else {
           
((Button)findViewById(R.id.btnWifiToggle)).setText("Turn on");
            findViewById
(R.id.bg).setBackgroundResource(R.drawable.bg_wifi_off);
       
}

   
}


   
class SetWifiAPTask extends AsyncTask<Void, Void, Void> {

       
boolean mMode;
       
boolean mFinish;

       
public SetWifiAPTask(boolean mode, boolean finish) {
            mMode
= mode;
            mFinish
= finish;
       
}

       
ProgressDialog d = new ProgressDialog(WifiAP.this);

       
@Override
       
protected void onPreExecute() {
           
super.onPreExecute();
            d
.setTitle("Turning WiFi AP " + (mMode?"on":"off") + "...");
            d
.setMessage("...please wait a moment.");
            d
.show();
       
}

       
@Override
       
protected void onPostExecute(Void aVoid) {
           
super.onPostExecute(aVoid);
           
try {d.dismiss();} catch (IllegalArgumentException e) {};
            updateStatusDisplay
();
           
if (mFinish) finish();
       
}

       
@Override
       
protected Void doInBackground(Void... params) {
            setWifiApEnabled
(mMode);
           
return null;
       
}
   
}

 
} 



出處:
http://stackoverflow.com/questions/7048922/android-2-3-wifi-hotspot-api

[Android] Android Tethering API (froyo or above) --JAVA Reflection

Android Tethering API (froyo or above)

ConnectivityManager class has tethering API methods but those methods are not visible in SDK.
But tethering methods exists in ConnectivityManager class and they works properly.
I used java reflection the standard java feature.
For using those methods, do as following.

1. Get ConnectivityManager class
Object obj = getSystemService(Context.CONNECTIVITY_SERVICE);

2. Find "tether" method on the object
Method m = obj.getClass().getDeclaredMethod("tether", String.class);

3. Invoke that method: When invoke the method send tethering interface usually 'usb0'
m.invoke(obj, "usb0")

If you want to turn off the tethering connection, you simply invoke the "untether" method in this way.

I hope this information helps you.
 
 
出處:
http://tjandroid.blogspot.com/2010/12/enabledisable-usb-tethering.html
 

[android] disable/enable data connection -- JAVA Reflection

Starting from 'FROYO' you can use the IConnectivityManager.setMobileDataEnabled() method. It's hidden in API, but can be accessed with reflection. http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.2_r1.1/android/net/ConnectivityManager.java#376
With this method you can change the system setting: 'Settings -> Wireless & network -> Mobile network settings -> Data Enabled'


Code example:
private void setMobileDataEnabled(Context context, boolean enabled) { 
    final ConnectivityManager conman = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); 
    final Class conmanClass = Class.forName(conman.getClass().getName()); 
    final Field iConnectivityManagerField = conmanClass.getDeclaredField("mService"); 
    iConnectivityManagerField.setAccessible(true); 
    final Object iConnectivityManager = iConnectivityManagerField.get(conman); 
    final Class iConnectivityManagerClass = Class.forName(iConnectivityManager.getClass().getName()); 
    final Method setMobileDataEnabledMethod = iConnectivityManagerClass.getDeclaredMethod("setMobileDataEnabled", Boolean.TYPE); 
    setMobileDataEnabledMethod.setAccessible(true); 
 
    setMobileDataEnabledMethod.invoke(iConnectivityManager, enabled); } 

 
Also you need the CHANGE_NETWORK_STATE permission.
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/> 
Needless to say that this approach might not work in future android versions. But I guess that applications such as '3G watchdog', 'APNdroid' or 'DataLock' work this way.


出處http://stackoverflow.com/questions/3644144/how-to-disable-mobile-data-on-android

JAVA Reflection

  Reflection 是 Java 程式開發語言的特徵之一,它允許營運中的 Java 程式對自身進行檢查,或者說搜尋 Java 類中各成員的名稱並顯示出來。

 
  考慮下面這個簡單的例子,讓我們看看 reflection 是如何工作的。

DumpMethods.java
import java.lang.reflect.*;

public class DumpMethods {

    public static void main(String args[]) {
        try {
            Class c = Class.forName(args[0]);
            Method m[] = c.getDeclaredMethods();
            for (int i = 0; i < m.length; i++)
                System.out.println(m[i].toString());
        } catch (Throwable e) {
            System.err.println(e);
        }
    }
}
 
按如下語句執行︰
java DumpMethods java.util.Stack
它的結果輸出為︰
public java.lang.Object java.util.Stack.push(java.lang.Object)
public synchronized java.lang.Object java.util.Stack.pop()
public synchronized java.lang.Object java.util.Stack.peek()
public boolean java.util.Stack.empty()
public synchronized int java.util.Stack.search(java.lang.Object)
這樣就列出了java.util.Stack 類的各方法名以及它們的限制符和返回類型。
這個程式使用 Class.forName 載入指定的類,然後調用 getDeclaredMethods 來獲取這個類中定義了的方法列表。
java.lang.reflect.Methods 是用來描述某個類中單個方法的一個類。
 
 
出處:
http://www.javaworld.com.tw/confluence/display/J2SE/Reflection