first commit and add gitignore, README.md

This commit is contained in:
ChesterTseng 2016-06-04 19:09:35 +08:00
commit 760756ba2c
1861 changed files with 709236 additions and 0 deletions

Binary file not shown.

View file

@ -0,0 +1,6 @@
The exe file is used to send image to device based on socket by OTA function.
Command :
DownloadServer "PORT" "FILE_PATH"
You can edit start.bat to change port and file path.

3
tools/DownloadServer/start.bat Executable file
View file

@ -0,0 +1,3 @@
@echo off
DownloadServer 8082 New_Project.bin
set /p DUMMY=Press Enter to Continue ...

View file

@ -0,0 +1,63 @@
#include "autoconf.h"
#if !defined(CONFIG_PLATFORM_8195A) && !defined(CONFIG_PLATFORM_8711B)
#include <flash/stm32_flash.h>
#if defined(STM32F2XX)
#include <stm32f2xx_flash.h>
#elif defined(STM32F4XX)
#include <stm32f4xx_flash.h>
#elif defined(STM32f1xx)
#include <stm32f10x_flash.h>
#endif
#include "cloud_updater.h"
#else
#include "flash_api.h"
#endif
#define BUF_LEN 512
#define CONFIG_MD5_USE_SSL
#ifdef CONFIG_MD5_USE_SSL
#include "md5.h"
#define file_md5_context md5_context
#define file_md5_init(ctx) md5_init(ctx)
#define file_md5_starts(ctx) md5_starts(ctx)
#define file_md5_update(ctx, input, len) md5_update(ctx, input, len)
#define file_md5_finish(ctx, output) md5_finish(ctx, output)
#define file_md5_free(ctx) md5_free(ctx)
#else
#include "rom_md5.h"
#define file_md5_context md5_ctx
#define file_md5_init(ctx) rt_md5_init(ctx)
#define file_md5_starts(ctx)
#define file_md5_update(ctx, input, len) rt_md5_append(ctx, input, len)
#define file_md5_finish(ctx, output) rt_md5_final(output, ctx)
#define file_md5_free(ctx)
#endif
int file_check_sum(uint32_t addr, uint32_t image_len, u8* check_sum)
{
int ret = -1 ;
flash_t flash;
file_md5_context md5;
unsigned char buf[BUF_LEN];
uint32_t read_addr = addr;
int len = 0;
file_md5_init(&md5);
file_md5_starts(&md5);
while(len < image_len){
if ((image_len-len) >= BUF_LEN){
flash_stream_read(&flash, read_addr, BUF_LEN, buf);
file_md5_update(&md5, buf, BUF_LEN);
}else{
flash_stream_read(&flash, read_addr, (image_len-len), buf);
file_md5_update(&md5, buf, (image_len-len));
}
len += BUF_LEN;
read_addr = read_addr + BUF_LEN;
}
file_md5_finish(&md5, check_sum);
file_md5_free(&md5);
}

BIN
tools/iperf.exe Executable file

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,30 @@
ChangeLog
----------------------------------------------------------------
2015/07/23
- device type : 0xff00~0xffff for customer
2015/04/22
- Show one AP of the same SSID multiple APs on AP List by site survey
2015/02/11
- Bug fixed: Reconnection WiFi AP issue.
- Bug fixed: Type transformation for Encryption WiFi profile.
- Re-fine time interval(ms) between sending two packets
2014/10/20
- Re-fine configure flow when DUT receives first UDP packet.
2014/10/01
- Refined if the profile length>127, configure will fail issue.
2014/08/13
- Add Hidden SSID Support
2014/08/04
- Re-fine configure flow
- Re-fine control flow
- Re-fine discovery flow
- Add descriptions of the delay about sending packet
2014/06/19
- Initial Release

View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.DEPENDENCIES"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="gen"/>
<classpathentry kind="output" path="bin/classes"/>
</classpath>

View file

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>SimpleConfigWizard</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>com.android.ide.eclipse.adt.ApkBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>com.android.ide.eclipse.adt.AndroidNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

View file

@ -0,0 +1,4 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
org.eclipse.jdt.core.compiler.compliance=1.6
org.eclipse.jdt.core.compiler.source=1.6

View file

@ -0,0 +1,79 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.rtk.simpleconfig_wizard"
android:versionCode="1"
android:versionName="1.0.9.20150806"
android:installLocation="auto">
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="18" />
<!-- wifi usage -->
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"></uses-permission>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
<uses-permission android:name="android.permission.INTERNET" ></uses-permission>
<uses-permission android:name="android.permission.READ_SMS"></uses-permission>
<!-- Camera usage -->
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.FLASHLIGHT" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<!-- file and SD Card usage -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"></uses-permission>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"></uses-permission>
<application
android:allowBackup="true"
android:icon="@drawable/icon"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.rtk.simpleconfig_wizard.MainActivity"
android:screenOrientation="portrait"
android:configChanges="orientation|keyboardHidden|screenSize"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="com.wifi.connection.MainActivity"
android:theme="@android:style/Theme.Dialog"
android:launchMode="singleInstance"
android:excludeFromRecents="true"
android:noHistory="true">
<intent-filter>
<category android:name="android.intent.category.INFO" />
</intent-filter>
<intent-filter>
<action android:name="com.wifi.connection.CONNECT_OR_EDIT" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity
android:name="com.zxing.activity.CaptureActivity"
android:configChanges="orientation|keyboardHidden"
android:screenOrientation="portrait"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
android:windowSoftInputMode="stateAlwaysHidden" >
</activity>
</application>
</manifest>

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

View file

@ -0,0 +1,20 @@
# To enable ProGuard in your project, edit project.properties
# to define the proguard.config property as described in that file.
#
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in ${sdk.dir}/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the ProGuard
# include property in project.properties.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}

View file

@ -0,0 +1,14 @@
# This file is automatically generated by Android Tools.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must be checked in Version Control Systems.
#
# To customize properties used by the Ant build system edit
# "ant.properties", and override values to adapt the script to your
# project structure.
#
# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
# Project target.
target=android-19

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5 KiB

View file

@ -0,0 +1,86 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:id="@+id/mainlayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
xmlns:android="http://schemas.android.com/apk/res/android">
<LinearLayout
android:id="@+id/layer1_linear1"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:orientation="horizontal"
android:background="#CACACA"
android:layout_weight="1">
<TextView
android:id="@+id/textDeviceTitle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|left"
android:layout_weight="5"
android:text="Configured Device"
android:textSize="25dip"/>
<ImageButton
android:id="@+id/btn_scanDevices"
android:contentDescription="@string/app_name"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|right"
android:scaleType="fitCenter"
android:text="Scan Configured Devices"
android:src="@drawable/refresh"
android:adjustViewBounds="true"
android:padding="15dp"
android:onClick="ScanDevices_OnClick"/>
</LinearLayout>
<ScrollView
android:id="@+id/layer1_linear2"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="10">
<LinearLayout
android:id="@+id/layer2_linear1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ListView android:id="@+id/listView1"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
</ListView>
</LinearLayout>
</ScrollView>
<LinearLayout
android:id="@+id/layer1_linear3"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:orientation="vertical"
android:background="#737373"
android:layout_weight="1">
<LinearLayout
android:id="@+id/layer2_linear2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_weight="4">
<Button
android:id="@+id/btn_configNewDevice"
android:contentDescription="@string/app_name"
android:layout_width="0dp"
android:layout_height="fill_parent"
android:layout_weight="1"
android:text="Configure New Device"
android:onClick="configNewDevice_OnClick"/>
</LinearLayout>
</LinearLayout>
</LinearLayout>

View file

@ -0,0 +1,85 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="5sp"
android:id="@+id/add_network_dialog"
>
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TextView
style="@style/textAppearanceBaseContent"
android:text="SSID Name: "
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="10sp"
/>
<EditText android:id="@+id/network_name_edit"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="text"/>
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TextView
style="@style/textAppearanceBaseContent"
android:text="Encryption: "
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="10sp"
/>
<Spinner
android:id="@+id/encrypt_type"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TextView
style="@style/textAppearanceBaseContent"
android:text="Password: "
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="10sp"/>
<EditText
android:id="@+id/id_ap_password"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="@android:drawable/editbox_background_normal"
android:padding="5dip"
android:singleLine="true"
android:textColor="#999999"
android:inputType="textPassword"
android:textSize="20dp"/>
</LinearLayout>
<CheckBox
android:id="@+id/checkBox_password"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Show Password" />
<!-- CheckBox android:id="@+id/is_hidden_ssid"
style="@style/textAppearanceBaseContent"
android:text="Is Hidden SSID"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/-->
</LinearLayout>

View file

@ -0,0 +1,178 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
/*
* Wifi Connector
*
* Copyright (c) 20101 Kevin Yuan (farproc@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
**/
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="5sp"
>
<LinearLayout android:id="@+id/Status"
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
style="@style/textAppearanceBaseContent"
android:text="@string/wifi_status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<TextView android:id="@+id/Status_TextView"
style="@style/textAppearanceBaseContent"
android:text="@string/status_connected"
android:paddingLeft = "5sp"
android:textStyle="bold"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</LinearLayout>
<LinearLayout android:id="@+id/Speed"
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
style="@style/textAppearanceBaseContent"
android:text="@string/wifi_link_speed"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<TextView android:id="@+id/LinkSpeed_TextView"
style="@style/textAppearanceBaseContent"
android:text="54Mbps"
android:paddingLeft = "5sp"
android:textStyle="bold"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
style="@style/textAppearanceBaseContent"
android:text="@string/signal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<TextView android:id="@+id/SignalStrength_TextView"
style="@style/textAppearanceBaseContent"
android:text="Poor"
android:paddingLeft = "5sp"
android:textStyle="bold"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
style="@style/textAppearanceBaseContent"
android:text="@string/security"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<TextView android:id="@+id/Security_TextView"
style="@style/textAppearanceBaseContent"
android:text="WEP"
android:paddingLeft = "5sp"
android:textStyle="bold"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</LinearLayout>
<LinearLayout android:id="@+id/IPAddress"
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
style="@style/textAppearanceBaseContent"
android:text="@string/ip_address"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<TextView android:id="@+id/IPAddress_TextView"
style="@style/textAppearanceBaseContent"
android:text="192.168.0.1"
android:paddingLeft = "5sp"
android:textStyle="bold"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</LinearLayout>
<LinearLayout android:id="@+id/Password"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TextView android:id="@+id/Password_TextView"
style="@style/textAppearanceBaseContent"
android:text="@string/please_type_passphrase"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="10sp"
/>
<com.wifi.connection.ChangingAwareEditText android:id="@+id/Password_EditText"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="text|textPassword"/>
<CheckBox android:id="@+id/ShowPassword_CheckBox"
style="@style/textAppearanceBaseContent"
android:text="@string/wifi_show_password"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
</LinearLayout>

View file

@ -0,0 +1,6 @@
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@android:drawable/divider_horizontal_dark"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:contentDescription="@string/dummy_content_description"
android:scaleType="fitXY"/>

View file

@ -0,0 +1,52 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent"
android:orientation="horizontal">
<LinearLayout android:id="@+id/linearLayout2"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal">
<ImageView android:src="@drawable/ic_dialog_icon"
android:layout_alignParentLeft="true"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_gravity="center_vertical|left"
android:padding="3dp"
android:id="@+id/img">
</ImageView>
<LinearLayout android:id="@+id/linearLayout1"
android:layout_width="0dp"
android:layout_height="60dp"
android:orientation="vertical"
android:layout_weight="9">
<TextView android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:textSize = "25dp"
android:layout_gravity="center_vertical|left"
android:gravity="center_vertical|left"
android:layout_weight="2"></TextView>
<LinearLayout android:id="@+id/linearLayout1"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:orientation="horizontal"
android:layout_weight="1">
<TextView android:id="@+id/info"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textSize = "15dp"
android:textColor="#3333ff"
android:layout_gravity="center_vertical|left"
android:gravity="center_vertical|left"
android:layout_weight="1"></TextView>
</LinearLayout>
</LinearLayout>
</LinearLayout>
</LinearLayout>

View file

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent"
android:orientation="horizontal">
<ImageButton
android:id="@+id/btn_scan"
android:contentDescription="@string/app_name"
android:layout_width="0dp"
android:layout_height="fill_parent"
android:layout_weight="1"
android:src="@drawable/qrcode_img"
android:onClick="qrcode_onclick"/>
<EditText
android:id="@+id/id_ap_password"
android:layout_width="0dp"
android:layout_height="fill_parent"
android:layout_weight="5"
android:background="@android:drawable/editbox_background_normal"
android:padding="5dip"
android:singleLine="true"
android:textColor="#999999"
android:textSize="20dp"/>
</LinearLayout>

View file

@ -0,0 +1,66 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="#525f67">
<LinearLayout
android:id="@+id/icon"
android:layout_width="match_parent"
android:layout_height="40dp"
android:orientation="horizontal">
<RelativeLayout
android:layout_width="0dp"
android:layout_height="40dp"
android:layout_weight="4"
android:orientation="vertical"
android:background="#525f67">
<ImageView
android:id="@+id/icon_sub"
android:layout_width="40dp"
android:layout_height="40dp"
android:padding="2dp"
android:src="@drawable/settings_icon"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true" >
</ImageView>
<TextView
android:id="@+id/customtitlebar"
android:layout_width="match_parent"
android:layout_height="40dp"
android:textColor="#ffffff"
android:text="Connect to home AP"
android:padding="3px"
android:textStyle="bold"
android:layout_toRightOf="@id/icon_sub"
android:layout_alignParentTop="true"
android:gravity="center_vertical"/>
</RelativeLayout>
<ImageButton
android:id="@+id/addNewNetworkBtn"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="@null"
android:contentDescription="@string/app_name"
android:adjustViewBounds="true"
android:scaleType="fitCenter"
android:padding="2dp"
android:onClick="addNewNetwork_OnClick"
android:src="@drawable/add_icon"/>
</LinearLayout>
<ImageView
android:layout_width="match_parent"
android:layout_height="2dp"
android:background="#ff0000"
android:layout_below="@id/icon"><!-- This is line below the title -->
</ImageView>
</RelativeLayout>

View file

@ -0,0 +1,51 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent"
android:orientation="horizontal">
<LinearLayout android:id="@+id/linearLayout2"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal">
<ImageView android:src="@drawable/ic_dialog_icon"
android:layout_alignParentLeft="true"
android:layout_height="35dp"
android:layout_width="35dp"
android:layout_gravity="center_vertical|left"
android:padding="3dp"
android:id="@+id/img">
</ImageView>
<LinearLayout android:id="@+id/linearLayout1"
android:layout_width="0dp"
android:layout_height="60dp"
android:orientation="vertical"
android:layout_weight="9">
<TextView android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:textSize = "25dp"
android:layout_gravity="center_vertical|left"
android:gravity="center_vertical|left"
android:layout_weight="2"></TextView>
<LinearLayout android:id="@+id/linearLayout1"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:orientation="horizontal"
android:layout_weight="1">
<TextView android:id="@+id/info"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textSize = "15dp"
android:textColor="#3333ff"
android:layout_gravity="center_vertical|left"
android:gravity="center_vertical|left"
android:layout_weight="1"></TextView>
</LinearLayout>
</LinearLayout>
</LinearLayout>
</LinearLayout>

View file

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent"
android:orientation="vertical">
<EditText
android:id="@+id/id_device_name"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="@android:drawable/editbox_background_normal"
android:padding="5dp"
android:singleLine="true"
android:textColor="#999999"
android:textSize="14dip"/>
</LinearLayout>

View file

@ -0,0 +1,78 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
/*
* Wifi Connector
*
* Copyright (c) 20101 Kevin Yuan (farproc@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
**/
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical" >
<include
android:layout_width="fill_parent"
android:layout_height="wrap_content"
layout="@layout/title_view" />
<ScrollView
android:id="@+id/content"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="@color/content_bk" >
</ScrollView>
<include layout="@layout/buttons_view_divider"/>
<LinearLayout
android:id="@+id/buttons_view"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="@color/buttons_view_bk"
android:gravity="center_vertical"
android:orientation="horizontal"
android:padding="5sp" >
<Button
android:id="@+id/button1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<Button
android:id="@+id/button2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<Button
android:id="@+id/button3"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
</LinearLayout>
</LinearLayout>

View file

@ -0,0 +1,51 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<SurfaceView
android:id="@+id/preview_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center" />
<com.zxing.view.ViewfinderView
android:id="@+id/viewfinder_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="center"
android:orientation="vertical" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerInParent="true"
android:background="@drawable/navbar"
android:gravity="center"
android:paddingBottom="10dp"
android:paddingTop="10dp"
android:textColor="@android:color/white"
android:textSize="18sp"
android:textStyle="bold"
android:text="@string/qrcode_title" />
<Button
android:id="@+id/btn_cancel_scan"
android:layout_width="248dp"
android:layout_height="40dp"
android:layout_alignParentBottom="true"
android:layout_centerInParent="true"
android:layout_marginBottom="75dp"
android:textSize="18sp"
android:textStyle="bold"
android:text="@string/qrcode_cancel" />
</RelativeLayout>
</FrameLayout>

View file

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:drawableLeft="@drawable/ic_dialog_icon"
android:drawablePadding="5dp"
android:gravity="center_vertical"
android:textColor="@android:color/primary_text_dark"
android:textSize="20sp"
android:padding="10dp" />

View file

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent"
android:orientation="vertical">
<EditText
android:id="@+id/id_ap_password"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="@android:drawable/editbox_background_normal"
android:padding="5dip"
android:singleLine="true"
android:textColor="#999999"
android:inputType="textPassword"
android:textSize="20dp"/>
<CheckBox
android:id="@+id/checkBox_password"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Show Password" />
</LinearLayout>

View file

@ -0,0 +1,54 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent"
android:orientation="horizontal">
<LinearLayout android:id="@+id/linearLayout2"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal">
<ImageView
android:layout_alignParentLeft="true"
android:layout_height="35dp"
android:layout_width="35dp"
android:layout_gravity="center_vertical|left"
android:padding="3dp"
android:id="@+id/signalImg">
</ImageView>
<LinearLayout android:id="@+id/linearLayout1"
android:layout_width="0dp"
android:layout_height="60dp"
android:orientation="horizontal"
android:layout_weight="9">
<TextView android:id="@+id/title_aplist"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize = "20dp"
android:layout_gravity="center_vertical|left"
android:gravity="center_vertical|left"
android:layout_weight="6"></TextView>
<TextView android:id="@+id/info_aplist"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize = "15dp"
android:textColor="#3333ff"
android:layout_gravity="center_vertical|right"
android:gravity="center_vertical|left"
android:layout_weight="1"></TextView>
<RadioGroup
android:id="@+id/radioButton1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|right"
android:gravity="center_vertical|left"
android:text="" />
</LinearLayout>
</LinearLayout>
</LinearLayout>

View file

@ -0,0 +1,9 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="@+id/action_settings"
android:orderInCategory="100"
android:showAsAction="never"
android:title="@string/action_settings"/>
</menu>

View file

@ -0,0 +1,8 @@
<resources>
<!--
Customize dimensions originally defined in res/values/dimens.xml (such as
screen margins) for sw600dp devices (e.g. 7" tablets) here.
-->
</resources>

View file

@ -0,0 +1,9 @@
<resources>
<!--
Customize dimensions originally defined in res/values/dimens.xml (such as
screen margins) for sw720dp devices (e.g. 10" tablets) in landscape here.
-->
<dimen name="activity_horizontal_margin">128dp</dimen>
</resources>

View file

@ -0,0 +1,11 @@
<resources>
<!--
Base application theme for API 11+. This theme completely replaces
AppBaseTheme from res/values/styles.xml on API 11+ devices.
-->
<style name="AppBaseTheme" parent="android:Theme.Holo.Light">
<!-- API 11 theme customizations can go here. -->
</style>
</resources>

View file

@ -0,0 +1,12 @@
<resources>
<!--
Base application theme for API 14+. This theme completely replaces
AppBaseTheme from BOTH res/values/styles.xml and
res/values-v11/styles.xml on API 14+ devices.
-->
<style name="AppBaseTheme" parent="android:Theme.Holo.Light.DarkActionBar">
<!-- API 14 theme customizations can go here. -->
</style>
</resources>

View file

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="buttons_view_bk">@android:color/darker_gray</color>
<color name="content_bk">@android:color/background_light</color>
<color name="bg_color">#EDEDED</color>
<color name="contents_text">#ff000000</color>
<color name="encode_view">#ffffffff</color>
<color name="help_button_view">#ffcccccc</color>
<color name="help_view">#ff404040</color>
<color name="possible_result_points">#c0ffff00</color>
<color name="result_image_border">#ffffffff</color>
<color name="result_minor_text">#ffc0c0c0</color>
<color name="result_points">#c000ff00</color>
<color name="result_text">#ffffffff</color>
<color name="result_view">#b0000000</color>
<color name="sbc_header_text">#ff808080</color>
<color name="sbc_header_view">#ffffffff</color>
<color name="sbc_list_item">#fffff0e0</color>
<color name="sbc_layout_view">#ffffffff</color>
<color name="sbc_page_number_text">#ff000000</color>
<color name="sbc_snippet_text">#ff4b4b4b</color>
<color name="share_text">#ff000000</color>
<color name="share_view">#ffffffff</color>
<color name="status_view">#50000000</color>
<color name="status_text">#ffffffff</color>
<color name="transparent">#00000000</color>
<color name="viewfinder_frame">#ff000000</color>
<color name="viewfinder_laser">#ffff0000</color>
<color name="viewfinder_mask">#60000000</color>
<color name="header">#58567D</color>
<color name="grgray">#686868</color>
</resources>

View file

@ -0,0 +1,7 @@
<resources>
<!-- Default screen margins, per the Android Design guidelines. -->
<dimen name="activity_horizontal_margin">16dp</dimen>
<dimen name="activity_vertical_margin">16dp</dimen>
</resources>

View file

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (C) 2008 ZXing authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources>
<!-- Messages IDs -->
<item type="id" name="auto_focus"/>
<item type="id" name="decode"/>
<item type="id" name="decode_failed"/>
<item type="id" name="decode_succeeded"/>
<item type="id" name="encode_failed"/>
<item type="id" name="encode_succeeded"/>
<item type="id" name="launch_product_query"/>
<item type="id" name="quit"/>
<item type="id" name="restart_preview"/>
<item type="id" name="return_scan_result"/>
<item type="id" name="search_book_contents_failed"/>
<item type="id" name="search_book_contents_succeeded"/>
</resources>

View file

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Simple Config Wizard</string>
<string name="action_settings">Settings</string>
<string name="hello_world">Hello world!</string>
<string name="ap_connected">connected</string>
<string name="ap_unconnected"></string>
</resources>

View file

@ -0,0 +1,97 @@
<resources>
<!--
Base application theme, dependent on API level. This theme is replaced
by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
-->
<style name="AppBaseTheme" parent="android:Theme.Light">
<!--
Theme customizations available in newer API levels can go in
res/values-vXX/styles.xml, while customizations related to
backward-compatibility can go here.
-->
</style>
<!-- Application theme. -->
<style name="AppTheme" parent="AppBaseTheme">
<!-- All customizations that are NOT specific to a particular API-level can go here. -->
</style>
<string name="toastFailed">Failed!</string>
<string name="buttonOp">More&#8230;</string>
<!-- For Simple Config Layout Interface -->
<string name="wifi_scan">Wi-Fi Network</string>
<string name="pin_text">PIN</string>
<string name="qrcode_desc">QRCode</string>
<string name="qrcode_title">QRCode Scan</string>
<string name="qrcode_cancel">Cancel</string>
<string name="start_config">Start</string>
<string name="stop_config">Press to Stop</string>
<!-- For Simple Control Layout Interface -->
<string name="dev_discovery">Connected Device</string>
<string name="rename_dev">Rename Device</string>
<string name="del_prof">Remove Device</string>
<!-- Button label to connect to a wifi network-->
<string name="connect">Connect</string>
<string name="cancel">Cancel</string>
<!-- !!!!!!!! vpn_connect_toTitle of VPN connect dialog -->
<string name="wifi_connect_to">Connect to %s</string>
<!-- Wi-Fi IP address label -->
<string name="ip_address">IP address</string>
<!-- Label for the signal strength -->
<string name="signal">Signal strength</string>
<!-- Button caption to forget a wifi network -->
<string name="forget_network">Forget</string>
<!-- Label for status of connection -->
<string name="wifi_status">Status</string>
<!--Wi-Fi settings screen, summary text for network when connected -->
<string name="status_connected">Connected</string>
<string name="status_connecting">Connecting&#8230;</string>
<!-- Label for link speed (wifi) -->
<string name="wifi_link_speed">Speed</string>
<!-- Verbose wifi signal strength. This is the best out of 4 levels. -->
<string name="wifi_signal_3">Excellent</string>
<!-- Verbose wifi signal strength. This is the 2nd best out of 4 levels. -->
<string name="wifi_signal_2">Good</string>
<!-- Verbose wifi signal strength. This is the 3rd best out of 4 levels. -->
<string name="wifi_signal_1">Fair</string>
<!-- Verbose wifi signal strength. This is the worst out of 4 levels. -->
<string name="wifi_signal_0">Poor</string>
<!-- Label for the security of a wifi network -->
<string name="security">Security</string>
<!-- Value for the wifi security. This means no encryption. -->
<string name="wifi_security_open">Open</string>
<!-- Value for the wifi security -->
<string name="wifi_security_wep">WEP</string>
<!-- Value for the wifi security -->
<string name="wifi_security_wpa">WPA</string>
<!-- Value for the wifi security -->
<string name="wifi_security_wpa2">WPA2</string>
<!-- Value for the wifi security -->
<string name="wifi_security_wpa_eap">WPA-EAP</string>
<!-- Value for the wifi security -->
<string name="wifi_security_ieee8021x">IEEE8021X</string>
<string name="please_type_passphrase">Wireless password</string>
<string name="wifi_show_password">Show password.</string>
<string name="wifi_change_password">Change password</string>
<string name="button_change_password">Modify</string>
<!-- An edit field's grayed out value when it has not been modified -->
<string name="wifi_password_unchanged">(unchanged)</string>
<!-- Button caption to save a configuration wifi -->
<string name="wifi_save_config">Save</string>
<string name="adhoc_not_supported_yet">AdHoc is not supported by Android platform yet!</string>
<string name="dummy_content_description">""</string>
<style name="PlatformDialog" parent="android:Theme.Dialog"/>
<style name="textAppearanceBaseContent" parent="@android:style/TextAppearance.Small.Inverse" />
</resources>

View file

@ -0,0 +1,78 @@
package com.rtk.simpleconfig_wizard;
import java.security.MessageDigest;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
public class AESCrypt {
// private static final String TAG = "AESCrypt";
public static String encrypt(String key, String cleartext) throws Exception {
byte[] md5Key = MD5(key.getBytes());
byte[] result = encrypt(md5Key, cleartext.getBytes());
return toHex(result);
}
public static String decrypt(String key, String encrypted) throws Exception {
byte[] md5Key = MD5(key.getBytes());
byte[] result = decrypt(md5Key, toByte(encrypted));
return new String(result);
}
public static byte[] MD5(byte[] key) throws Exception {
byte[] md5_digest = new byte[16];
MessageDigest mDigest;
mDigest = MessageDigest.getInstance("MD5");
mDigest.update(key, 0, key.length);
md5_digest = mDigest.digest();
// System.out.printf("MD5: ");
// for(int i=0; i<16; i++) {
// System.out.printf("%02x ", md5_digest[i]);
// }
// System.out.printf("\n");
return md5_digest;
}
public static byte[] encrypt(byte[] raw, byte[] clear) throws Exception {
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES/ECB/PKCS5Padding");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
byte[] encrypted = cipher.doFinal(clear);
return encrypted;
}
public static byte[] decrypt(byte[] raw, byte[] encrypted) throws Exception {
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES/ECB/PKCS5Padding");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, skeySpec);
byte[] decrypted = cipher.doFinal(encrypted);
return decrypted;
}
public static byte[] toByte(String hexString) {
int len = hexString.length()/2;
byte[] result = new byte[len];
for (int i = 0; i < len; i++)
result[i] = Integer.valueOf(hexString.substring(2*i, 2*i+2), 16).byteValue();
return result;
}
public static String toHex(byte[] buf) {
if (buf == null)
return "";
StringBuffer result = new StringBuffer(2*buf.length);
for (int i = 0; i < buf.length; i++) {
appendHex(result, buf[i]);
}
return result.toString();
}
private final static String HEX = "0123456789ABCDEF";
private static void appendHex(StringBuffer sb, byte b) {
sb.append(HEX.charAt((b>>4)&0x0f)).append(HEX.charAt(b&0x0f));
}
}

View file

@ -0,0 +1,77 @@
package com.rtk.simpleconfig_wizard;
import android.graphics.drawable.Drawable;
public class ConfigurationDevice {
public static class DeviceInfo
{
private int aliveFlag;
private String name;
private String IP;
private String macAdrress;
private int securityType;
private Drawable img;
private boolean connectedflag;
public int getaliveFlag()
{
return this.aliveFlag;
}
public void setaliveFlag(int aliveFlag)
{
this.aliveFlag = aliveFlag;
}
public String getName()
{
return this.name;
}
public void setName(String name)
{
this.name= name;
}
public String getIP()
{
return this.IP;
}
public void setIP(String IP)
{
this.IP= IP;
}
public String getmacAdrress()
{
return this.macAdrress;
}
public void setmacAdrress(String macAdrress)
{
this.macAdrress= macAdrress;
}
public int getsecurityType()
{
return this.securityType;
}
public void setsecurityType(int securityType)
{
this.securityType= securityType;
}
public Drawable getimg()
{
return this.img;
}
public void setimg(Drawable img)
{
this.img= img;
}
public boolean getconnectedflag()
{
return this.connectedflag;
}
public void setconnectedflag(boolean connectedflag)
{
this.connectedflag= connectedflag;
}
}
}

View file

@ -0,0 +1,472 @@
package com.rtk.simpleconfig_wizard;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import android.os.Environment;
import android.util.Log;
public class FileOps {
private static final String TAG = "FileOps";
private String SDPATH = Environment.getExternalStorageDirectory()+"/";
//private String SDPATH = "/data/data/com.realtek.simpleconfig_wizard/files/";
private String CFGFOLDER = "rtk_sc_wizard/";
public static String SsidPasswdFile = "wizard1";
public static String CfgPinFile = "wizard2";
public static String CtlPinFile = "wizard3";
public static String PASSWD;
private boolean checkFileExists(String path) {
File file = new File(path);
return file.exists();
}
private boolean createDir(String dir) {
File dfile = new File(dir);
if(dfile.exists())
return true;
// Log.d(TAG, "createDir: " + dfile);
return dfile.mkdir();
}
private boolean createFile(String file) throws Exception
{
File ffile = new File(file);
// Log.d(TAG, "createFile: " + ffile);
return ffile.createNewFile();
}
// private boolean deleteFile(String file) throws Exception
// {
// File ffile = new File(file);
// Log.d(TAG, "createFile: " + ffile);
// return ffile.delete();
// }
public void SetKey(String key)
{
PASSWD = key;
// Log.d(TAG, "PASSWD: " + PASSWD);
}
public RandomAccessFile openFile(String filename) throws Exception
{
RandomAccessFile rf = null;
String dir = SDPATH + CFGFOLDER;
String file = dir + filename;
// Log.d(TAG, "openFile: " + file);
if(!checkFileExists(file)) {
if(!createDir(dir)) {
//Log.e(TAG, "Create Dir Error");
return null;
}
if(!createFile(file)) {
Log.e(TAG, "Create File Error");
return null;
}
}
rf = new RandomAccessFile(file, "rw");
return rf;
}
public void writeFile(RandomAccessFile rf, String str) throws Exception
{
if(rf==null) {
return;
}
String estr = AESCrypt.encrypt(PASSWD, str);
// Log.d(TAG, "estr: " + estr);
rf.writeBytes(estr);
}
public String readFile(RandomAccessFile rf) throws Exception
{
String str = null;
byte[] strbuf = null;
int len = 0 ;
if(rf==null) {
return null;
}
len = (int)rf.length();
if(len==0) {
return null;
}
strbuf = new byte[len];
rf.read(strbuf, 0, len);
// for(int i=0; i<strbuf.length; i++)
// Log.d(TAG, "" + strbuf[i]);
str = new String(strbuf);
// Log.d(TAG, "read str: " + str);
String dstr = AESCrypt.decrypt(PASSWD, str);
// Log.d(TAG, "decrypt str: " + dstr);
return dstr;
}
public void closeFile(RandomAccessFile rf) throws Exception
{
if(rf==null)
return;
rf.close();
}
public void ParseSsidPasswdFile(String ssid)
{
RandomAccessFile rf = null;
String str = null;
try {
rf = openFile(FileOps.SsidPasswdFile);
} catch (Exception e1) {
e1.printStackTrace();
Log.e(TAG, "Open File Error");
return;
}
try {
str = readFile(rf);
} catch (Exception e) {
e.printStackTrace();
Log.e(TAG, "Read File Error");
try {
rf.setLength(0);
} catch (IOException e1) {
e1.printStackTrace();
Log.e(TAG, "Set Length Error");
return;
}
return;
}
// Log.d(TAG, "Read: " + str);
SCCtlOps.StoredPasswd = new String();
if(str==null) {
//Log.e(TAG, "Null File");
} else {
String[] items = str.split("\\|");
for(int i=0; i<items.length; i++) {
// System.out.printf("items[%d]: %s\n", i, items[i]);
String[] subitems = items[i].split("\\:");
// for(int j=0; j<subitems.length; j++) {
// Log.d(TAG, String.format("subitems[%d]: %s\n", j, subitems[j]));
// }
// Log.d(TAG, String.format("Selected SSID: %s\n", ssid));
if(ssid.equals(subitems[0]) && !subitems[1].equals("null")) {
SCCtlOps.StoredPasswd += subitems[1];
// Log.d(TAG, "Find already existed SSID");
break;
}
}
}
try {
closeFile(rf);
} catch (Exception e) {
e.printStackTrace();
Log.e(TAG, "Close File Error");
}
}
public void UpdateSsidPasswdFile(boolean isOpenNetwork)
{
RandomAccessFile rf;
try {
rf = openFile(FileOps.SsidPasswdFile);
} catch (Exception e2) {
e2.printStackTrace();
Log.e(TAG, "Open File Error");
return;
}
long len=0;
boolean isOld = false;
String getstr = new String();
String setstr = new String();
try {
len = rf.length();
} catch (IOException e1) {
e1.printStackTrace();
Log.e(TAG, "Get Length Error");
return;
}
if(len>0) {
try {
getstr = readFile(rf);
} catch (Exception e) {
e.printStackTrace();
Log.e(TAG, "Read File Error");
return;
}
// Log.d(TAG, "getstr: " + getstr);
String[] items = getstr.split("\\|");
for(int i=0; i<items.length; i++) {
// System.out.printf("items[%d]: %s\n", i, items[i]);
String[] subitems = items[i].split("\\:");
// for(int j=0; j<subitems.length; j++) {
// System.out.printf("subitems[%d]: %s\n", j, subitems[j]);
// }
if(SCCtlOps.ConnectedSSID.equals(subitems[0])) {
isOld = true;
// Log.d(TAG, "Refresh old");
if(isOpenNetwork)
setstr += SCCtlOps.ConnectedSSID + ":null|";
else
setstr += SCCtlOps.ConnectedSSID + ":" + SCCtlOps.ConnectedPasswd + "|";
} else {
// Log.d(TAG, "Re-Add existed");
setstr += subitems[0] + ":" + subitems[1] + "|";
}
}
}
if(!isOld) {
// Log.d(TAG, "Add new");
if(isOpenNetwork)
setstr += SCCtlOps.ConnectedSSID + ":null|";
else
setstr += SCCtlOps.ConnectedSSID + ":" + SCCtlOps.ConnectedPasswd + "|";
}
// Log.d(TAG, "setstr: " + setstr);
try {
rf.seek(0); //re-write all info
} catch (IOException e) {
e.printStackTrace();
Log.e(TAG, "Re-Seek Error");
return;
}
try {
writeFile(rf, setstr);
} catch (Exception e) {
e.printStackTrace();
Log.e(TAG, "Write File Error");
return;
}
try {
closeFile(rf);
} catch (Exception e) {
e.printStackTrace();
Log.e(TAG, "Close File Error");
return;
}
}
public String ParseCfgPinFile()
{
RandomAccessFile rf = null;
String getstr = null;
try {
rf = openFile(FileOps.CfgPinFile);
} catch (Exception e1) {
e1.printStackTrace();
Log.e(TAG, "Open File Error");
return null;
}
try {
getstr = readFile(rf);
} catch (Exception e) {
e.printStackTrace();
Log.e(TAG, "Read File Error");
try {
rf.setLength(0);
} catch (IOException e1) {
e1.printStackTrace();
Log.e(TAG, "Set Length Error");
return null;
}
return null;
}
// Log.d(TAG, "Read: " + getstr);
try {
closeFile(rf);
} catch (Exception e) {
e.printStackTrace();
Log.e(TAG, "Close File Error");
}
return getstr;
}
public void UpdateCfgPinFile(String pin)
{
RandomAccessFile rf;
try {
rf = openFile(FileOps.CfgPinFile);
} catch (Exception e2) {
e2.printStackTrace();
Log.e(TAG, "Open File Error");
return;
}
try {
writeFile(rf, pin);
} catch (Exception e) {
e.printStackTrace();
Log.e(TAG, "Write File Error");
return;
}
try {
closeFile(rf);
} catch (Exception e) {
e.printStackTrace();
Log.e(TAG, "Close File Error");
return;
}
}
public String ParseCtlPinFile(String mac)
{
RandomAccessFile rf = null;
String getstr = null;
String pin = null;
try {
rf = openFile(FileOps.CtlPinFile);
} catch (Exception e1) {
e1.printStackTrace();
Log.e(TAG, "Open File Error");
return null;
}
try {
getstr = readFile(rf);
} catch (Exception e) {
e.printStackTrace();
Log.e(TAG, "Read File Error");
try {
rf.setLength(0);
} catch (IOException e1) {
e1.printStackTrace();
Log.e(TAG, "Set Length Error");
return null;
}
return null;
}
// Log.d(TAG, "Read: " + getstr);
if(getstr==null) {
//Log.e(TAG, "Null File");
} else {
String[] items = getstr.split("\\;");
for(int i=0; i<items.length; i++) {
// System.out.printf("items[%d]: %s\n", i, items[i]);
String[] subitems = items[i].split("\\|");
// for(int j=0; j<subitems.length; j++) {
// Log.d(TAG, String.format("subitems[%d]: %s\n", j, subitems[j]));
// }
// Log.d(TAG, String.format("Selected MAC: %s\n", mac));
if(mac.equals(subitems[0]) && !subitems[1].equals("null")) {
pin = subitems[1];
// Log.d(TAG, "Find PIN");
break;
}
}
}
try {
closeFile(rf);
} catch (Exception e) {
e.printStackTrace();
Log.e(TAG, "Close File Error");
}
return pin;
}
public void UpdateCtlPinFile(String mac, String pin)
{
RandomAccessFile rf;
try {
rf = openFile(FileOps.CtlPinFile);
} catch (Exception e2) {
e2.printStackTrace();
Log.e(TAG, "Open File Error");
return;
}
long len=0;
boolean isOld = false;
String getstr = new String();
String setstr = new String();
try {
len = rf.length();
} catch (IOException e1) {
e1.printStackTrace();
Log.e(TAG, "Get Length Error");
return;
}
if(len>0) {
try {
getstr = readFile(rf);
} catch (Exception e) {
e.printStackTrace();
Log.e(TAG, "Read File Error");
return;
}
// Log.d(TAG, "getstr: " + getstr);
String[] items = getstr.split("\\;");
for(int i=0; i<items.length; i++) {
// System.out.printf("items[%d]: %s\n", i, items[i]);
String[] subitems = items[i].split("\\|");
// for(int j=0; j<subitems.length; j++) {
// System.out.printf("subitems[%d]: %s\n", j, subitems[j]);
// }
if(mac.equals(subitems[0])) {
isOld = true;
// Log.d(TAG, "Refresh old");
setstr += subitems[0] + "|" + pin + ";";
} else {
// Log.d(TAG, "Re-Add existed");
setstr += subitems[0] + "|" + subitems[1] + ";";
}
}
}
if(!isOld) {
// Log.d(TAG, "Add new");
setstr += mac + "|" + pin + ";";
}
// Log.d(TAG, "setstr: " + setstr);
try {
rf.seek(0); //re-write all info
} catch (IOException e) {
e.printStackTrace();
Log.e(TAG, "Re-Seek Error");
return;
}
try {
writeFile(rf, setstr);
} catch (Exception e) {
e.printStackTrace();
Log.e(TAG, "Write File Error");
return;
}
try {
closeFile(rf);
} catch (Exception e) {
e.printStackTrace();
Log.e(TAG, "Close File Error");
return;
}
}
}

View file

@ -0,0 +1,494 @@
package com.rtk.simpleconfig_wizard;
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Random;
import android.net.wifi.ScanResult;
import android.util.Log;
public class SCCtlOps {
private static final String TAG = "SCCtlOps";
public static boolean IsOpenNetwork = false; // Default has password, not open network
public static String ConnectedSSID; // Connected WIFI's SSID
public static String ConnectedPasswd; // Connected WIFI's Password
public static String StoredPasswd;
public static boolean isHiddenSSID;
public static boolean addNewNetwork;
public static ScanResult reBuiltScanResult;
public static final int MAX_CLIENTS_NUM = 32;
public static boolean DiscoveredNew;
public static boolean SetAble = true;
/** For UDP Data Receive */
// public static byte[] RecvBuf = new byte[512];
/** UDP Payload Format Flag */
public static class Flag{
private Flag(){
}
/** Flag */
public static final int Version = (0x00<<6); // 2 bits
public static final int RequestFlag = (0<<5); // 1 bit
public static final int ResponseFlag = (1<<5);
/** Request */
public static final int Discover = 0x00; // 5 bits
public static final int SaveProf = 0x01;
public static final int DelProf = 0x02;
public static final int RenameDev = 0x03;
public static final int ReturnACK = 0x04;
/** Response */
public static final int CfgSuccessACK = 0x00; // 5 bits
public static final int DiscoverACK = 0x01;
public static final int SaveProfACK = 0x02;
public static final int DelProfACK = 0x03;
public static final int RenameDevACK = 0x04;
public static final int CfgSuccessACKSendBack = 0x05;
}
/** UDP Payload Format ACK to Scan */
public static class ScanACK{
private ScanACK(){
}
/** MAC */
public static int MaxDevNum = 0;
public static byte[][] Mac = new byte[MAX_CLIENTS_NUM][6]; // Record the connected STA
/** Status */
public static byte[] Status = new byte[MAX_CLIENTS_NUM];
/** Device Type */
public static byte[][] Type = new byte[MAX_CLIENTS_NUM][2];
/** Device IP */
public static byte[][] IPBuf = new byte[MAX_CLIENTS_NUM][4];
public static String[] IP = new String[MAX_CLIENTS_NUM];
/** Device Name */
public static byte[][] NameBuf = new byte[MAX_CLIENTS_NUM][64];
public static String[] Name = new String[MAX_CLIENTS_NUM];
}
public static byte[] rtk_sc_gen_digest(byte[] inputData)
{
try {
return AESCrypt.MD5(inputData);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static void rtk_sc_control_reset()
{
ScanACK.MaxDevNum = 0;
Arrays.fill(ScanACK.Status, (byte)0);
for(int i=0; i<MAX_CLIENTS_NUM; i++) {
Arrays.fill(ScanACK.Mac[i], (byte)0);
Arrays.fill(ScanACK.Type[i], (byte)0);
Arrays.fill(ScanACK.IPBuf[i], (byte)0);
Arrays.fill(ScanACK.NameBuf[i], (byte)0);
}
ScanACK.IP = new String[MAX_CLIENTS_NUM];
ScanACK.Name = new String[MAX_CLIENTS_NUM];
}
public static byte[] rtk_sc_gen_discover_packet(String defaultPIN)
{
byte[] CmdBuf = new byte[92];
short PayloadLen = 0;
Arrays.fill(CmdBuf, (byte)0);
/** Flag */
CmdBuf[0] += Flag.Version;
CmdBuf[0] += Flag.RequestFlag;
CmdBuf[0] += Flag.Discover;
/** Encrypt Flag */
CmdBuf[3] = 0x01;
PayloadLen += 1;
/** Nonce */
if(CmdBuf[3] == 0x01) {
for(int i=0; i<64; i++) {
Random r = new Random();
CmdBuf[4+i] = (byte) (r.nextInt(256) + 1);
}
}
PayloadLen += 64;
/** Default PIN Digest */
byte[] inputData = new byte[64 + defaultPIN.length()];
System.arraycopy(CmdBuf, 4, inputData, 0, 64);
System.arraycopy(defaultPIN.getBytes(), 0, inputData, 64, defaultPIN.length());
byte[] digest = rtk_sc_gen_digest(inputData);
System.arraycopy(digest, 0, CmdBuf, PayloadLen+3, 16);
PayloadLen += 16;
/** MAC Address */
PayloadLen += 6;
/** Device Type */
PayloadLen += 2;
/** Length */
byte[] buf = new byte[2];
buf[0] = (byte)((PayloadLen >> 8) & 0xff);
buf[1] = (byte)(PayloadLen & 0xff);
System.arraycopy(buf, 0, CmdBuf, 1, 2);
/*String dbgStr = new String();
for(int i=0; i<92; i++)
dbgStr += String.format("%02x ", CmdBuf[i]);
Log.d(TAG, "Client Discover Packet: " + dbgStr);*/
return CmdBuf;
}
public static byte[] rtk_sc_gen_control_packet(int flag, String defaultPIN, String inputPIN, String nameStr)
{
byte[] CmdBuf;
short PayloadLen = 0;
byte[] digest;
byte[] inputData;
byte[] nameBuf = null;
if(flag == Flag.RenameDev) {
// Log.d(TAG, "nameStr: " + nameStr);
try {
nameBuf = nameStr.getBytes("UTF-8");
} catch (UnsupportedEncodingException e) {
Log.e(TAG, "Get name bytes error");
e.printStackTrace();
return null;
}
CmdBuf = new byte[100+nameBuf.length];
} else {
CmdBuf = new byte[100];
}
Arrays.fill(CmdBuf, (byte)0);
/** Flag */
CmdBuf[0] += Flag.Version;
CmdBuf[0] += Flag.RequestFlag;
CmdBuf[0] += flag;
/** Encrypt Flag */
CmdBuf[3] = 0x01;
PayloadLen += 1;
/** Nonce */
if(CmdBuf[3] == 0x01) {
for(int i=0; i<64; i++) {
Random r = new Random();
CmdBuf[4+i] = (byte) (r.nextInt(256) + 1);
}
}
PayloadLen += 64;
/** Default PIN Digest */
// Log.d(TAG, "defaultPIN: " + defaultPIN);
inputData = new byte[64 + defaultPIN.length()];
System.arraycopy(CmdBuf, 4, inputData, 0, 64);
System.arraycopy(defaultPIN.getBytes(), 0, inputData, 64, defaultPIN.length());
digest = rtk_sc_gen_digest(inputData);
System.arraycopy(digest, 0, CmdBuf, PayloadLen+3, 16);
PayloadLen += 16;
/** User Input PIN Digest */
// Log.d(TAG, "inputPIN: " + inputPIN);
inputData = new byte[64 + inputPIN.length()];
System.arraycopy(CmdBuf, 4, inputData, 0, 64);
System.arraycopy(inputPIN.getBytes(), 0, inputData, 64, inputPIN.length());
digest = rtk_sc_gen_digest(inputData);
System.arraycopy(digest, 0, CmdBuf, PayloadLen+3, 16);
PayloadLen += 16;
/** Device Name */
if(flag == Flag.RenameDev) {
// String tmp = new String();
// for(int i=0; i<nameBuf.length; i++) {
// tmp += String.format("%02x ", nameBuf[i]);
// }
// Log.d(TAG, "nameBuf: " + tmp);
System.arraycopy(nameBuf, 0, CmdBuf, PayloadLen+3, nameBuf.length);
PayloadLen += nameBuf.length;
}
/** Length */
byte[] buf = new byte[2];
buf[0] = (byte)((PayloadLen >> 8) & 0xff);
buf[1] = (byte)(PayloadLen & 0xff);
System.arraycopy(buf, 0, CmdBuf, 1, 2);
return CmdBuf;
}
public static byte[] rtk_sc_gen_control_confirm_packet(int flag, String defaultPIN, String inputPIN)
{
byte[] CmdBuf;
short PayloadLen = 0;
byte[] digest;
byte[] inputData;
CmdBuf = new byte[101];
Arrays.fill(CmdBuf, (byte)0);
/** Flag */
CmdBuf[0] += Flag.Version;
CmdBuf[0] += Flag.RequestFlag;
CmdBuf[0] += Flag.ReturnACK;
/** Encrypt Flag */
CmdBuf[3] = 0x01;
PayloadLen += 1;
/** Nonce */
if(CmdBuf[3] == 0x01) {
for(int i=0; i<64; i++) {
Random r = new Random();
CmdBuf[4+i] = (byte) (r.nextInt(256) + 1);
}
}
PayloadLen += 64;
/** Default PIN Digest */
// Log.d(TAG, "defaultPIN: " + defaultPIN);
inputData = new byte[64 + defaultPIN.length()];
System.arraycopy(CmdBuf, 4, inputData, 0, 64);
System.arraycopy(defaultPIN.getBytes(), 0, inputData, 64, defaultPIN.length());
digest = rtk_sc_gen_digest(inputData);
System.arraycopy(digest, 0, CmdBuf, PayloadLen+3, 16);
PayloadLen += 16;
/** User Input PIN Digest */
// Log.d(TAG, "inputPIN: " + inputPIN);
inputData = new byte[64 + inputPIN.length()];
System.arraycopy(CmdBuf, 4, inputData, 0, 64);
System.arraycopy(inputPIN.getBytes(), 0, inputData, 64, inputPIN.length());
digest = rtk_sc_gen_digest(inputData);
System.arraycopy(digest, 0, CmdBuf, PayloadLen+3, 16);
PayloadLen += 16;
/** Encrypt Flag */
CmdBuf[PayloadLen+3] += flag;
PayloadLen += 1;
/** Length */
byte[] buf = new byte[2];
buf[0] = (byte)((PayloadLen >> 8) & 0xff);
buf[1] = (byte)(PayloadLen & 0xff);
System.arraycopy(buf, 0, CmdBuf, 1, 2);
return CmdBuf;
}
public static int handle_discover_ack(byte[] recv_buf)
{
int length, equalCnt=0;
String dbgStr;
if(SetAble==false)
return -1;
DiscoveredNew = false;
// System.arraycopy(recv_buf, 0, RecvBuf, 0, recv_buf.length);
length = (recv_buf[1]<<8)&0xFF00 | (recv_buf[2])&0xFF;
// Log.d(TAG, String.format("length: 0x%02x", length));
if(length < 6) {
Log.e(TAG, "At least a mac\n");
return -1;
}
if(ScanACK.MaxDevNum > MAX_CLIENTS_NUM) {
Log.e(TAG, "The receive buf is full\n");
return -1;
}
/** Judge if it is the same MAC */
// Log.d(TAG, "Max Device Number: " + ScanACK.MaxDevNum);
if(ScanACK.MaxDevNum > 0) {/* Not the first time */
for(int j=0; j<ScanACK.MaxDevNum; j++) {
for(int i=0; i<6; i++) {
if(recv_buf[3+i] == ScanACK.Mac[j][i])
equalCnt++;
}
if(equalCnt == 6)
return -1; //find the same MAC
equalCnt = 0; //for the second judge(if has)
}
}
/** Not the same MAC */
System.arraycopy(recv_buf, 3, ScanACK.Mac[ScanACK.MaxDevNum], 0, 6);
dbgStr = new String();
for(int i=0; i<6; i++) {
dbgStr += String.format("%02x", ScanACK.Mac[ScanACK.MaxDevNum][i]);
if(i<5)
dbgStr += ":";
}
Log.i(TAG, "Discovered MAC: " + dbgStr);
/** Status */
if(length > 7) {
ScanACK.Status[ScanACK.MaxDevNum] = recv_buf[9];
// Log.d(TAG, String.format("Status: %02x", ScanACK.Status[ScanACK.MaxDevNum]));
}
/** Device Type */
if(length > 9) {
System.arraycopy(recv_buf, 10, ScanACK.Type[ScanACK.MaxDevNum], 0, 2);
// Log.d(TAG, String.format("Device Type: %02x %02x", ScanACK.DevType[ScanACK.MaxDevNum][0],
// ScanACK.DevType[ScanACK.MaxDevNum][1]));
}
/** Device IP */
if(length > 13) {
System.arraycopy(recv_buf, 12, ScanACK.IPBuf[ScanACK.MaxDevNum], 0, 4);
ScanACK.IP[ScanACK.MaxDevNum] = String.format("%d.%d.%d.%d",
ScanACK.IPBuf[ScanACK.MaxDevNum][0]&0xff,
ScanACK.IPBuf[ScanACK.MaxDevNum][1]&0xff,
ScanACK.IPBuf[ScanACK.MaxDevNum][2]&0xff,
ScanACK.IPBuf[ScanACK.MaxDevNum][3]&0xff);
Log.i(TAG, "Device IP: " + ScanACK.IP[ScanACK.MaxDevNum]);
}
/** Device Name */
if(length > 14) {
System.arraycopy(recv_buf, 16, ScanACK.NameBuf[ScanACK.MaxDevNum], 0, 64);
String name = null;
try {
name = new String(ScanACK.NameBuf[ScanACK.MaxDevNum], "UTF-8").trim();
} catch (UnsupportedEncodingException e) {
Log.e(TAG, "Get device name error");
e.printStackTrace();
}
if(name.length()>0)
ScanACK.Name[ScanACK.MaxDevNum] = name;
else
ScanACK.Name[ScanACK.MaxDevNum] = null;
Log.i(TAG, "Device Name: " + ScanACK.Name[ScanACK.MaxDevNum]);
}
ScanACK.MaxDevNum++;
DiscoveredNew = true;
return 0;
}
public static int rtk_sc_get_discovered_dev_num()
{
return ScanACK.MaxDevNum;
}
// public static void rtk_get_connected_dev_test1()
// {
// /** For test */
// byte[] tmp = {0x21,
// 00,0x2c,
// 00,0x18,(byte)0x95,0x61,(byte)0x89,0x75,
// 0x01,
// 00,0x01,
// (byte)0xc0,(byte)0xa8,0x01,(byte)0xdd,00,
// (byte)0xe7,(byte)0xa9,(byte)0xba,(byte)0xe8,(byte)0xb0,
// (byte)0x83,00,00,00,00,
// 00,00,00,00,00,
// 00,00,00,00,00,
// 00,00,00,00,00,
// 00,00};
// System.arraycopy(tmp, 0, RecvBuf, 0, tmp.length);
// handle_discover_ack();
// }
//
// public static void rtk_get_connected_dev_test2()
// {
// byte[] tmp = {0x21,
// 00,0x2c,
// 00,0x44,0x46,0x66,0x66,0x76,
// 0x02,
// 00,0x02,
// (byte)0xc0,(byte)0xa8,0x01,(byte)0xde,00,
// 0x54,0x56,00,00,00,
// 00,00,00,00,00,
// 00,00,00,00,00,
// 00,00,00,00,00,
// 00,00,00,00,00,
// 00,00};
// System.arraycopy(tmp, 0, RecvBuf, 0, tmp.length);
// handle_discover_ack();
// }
public static int rtk_sc_get_discovered_dev_info(List<HashMap<String, Object>> DevInfo)
{
int i;
String buf;
HashMap<String, Object> hmap;
SetAble = false;
// Log.d(TAG, "ScanACK.MaxDevNum: " + ScanACK.MaxDevNum);
for(int index=0; index<ScanACK.MaxDevNum; index++) {
buf = new String();
hmap = new HashMap<String, Object>();
for(i=0; i<6; i++) {
buf += String.format("%02x", ScanACK.Mac[index][i]);
if(i<5)
buf += ":";
}
// Log.d(TAG, "Mac: " + buf);
hmap.put("MAC", buf);
buf = new String();
switch(ScanACK.Status[index]) {
case 0x01:
buf = "Connected";
break;
case 0x02:
buf = "Profile saved";
break;
default:
buf = "Unkown status";
break;
}
// Log.d(TAG, "Status: " + buf);
hmap.put("Status", buf);
buf = new String();
short type = (short)((ScanACK.Type[index][0]&0xff<<8) + (ScanACK.Type[index][1]&0xff) );
switch(type) {
case 0x0000:
buf = "Any type";
break;
case 0x0001:
buf = "TV";
break;
case 0x0002:
buf = "Air conditioner";
break;
default:
buf = "Unkown type";
break;
}
// Log.d(TAG, "DevType: " + buf);
hmap.put("Type", buf);
// Log.d(TAG, "IP: " + ScanACK.DevIP[index]);
hmap.put("IP", ScanACK.IP[index]);
// Log.d(TAG, "Name: " + ScanACK.DevName[index]);
hmap.put("Name", ScanACK.Name[index]);
DevInfo.add(hmap);
}
SetAble = true;
return 0;
}
}

View file

@ -0,0 +1,116 @@
/*
* Wifi Connecter
*
* Copyright (c) 20101 Kevin Yuan (farproc@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
**/
package com.wifi.connection;
import com.rtk.simpleconfig_wizard.R;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiManager;
import android.provider.Settings;
import android.text.InputType;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.CompoundButton.OnCheckedChangeListener;
public abstract class BaseContent implements Floating.Content, OnCheckedChangeListener {
protected final WifiManager mWifiManager;
protected final Floating mFloating;
protected final ScanResult mScanResult;
protected final String mScanResultSecurity;
protected final boolean mIsOpenNetwork ;
protected int mNumOpenNetworksKept;
protected View mView;
protected OnClickListener mCancelOnClick = new OnClickListener() {
@Override
public void onClick(View v) {
mFloating.finish();
}
};
protected String getCancelString() {
return mFloating.getString(android.R.string.cancel);
}
private static final int[] SIGNAL_LEVEL = {R.string.wifi_signal_0, R.string.wifi_signal_1,
R.string.wifi_signal_2, R.string.wifi_signal_3};
public BaseContent(final Floating floating, final WifiManager wifiManager, final ScanResult scanResult) {
super();
mWifiManager = wifiManager;
mFloating = floating;
mScanResult = scanResult;
mScanResultSecurity = Wifi.ConfigSec.getScanResultSecurity(mScanResult);
mIsOpenNetwork = Wifi.ConfigSec.isOpenNetwork(mScanResultSecurity);
mView = View.inflate(mFloating, R.layout.base_content, null);
((TextView)mView.findViewById(R.id.SignalStrength_TextView)).setText(SIGNAL_LEVEL[WifiManager.calculateSignalLevel(mScanResult.level, SIGNAL_LEVEL.length)]);
final String rawSecurity = Wifi.ConfigSec.getDisplaySecirityString(mScanResult);
final String readableSecurity = Wifi.ConfigSec.isOpenNetwork(rawSecurity) ? mFloating.getString(R.string.wifi_security_open) : rawSecurity;
((TextView)mView.findViewById(R.id.Security_TextView)).setText(readableSecurity);
((CheckBox)mView.findViewById(R.id.ShowPassword_CheckBox)).setOnCheckedChangeListener(this);
mNumOpenNetworksKept = Settings.Secure.getInt(floating.getContentResolver(),
Settings.Secure.WIFI_NUM_OPEN_NETWORKS_KEPT, 10);
}
@Override
public View getView() {
return mView;
}
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
((EditText)mView.findViewById(R.id.Password_EditText)).setInputType(
InputType.TYPE_CLASS_TEXT |
(isChecked ? InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD
:InputType.TYPE_TEXT_VARIATION_PASSWORD));
}
public OnClickListener mChangePasswordOnClick = new OnClickListener() {
@Override
public void onClick(View v) {
changePassword();
}
};
public void changePassword() {
mFloating.setContent(new ChangePasswordContent(mFloating, mWifiManager, mScanResult));
}
}

View file

@ -0,0 +1,122 @@
/*
* Wifi Connecter
*
* Copyright (c) 20101 Kevin Yuan (farproc@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
**/
package com.wifi.connection;
import com.rtk.simpleconfig_wizard.R;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
import android.view.ContextMenu;
import android.view.MenuItem;
import android.view.View;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.View.OnClickListener;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
public class ChangePasswordContent extends BaseContent {
private ChangingAwareEditText mPasswordEditText;
public ChangePasswordContent(Floating floating, WifiManager wifiManager,
ScanResult scanResult) {
super(floating, wifiManager, scanResult);
mView.findViewById(R.id.Status).setVisibility(View.GONE);
mView.findViewById(R.id.Speed).setVisibility(View.GONE);
mView.findViewById(R.id.IPAddress).setVisibility(View.GONE);
mPasswordEditText = ((ChangingAwareEditText)mView.findViewById(R.id.Password_EditText));
((TextView)mView.findViewById(R.id.Password_TextView)).setText(R.string.please_type_passphrase);
((EditText)mView.findViewById(R.id.Password_EditText)).setHint(R.string.wifi_password_unchanged);
}
@Override
public int getButtonCount() {
return 2;
}
@Override
public OnClickListener getButtonOnClickListener(int index) {
return mOnClickListeners[index];
}
@Override
public CharSequence getButtonText(int index) {
switch(index) {
case 0:
return mFloating.getString(R.string.wifi_save_config);
case 1:
return getCancelString();
default:
return null;
}
}
@Override
public CharSequence getTitle() {
return mScanResult.SSID;
}
private OnClickListener mSaveOnClick = new OnClickListener() {
@Override
public void onClick(View v) {
if(mPasswordEditText.getChanged()) {
final WifiConfiguration config = Wifi.getWifiConfiguration(mWifiManager, mScanResult, mScanResultSecurity);
boolean saveResult = false;
if(config != null) {
saveResult = Wifi.changePasswordAndConnect(mFloating, mWifiManager, config
, mPasswordEditText.getText().toString()
, mNumOpenNetworksKept);
}
if(!saveResult) {
Toast.makeText(mFloating, R.string.toastFailed, Toast.LENGTH_LONG).show();
}
}
mFloating.finish();
}
};
OnClickListener mOnClickListeners[] = {mSaveOnClick, mCancelOnClick};
@Override
public boolean onContextItemSelected(MenuItem item) {
return false;
}
@Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
}
}

View file

@ -0,0 +1,47 @@
/*
* Wifi Connecter
*
* Copyright (c) 20101 Kevin Yuan (farproc@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
**/
package com.wifi.connection;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.EditText;
public class ChangingAwareEditText extends EditText {
public ChangingAwareEditText(Context context, AttributeSet attrs) {
super(context, attrs);
}
private boolean mChanged = false;
public boolean getChanged() {
return mChanged;
}
protected void onTextChanged (CharSequence text, int start, int before, int after) {
mChanged = true;
}
}

View file

@ -0,0 +1,34 @@
package com.wifi.connection;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
public abstract class ConfigurationSecurities {
/**
* @return The security of a given {@link WifiConfiguration}.
*/
public abstract String getWifiConfigurationSecurity(WifiConfiguration wifiConfig);
/**
* @return The security of a given {@link ScanResult}.
*/
public abstract String getScanResultSecurity(ScanResult scanResult);
/**
* Fill in the security fields of WifiConfiguration config.
* @param config The object to fill.
* @param security If is OPEN, password is ignored.
* @param password Password of the network if security is not OPEN.
*/
public abstract void setupSecurity(WifiConfiguration config, String security, final String password);
public abstract String getDisplaySecirityString(final ScanResult scanResult);
public abstract boolean isOpenNetwork(final String security);
public static ConfigurationSecurities newInstance() {
// System.out.printf("Version.SDK: %d\n", Version.SDK);
if(Version.SDK < 8) {
return new ConfigurationSecuritiesOld();
} else {
return new ConfigurationSecuritiesV8();
}
}
}

View file

@ -0,0 +1,185 @@
package com.wifi.connection;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiConfiguration.AuthAlgorithm;
import android.net.wifi.WifiConfiguration.GroupCipher;
import android.net.wifi.WifiConfiguration.KeyMgmt;
import android.net.wifi.WifiConfiguration.PairwiseCipher;
import android.net.wifi.WifiConfiguration.Protocol;
import android.text.TextUtils;
import android.util.Log;
public class ConfigurationSecuritiesOld extends ConfigurationSecurities {
// Constants used for different security types
public static final String WPA2 = "WPA2";
public static final String WPA = "WPA";
public static final String WEP = "WEP";
public static final String OPEN = "Open";
// For EAP Enterprise fields
public static final String WPA_EAP = "WPA-EAP";
public static final String IEEE8021X = "IEEE8021X";
public static final String[] EAP_METHOD = { "PEAP", "TLS", "TTLS" };
public static final int WEP_PASSWORD_AUTO = 0;
public static final int WEP_PASSWORD_ASCII = 1;
public static final int WEP_PASSWORD_HEX = 2;
static final String[] SECURITY_MODES = { WEP, WPA, WPA2, WPA_EAP, IEEE8021X };
private static final String TAG = "ConfigurationSecuritiesOld";
@Override
public String getWifiConfigurationSecurity(WifiConfiguration wifiConfig) {
if (wifiConfig.allowedKeyManagement.get(KeyMgmt.NONE)) {
// If we never set group ciphers, wpa_supplicant puts all of them.
// For open, we don't set group ciphers.
// For WEP, we specifically only set WEP40 and WEP104, so CCMP
// and TKIP should not be there.
if (!wifiConfig.allowedGroupCiphers.get(GroupCipher.CCMP)
&&
(wifiConfig.allowedGroupCiphers.get(GroupCipher.WEP40)
|| wifiConfig.allowedGroupCiphers.get(GroupCipher.WEP104))) {
return WEP;
} else {
return OPEN;
}
} else if (wifiConfig.allowedProtocols.get(Protocol.RSN)) {
return WPA2;
} else if (wifiConfig.allowedKeyManagement.get(KeyMgmt.WPA_EAP)) {
return WPA_EAP;
} else if (wifiConfig.allowedKeyManagement.get(KeyMgmt.IEEE8021X)) {
return IEEE8021X;
} else if (wifiConfig.allowedProtocols.get(Protocol.WPA)) {
return WPA;
} else {
Log.w(TAG, "Unknown security type from WifiConfiguration, falling back on open.");
return OPEN;
}
}
@Override
public String getScanResultSecurity(ScanResult scanResult) {
final String cap = scanResult.capabilities;
for (int i = SECURITY_MODES.length - 1; i >= 0; i--) {
if (cap.contains(SECURITY_MODES[i])) {
return SECURITY_MODES[i];
}
}
return OPEN;
}
@Override
public String getDisplaySecirityString(final ScanResult scanResult) {
return getScanResultSecurity(scanResult);
}
private static boolean isHexWepKey(String wepKey) {
final int len = wepKey.length();
// WEP-40, WEP-104, and some vendors using 256-bit WEP (WEP-232?)
if (len != 10 && len != 26 && len != 58) {
return false;
}
return isHex(wepKey);
}
private static boolean isHex(String key) {
for (int i = key.length() - 1; i >= 0; i--) {
final char c = key.charAt(i);
if (!(c >= '0' && c <= '9' || c >= 'A' && c <= 'F' || c >= 'a' && c <= 'f')) {
return false;
}
}
return true;
}
@Override
public void setupSecurity(WifiConfiguration config, String security, final String password) {
config.allowedAuthAlgorithms.clear();
config.allowedGroupCiphers.clear();
config.allowedKeyManagement.clear();
config.allowedPairwiseCiphers.clear();
config.allowedProtocols.clear();
if (TextUtils.isEmpty(security)) {
security = OPEN;
Log.w(TAG, "Empty security, assuming open");
}
if (security.equals(WEP)) {
int wepPasswordType = WEP_PASSWORD_AUTO;
// If password is empty, it should be left untouched
if (!TextUtils.isEmpty(password)) {
if (wepPasswordType == WEP_PASSWORD_AUTO) {
if (isHexWepKey(password)) {
config.wepKeys[0] = password;
} else {
config.wepKeys[0] = Wifi.convertToQuotedString(password);
}
} else {
config.wepKeys[0] = wepPasswordType == WEP_PASSWORD_ASCII
? Wifi.convertToQuotedString(password)
: password;
}
}
config.wepTxKeyIndex = 0;
config.allowedAuthAlgorithms.set(AuthAlgorithm.OPEN);
config.allowedAuthAlgorithms.set(AuthAlgorithm.SHARED);
config.allowedKeyManagement.set(KeyMgmt.NONE);
config.allowedGroupCiphers.set(GroupCipher.WEP40);
config.allowedGroupCiphers.set(GroupCipher.WEP104);
} else if (security.equals(WPA) || security.equals(WPA2)){
config.allowedGroupCiphers.set(GroupCipher.TKIP);
config.allowedGroupCiphers.set(GroupCipher.CCMP);
config.allowedKeyManagement.set(KeyMgmt.WPA_PSK);
config.allowedPairwiseCiphers.set(PairwiseCipher.CCMP);
config.allowedPairwiseCiphers.set(PairwiseCipher.TKIP);
config.allowedProtocols.set(security.equals(WPA2) ? Protocol.RSN : Protocol.WPA);
// If password is empty, it should be left untouched
if (!TextUtils.isEmpty(password)) {
if (password.length() == 64 && isHex(password)) {
// Goes unquoted as hex
config.preSharedKey = password;
} else {
// Goes quoted as ASCII
config.preSharedKey = Wifi.convertToQuotedString(password);
}
}
} else if (security.equals(OPEN)) {
config.allowedKeyManagement.set(KeyMgmt.NONE);
} else if (security.equals(WPA_EAP) || security.equals(IEEE8021X)) {
config.allowedGroupCiphers.set(GroupCipher.TKIP);
config.allowedGroupCiphers.set(GroupCipher.CCMP);
if (security.equals(WPA_EAP)) {
config.allowedKeyManagement.set(KeyMgmt.WPA_EAP);
} else {
config.allowedKeyManagement.set(KeyMgmt.IEEE8021X);
}
if (!TextUtils.isEmpty(password)) {
config.preSharedKey = Wifi.convertToQuotedString(password);
}
}
}
@Override
public boolean isOpenNetwork(String security) {
return OPEN.equals(security);
}
}

View file

@ -0,0 +1,180 @@
package com.wifi.connection;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiConfiguration.AuthAlgorithm;
import android.net.wifi.WifiConfiguration.KeyMgmt;
import android.util.Log;
public class ConfigurationSecuritiesV8 extends ConfigurationSecurities {
static final int SECURITY_NONE = 0;
static final int SECURITY_WEP = 1;
static final int SECURITY_PSK = 2;
static final int SECURITY_EAP = 3;
enum PskType {
UNKNOWN,
WPA,
WPA2,
WPA_WPA2
}
private static final String TAG = "ConfigurationSecuritiesV14";
private static int getSecurity(WifiConfiguration config) {
if (config.allowedKeyManagement.get(KeyMgmt.WPA_PSK)) {
return SECURITY_PSK;
}
if (config.allowedKeyManagement.get(KeyMgmt.WPA_EAP) ||
config.allowedKeyManagement.get(KeyMgmt.IEEE8021X)) {
return SECURITY_EAP;
}
return (config.wepKeys[0] != null) ? SECURITY_WEP : SECURITY_NONE;
}
private static int getSecurity(ScanResult result) {
if (result.capabilities.contains("WEP")) {
return SECURITY_WEP;
} else if (result.capabilities.contains("PSK")) {
return SECURITY_PSK;
} else if (result.capabilities.contains("EAP")) {
return SECURITY_EAP;
}
return SECURITY_NONE;
}
@Override
public String getWifiConfigurationSecurity(WifiConfiguration wifiConfig) {
return String.valueOf(getSecurity(wifiConfig));
}
@Override
public String getScanResultSecurity(ScanResult scanResult) {
return String.valueOf(getSecurity(scanResult));
}
@Override
public void setupSecurity(WifiConfiguration config, String security, String password) {
config.allowedAuthAlgorithms.clear();
config.allowedGroupCiphers.clear();
config.allowedKeyManagement.clear();
config.allowedPairwiseCiphers.clear();
config.allowedProtocols.clear();
final int sec = security == null ? SECURITY_NONE : Integer.valueOf(security);
final int passwordLen = password == null ? 0 : password.length();
switch (sec) {
case SECURITY_NONE:
config.allowedKeyManagement.set(KeyMgmt.NONE);
break;
case SECURITY_WEP:
config.allowedKeyManagement.set(KeyMgmt.NONE);
config.allowedAuthAlgorithms.set(AuthAlgorithm.OPEN);
config.allowedAuthAlgorithms.set(AuthAlgorithm.SHARED);
if (passwordLen != 0) {
// WEP-40, WEP-104, and 256-bit WEP (WEP-232?)
if ((passwordLen == 10 || passwordLen == 26 || passwordLen == 58) &&
password.matches("[0-9A-Fa-f]*")) {
config.wepKeys[0] = password;
} else {
config.wepKeys[0] = '"' + password + '"';
}
}
break;
case SECURITY_PSK:
config.allowedKeyManagement.set(KeyMgmt.WPA_PSK);
if (passwordLen != 0) {
if (password.matches("[0-9A-Fa-f]{64}")) {
config.preSharedKey = password;
} else {
config.preSharedKey = '"' + password + '"';
}
}
break;
case SECURITY_EAP:
config.allowedKeyManagement.set(KeyMgmt.WPA_EAP);
config.allowedKeyManagement.set(KeyMgmt.IEEE8021X);
// config.eap.setValue((String) mEapMethodSpinner.getSelectedItem());
//
// config.phase2.setValue((mPhase2Spinner.getSelectedItemPosition() == 0) ? "" :
// "auth=" + mPhase2Spinner.getSelectedItem());
// config.ca_cert.setValue((mEapCaCertSpinner.getSelectedItemPosition() == 0) ? "" :
// KEYSTORE_SPACE + Credentials.CA_CERTIFICATE +
// (String) mEapCaCertSpinner.getSelectedItem());
// config.client_cert.setValue((mEapUserCertSpinner.getSelectedItemPosition() == 0) ?
// "" : KEYSTORE_SPACE + Credentials.USER_CERTIFICATE +
// (String) mEapUserCertSpinner.getSelectedItem());
// config.private_key.setValue((mEapUserCertSpinner.getSelectedItemPosition() == 0) ?
// "" : KEYSTORE_SPACE + Credentials.USER_PRIVATE_KEY +
// (String) mEapUserCertSpinner.getSelectedItem());
// config.identity.setValue((mEapIdentityView.length() == 0) ? "" :
// mEapIdentityView.getText().toString());
// config.anonymous_identity.setValue((mEapAnonymousView.length() == 0) ? "" :
// mEapAnonymousView.getText().toString());
// if (mPasswordView.length() != 0) {
// config.password.setValue(mPasswordView.getText().toString());
// }
break;
default:
Log.e(TAG, "Invalid security type: " + sec);
}
// config.proxySettings = mProxySettings;
// config.ipAssignment = mIpAssignment;
// config.linkProperties = new LinkProperties(mLinkProperties);
}
private static PskType getPskType(ScanResult result) {
boolean wpa = result.capabilities.contains("WPA-PSK");
boolean wpa2 = result.capabilities.contains("WPA2-PSK");
if (wpa2 && wpa) {
return PskType.WPA_WPA2;
} else if (wpa2) {
return PskType.WPA2;
} else if (wpa) {
return PskType.WPA;
} else {
Log.w(TAG, "Received abnormal flag string: " + result.capabilities);
return PskType.UNKNOWN;
}
}
@Override
public String getDisplaySecirityString(final ScanResult scanResult) {
final int security = getSecurity(scanResult);
if(security == SECURITY_PSK) {
switch(getPskType(scanResult)) {
case WPA:
return "WPA";
case WPA_WPA2:
case WPA2:
return "WPA2";
default:
return "?";
}
} else {
switch(security) {
case SECURITY_NONE:
return "OPEN";
case SECURITY_WEP:
return "WEP";
case SECURITY_EAP:
return "EAP";
}
}
return "?";
}
@Override
public boolean isOpenNetwork(String security) {
return String.valueOf(SECURITY_NONE).equals(security);
}
}

View file

@ -0,0 +1,171 @@
/*
* Wifi Connecter
*
* Copyright (c) 20101 Kevin Yuan (farproc@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
**/
package com.wifi.connection;
import com.rtk.simpleconfig_wizard.R;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
import android.view.ContextMenu;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.View.OnClickListener;
import android.widget.Toast;
public class ConfiguredNetworkContent extends BaseContent {
public ConfiguredNetworkContent(Floating floating, WifiManager wifiManager,
ScanResult scanResult) {
super(floating, wifiManager, scanResult);
mView.findViewById(R.id.Status).setVisibility(View.GONE);
mView.findViewById(R.id.Speed).setVisibility(View.GONE);
mView.findViewById(R.id.IPAddress).setVisibility(View.GONE);
mView.findViewById(R.id.Password).setVisibility(View.GONE);
}
@Override
public int getButtonCount() {
return 3;
}
@Override
public OnClickListener getButtonOnClickListener(int index) {
switch(index) {
case 0:
return mConnectOnClick;
case 1:
if(mIsOpenNetwork) {
return mForgetOnClick;
} else {
return mOpOnClick;
}
case 2:
return mCancelOnClick;
default:
return null;
}
}
@Override
public CharSequence getButtonText(int index) {
switch(index) {
case 0:
return mFloating.getString(R.string.connect);
case 1:
if(mIsOpenNetwork) {
return mFloating.getString(R.string.forget_network);
} else {
return mFloating.getString(R.string.buttonOp);
}
case 2:
return getCancelString();
default:
return null;
}
}
@Override
public CharSequence getTitle() {
return mFloating.getString(R.string.wifi_connect_to, mScanResult.SSID);
}
private OnClickListener mConnectOnClick = new OnClickListener() {
@Override
public void onClick(View v) {
final WifiConfiguration config = Wifi.getWifiConfiguration(mWifiManager, mScanResult, mScanResultSecurity);
boolean connResult = false;
if(config != null) {
connResult = Wifi.connectToConfiguredNetwork(mFloating, mWifiManager, config, false);
}
if(!connResult) {
Toast.makeText(mFloating, R.string.toastFailed, Toast.LENGTH_LONG).show();
}
mFloating.finish();
}
};
private OnClickListener mOpOnClick = new OnClickListener() {
@Override
public void onClick(View v) {
mFloating.registerForContextMenu(v);
mFloating.openContextMenu(v);
mFloating.unregisterForContextMenu(v);
}
};
private OnClickListener mForgetOnClick = new OnClickListener() {
@Override
public void onClick(View v) {
forget();
}
};
private void forget() {
final WifiConfiguration config = Wifi.getWifiConfiguration(mWifiManager, mScanResult, mScanResultSecurity);
boolean result = false;
if(config != null) {
result = mWifiManager.removeNetwork(config.networkId)
&& mWifiManager.saveConfiguration();
}
if(!result) {
Toast.makeText(mFloating, R.string.toastFailed, Toast.LENGTH_LONG).show();
}
mFloating.finish();
}
private static final int MENU_FORGET = 0;
private static final int MENU_CHANGE_PASSWORD = 1;
@Override
public boolean onContextItemSelected(MenuItem item) {
switch(item.getItemId()) {
case MENU_FORGET:
forget();
break;
case MENU_CHANGE_PASSWORD:
changePassword();
break;
}
return false;
}
@Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
menu.add(Menu.NONE, MENU_FORGET, Menu.NONE, R.string.forget_network);
menu.add(Menu.NONE, MENU_CHANGE_PASSWORD, Menu.NONE, R.string.wifi_change_password);
}
}

View file

@ -0,0 +1,163 @@
/*
* Wifi Connecter
*
* Copyright (c) 20101 Kevin Yuan (farproc@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
**/
package com.wifi.connection;
import com.rtk.simpleconfig_wizard.R;
import android.net.NetworkInfo;
import android.net.wifi.ScanResult;
import android.net.wifi.SupplicantState;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.util.Log;
import android.view.ContextMenu;
import android.view.MenuItem;
import android.view.View;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.View.OnClickListener;
import android.widget.TextView;
import android.widget.Toast;
public class CurrentNetworkContent extends BaseContent {
private static final String TAG = "CurrentNetworkContent";
public CurrentNetworkContent(Floating floating, WifiManager wifiManager,
ScanResult scanResult) {
super(floating, wifiManager, scanResult);
mView.findViewById(R.id.Status).setVisibility(View.GONE);
mView.findViewById(R.id.Speed).setVisibility(View.GONE);
mView.findViewById(R.id.IPAddress).setVisibility(View.GONE);
mView.findViewById(R.id.Password).setVisibility(View.GONE);
final WifiInfo wifiInfo = mWifiManager.getConnectionInfo();
if(wifiInfo == null) {
Log.d(TAG, "Get WifiInfo Failed\n");
Toast.makeText(mFloating, R.string.toastFailed, Toast.LENGTH_LONG).show();
} else {
Log.d(TAG, "Get WifiInfo Ok\n");
final SupplicantState state = wifiInfo.getSupplicantState();
final NetworkInfo.DetailedState detailedState = WifiInfo.getDetailedStateOf(state);
if(detailedState == NetworkInfo.DetailedState.CONNECTED
|| (detailedState == NetworkInfo.DetailedState.OBTAINING_IPADDR && wifiInfo.getIpAddress() != 0)) {
mView.findViewById(R.id.Status).setVisibility(View.VISIBLE);
mView.findViewById(R.id.Speed).setVisibility(View.VISIBLE);
mView.findViewById(R.id.IPAddress).setVisibility(View.VISIBLE);
((TextView)mView.findViewById(R.id.Status_TextView)).setText(R.string.status_connected);
((TextView)mView.findViewById(R.id.LinkSpeed_TextView)).setText(wifiInfo.getLinkSpeed() + " " + WifiInfo.LINK_SPEED_UNITS);
((TextView)mView.findViewById(R.id.IPAddress_TextView)).setText(getIPAddress(wifiInfo.getIpAddress()));
} else if(detailedState == NetworkInfo.DetailedState.AUTHENTICATING
|| detailedState == NetworkInfo.DetailedState.CONNECTING
|| detailedState == NetworkInfo.DetailedState.OBTAINING_IPADDR) {
mView.findViewById(R.id.Status).setVisibility(View.VISIBLE);
((TextView)mView.findViewById(R.id.Status_TextView)).setText(R.string.status_connecting);
}
}
}
@Override
public int getButtonCount() {
// No Modify button for open network.
return mIsOpenNetwork ? 2 : 3;
}
@Override
public OnClickListener getButtonOnClickListener(int index) {
if(mIsOpenNetwork && index == 1) {
// No Modify button for open network.
// index 1 is Cancel(index 2).
return mOnClickListeners[2];
}
return mOnClickListeners[index];
}
@Override
public CharSequence getButtonText(int index) {
switch(index) {
case 0:
return mFloating.getString(R.string.forget_network);
case 1:
if(mIsOpenNetwork) {
// No Modify button for open network.
// index 1 is Cancel.
return getCancelString();
}
return mFloating.getString(R.string.button_change_password);
case 2:
return getCancelString();
default:
return null;
}
}
@Override
public CharSequence getTitle() {
return mScanResult.SSID;
}
private OnClickListener mForgetOnClick = new OnClickListener() {
@Override
public void onClick(View v) {
final WifiConfiguration config = Wifi.getWifiConfiguration(mWifiManager, mScanResult, mScanResultSecurity);
boolean result = false;
if(config != null) {
result = mWifiManager.removeNetwork(config.networkId)
&& mWifiManager.saveConfiguration();
}
if(!result) {
Toast.makeText(mFloating, R.string.toastFailed, Toast.LENGTH_LONG).show();
}
mFloating.finish();
}
};
private OnClickListener mOnClickListeners[] = {mForgetOnClick, mChangePasswordOnClick, mCancelOnClick};
private String getIPAddress(int address) {
StringBuilder sb = new StringBuilder();
sb.append(address & 0x000000FF).append(".")
.append((address & 0x0000FF00) >> 8).append(".")
.append((address & 0x00FF0000) >> 16).append(".")
.append((address & 0xFF000000L) >> 24);
return sb.toString();
}
@Override
public boolean onContextItemSelected(MenuItem item) {
return false;
}
@Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
}
}

View file

@ -0,0 +1,138 @@
/*
* Wifi Connecter
*
* Copyright (c) 20101 Kevin Yuan (farproc@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
**/
package com.wifi.connection;
import com.rtk.simpleconfig_wizard.R;
import android.app.Activity;
import android.os.Bundle;
import android.util.DisplayMetrics;
//import android.util.Log;
import android.view.ContextMenu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.Button;
import android.widget.TextView;
/**
* A dialog-like floating activity
* @author Kevin Yuan
*
*/
public class Floating extends Activity {
// private static final String TAG = "Floating";
private static final int[] BUTTONS = {R.id.button1, R.id.button2, R.id.button3};
private View mView;
private ViewGroup mContentViewContainer;
private Content mContent;
@Override
public void onCreate(Bundle savedInstanceState) {
// It will not work if we setTheme here.
// Please add android:theme="@android:style/Theme.Dialog" to any descendant class in AndroidManifest.xml!
// See http://code.google.com/p/android/issues/detail?id=4394
setTheme(android.R.style.Theme_Dialog);
getWindow().requestFeature(Window.FEATURE_NO_TITLE);
super.onCreate(savedInstanceState);
mView = View.inflate(this, R.layout.floating, null);
final DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
mView.setMinimumWidth(Math.min(dm.widthPixels, dm.heightPixels) - 20);
setContentView(mView);
mContentViewContainer = (ViewGroup) mView.findViewById(R.id.content);
}
private void setDialogContentView(final View contentView) {
// Log.d(TAG, "setDialogContentView\n");
mContentViewContainer.removeAllViews();
//mContentViewContainer.addView(contentView, new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
/* FILL_PARENT is renamed MATCH_PARENT in API Level 8 and higher */
mContentViewContainer.addView(contentView, new LayoutParams(LayoutParams.MATCH_PARENT , LayoutParams.WRAP_CONTENT));
}
public void setContent(Content content) {
mContent = content;
refreshContent();
}
public void refreshContent() {
// Log.d(TAG, "refreshContent");
setDialogContentView(mContent.getView());
((TextView)findViewById(R.id.title)).setText(mContent.getTitle()); //getTitle
final int btnCount = mContent.getButtonCount();
if(btnCount > BUTTONS.length) {
throw new RuntimeException(String.format("%d exceeds maximum button count: %d!", btnCount, BUTTONS.length));
}
findViewById(R.id.buttons_view).setVisibility(btnCount > 0 ? View.VISIBLE : View.GONE);
for(int buttonId:BUTTONS) {
final Button btn = (Button) findViewById(buttonId);
btn.setOnClickListener(null);
btn.setVisibility(View.GONE);
}
for(int btnIndex = 0; btnIndex < btnCount; btnIndex++){
final Button btn = (Button)findViewById(BUTTONS[btnIndex]);
// Log.d(TAG, "getButtonText(" + btnIndex + "): " + mContent.getButtonText(btnIndex));
btn.setText(mContent.getButtonText(btnIndex));
btn.setVisibility(View.VISIBLE);
btn.setOnClickListener(mContent.getButtonOnClickListener(btnIndex));
}
}
public void onCreateContextMenu (ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
if(mContent != null) {
mContent.onCreateContextMenu(menu, v, menuInfo);
}
}
public boolean onContextItemSelected (MenuItem item) {
if(mContent != null) {
return mContent.onContextItemSelected(item);
}
return false;
}
public interface Content {
CharSequence getTitle();
View getView();
int getButtonCount();
CharSequence getButtonText(int index);
OnClickListener getButtonOnClickListener(int index);
void onCreateContextMenu (ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo);
boolean onContextItemSelected (MenuItem item);
}
}

View file

@ -0,0 +1,124 @@
/*
* Wifi Connecter
*
* Copyright (c) 20101 Kevin Yuan (farproc@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
**/
package com.wifi.connection;
import com.rtk.simpleconfig_wizard.R;
import com.rtk.simpleconfig_wizard.SCCtlOps;
import android.content.Intent;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
//import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Bundle;
//import android.util.Log;
import android.widget.Toast;
public class MainActivity extends Floating {
// private static final String TAG = "WifiMainActivity";
public static final String EXTRA_HOTSPOT = "com.wifi.connection.HOTSPOT";
private ScanResult mScanResult;
private Floating.Content mContent;
private WifiManager mWifiManager;
@Override
protected void onNewIntent (Intent intent) {
setIntent(intent);
// This activity has "singleInstance" launch mode.
// Update content to reflect the newest intent.
doNewIntent(intent);
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mWifiManager = (WifiManager)getSystemService(WIFI_SERVICE);
doNewIntent(getIntent());
}
private boolean isAdHoc(final ScanResult scanResule) {
return scanResule.capabilities.indexOf("IBSS") != -1;
}
private void doNewIntent(final Intent intent) {
if(SCCtlOps.addNewNetwork)
mScanResult = SCCtlOps.reBuiltScanResult;
else
mScanResult = intent.getParcelableExtra(EXTRA_HOTSPOT);
// Log.i(TAG, "mScanResult: " + mScanResult);
// Log.d(TAG, "mScanResult.SSID: " + mScanResult.SSID);
// Log.d(TAG, "mScanResult.BSSID: " + mScanResult.BSSID);
// Log.d(TAG, "mScanResult.capabilities: " + mScanResult.capabilities);
// Log.d(TAG, "mScanResult.level: " + mScanResult.level);
// Log.d(TAG, "mScanResult.frequency: " + mScanResult.frequency);
if(mScanResult == null) {
Toast.makeText(this, "No data in Intent!", Toast.LENGTH_LONG).show();
finish();
return;
}
if(isAdHoc(mScanResult)) {
Toast.makeText(this, R.string.adhoc_not_supported_yet, Toast.LENGTH_LONG).show();
finish();
return;
}
final String security = Wifi.ConfigSec.getScanResultSecurity(mScanResult);
final WifiConfiguration config = Wifi.getWifiConfiguration(mWifiManager, mScanResult, security);
if(config != null) {
// Log.d(TAG, "Remove already configured network\n");
mWifiManager.removeNetwork(config.networkId);
}
// Log.d(TAG, "NewNetworkContent\n");
mContent = new NewNetworkContent(this, mWifiManager, mScanResult);
// if(config == null) {
// Log.d(TAG, "NewNetworkContent\n");
// mContent = new NewNetworkContent(this, mWifiManager, mScanResult);
// } else {
// final boolean isCurrentNetwork_ConfigurationStatus = config.status == WifiConfiguration.Status.CURRENT;
// final WifiInfo info = mWifiManager.getConnectionInfo();
// final boolean isCurrentNetwork_WifiInfo = info != null
// && android.text.TextUtils.equals(info.getSSID(), mScanResult.SSID)
// && android.text.TextUtils.equals(info.getBSSID(), mScanResult.BSSID);
// if(isCurrentNetwork_ConfigurationStatus || isCurrentNetwork_WifiInfo) {
// Log.d(TAG, "CurrentNetworkContent\n");
// mContent = new CurrentNetworkContent(this, mWifiManager, mScanResult);
// } else {
// Log.d(TAG, "ConfiguredNetworkContent\n");
// mContent = new ConfiguredNetworkContent(this, mWifiManager, mScanResult);
// }
// }
setContent(mContent);
}
}

View file

@ -0,0 +1,151 @@
/*
* Wifi Connecter
*
* Copyright (c) 20101 Kevin Yuan (farproc@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
**/
package com.wifi.connection;
import com.rtk.simpleconfig_wizard.FileOps;
import com.rtk.simpleconfig_wizard.R;
import com.rtk.simpleconfig_wizard.SCCtlOps;
import com.rtk.simpleconfig_wizard.MainActivity;
import android.app.ProgressDialog;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiManager;
//import android.util.Log;
import android.view.ContextMenu;
import android.view.MenuItem;
import android.view.View;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.View.OnClickListener;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
public class NewNetworkContent extends BaseContent {
// private static final String TAG = "NewNetworkContent";
private boolean mIsOpenNetwork = false;
public NewNetworkContent(final Floating floating, final WifiManager wifiManager, ScanResult scanResult) {
super(floating, wifiManager, scanResult);
mView.findViewById(R.id.Status).setVisibility(View.GONE);
mView.findViewById(R.id.Speed).setVisibility(View.GONE);
mView.findViewById(R.id.IPAddress).setVisibility(View.GONE);
if(Wifi.ConfigSec.isOpenNetwork(mScanResultSecurity)) {
mIsOpenNetwork = true;
mView.findViewById(R.id.Password).setVisibility(View.GONE);
} else {
((TextView)mView.findViewById(R.id.Password_TextView)).setText(R.string.please_type_passphrase);
((EditText)mView.findViewById(R.id.Password_EditText)).setText(SCCtlOps.StoredPasswd); //The last password hint
}
}
private OnClickListener mConnectOnClick = new OnClickListener() {
@Override
public void onClick(View v) {
SCCtlOps.ConnectedSSID = mScanResult.SSID; // Store SSID
// Log.d(TAG, "SSID£º" + mScanResult.SSID);
boolean connResult = false;
if(mIsOpenNetwork) {
SCCtlOps.IsOpenNetwork = true;
connResult = Wifi.connectToNewNetwork(mFloating, mWifiManager, mScanResult, null, mNumOpenNetworksKept);
} else {
SCCtlOps.IsOpenNetwork = false;
String passwd = ((EditText)mView.findViewById(R.id.Password_EditText)).getText().toString();
connResult = Wifi.connectToNewNetwork(mFloating, mWifiManager, mScanResult
, passwd
, mNumOpenNetworksKept);
if(connResult) {
SCCtlOps.ConnectedPasswd = new String(passwd); // Store password
// Log.d(TAG, "Password£º" + passwd);
}
}
// if(!connResult) {
// Toast.makeText(mFloating, R.string.toastFailed, Toast.LENGTH_LONG).show();
// }
mFloating.finish();
// /** Update SSID and password */
// if(connResult) {
// FileOps fileOps = new FileOps();
// fileOps.UpdateSsidPasswdFile(mIsOpenNetwork);
// }
}
};
private OnClickListener mOnClickListeners[] = {mConnectOnClick, mCancelOnClick};
@Override
public int getButtonCount() {
return 2;
}
@Override
public OnClickListener getButtonOnClickListener(int index) {
return mOnClickListeners[index];
}
@Override
public CharSequence getButtonText(int index) {
switch(index) {
case 0:
return mFloating.getText(R.string.connect);
case 1:
return mFloating.getText(R.string.cancel);
// return getCancelString();
default:
return null;
}
}
@Override
public CharSequence getTitle() {
return mFloating.getString(R.string.wifi_connect_to, mScanResult.SSID);
}
@Override
public boolean onContextItemSelected(MenuItem item) {
return false;
}
@Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
}
}

View file

@ -0,0 +1,102 @@
/*
* Wifi Connecter
*
* Copyright (c) 20101 Kevin Yuan (farproc@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
**/
package com.wifi.connection;
import java.util.List;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.NetworkInfo;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
import android.os.IBinder;
public class ReenableAllApsWhenNetworkStateChanged {
public static void schedule(final Context ctx) {
ctx.startService(new Intent(ctx, BackgroundService.class));
}
private static void reenableAllAps(final Context ctx) {
final WifiManager wifiMgr = (WifiManager)ctx.getSystemService(Context.WIFI_SERVICE);
final List<WifiConfiguration> configurations = wifiMgr.getConfiguredNetworks();
if(configurations != null) {
for(final WifiConfiguration config:configurations) {
wifiMgr.enableNetwork(config.networkId, false);
}
}
}
public static class BackgroundService extends Service {
private boolean mReenabled;
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if(WifiManager.NETWORK_STATE_CHANGED_ACTION.equals(action)) {
final NetworkInfo networkInfo = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
final NetworkInfo.DetailedState detailed = networkInfo.getDetailedState();
if(detailed != NetworkInfo.DetailedState.DISCONNECTED
&& detailed != NetworkInfo.DetailedState.DISCONNECTING
&& detailed != NetworkInfo.DetailedState.SCANNING) {
if(!mReenabled) {
mReenabled = true;
reenableAllAps(context);
stopSelf();
}
}
}
}
};
private IntentFilter mIntentFilter;
@Override
public IBinder onBind(Intent intent) {
return null; // We need not bind to it at all.
}
@Override
public void onCreate() {
super.onCreate();
mReenabled = false;
mIntentFilter = new IntentFilter(WifiManager.NETWORK_STATE_CHANGED_ACTION);
registerReceiver(mReceiver, mIntentFilter);
}
@Override
public void onDestroy() {
super.onDestroy();
unregisterReceiver(mReceiver);
}
}
}

View file

@ -0,0 +1,29 @@
package com.wifi.connection;
import java.lang.reflect.Field;
import android.os.Build.VERSION;;
/**
* Get Android version in different Android versions. :)
* @author yuanxiaohui
*
*/
public class Version {
public final static int SDK = get();
private static int get() {
final Class<VERSION> versionClass = VERSION.class;
try {
// First try to read the recommended field android.os.Build.VERSION.SDK_INT.
final Field sdkIntField = versionClass.getField("SDK_INT");
return sdkIntField.getInt(null);
//} catch (NoSuchFieldException e) {
// If SDK_INT does not exist, read the deprecated field SDK.
// return Integer.valueOf(VERSION.SDK);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}

View file

@ -0,0 +1,313 @@
/*
* Wifi Connecter
*
* Copyright (c) 20101 Kevin Yuan (farproc@gmail.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
**/
package com.wifi.connection;
import java.util.Comparator;
import java.util.List;
import com.rtk.simpleconfig_wizard.SCCtlOps;
import android.content.Context;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
import android.text.TextUtils;
import android.util.Log;
public class Wifi {
public static final ConfigurationSecurities ConfigSec = ConfigurationSecurities.newInstance();
private static final String TAG = "Wifi Connecter";
/**
* Change the password of an existing configured network and connect to it
* @param wifiMgr
* @param config
* @param newPassword
* @return
*/
public static boolean changePasswordAndConnect(final Context ctx, final WifiManager wifiMgr, final WifiConfiguration config, final String newPassword, final int numOpenNetworksKept) {
ConfigSec.setupSecurity(config, ConfigSec.getWifiConfigurationSecurity(config), newPassword);
final int networkId = wifiMgr.updateNetwork(config);
if(networkId == -1) {
// Update failed.
return false;
}
// Force the change to apply.
wifiMgr.disconnect();
return connectToConfiguredNetwork(ctx, wifiMgr, config, true);
}
/**
* Configure a network, and connect to it.
* @param wifiMgr
* @param scanResult
* @param password Password for secure network or is ignored.
* @return
*/
public static boolean connectToNewNetwork(final Context ctx, final WifiManager wifiMgr, final ScanResult scanResult, final String password, final int numOpenNetworksKept) {
final String security = ConfigSec.getScanResultSecurity(scanResult);
if(ConfigSec.isOpenNetwork(security)) {
checkForExcessOpenNetworkAndSave(wifiMgr, numOpenNetworksKept);
}
WifiConfiguration config = new WifiConfiguration();
if(SCCtlOps.isHiddenSSID)
config.hiddenSSID = true;
config.SSID = convertToQuotedString(scanResult.SSID);
if(!SCCtlOps.isHiddenSSID)
config.BSSID = scanResult.BSSID;
ConfigSec.setupSecurity(config, security, password);
int id = -1;
try {
id = wifiMgr.addNetwork(config);
} catch(NullPointerException e) {
Log.e(TAG, "Weird!! Really!! What's wrong??", e);
// Weird!! Really!!
// This exception is reported by user to Android Developer Console(https://market.android.com/publish/Home)
}
if(id == -1) {
return false;
}
if(!wifiMgr.saveConfiguration()) {
return false;
}
config = getWifiConfiguration(wifiMgr, config, security);
if(config == null) {
return false;
}
return connectToConfiguredNetwork(ctx, wifiMgr, config, true);
}
/**
* Connect to a configured network.
* @param wifiManager
* @param config
* @param numOpenNetworksKept Settings.Secure.WIFI_NUM_OPEN_NETWORKS_KEPT
* @return
*/
public static boolean connectToConfiguredNetwork(final Context ctx, final WifiManager wifiMgr, WifiConfiguration config, boolean reassociate) {
final String security = ConfigSec.getWifiConfigurationSecurity(config);
int oldPri = config.priority;
// Make it the highest priority.
int newPri = getMaxPriority(wifiMgr) + 1;
if(newPri > MAX_PRIORITY) {
newPri = shiftPriorityAndSave(wifiMgr);
config = getWifiConfiguration(wifiMgr, config, security);
if(config == null) {
return false;
}
}
// Set highest priority to this configured network
config.priority = newPri;
int networkId = wifiMgr.updateNetwork(config);
if(networkId == -1) {
return false;
}
// Do not disable others
if(!wifiMgr.enableNetwork(networkId, false)) {
config.priority = oldPri;
return false;
}
if(!wifiMgr.saveConfiguration()) {
config.priority = oldPri;
return false;
}
// We have to retrieve the WifiConfiguration after save.
config = getWifiConfiguration(wifiMgr, config, security);
if(config == null) {
return false;
}
ReenableAllApsWhenNetworkStateChanged.schedule(ctx);
// Disable others, but do not save.
// Just to force the WifiManager to connect to it.
if(!wifiMgr.enableNetwork(config.networkId, true)) {
return false;
}
final boolean connect = reassociate ? wifiMgr.reassociate() : wifiMgr.reconnect();
if(!connect) {
return false;
}
return true;
}
private static void sortByPriority(final List<WifiConfiguration> configurations) {
java.util.Collections.sort(configurations, new Comparator<WifiConfiguration>() {
@Override
public int compare(WifiConfiguration object1,
WifiConfiguration object2) {
return object1.priority - object2.priority;
}
});
}
/**
* Ensure no more than numOpenNetworksKept open networks in configuration list.
* @param wifiMgr
* @param numOpenNetworksKept
* @return Operation succeed or not.
*/
private static boolean checkForExcessOpenNetworkAndSave(final WifiManager wifiMgr, final int numOpenNetworksKept) {
final List<WifiConfiguration> configurations = wifiMgr.getConfiguredNetworks();
sortByPriority(configurations);
boolean modified = false;
int tempCount = 0;
for(int i = configurations.size() - 1; i >= 0; i--) {
final WifiConfiguration config = configurations.get(i);
if(ConfigSec.isOpenNetwork(ConfigSec.getWifiConfigurationSecurity(config))) {
tempCount++;
if(tempCount >= numOpenNetworksKept) {
modified = true;
wifiMgr.removeNetwork(config.networkId);
}
}
}
if(modified) {
return wifiMgr.saveConfiguration();
}
return true;
}
private static final int MAX_PRIORITY = 99999;
private static int shiftPriorityAndSave(final WifiManager wifiMgr) {
final List<WifiConfiguration> configurations = wifiMgr.getConfiguredNetworks();
sortByPriority(configurations);
final int size = configurations.size();
for(int i = 0; i < size; i++) {
final WifiConfiguration config = configurations.get(i);
config.priority = i;
wifiMgr.updateNetwork(config);
}
wifiMgr.saveConfiguration();
return size;
}
private static int getMaxPriority(final WifiManager wifiManager) {
final List<WifiConfiguration> configurations = wifiManager.getConfiguredNetworks();
int pri = 0;
for(final WifiConfiguration config : configurations) {
if(config.priority > pri) {
pri = config.priority;
}
}
return pri;
}
public static WifiConfiguration getWifiConfiguration(final WifiManager wifiMgr, final ScanResult hotsopt, String hotspotSecurity) {
final String ssid = convertToQuotedString(hotsopt.SSID);
if(ssid.length() == 0) {
return null;
}
final String bssid = hotsopt.BSSID;
if(bssid == null) {
return null;
}
if(hotspotSecurity == null) {
hotspotSecurity = ConfigSec.getScanResultSecurity(hotsopt);
}
final List<WifiConfiguration> configurations = wifiMgr.getConfiguredNetworks();
if(configurations == null) {
return null;
}
for(final WifiConfiguration config : configurations) {
if(config.SSID == null || !ssid.equals(config.SSID)) {
continue;
}
if(config.BSSID == null || bssid.equals(config.BSSID)) {
final String configSecurity = ConfigSec.getWifiConfigurationSecurity(config);
if(hotspotSecurity.equals(configSecurity)) {
return config;
}
}
}
return null;
}
public static WifiConfiguration getWifiConfiguration(final WifiManager wifiMgr, final WifiConfiguration configToFind, String security) {
final String ssid = configToFind.SSID;
if(ssid.length() == 0) {
return null;
}
final String bssid = configToFind.BSSID;
if(security == null) {
security = ConfigSec.getWifiConfigurationSecurity(configToFind);
}
final List<WifiConfiguration> configurations = wifiMgr.getConfiguredNetworks();
for(final WifiConfiguration config : configurations) {
if(config.SSID == null || !ssid.equals(config.SSID)) {
continue;
}
if(config.BSSID == null || bssid == null || bssid.equals(config.BSSID)) {
final String configSecurity = ConfigSec.getWifiConfigurationSecurity(config);
if(security.equals(configSecurity)) {
return config;
}
}
}
return null;
}
public static String convertToQuotedString(String string) {
if (TextUtils.isEmpty(string)) {
return "";
}
final int lastPos = string.length() - 1;
if(lastPos > 0 && (string.charAt(0) == '"' && string.charAt(lastPos) == '"')) {
return string;
}
return "\"" + string + "\"";
}
}

View file

@ -0,0 +1,232 @@
package com.zxing.activity;
import java.io.IOException;
import java.util.Vector;
import android.app.Activity;
import android.content.Intent;
import android.content.res.AssetFileDescriptor;
import android.graphics.Bitmap;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.os.Bundle;
import android.os.Handler;
import android.os.Vibrator;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
import com.rtk.simpleconfig_wizard.R;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.Result;
import com.wifi.connection.MainActivity;
import com.zxing.camera.CameraManager;
import com.zxing.decoding.CaptureActivityHandler;
import com.zxing.decoding.InactivityTimer;
import com.zxing.view.ViewfinderView;
/**
* Initial the camera
* @author Ryan.Tang
*/
public class CaptureActivity extends Activity implements Callback {
private CaptureActivityHandler handler;
private ViewfinderView viewfinderView;
private boolean hasSurface;
private Vector<BarcodeFormat> decodeFormats;
private String characterSet;
private InactivityTimer inactivityTimer;
private MediaPlayer mediaPlayer;
private boolean playBeep;
private static final float BEEP_VOLUME = 0.10f;
private boolean vibrate;
private Button cancelScanButton;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.qrcode_scanner);
//ViewUtil.addTopView(getApplicationContext(), this, R.string.scan_card);
CameraManager.init(getApplication());
viewfinderView = (ViewfinderView) findViewById(R.id.viewfinder_view);
cancelScanButton = (Button) this.findViewById(R.id.btn_cancel_scan);
hasSurface = false;
inactivityTimer = new InactivityTimer(this);
}
@SuppressWarnings("deprecation")
@Override
protected void onResume() {
super.onResume();
SurfaceView surfaceView = (SurfaceView) findViewById(R.id.preview_view);
SurfaceHolder surfaceHolder = surfaceView.getHolder();
if (hasSurface) {
initCamera(surfaceHolder);
} else {
surfaceHolder.addCallback(this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
decodeFormats = null;
characterSet = null;
playBeep = true;
AudioManager audioService = (AudioManager) getSystemService(AUDIO_SERVICE);
if (audioService.getRingerMode() != AudioManager.RINGER_MODE_NORMAL) {
playBeep = false;
}
initBeepSound();
vibrate = true;
//quit the scan view
cancelScanButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
CaptureActivity.this.finish();
}
});
}
@Override
protected void onPause() {
super.onPause();
if (handler != null) {
handler.quitSynchronously();
handler = null;
}
CameraManager.get().closeDriver();
}
@Override
protected void onDestroy() {
inactivityTimer.shutdown();
super.onDestroy();
}
/**
* Handler scan result
* @param result
* @param barcode
*/
public void handleDecode(Result result, Bitmap barcode) {
inactivityTimer.onActivity();
playBeepSoundAndVibrate();
String resultString = result.getText();
//FIXME
if (resultString.equals("")) {
Toast.makeText(CaptureActivity.this, "Scan failed!", Toast.LENGTH_SHORT).show();
}else {
// System.out.println("Result:"+resultString);
Intent resultIntent = new Intent(CaptureActivity.this,MainActivity.class);
//resultIntent.putExtra("result", resultString);
//setResult(RESULT_OK, resultIntent);
Bundle bundle = new Bundle();
bundle.putString("result", resultString);
resultIntent.putExtras(bundle);
setResult(RESULT_OK, resultIntent);
}
CaptureActivity.this.finish();
}
private void initCamera(SurfaceHolder surfaceHolder) {
try {
CameraManager.get().openDriver(surfaceHolder);
} catch (IOException ioe) {
return;
} catch (RuntimeException e) {
return;
}
if (handler == null) {
handler = new CaptureActivityHandler(this, decodeFormats,
characterSet);
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
if (!hasSurface) {
hasSurface = true;
initCamera(holder);
}
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
hasSurface = false;
}
public ViewfinderView getViewfinderView() {
return viewfinderView;
}
public Handler getHandler() {
return handler;
}
public void drawViewfinder() {
viewfinderView.drawViewfinder();
}
private void initBeepSound() {
if (playBeep && mediaPlayer == null) {
// The volume on STREAM_SYSTEM is not adjustable, and users found it
// too loud,
// so we now play on the music stream.
setVolumeControlStream(AudioManager.STREAM_MUSIC);
mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setOnCompletionListener(beepListener);
AssetFileDescriptor file = getResources().openRawResourceFd(
R.raw.beep);
try {
mediaPlayer.setDataSource(file.getFileDescriptor(),
file.getStartOffset(), file.getLength());
file.close();
mediaPlayer.setVolume(BEEP_VOLUME, BEEP_VOLUME);
mediaPlayer.prepare();
} catch (IOException e) {
mediaPlayer = null;
}
}
}
private static final long VIBRATE_DURATION = 200L;
private void playBeepSoundAndVibrate() {
if (playBeep && mediaPlayer != null) {
mediaPlayer.start();
}
if (vibrate) {
Vibrator vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
vibrator.vibrate(VIBRATE_DURATION);
}
}
/**
* When the beep has finished playing, rewind to queue up another one.
*/
private final OnCompletionListener beepListener = new OnCompletionListener() {
public void onCompletion(MediaPlayer mediaPlayer) {
mediaPlayer.seekTo(0);
}
};
}

View file

@ -0,0 +1,48 @@
/*
* Copyright (C) 2010 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.zxing.camera;
import android.hardware.Camera;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
final class AutoFocusCallback implements Camera.AutoFocusCallback {
private static final String TAG = AutoFocusCallback.class.getSimpleName();
private static final long AUTOFOCUS_INTERVAL_MS = 1500L;
private Handler autoFocusHandler;
private int autoFocusMessage;
void setHandler(Handler autoFocusHandler, int autoFocusMessage) {
this.autoFocusHandler = autoFocusHandler;
this.autoFocusMessage = autoFocusMessage;
}
public void onAutoFocus(boolean success, Camera camera) {
if (autoFocusHandler != null) {
Message message = autoFocusHandler.obtainMessage(autoFocusMessage, success);
autoFocusHandler.sendMessageDelayed(message, AUTOFOCUS_INTERVAL_MS);
autoFocusHandler = null;
} else {
Log.d(TAG, "Got auto-focus callback, but no handler for it");
}
}
}

View file

@ -0,0 +1,267 @@
/*
* Copyright (C) 2010 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.zxing.camera;
import android.content.Context;
import android.graphics.Point;
import android.hardware.Camera;
import android.os.Build;
import android.util.Log;
import android.view.Display;
import android.view.WindowManager;
import java.util.regex.Pattern;
final class CameraConfigurationManager {
private static final String TAG = CameraConfigurationManager.class.getSimpleName();
private static final int TEN_DESIRED_ZOOM = 27;
private static final int DESIRED_SHARPNESS = 30;
private static final Pattern COMMA_PATTERN = Pattern.compile(",");
private final Context context;
private Point screenResolution;
private Point cameraResolution;
private int previewFormat;
private String previewFormatString;
CameraConfigurationManager(Context context) {
this.context = context;
}
/**
* Reads, one time, values from the camera that are needed by the app.
*/
@SuppressWarnings("deprecation")
void initFromCameraParameters(Camera camera) {
Camera.Parameters parameters = camera.getParameters();
previewFormat = parameters.getPreviewFormat();
previewFormatString = parameters.get("preview-format");
Log.d(TAG, "Default preview format: " + previewFormat + '/' + previewFormatString);
WindowManager manager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = manager.getDefaultDisplay();
screenResolution = new Point(display.getWidth(), display.getHeight());
Log.d(TAG, "Screen resolution: " + screenResolution);
cameraResolution = getCameraResolution(parameters, screenResolution);
Log.d(TAG, "Camera resolution: " + screenResolution);
}
/**
* Sets the camera up to take preview images which are used for both preview and decoding.
* We detect the preview format here so that buildLuminanceSource() can build an appropriate
* LuminanceSource subclass. In the future we may want to force YUV420SP as it's the smallest,
* and the planar Y can be used for barcode scanning without a copy in some cases.
*/
void setDesiredCameraParameters(Camera camera) {
Camera.Parameters parameters = camera.getParameters();
Log.d(TAG, "Setting preview size: " + cameraResolution);
parameters.setPreviewSize(cameraResolution.x, cameraResolution.y);
setFlash(parameters);
setZoom(parameters);
//setSharpness(parameters);
//modify here
camera.setDisplayOrientation(90);
camera.setParameters(parameters);
}
Point getCameraResolution() {
return cameraResolution;
}
Point getScreenResolution() {
return screenResolution;
}
int getPreviewFormat() {
return previewFormat;
}
String getPreviewFormatString() {
return previewFormatString;
}
private static Point getCameraResolution(Camera.Parameters parameters, Point screenResolution) {
String previewSizeValueString = parameters.get("preview-size-values");
// saw this on Xperia
if (previewSizeValueString == null) {
previewSizeValueString = parameters.get("preview-size-value");
}
Point cameraResolution = null;
if (previewSizeValueString != null) {
Log.d(TAG, "preview-size-values parameter: " + previewSizeValueString);
cameraResolution = findBestPreviewSizeValue(previewSizeValueString, screenResolution);
}
if (cameraResolution == null) {
// Ensure that the camera resolution is a multiple of 8, as the screen may not be.
cameraResolution = new Point(
(screenResolution.x >> 3) << 3,
(screenResolution.y >> 3) << 3);
}
return cameraResolution;
}
private static Point findBestPreviewSizeValue(CharSequence previewSizeValueString, Point screenResolution) {
int bestX = 0;
int bestY = 0;
int diff = Integer.MAX_VALUE;
for (String previewSize : COMMA_PATTERN.split(previewSizeValueString)) {
previewSize = previewSize.trim();
int dimPosition = previewSize.indexOf('x');
if (dimPosition < 0) {
Log.w(TAG, "Bad preview-size: " + previewSize);
continue;
}
int newX;
int newY;
try {
newX = Integer.parseInt(previewSize.substring(0, dimPosition));
newY = Integer.parseInt(previewSize.substring(dimPosition + 1));
} catch (NumberFormatException nfe) {
Log.w(TAG, "Bad preview-size: " + previewSize);
continue;
}
int newDiff = Math.abs(newX - screenResolution.x) + Math.abs(newY - screenResolution.y);
if (newDiff == 0) {
bestX = newX;
bestY = newY;
break;
} else if (newDiff < diff) {
bestX = newX;
bestY = newY;
diff = newDiff;
}
}
if (bestX > 0 && bestY > 0) {
return new Point(bestX, bestY);
}
return null;
}
private static int findBestMotZoomValue(CharSequence stringValues, int tenDesiredZoom) {
int tenBestValue = 0;
for (String stringValue : COMMA_PATTERN.split(stringValues)) {
stringValue = stringValue.trim();
double value;
try {
value = Double.parseDouble(stringValue);
} catch (NumberFormatException nfe) {
return tenDesiredZoom;
}
int tenValue = (int) (10.0 * value);
if (Math.abs(tenDesiredZoom - value) < Math.abs(tenDesiredZoom - tenBestValue)) {
tenBestValue = tenValue;
}
}
return tenBestValue;
}
private void setFlash(Camera.Parameters parameters) {
// FIXME: This is a hack to turn the flash off on the Samsung Galaxy.
// And this is a hack-hack to work around a different value on the Behold II
// Restrict Behold II check to Cupcake, per Samsung's advice
//if (Build.MODEL.contains("Behold II") &&
// CameraManager.SDK_INT == Build.VERSION_CODES.CUPCAKE) {
if (Build.MODEL.contains("Behold II") && CameraManager.SDK_INT == 3) { // 3 = Cupcake
parameters.set("flash-value", 1);
} else {
parameters.set("flash-value", 2);
}
// This is the standard setting to turn the flash off that all devices should honor.
parameters.set("flash-mode", "off");
}
private void setZoom(Camera.Parameters parameters) {
String zoomSupportedString = parameters.get("zoom-supported");
if (zoomSupportedString != null && !Boolean.parseBoolean(zoomSupportedString)) {
return;
}
int tenDesiredZoom = TEN_DESIRED_ZOOM;
String maxZoomString = parameters.get("max-zoom");
if (maxZoomString != null) {
try {
int tenMaxZoom = (int) (10.0 * Double.parseDouble(maxZoomString));
if (tenDesiredZoom > tenMaxZoom) {
tenDesiredZoom = tenMaxZoom;
}
} catch (NumberFormatException nfe) {
Log.w(TAG, "Bad max-zoom: " + maxZoomString);
}
}
String takingPictureZoomMaxString = parameters.get("taking-picture-zoom-max");
if (takingPictureZoomMaxString != null) {
try {
int tenMaxZoom = Integer.parseInt(takingPictureZoomMaxString);
if (tenDesiredZoom > tenMaxZoom) {
tenDesiredZoom = tenMaxZoom;
}
} catch (NumberFormatException nfe) {
Log.w(TAG, "Bad taking-picture-zoom-max: " + takingPictureZoomMaxString);
}
}
String motZoomValuesString = parameters.get("mot-zoom-values");
if (motZoomValuesString != null) {
tenDesiredZoom = findBestMotZoomValue(motZoomValuesString, tenDesiredZoom);
}
String motZoomStepString = parameters.get("mot-zoom-step");
if (motZoomStepString != null) {
try {
double motZoomStep = Double.parseDouble(motZoomStepString.trim());
int tenZoomStep = (int) (10.0 * motZoomStep);
if (tenZoomStep > 1) {
tenDesiredZoom -= tenDesiredZoom % tenZoomStep;
}
} catch (NumberFormatException nfe) {
// continue
}
}
// Set zoom. This helps encourage the user to pull back.
// Some devices like the Behold have a zoom parameter
if (maxZoomString != null || motZoomValuesString != null) {
parameters.set("zoom", String.valueOf(tenDesiredZoom / 10.0));
}
// Most devices, like the Hero, appear to expose this zoom parameter.
// It takes on values like "27" which appears to mean 2.7x zoom
if (takingPictureZoomMaxString != null) {
parameters.set("taking-picture-zoom", tenDesiredZoom);
}
}
public static int getDesiredSharpness() {
return DESIRED_SHARPNESS;
}
}

View file

@ -0,0 +1,327 @@
/*
* Copyright (C) 2008 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.zxing.camera;
import java.io.IOException;
import android.content.Context;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.graphics.Rect;
import android.hardware.Camera;
import android.os.Build;
import android.os.Handler;
import android.util.Log;
import android.view.SurfaceHolder;
/**
* This object wraps the Camera service object and expects to be the only one talking to it. The
* implementation encapsulates the steps needed to take preview-sized images, which are used for
* both preview and decoding.
*
*/
@SuppressWarnings("deprecation")
public final class CameraManager {
private static final String TAG = CameraManager.class.getSimpleName();
private static final int MIN_FRAME_WIDTH = 240;
private static final int MIN_FRAME_HEIGHT = 240;
private static final int MAX_FRAME_WIDTH = 480;
private static final int MAX_FRAME_HEIGHT = 360;
private static CameraManager cameraManager;
static final int SDK_INT; // Later we can use Build.VERSION.SDK_INT
static {
int sdkInt;
try {
sdkInt = Integer.parseInt(Build.VERSION.SDK);
} catch (NumberFormatException nfe) {
// Just to be safe
sdkInt = 10000;
}
SDK_INT = sdkInt;
}
private final Context context;
private final CameraConfigurationManager configManager;
private Camera camera;
private Rect framingRect;
private Rect framingRectInPreview;
private boolean initialized;
private boolean previewing;
private final boolean useOneShotPreviewCallback;
/**
* Preview frames are delivered here, which we pass on to the registered handler. Make sure to
* clear the handler so it will only receive one message.
*/
private final PreviewCallback previewCallback;
/** Autofocus callbacks arrive here, and are dispatched to the Handler which requested them. */
private final AutoFocusCallback autoFocusCallback;
/**
* Initializes this static object with the Context of the calling Activity.
*
* @param context The Activity which wants to use the camera.
*/
public static void init(Context context) {
if (cameraManager == null) {
cameraManager = new CameraManager(context);
}
}
/**
* Gets the CameraManager singleton instance.
*
* @return A reference to the CameraManager singleton.
*/
public static CameraManager get() {
return cameraManager;
}
private CameraManager(Context context) {
this.context = context;
this.configManager = new CameraConfigurationManager(context);
// Camera.setOneShotPreviewCallback() has a race condition in Cupcake, so we use the older
// Camera.setPreviewCallback() on 1.5 and earlier. For Donut and later, we need to use
// the more efficient one shot callback, as the older one can swamp the system and cause it
// to run out of memory. We can't use SDK_INT because it was introduced in the Donut SDK.
//useOneShotPreviewCallback = Integer.parseInt(Build.VERSION.SDK) > Build.VERSION_CODES.CUPCAKE;
useOneShotPreviewCallback = Integer.parseInt(Build.VERSION.SDK) > 3; // 3 = Cupcake
previewCallback = new PreviewCallback(configManager, useOneShotPreviewCallback);
autoFocusCallback = new AutoFocusCallback();
}
/**
* Opens the camera driver and initializes the hardware parameters.
*
* @param holder The surface object which the camera will draw preview frames into.
* @throws IOException Indicates the camera driver failed to open.
*/
public void openDriver(SurfaceHolder holder) throws IOException {
if (camera == null) {
camera = Camera.open();
if (camera == null) {
throw new IOException();
}
camera.setPreviewDisplay(holder);
if (!initialized) {
initialized = true;
configManager.initFromCameraParameters(camera);
}
configManager.setDesiredCameraParameters(camera);
//FIXME
// SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
//ÊÇ·ñʹÓÃǰµÆ
// if (prefs.getBoolean(PreferencesActivity.KEY_FRONT_LIGHT, false)) {
// FlashlightManager.enableFlashlight();
// }
FlashlightManager.enableFlashlight();
}
}
/**
* Closes the camera driver if still in use.
*/
public void closeDriver() {
if (camera != null) {
FlashlightManager.disableFlashlight();
camera.release();
camera = null;
}
}
/**
* Asks the camera hardware to begin drawing preview frames to the screen.
*/
public void startPreview() {
if (camera != null && !previewing) {
camera.startPreview();
previewing = true;
}
}
/**
* Tells the camera to stop drawing preview frames.
*/
public void stopPreview() {
if (camera != null && previewing) {
if (!useOneShotPreviewCallback) {
camera.setPreviewCallback(null);
}
camera.stopPreview();
previewCallback.setHandler(null, 0);
autoFocusCallback.setHandler(null, 0);
previewing = false;
}
}
/**
* A single preview frame will be returned to the handler supplied. The data will arrive as byte[]
* in the message.obj field, with width and height encoded as message.arg1 and message.arg2,
* respectively.
*
* @param handler The handler to send the message to.
* @param message The what field of the message to be sent.
*/
public void requestPreviewFrame(Handler handler, int message) {
if (camera != null && previewing) {
previewCallback.setHandler(handler, message);
if (useOneShotPreviewCallback) {
camera.setOneShotPreviewCallback(previewCallback);
} else {
camera.setPreviewCallback(previewCallback);
}
}
}
/**
* Asks the camera hardware to perform an autofocus.
*
* @param handler The Handler to notify when the autofocus completes.
* @param message The message to deliver.
*/
public void requestAutoFocus(Handler handler, int message) {
if (camera != null && previewing) {
autoFocusCallback.setHandler(handler, message);
//Log.d(TAG, "Requesting auto-focus callback");
camera.autoFocus(autoFocusCallback);
}
}
/**
* Calculates the framing rect which the UI should draw to show the user where to place the
* barcode. This target helps with alignment as well as forces the user to hold the device
* far enough away to ensure the image will be in focus.
*
* @return The rectangle to draw on screen in window coordinates.
*/
public Rect getFramingRect() {
Point screenResolution = configManager.getScreenResolution();
if (framingRect == null) {
if (camera == null) {
return null;
}
int width = screenResolution.x * 3 / 4;
if (width < MIN_FRAME_WIDTH) {
width = MIN_FRAME_WIDTH;
} else if (width > MAX_FRAME_WIDTH) {
width = MAX_FRAME_WIDTH;
}
int height = screenResolution.y * 3 / 4;
if (height < MIN_FRAME_HEIGHT) {
height = MIN_FRAME_HEIGHT;
} else if (height > MAX_FRAME_HEIGHT) {
height = MAX_FRAME_HEIGHT;
}
int leftOffset = (screenResolution.x - width) / 2;
int topOffset = (screenResolution.y - height) / 2;
framingRect = new Rect(leftOffset, topOffset, leftOffset + width, topOffset + height);
Log.d(TAG, "Calculated framing rect: " + framingRect);
}
return framingRect;
}
/**
* Like {@link #getFramingRect} but coordinates are in terms of the preview frame,
* not UI / screen.
*/
public Rect getFramingRectInPreview() {
if (framingRectInPreview == null) {
Rect rect = new Rect(getFramingRect());
Point cameraResolution = configManager.getCameraResolution();
Point screenResolution = configManager.getScreenResolution();
//modify here
// rect.left = rect.left * cameraResolution.x / screenResolution.x;
// rect.right = rect.right * cameraResolution.x / screenResolution.x;
// rect.top = rect.top * cameraResolution.y / screenResolution.y;
// rect.bottom = rect.bottom * cameraResolution.y / screenResolution.y;
rect.left = rect.left * cameraResolution.y / screenResolution.x;
rect.right = rect.right * cameraResolution.y / screenResolution.x;
rect.top = rect.top * cameraResolution.x / screenResolution.y;
rect.bottom = rect.bottom * cameraResolution.x / screenResolution.y;
framingRectInPreview = rect;
}
return framingRectInPreview;
}
/**
* Converts the result points from still resolution coordinates to screen coordinates.
*
* @param points The points returned by the Reader subclass through Result.getResultPoints().
* @return An array of Points scaled to the size of the framing rect and offset appropriately
* so they can be drawn in screen coordinates.
*/
/*
public Point[] convertResultPoints(ResultPoint[] points) {
Rect frame = getFramingRectInPreview();
int count = points.length;
Point[] output = new Point[count];
for (int x = 0; x < count; x++) {
output[x] = new Point();
output[x].x = frame.left + (int) (points[x].getX() + 0.5f);
output[x].y = frame.top + (int) (points[x].getY() + 0.5f);
}
return output;
}
*/
/**
* A factory method to build the appropriate LuminanceSource object based on the format
* of the preview buffers, as described by Camera.Parameters.
*
* @param data A preview frame.
* @param width The width of the image.
* @param height The height of the image.
* @return A PlanarYUVLuminanceSource instance.
*/
public PlanarYUVLuminanceSource buildLuminanceSource(byte[] data, int width, int height) {
Rect rect = getFramingRectInPreview();
int previewFormat = configManager.getPreviewFormat();
String previewFormatString = configManager.getPreviewFormatString();
switch (previewFormat) {
// This is the standard Android format which all devices are REQUIRED to support.
// In theory, it's the only one we should ever care about.
case PixelFormat.YCbCr_420_SP:
// This format has never been seen in the wild, but is compatible as we only care
// about the Y channel, so allow it.
case PixelFormat.YCbCr_422_SP:
return new PlanarYUVLuminanceSource(data, width, height, rect.left, rect.top,
rect.width(), rect.height());
default:
// The Samsung Moment incorrectly uses this variant instead of the 'sp' version.
// Fortunately, it too has all the Y data up front, so we can read it.
if ("yuv420p".equals(previewFormatString)) {
return new PlanarYUVLuminanceSource(data, width, height, rect.left, rect.top,
rect.width(), rect.height());
}
}
throw new IllegalArgumentException("Unsupported picture format: " +
previewFormat + '/' + previewFormatString);
}
public Context getContext() {
return context;
}
}

View file

@ -0,0 +1,150 @@
/*
* Copyright (C) 2010 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.zxing.camera;
import android.os.IBinder;
import android.util.Log;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* This class is used to activate the weak light on some camera phones (not flash)
* in order to illuminate surfaces for scanning. There is no official way to do this,
* but, classes which allow access to this function still exist on some devices.
* This therefore proceeds through a great deal of reflection.
*
* See <a href="http://almondmendoza.com/2009/01/05/changing-the-screen-brightness-programatically/">
* http://almondmendoza.com/2009/01/05/changing-the-screen-brightness-programatically/</a> and
* <a href="http://code.google.com/p/droidled/source/browse/trunk/src/com/droidled/demo/DroidLED.java">
* http://code.google.com/p/droidled/source/browse/trunk/src/com/droidled/demo/DroidLED.java</a>.
* Thanks to Ryan Alford for pointing out the availability of this class.
*/
final class FlashlightManager {
private static final String TAG = FlashlightManager.class.getSimpleName();
private static final Object iHardwareService;
private static final Method setFlashEnabledMethod;
static {
iHardwareService = getHardwareService();
setFlashEnabledMethod = getSetFlashEnabledMethod(iHardwareService);
if (iHardwareService == null) {
Log.v(TAG, "This device does supports control of a flashlight");
} else {
Log.v(TAG, "This device does not support control of a flashlight");
}
}
private FlashlightManager() {
}
/**
* ¿ØÖÆÏà»úÉÁ¹âµÆ¿ª¹Ø
*/
//FIXME
static void enableFlashlight() {
setFlashlight(false);
}
static void disableFlashlight() {
setFlashlight(false);
}
private static Object getHardwareService() {
Class<?> serviceManagerClass = maybeForName("android.os.ServiceManager");
if (serviceManagerClass == null) {
return null;
}
Method getServiceMethod = maybeGetMethod(serviceManagerClass, "getService", String.class);
if (getServiceMethod == null) {
return null;
}
Object hardwareService = invoke(getServiceMethod, null, "hardware");
if (hardwareService == null) {
return null;
}
Class<?> iHardwareServiceStubClass = maybeForName("android.os.IHardwareService$Stub");
if (iHardwareServiceStubClass == null) {
return null;
}
Method asInterfaceMethod = maybeGetMethod(iHardwareServiceStubClass, "asInterface", IBinder.class);
if (asInterfaceMethod == null) {
return null;
}
return invoke(asInterfaceMethod, null, hardwareService);
}
private static Method getSetFlashEnabledMethod(Object iHardwareService) {
if (iHardwareService == null) {
return null;
}
Class<?> proxyClass = iHardwareService.getClass();
return maybeGetMethod(proxyClass, "setFlashlightEnabled", boolean.class);
}
private static Class<?> maybeForName(String name) {
try {
return Class.forName(name);
} catch (ClassNotFoundException cnfe) {
// OK
return null;
} catch (RuntimeException re) {
Log.w(TAG, "Unexpected error while finding class " + name, re);
return null;
}
}
private static Method maybeGetMethod(Class<?> clazz, String name, Class<?>... argClasses) {
try {
return clazz.getMethod(name, argClasses);
} catch (NoSuchMethodException nsme) {
// OK
return null;
} catch (RuntimeException re) {
Log.w(TAG, "Unexpected error while finding method " + name, re);
return null;
}
}
private static Object invoke(Method method, Object instance, Object... args) {
try {
return method.invoke(instance, args);
} catch (IllegalAccessException e) {
Log.w(TAG, "Unexpected error while invoking " + method, e);
return null;
} catch (InvocationTargetException e) {
Log.w(TAG, "Unexpected error while invoking " + method, e.getCause());
return null;
} catch (RuntimeException re) {
Log.w(TAG, "Unexpected error while invoking " + method, re);
return null;
}
}
private static void setFlashlight(boolean active) {
if (iHardwareService != null) {
invoke(setFlashEnabledMethod, iHardwareService, active);
}
}
}

View file

@ -0,0 +1,133 @@
/*
* Copyright 2009 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.zxing.camera;
import com.google.zxing.LuminanceSource;
import android.graphics.Bitmap;
/**
* This object extends LuminanceSource around an array of YUV data returned from the camera driver,
* with the option to crop to a rectangle within the full data. This can be used to exclude
* superfluous pixels around the perimeter and speed up decoding.
*
* It works for any pixel format where the Y channel is planar and appears first, including
* YCbCr_420_SP and YCbCr_422_SP.
*
* @author dswitkin@google.com (Daniel Switkin)
*/
public final class PlanarYUVLuminanceSource extends LuminanceSource {
private final byte[] yuvData;
private final int dataWidth;
private final int dataHeight;
private final int left;
private final int top;
public PlanarYUVLuminanceSource(byte[] yuvData, int dataWidth, int dataHeight, int left, int top,
int width, int height) {
super(width, height);
if (left + width > dataWidth || top + height > dataHeight) {
throw new IllegalArgumentException("Crop rectangle does not fit within image data.");
}
this.yuvData = yuvData;
this.dataWidth = dataWidth;
this.dataHeight = dataHeight;
this.left = left;
this.top = top;
}
@Override
public byte[] getRow(int y, byte[] row) {
if (y < 0 || y >= getHeight()) {
throw new IllegalArgumentException("Requested row is outside the image: " + y);
}
int width = getWidth();
if (row == null || row.length < width) {
row = new byte[width];
}
int offset = (y + top) * dataWidth + left;
System.arraycopy(yuvData, offset, row, 0, width);
return row;
}
@Override
public byte[] getMatrix() {
int width = getWidth();
int height = getHeight();
// If the caller asks for the entire underlying image, save the copy and give them the
// original data. The docs specifically warn that result.length must be ignored.
if (width == dataWidth && height == dataHeight) {
return yuvData;
}
int area = width * height;
byte[] matrix = new byte[area];
int inputOffset = top * dataWidth + left;
// If the width matches the full width of the underlying data, perform a single copy.
if (width == dataWidth) {
System.arraycopy(yuvData, inputOffset, matrix, 0, area);
return matrix;
}
// Otherwise copy one cropped row at a time.
byte[] yuv = yuvData;
for (int y = 0; y < height; y++) {
int outputOffset = y * width;
System.arraycopy(yuv, inputOffset, matrix, outputOffset, width);
inputOffset += dataWidth;
}
return matrix;
}
@Override
public boolean isCropSupported() {
return true;
}
public int getDataWidth() {
return dataWidth;
}
public int getDataHeight() {
return dataHeight;
}
public Bitmap renderCroppedGreyscaleBitmap() {
int width = getWidth();
int height = getHeight();
int[] pixels = new int[width * height];
byte[] yuv = yuvData;
int inputOffset = top * dataWidth + left;
for (int y = 0; y < height; y++) {
int outputOffset = y * width;
for (int x = 0; x < width; x++) {
int grey = yuv[inputOffset + x] & 0xff;
pixels[outputOffset + x] = 0xFF000000 | (grey * 0x00010101);
}
inputOffset += dataWidth;
}
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
return bitmap;
}
}

View file

@ -0,0 +1,59 @@
/*
* Copyright (C) 2010 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.zxing.camera;
import android.graphics.Point;
import android.hardware.Camera;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
final class PreviewCallback implements Camera.PreviewCallback {
private static final String TAG = PreviewCallback.class.getSimpleName();
private final CameraConfigurationManager configManager;
private final boolean useOneShotPreviewCallback;
private Handler previewHandler;
private int previewMessage;
PreviewCallback(CameraConfigurationManager configManager, boolean useOneShotPreviewCallback) {
this.configManager = configManager;
this.useOneShotPreviewCallback = useOneShotPreviewCallback;
}
void setHandler(Handler previewHandler, int previewMessage) {
this.previewHandler = previewHandler;
this.previewMessage = previewMessage;
}
public void onPreviewFrame(byte[] data, Camera camera) {
Point cameraResolution = configManager.getCameraResolution();
if (!useOneShotPreviewCallback) {
camera.setPreviewCallback(null);
}
if (previewHandler != null) {
Message message = previewHandler.obtainMessage(previewMessage, cameraResolution.x,
cameraResolution.y, data);
message.sendToTarget();
previewHandler = null;
} else {
Log.d(TAG, "Got preview callback, but no handler for it");
}
}
}

View file

@ -0,0 +1,137 @@
/*
* Copyright (C) 2008 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.zxing.decoding;
import java.util.Vector;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import com.rtk.simpleconfig_wizard.R;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.Result;
import com.zxing.activity.CaptureActivity;
import com.zxing.camera.CameraManager;
import com.zxing.view.ViewfinderResultPointCallback;
/**
* This class handles all the messaging which comprises the state machine for capture.
*/
public final class CaptureActivityHandler extends Handler {
private static final String TAG = CaptureActivityHandler.class.getSimpleName();
private final CaptureActivity activity;
private final DecodeThread decodeThread;
private State state;
private enum State {
PREVIEW,
SUCCESS,
DONE
}
public CaptureActivityHandler(CaptureActivity activity, Vector<BarcodeFormat> decodeFormats,
String characterSet) {
this.activity = activity;
decodeThread = new DecodeThread(activity, decodeFormats, characterSet,
new ViewfinderResultPointCallback(activity.getViewfinderView()));
decodeThread.start();
state = State.SUCCESS;
// Start ourselves capturing previews and decoding.
CameraManager.get().startPreview();
restartPreviewAndDecode();
}
@Override
public void handleMessage(Message message) {
switch (message.what) {
case R.id.auto_focus:
//Log.d(TAG, "Got auto-focus message");
// When one auto focus pass finishes, start another. This is the closest thing to
// continuous AF. It does seem to hunt a bit, but I'm not sure what else to do.
if (state == State.PREVIEW) {
CameraManager.get().requestAutoFocus(this, R.id.auto_focus);
}
break;
case R.id.restart_preview:
Log.d(TAG, "Got restart preview message");
restartPreviewAndDecode();
break;
case R.id.decode_succeeded:
Log.d(TAG, "Got decode succeeded message");
state = State.SUCCESS;
Bundle bundle = message.getData();
/***********************************************************************/
Bitmap barcode = bundle == null ? null :
(Bitmap) bundle.getParcelable(DecodeThread.BARCODE_BITMAP);
activity.handleDecode((Result) message.obj, barcode);/***********************************************************************/
break;
case R.id.decode_failed:
// We're decoding as fast as possible, so when one decode fails, start another.
state = State.PREVIEW;
CameraManager.get().requestPreviewFrame(decodeThread.getHandler(), R.id.decode);
break;
case R.id.return_scan_result:
Log.d(TAG, "Got return scan result message");
activity.setResult(Activity.RESULT_OK, (Intent) message.obj);
activity.finish();
break;
case R.id.launch_product_query:
Log.d(TAG, "Got product query message");
String url = (String) message.obj;
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
activity.startActivity(intent);
break;
}
}
public void quitSynchronously() {
state = State.DONE;
CameraManager.get().stopPreview();
Message quit = Message.obtain(decodeThread.getHandler(), R.id.quit);
quit.sendToTarget();
try {
decodeThread.join();
} catch (InterruptedException e) {
// continue
}
// Be absolutely sure we don't send any queued up messages
removeMessages(R.id.decode_succeeded);
removeMessages(R.id.decode_failed);
}
private void restartPreviewAndDecode() {
if (state == State.SUCCESS) {
state = State.PREVIEW;
CameraManager.get().requestPreviewFrame(decodeThread.getHandler(), R.id.decode);
CameraManager.get().requestAutoFocus(this, R.id.auto_focus);
activity.drawViewfinder();
}
}
}

View file

@ -0,0 +1,104 @@
/*
* Copyright (C) 2010 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.zxing.decoding;
import java.util.Arrays;
import java.util.List;
import java.util.Vector;
import java.util.regex.Pattern;
import android.content.Intent;
import android.net.Uri;
import com.google.zxing.BarcodeFormat;
final class DecodeFormatManager {
private static final Pattern COMMA_PATTERN = Pattern.compile(",");
static final Vector<BarcodeFormat> PRODUCT_FORMATS;
static final Vector<BarcodeFormat> ONE_D_FORMATS;
static final Vector<BarcodeFormat> QR_CODE_FORMATS;
static final Vector<BarcodeFormat> DATA_MATRIX_FORMATS;
static {
PRODUCT_FORMATS = new Vector<BarcodeFormat>(5);
PRODUCT_FORMATS.add(BarcodeFormat.UPC_A);
PRODUCT_FORMATS.add(BarcodeFormat.UPC_E);
PRODUCT_FORMATS.add(BarcodeFormat.EAN_13);
PRODUCT_FORMATS.add(BarcodeFormat.EAN_8);
PRODUCT_FORMATS.add(BarcodeFormat.RSS14);
ONE_D_FORMATS = new Vector<BarcodeFormat>(PRODUCT_FORMATS.size() + 4);
ONE_D_FORMATS.addAll(PRODUCT_FORMATS);
ONE_D_FORMATS.add(BarcodeFormat.CODE_39);
ONE_D_FORMATS.add(BarcodeFormat.CODE_93);
ONE_D_FORMATS.add(BarcodeFormat.CODE_128);
ONE_D_FORMATS.add(BarcodeFormat.ITF);
QR_CODE_FORMATS = new Vector<BarcodeFormat>(1);
QR_CODE_FORMATS.add(BarcodeFormat.QR_CODE);
DATA_MATRIX_FORMATS = new Vector<BarcodeFormat>(1);
DATA_MATRIX_FORMATS.add(BarcodeFormat.DATA_MATRIX);
}
private DecodeFormatManager() {}
static Vector<BarcodeFormat> parseDecodeFormats(Intent intent) {
List<String> scanFormats = null;
String scanFormatsString = intent.getStringExtra(Intents.Scan.SCAN_FORMATS);
if (scanFormatsString != null) {
scanFormats = Arrays.asList(COMMA_PATTERN.split(scanFormatsString));
}
return parseDecodeFormats(scanFormats, intent.getStringExtra(Intents.Scan.MODE));
}
static Vector<BarcodeFormat> parseDecodeFormats(Uri inputUri) {
List<String> formats = inputUri.getQueryParameters(Intents.Scan.SCAN_FORMATS);
if (formats != null && formats.size() == 1 && formats.get(0) != null){
formats = Arrays.asList(COMMA_PATTERN.split(formats.get(0)));
}
return parseDecodeFormats(formats, inputUri.getQueryParameter(Intents.Scan.MODE));
}
private static Vector<BarcodeFormat> parseDecodeFormats(Iterable<String> scanFormats,
String decodeMode) {
if (scanFormats != null) {
Vector<BarcodeFormat> formats = new Vector<BarcodeFormat>();
try {
for (String format : scanFormats) {
formats.add(BarcodeFormat.valueOf(format));
}
return formats;
} catch (IllegalArgumentException iae) {
// ignore it then
}
}
if (decodeMode != null) {
if (Intents.Scan.PRODUCT_MODE.equals(decodeMode)) {
return PRODUCT_FORMATS;
}
if (Intents.Scan.QR_CODE_MODE.equals(decodeMode)) {
return QR_CODE_FORMATS;
}
if (Intents.Scan.DATA_MATRIX_MODE.equals(decodeMode)) {
return DATA_MATRIX_FORMATS;
}
if (Intents.Scan.ONE_D_MODE.equals(decodeMode)) {
return ONE_D_FORMATS;
}
}
return null;
}
}

View file

@ -0,0 +1,110 @@
/*
* Copyright (C) 2010 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.zxing.decoding;
import java.util.Hashtable;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
//import android.util.Log;
import com.rtk.simpleconfig_wizard.R;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.DecodeHintType;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.ReaderException;
import com.google.zxing.Result;
import com.google.zxing.common.HybridBinarizer;
import com.zxing.activity.CaptureActivity;
import com.zxing.camera.CameraManager;
import com.zxing.camera.PlanarYUVLuminanceSource;
final class DecodeHandler extends Handler {
// private static final String TAG = DecodeHandler.class.getSimpleName();
private final CaptureActivity activity;
private final MultiFormatReader multiFormatReader;
DecodeHandler(CaptureActivity activity, Hashtable<DecodeHintType, Object> hints) {
multiFormatReader = new MultiFormatReader();
multiFormatReader.setHints(hints);
this.activity = activity;
}
@Override
public void handleMessage(Message message) {
switch (message.what) {
case R.id.decode:
//Log.d(TAG, "Got decode message");
decode((byte[]) message.obj, message.arg1, message.arg2);
break;
case R.id.quit:
Looper.myLooper().quit();
break;
}
}
/**
* Decode the data within the viewfinder rectangle, and time how long it took. For efficiency,
* reuse the same reader objects from one decode to the next.
*
* @param data The YUV preview frame.
* @param width The width of the preview frame.
* @param height The height of the preview frame.
*/
private void decode(byte[] data, int width, int height) {
// long start = System.currentTimeMillis();
Result rawResult = null;
//modify here
byte[] rotatedData = new byte[data.length];
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++)
rotatedData[x * height + height - y - 1] = data[x + y * width];
}
int tmp = width; // Here we are swapping, that's the difference to #11
width = height;
height = tmp;
PlanarYUVLuminanceSource source = CameraManager.get().buildLuminanceSource(rotatedData, width, height);
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
try {
rawResult = multiFormatReader.decodeWithState(bitmap);
} catch (ReaderException re) {
// continue
} finally {
multiFormatReader.reset();
}
if (rawResult != null) {
// long end = System.currentTimeMillis();
// Log.d(TAG, "Found barcode (" + (end - start) + " ms):\n" + rawResult.toString());
Message message = Message.obtain(activity.getHandler(), R.id.decode_succeeded, rawResult);
Bundle bundle = new Bundle();
bundle.putParcelable(DecodeThread.BARCODE_BITMAP, source.renderCroppedGreyscaleBitmap());
message.setData(bundle);
//Log.d(TAG, "Sending decode succeeded message...");
message.sendToTarget();
} else {
Message message = Message.obtain(activity.getHandler(), R.id.decode_failed);
message.sendToTarget();
}
}
}

Some files were not shown because too many files have changed in this diff Show more