❶ Android APP數據如何在SqlIte中初始化
問題一可以。
沒有過sqlite developer,問題就不知道了。
❷ 讀取android中assets中的txt文檔。亂碼怎麼辦
一. 前言
最近自己寫一個程序,需要把文本文件裡面的一些數據在程序第一次啟動的時候初始化到資料庫中去。所以就涉及到了讀取文件的操作。在我們android項目裡面,有個assets文件夾,就是用來存儲資源文件的,可以通過AssetManager訪問。本來以為這是一件三隻手指抓田螺--十拿九穩的事情,結果還是花了自己一個小時來調試它,就是讀取文件出現了亂碼。出現這種東西 "��1��0��0��0��1��",有些問號在裡面。。
二. 解決辦法
後來在網上找了些資料看了下,說是要把文本文件保存成UTF-8類型才可以。試了下,果然ok..下面分享下自己這塊功能的代碼
三. 代碼
1. 文本文件內容格式:
復制內容到剪貼板
代碼:
13076-5 2 0 9 5 0 1
13075-9 5 6 8 4 3 3
13074-2 0 4 0 2 8 8
13073-8 8 6 6 0 7 8
13072-2 0 8 8 6 3 5
大概就是這種格式,我需要對它們每行都進行解析,比如第一行解析成 13076 5 2 0 9 5 0 1 ,也就是8個數字,然後存入資料庫裡面分別對應的8列
2. 主要代碼
這里的話,自己新建了一個MyDbOpenHelper,然後重寫了onCreate方法,這個方法會在我們第一次調用db.getReadDatabase()或者getWriteDataBase()方法時調用,而且只會調用一次。就是程序第一次啟動的時候。
ok..在onCreate方法裡面,主要代碼的功能已經注釋,大家可以自己看。。private static class MyDbOpenHelper extends SQLiteOpenHelper{
private Context c;
public MyDbOpenHelper(Context context, String name,
CursorFactory factory, int version) {
super(context, name, factory, version);
c = context;
}
@Override
public void onCreate(SQLiteDatabase db) {
Log.d("Sandy", "onCreate database");
//execute when user invoke getReadDatabase/getWriteDatabase
//當用戶第一次程序的時候,我們會調用這里,創建我們的表。
db.execSQL("CREATE TABLE " + RAW_DATA_TABLE + " ("
+ RawData._ID + " INTEGER PRIMARY KEY,"
+ RawData.COLUMN_ISSUE + " TEXT,"
+ RawData.COLUMN_NUMBER_ONE + " TEXT,"
+ RawData.COLUMN_NUMBER_TWO + " TEXT , "
+ RawData.COLUMN_NUMBER_THREE + " TEXT,"
+ RawData.COLUMN_NUMBER_FOUR + " TEXT,"
+ RawData.COLUMN_NUMBER_FIVE + " TEXT,"
+ RawData.COLUMN_NUMBER_SIX + " TEXT,"
+ RawData.COLUMN_NUMBER_SEVEN + " TEXT"
+ ");");
ContentValues cv = new ContentValues();
//聲明解析文件的文件流對象
InputStream in = null;
BufferedReader reader = null;
try {
//通過AssetManager讀取文件
in = c.getResources().getAssets().open("qixingcai-data.txt", AssetManager.ACCESS_BUFFER);
//構造BufferedReader對象,以便逐行讀取
reader = new BufferedReader(new InputStreamReader(in));
String line ;
//逐行讀取文件內容,讀取一行,就把這一行數據進行拆分,然後保存進資料庫
while((line = reader.readLine()) != null){
cv.clear();
//根據分割符"-"和" "進行數據拆分,然後把得到的數據放到ContentValues對象中
String[] issueAndNumber = line.split("-");
String[] numbers = issueAndNumber[1].split(" ");
cv.put(RawData.COLUMN_ISSUE, issueAndNumber[0]);
cv.put(RawData.COLUMN_NUMBER_ONE, numbers[0]);
cv.put(RawData.COLUMN_NUMBER_TWO, numbers[1]);
cv.put(RawData.COLUMN_NUMBER_THREE, numbers[2]);
cv.put(RawData.COLUMN_NUMBER_FOUR, numbers[3]);
cv.put(RawData.COLUMN_NUMBER_FIVE, numbers[4]);
cv.put(RawData.COLUMN_NUMBER_SIX, numbers[5]);
cv.put(RawData.COLUMN_NUMBER_SEVEN, numbers[6]);
//插入資料庫
db.insert(RAW_DATA_TABLE, "_id", cv);
Log.d("Sandy", "issueAndNumber[0]" + issueAndNumber[0]
+ "one: " + numbers[0] + " all: " + issueAndNumber[1]);
}
} catch (IOException e) {
Log.d("Sandy", "", e);
}finally{
if (in != null){
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (reader != null){
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
❸ android 什麼時候初始化資料庫
1)它的資料庫初始化不是用sql語句,而是用一個現成的sqlite的二進制文件進行直接到Android系統的資料庫路徑中。我一方面不太放心這種二進制文件的直接,另一方面,如果sqlite資料庫的二進制結構有所升級或變動,我的程序就無法對所有sqlite版本兼容了。
2)DataBaseHelper 類雖然是extends SQLiteOpenHelper,但它完全沒有按照原來SQLiteOpenHelper類原先的使用邏輯,沒有重載onCreate和onOpen之類,自己去寫了檢測資料庫是否存在,打開和關閉資料庫等函數。使得這個類擴展SQLiteOpenHelper幾乎沒有意義,差不多是重建了應用邏輯,讓我用不了SQLiteOpenHelper。getReadableDatabase等函數,很不爽(也許是本人的潔癖)。
❹ android開發 資料庫的使用
SQLite是輕量級嵌入式資料庫引擎,它支持 SQL 語言,並且只利用很少的內存就有很好的性能。此外它還是開源的,任何人都可以使用它。許多開源項目((Mozilla, PHP, Python)都使用了 SQLite,SQLite 由以下幾個組件組成:SQL 編譯器、內核、後端以及附件。SQLite 通過利用虛擬機和虛擬資料庫引擎(VDBE),使調試、修改和擴展 SQLite 的內核變得更加方便。
特點:
面向資源有限的設備, 沒有伺服器進程, 所有數據存放在同一文件中跨平台,可自由復制。
SQLite 基本上符合 SQL-92 標准,和其他的主要 SQL 資料庫沒什麼區別。它的優點就是高效,Android 運行時環境包含了完整的 SQLite。
SQLite 和其他資料庫最大的不同就是對數據類型的支持,創建一個表時,可以在 CREATE TABLE 語句中指定某列的數據類型,但是你可以把任何數據類型放入任何列中。當某個值插入資料庫時,SQLite 將檢查它的類型。如果該類型與關聯的列不匹配,則 SQLite 會嘗試將該值轉換成該列的類型。如果不能轉換,則該值將作為其本身具有的類型存儲。比如可以把一個字元串(String)放入 INTEGER 列。SQLite 稱這為「弱類型」(manifest typing.)。 此外,SQLite 不支持一些標準的 SQL 功能,特別是外鍵約束(FOREIGN KEY constrains),嵌套 transcaction 和 RIGHT OUTER JOIN 和 FULL OUTER JOIN, 還有一些 ALTER TABLE 功能。 除了上述功能外,SQLite 是一個完整的 SQL 系統,擁有完整的觸發器,交易等等。
Android 集成了 SQLite 資料庫 Android 在運行時(run-time)集成了 SQLite,所以每個 Android 應用程序都可以使用 SQLite 資料庫。
對於熟悉 SQL 的開發人員來時,在 Android 開發中使用 SQLite 相當簡單。但是,由於 JDBC 會消耗太多的系統資源,所以 JDBC 對於手機這種內存受限設備來說並不合適。因此,Android 提供了一些新的 API 來使用 SQLite 資料庫,Android 開發中,程序員需要學使用這些 API。
資料庫存儲在 data/< 項目文件夾 >/databases/ 下。 Android 開發中使用 SQLite 資料庫 Activites 可以通過 Content Provider 或者 Service 訪問一個資料庫。
下面會詳細講解如果創建資料庫,添加數據和查詢資料庫。 創建資料庫 Android 不自動提供資料庫。在 Android 應用程序中使用 SQLite,必須自己創建資料庫,然後創建表、索引,填充數據。
Android 提供了 SQLiteOpenHelper 幫助你創建一個資料庫,你只要繼承 SQLiteOpenHelper 類,就可以輕松的創建資料庫。SQLiteOpenHelper 類根據開發應用程序的需要,封裝了創建和更新資料庫使用的邏輯。
SQLiteOpenHelper 的子類,至少需要實現三個方法:
1 構造函數,調用父類 SQLiteOpenHelper 的構造函數。這個方法需要四個參數:上下文環境(例如,一個 Activity),資料庫名字,一個可選的游標工廠(通常是 Null),一個代表你正在使用的資料庫模型版本的整數。
2 onCreate()方法,它需要一個 SQLiteDatabase 對象作為參數,根據需要對這個對象填充表和初始化數據。
3 onUpgrage() 方法,它需要三個參數,一個 SQLiteDatabase 對象,一個舊的版本號和一個新的版本號,這樣你就可以清楚如何把一個資料庫從舊的模型轉變到新的模型。
❺ 如何進行Android資料庫操作
在自己Android資料庫接收或發出一個系統action的時候,要名副其實。比如你響應一個view動作,做的確實edit的勾當,你發送一個pick消息,其實你想讓別人做edit的事,這樣都會造成混亂。
一個好的習慣是創建一個輔助類來簡化你的Android資料庫交互。考慮創建一個資料庫適配器,來添加一個與資料庫交互的包裝層。它應該提供直觀的、強類型的方法,如添加、刪除和更新項目。資料庫適配器還應該處理查詢和對創建、打開和關閉資料庫的包裝。
它還常用靜態的Android資料庫常量來定義表的名字、列的名字和列的索引。下面的代碼片段顯示了一個標准資料庫適配器類的框架。它包括一個SQLiteOpenHelper類的擴展類,用於簡化打開、創建和更新資料庫。
import android.content.Context; import android.database.*; import android.database.sqlite.*; import android.database.sqlite.SQLiteDatabase.CursorFactory; import android.util.Log; public class MyDBAdapter { // The name and column index of each column in your database. public static final String KEY_NAME=」name」; public static final int NAME_COLUMN = 1; // TODO: Create public field for each column in your table. // SQL Statement to create a new database. private static final String DATABASE_CREATE = 「create table 「 + DATABASE_TABLE + 「 (「 + KEY_ID + 「 integer primary key autoincrement, 「 + KEY_NAME + 「 text not null);」; // Variable to hold the database instance private SQLiteDatabase db; // Context of the application using the database. private final Context context; // Database open/upgrade helper private myDbHelper dbHelper; public MyDBAdapter(Context _context) { context = _context; dbHelper = new myDbHelper(context, DATABASE_NAME, null, DATABASE_VERSION); } public MyDBAdapter open() throws SQLException { db = dbHelper.getWritableDatabase(); return this; } public void close() { db.close(); } public long insertEntry(MyObject _myObject) { ContentValues contentValues = new ContentValues(); // TODO fill in ContentValues to represent the new row return db.insert(DATABASE_TABLE, null, contentValues); } public boolean removeEntry(long _rowIndex) { return db.delete(DATABASE_TABLE, KEY_ID + 「=」 + _rowIndex, null) > 0; } public Cursor getAllEntries () { return db.query(DATABASE_TABLE, new String[] {KEY_ID, KEY_NAME}, null, null, null, null, null); } public MyObject getEntry(long _rowIndex) { MyObject objectInstance = new MyObject(); // TODO Return a cursor to a row from the database and // use the values to populate an instance of MyObject return objectInstance; } public int updateEntry(long _rowIndex, MyObject _myObject) { String where = KEY_ID + 「=」 + _rowIndex; ContentValues contentValues = new ContentValues(); // TODO fill in the ContentValue based on the new object return db.update(DATABASE_TABLE, contentValues, where, null); } private static class myDbHelper extends SQLiteOpenHelper { public myDbHelper(Context context, String name, CursorFactory factory, int version) { super(context, name, factory, version); } // Called when no database exists in // disk and the helper class needs // to create a new one. @Override public void onCreate(SQLiteDatabase _db) { _db.execSQL(DATABASE_CREATE); }
❻ Android創建資料庫需要做哪些事情
首先:使用Eclipse創建一個Android項目,取名為Database
操作資料庫的最佳實踐是創建一個輔助類,由它封裝所有對資料庫的復雜訪問,對於調用代碼而言它是透明的,因此我創建了一個
DBAdapter
的輔助類,由它創建、打開、關閉和使用SQLite資料庫。
首先,在src/文件夾
(
在這個例子中是
src/net.learn2develop.Database)下添加一個DBAdapter.java文件。
在DBAdapter.java文件中,導入所有你要使用到的命名空間:
package net.learn2develop.Databases;
import android.content.ContentValues;
import android.content.Context;
import android.
database
.
Cursor
;
import android.
database
.SQLException;
import android.
database
.sqlite.SQLiteDatabase;
import android.
database
.sqlite.SQLiteOpenHelper;
import android.util.
Log
;
public
class DBAdapter
{
}
.sqlite.SQLiteDatabase;
import android.
database
.sqlite.SQLiteOpenHelper;
import android.util.
Log
;
public
class DBAdapter
{
}
接下來創建一個資料庫,取名為bookstitles在DBAdapter.java文件中,定義清單1中的常量。清單1 定義DBAdapter.java文件中的常量
package net.learn2develop.
Database
;
import android.content.ContentValues;
import android.content.Context;
import android.
database
.
Cursor
;
import android.
database
.SQLException;
import android.
database
.sqlite.SQLiteDatabase;
import android.
database
.sqlite.SQLiteOpenHelper;
import android.util.Log; public class DBAdapter {
public static final String KEY_ROWID = "_id"; public static final String KEY_ISBN = "isbn"; public static final String KEY_TITLE = "title";
public static final String KEY_PUBLISHER = "publisher"; private static final String TAG = "DBAdapter"; private static final String DATABASE_NAME = "books"; private static final String DATABASE_TABLE = "titles"; private static final int DATABASE_VERSION = 1; private static final String DATABASE_CREATE =
"create table titles (_id integer primary key autoincrement, " + "isbn text not null, title text not null, " + "publisher text not null);"; private final Context context; }
DATABASE_CREATE常量包括創建titles表的SQL語句。
在DBAdapter類中,你可以擴展SQLiteOpenHelper類,它是一個Android輔助類,主要用於資料庫創建和版本管理。實際上,你可以覆蓋onCreate()和onUpgrade()方法,如清單2所示。
清單2 在DBAdapter類中,擴展SQLiteOpenHelper類覆蓋onCreate() 和 onUpgrade()方法
package net.learn2develop.Database; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import android.util.Log; public class DBAdapter {
public static final String KEY_ROWID = "_id";
public static final String KEY_ISBN = "isbn";
public static final String KEY_TITLE = "title";
public static final String KEY_PUBLISHER = "publisher";
private static final String TAG = "DBAdapter";
private static final String DATABASE_NAME = "books";
private static final String DATABASE_TABLE = "titles";
private static final int DATABASE_VERSION = 1;
private static final String DATABASE_CREATE =
"create table titles (_id integer primary key autoincrement, "
+ "isbn text not null, title text not null, "
+ "publisher text not null);";
private final Context context;
private DatabaseHelper DBHelper;
private SQLiteDatabase db;
public DBAdapter(Context ctx)
{
this.context = ctx;
DBHelper = new DatabaseHelper(context);
}
private static class DatabaseHelper extends SQLiteOpenHelper
{
DatabaseHelper(Context context)
{
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db)
{
db.execSQL(DATABASE_CREATE);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion,
int newVersion)
{
Log.w(TAG, "Upgrading database from version " + oldVersion
+ " to "
+ newVersion + ", which will destroy all old data");
db.execSQL("DROP TABLE IF EXISTS titles");
onCreate(db);
}
}
}
onCreate()方法創建一個新的資料庫,onUpgrade()方法用於升級資料庫,這可以通過檢查DATABASE_VERSION常量定義的值來實現,對於onUpgrade()方法而言,只不過是簡單地刪除表,然後在創建表而已。
現在你可以定義不同的方法來打開和關閉資料庫,如清單3中的添加/編輯/刪除/行的函數。
清單3 定義打開和關閉資料庫以及增加/編輯/刪除表中行的方法
public class DBAdapter
{
//...
//...
//---打開資料庫---
public DBAdapter open() throws SQLException
{
db = DBHelper.getWritableDatabase();
return this;
}
//---關閉資料庫---
public void close()
{
DBHelper.close();
}
//---向資料庫插入一個標題---
public long insertTitle(String isbn, String title, String publisher)
{
ContentValues initialValues = new ContentValues();
initialValues.put(KEY_ISBN, isbn);
initialValues.put(KEY_TITLE, title);
initialValues.put(KEY_PUBLISHER, publisher);
return db.insert(DATABASE_TABLE, null, initialValues);
}
//---刪除一個指定的標題---
public boolean deleteTitle(long rowId)
{
return db.delete(DATABASE_TABLE, KEY_ROWID + "=" + rowId, null) > 0;
}
//---檢索所有標題---
public Cursor getAllTitles()
{
return db.query(DATABASE_TABLE, new String[] {
KEY_ROWID,
KEY_ISBN,
KEY_TITLE,
KEY_PUBLISHER},
null,
null,
null,
null,
null);
}
//---檢索一個指定的標題---
public Cursor getTitle(long rowId) throws SQLException
{
Cursor mCursor =
db.query(true, DATABASE_TABLE, new String[] {
KEY_ROWID,
KEY_ISBN,
KEY_TITLE,
KEY_PUBLISHER
},
KEY_ROWID + "=" + rowId,
null,
null,
null,
null,
null);
if (mCursor != null) {
mCursor.moveToFirst();
}
return mCursor;
}
//---更新一個標題---
public boolean updateTitle(long rowId, String isbn,
String title, String publisher)
{
ContentValues args = new ContentValues();
args.put(KEY_ISBN, isbn);
args.put(KEY_TITLE, title);
args.put(KEY_PUBLISHER, publisher);
return db.update(DATABASE_TABLE, args,
KEY_ROWID + "=" + rowId, null) > 0;
}
}
注意Android使用Cursor類返回一個需要的值,Cursor作為一個指針從資料庫查詢返回結果集,使用Cursor允許Android更有效地管理它們需要的行和列,你使用ContentValues對象存儲鍵/值對,它的put()方法允許你插入不同數據類型的鍵值。
清單4顯示了完整的DBAdapter.java源代碼。
清單4 DBAdapter.java完整源代碼
package net.learn2develop.Database;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
public class DBAdapter
{
public static final String KEY_ROWID = "_id";
public static final String KEY_ISBN = "isbn";
public static final String KEY_TITLE = "title";
public static final String KEY_PUBLISHER = "publisher";
private static final String TAG = "DBAdapter";
private static final String DATABASE_NAME = "books";
private static final String DATABASE_TABLE = "titles";
private static final int DATABASE_VERSION = 1;
private static final String DATABASE_CREATE =
"create table titles (_id integer primary key autoincrement, "
+ "isbn text not null, title text not null, "
+ "publisher text not null);";
private final Context context;
private DatabaseHelper DBHelper;
private SQLiteDatabase db;
public DBAdapter(Context ctx)
{
this.context = ctx;
DBHelper = new DatabaseHelper(context);
}
private static class DatabaseHelper extends SQLiteOpenHelper
{
DatabaseHelper(Context context)
{
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db)
{
db.execSQL(DATABASE_CREATE);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion,
int newVersion)
{
Log.w(TAG, "Upgrading database from version " + oldVersion
+ " to "
+ newVersion + ", which will destroy all old data");
db.execSQL("DROP TABLE IF EXISTS titles");
onCreate(db);
}
}
//---打開資料庫---
public DBAdapter open() throws SQLException
{
db = DBHelper.getWritableDatabase();
return this;
}
//---關閉資料庫---
public void close()
{
DBHelper.close();
}
//---向資料庫中插入一個標題---
public long insertTitle(String isbn, String title, String publisher)
{
ContentValues initialValues = new ContentValues();
initialValues.put(KEY_ISBN, isbn);
initialValues.put(KEY_TITLE, title);
initialValues.put(KEY_PUBLISHER, publisher);
return db.insert(DATABASE_TABLE, null, initialValues);
}
//---刪除一個指定標題---
public boolean deleteTitle(long rowId)
{
return db.delete(DATABASE_TABLE, KEY_ROWID +
"=" + rowId, null) > 0;
}
//---檢索所有標題---
public Cursor getAllTitles()
{
return db.query(DATABASE_TABLE, new String[] {
KEY_ROWID,
KEY_ISBN,
KEY_TITLE,
KEY_PUBLISHER},
null,
null,
null,
null,
null);
}
//---檢索一個指定標題---
public Cursor getTitle(long rowId) throws SQLException
{
Cursor mCursor =
db.query(true, DATABASE_TABLE, new String[] {
KEY_ROWID,
KEY_ISBN,
KEY_TITLE,
KEY_PUBLISHER
},
KEY_ROWID + "=" + rowId,
null,
null,
null,
null,
null);
if (mCursor != null) {
mCursor.moveToFirst();
}
return mCursor;
}
//---更新一個標題---
public boolean updateTitle(long rowId, String isbn,
String title, String publisher)
{
ContentValues args = new ContentValues();
args.put(KEY_ISBN, isbn);
args.put(KEY_TITLE, title);
args.put(KEY_PUBLISHER, publisher);
return db.update(DATABASE_TABLE, args,
KEY_ROWID + "=" + rowId, null) > 0;
}
}
❼ android 怎麼讀取資料庫中的數據
android讀取資料庫可以使用一些api進行讀取,實例如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
* 查找一條數據
* @param uid
*/
public User find(Integer uid){
SQLiteDatabase db=dbOpenHelper.getReadableDatabase(); //創建資料庫輔助類
Cursor cursor =db.rawQuery("select * from user where uid=?", new String[]{uid.toString()}); //創建一個游標
if(cursor.moveToFirst()){ //循環遍歷查找數組
int uid2=cursor.getInt(cursor.getColumnIndex("uid"));
String uname=cursor.getString(cursor.getColumnIndex("uname"));
String uaddress=cursor.getString(cursor.getColumnIndex("uaddress"));
User user=new User();
user.setUid(uid2);
user.setUname(uname);
user.setUaddress(uaddress);
return user;
}
cursor.close();
return null;
}
❽ android怎麼操作sqlite資料庫
在Android中操作SQLite資料庫使用SQLiteDatabase類,使用該類可以對資料庫進行添加(Create)、查詢(Retrieve)、更新(Update)和刪除(Delete)操作。需要重點掌握的是execSQL()和rawQuery()方法。其中 execSQL()方法可以執行insert、delete、update和CREATE TABLE之類有更改行為的SQL語句; rawQuery()方法用於執行select語句。
舉一例說明execSQL()使用方法:
SQLiteDatabase mydb = ....;
mydb.execSQL("insert into person(name, age) values('網蟲一族', 23)");
mydb.close();
從上面簡單的例子可以看出,SQLiteDatabase執行的是標準的SQL語句,所以,並不需要額外掌握更多的知識,在幫助文檔中熟悉下SQLiteDatabase類的幾個方法就可以了。
❾ android studio初始化配置 初始配置方法有哪些步驟
1、打開android studio軟體,啟動完成後,如果有下面的提示,點擊「取消」,如下圖
2、android studio能開發的app,有手機、平板、手錶、汽車等app
3、選擇android studio初始化時要安裝的組件和配置,這里選擇「標准」,如下圖
4、選擇源碼編輯器的主題樣式,根據自己的喜好進行選擇
5、這是初始化的確認配置項,會安裝一個新版的android sdk
6、提示正在下載的軟體包,安裝完成後,在系統設置里,打開被阻止的軟體