第三方

本文介绍了一个基于Android平台实现QQ第三方登录的应用示例,详细展示了如何通过Tencent SDK进行授权登录流程,包括登录按钮的点击事件处理、用户信息获取及展示等关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

package com.bwie.test;




import java.io.Serializable;


import org.json.JSONException;
import org.json.JSONObject;


import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;


import com.bwie.test.bean.QQInfo;
import com.bwie.test.util.Util;
import com.tencent.connect.UserInfo;
import com.tencent.connect.auth.QQAuth;
import com.tencent.tauth.IUiListener;
import com.tencent.tauth.Tencent;
import com.tencent.tauth.UiError;


public class MainActivity extends Activity {
private static final String TAG = MainActivity.class.getName();
public static String mAppid;
private Button mNewLoginButton;
private TextView mUserInfo;
private ImageView mUserLogo;
public static QQAuth mQQAuth;
private UserInfo mInfo;
private Tencent mTencent;
private final String APP_ID = "222222";// 测试时使用,真正发布的时候要换成自己的APP_ID


//由于 传递对象不成功 使用静态变量
public static String qqName;
public static Bitmap qqLogo;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(TAG, "-->onCreate");
// 固定竖屏
setContentView(R.layout.activity_main);
initViews();
}


@Override
protected void onStart() {
Log.d(TAG, "-->onStart");
final Context context = MainActivity.this;
final Context ctxContext = context.getApplicationContext();
mAppid = APP_ID;
mQQAuth = QQAuth.createInstance(mAppid, ctxContext);
mTencent = Tencent.createInstance(mAppid, MainActivity.this);
super.onStart();
}


@Override
protected void onResume() {
Log.d(TAG, "-->onResume");
super.onResume();
}


@Override
protected void onPause() {
Log.d(TAG, "-->onPause");
super.onPause();
}


@Override
protected void onStop() {
Log.d(TAG, "-->onStop");
super.onStop();
}


@Override
protected void onDestroy() {
Log.d(TAG, "-->onDestroy");
super.onDestroy();
}


private void initViews() {
mNewLoginButton = (Button) findViewById(R.id.new_login_btn);


LinearLayout linearLayout = (LinearLayout) findViewById(R.id.main_container);
OnClickListener listener = new NewClickListener();
for (int i = 0; i < linearLayout.getChildCount(); i++) {
View view = linearLayout.getChildAt(i);
if (view instanceof Button) {
view.setOnClickListener(listener);
}
}
mUserInfo = (TextView) findViewById(R.id.user_nickname);
mUserLogo = (ImageView) findViewById(R.id.user_logo);
updateLoginButton();
}


private void updateLoginButton() {
if (mQQAuth != null && mQQAuth.isSessionValid()) {
mNewLoginButton.setTextColor(Color.RED);
mNewLoginButton.setText(R.string.qq_logout);
} else {
mNewLoginButton.setTextColor(Color.BLUE);
mNewLoginButton.setText(R.string.qq_login);
}
}


private void updateUserInfo() {
if (mQQAuth != null && mQQAuth.isSessionValid()) {
IUiListener listener = new IUiListener() {


@Override
public void onError(UiError e) {
// TODO Auto-generated method stub


}


@Override
public void onComplete(final Object response) {
Message msg = new Message();
msg.obj = response;
msg.what = 0;
mHandler.sendMessage(msg);
new Thread() {


@Override
public void run() {
JSONObject json = (JSONObject) response;
if (json.has("figureurl")) {
Bitmap bitmap = null;
try {
bitmap = Util.getbitmap(json
.getString("figureurl_qq_2"));
} catch (JSONException e) {


}
Message msg = new Message();
msg.obj = bitmap;
msg.what = 1;
mHandler.sendMessage(msg);
}
}


}.start();
}


@Override
public void onCancel() {
}
};
mInfo = new UserInfo(this, mQQAuth.getQQToken());
mInfo.getUserInfo(listener);


} else {
mUserInfo.setText("");
mUserInfo.setVisibility(android.view.View.GONE);
mUserLogo.setVisibility(android.view.View.GONE);
}
}


Handler mHandler = new Handler() {


@Override
public void handleMessage(Message msg) {
QQInfo ui=new QQInfo();
Bitmap bitmap = null ;
//消息0是获取qq名称
if (msg.what == 0) {
JSONObject response = (JSONObject) msg.obj;
if (response.has("nickname")) {
try {
mUserInfo.setVisibility(android.view.View.VISIBLE);
mUserInfo.setText(response.getString("nickname"));
// ui.setQqname(response.getString("nickname"));
qqName=response.getString("nickname");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} else if (msg.what == 1) {//发送1消息是 获取qq头像
bitmap = (Bitmap) msg.obj;
mUserLogo.setImageBitmap(bitmap);
mUserLogo.setVisibility(android.view.View.VISIBLE);    
qqLogo=bitmap;
// ui.setQqLogo(bitmap);
Intent intent=new Intent(MainActivity.this,Main2Activity.class);
// intent.putExtra("ui",ui);
startActivity(intent);
}
}


};


private void onClickLogin() {
if (!mQQAuth.isSessionValid()) {
IUiListener listener = new BaseUiListener() {
@Override
protected void doComplete(JSONObject values) {
updateUserInfo();
updateLoginButton();
}
};
mQQAuth.login(this, "all", listener);
// mTencent.loginWithOEM(this, "all",
// listener,"10000144","10000144","xxxx");
mTencent.login(this, "all", listener);
} else {
mQQAuth.logout(this);
updateUserInfo();
updateLoginButton();
}
}


public static boolean ready(Context context) {
if (mQQAuth == null) {
return false;
}
boolean ready = mQQAuth.isSessionValid()
&& mQQAuth.getQQToken().getOpenId() != null;
if (!ready)
Toast.makeText(context, "login and get openId first, please!",
Toast.LENGTH_SHORT).show();
return ready;
}


private class BaseUiListener implements IUiListener {


@Override
public void onComplete(Object response) {
Util.showResultDialog(MainActivity.this, response.toString(),
"登录成功");
doComplete((JSONObject) response);
}


protected void doComplete(JSONObject values) {

}


@Override
public void onError(UiError e) {
Util.toastMessage(MainActivity.this, "onError: " + e.errorDetail);
Util.dismissDialog();
}


@Override
public void onCancel() {
Util.toastMessage(MainActivity.this, "onCancel: ");
Util.dismissDialog();
}
}




class NewClickListener implements OnClickListener {
@Override
public void onClick(View v) {
Context context = v.getContext();
Class<?> cls = null;
switch (v.getId()) {
case R.id.new_login_btn:
onClickLogin();
return;
}
if (cls != null) {
Intent intent = new Intent(context, cls);
context.startActivity(intent);
}
}
}

}


**********************************************************************************************************************************************

package com.bwie.test;


import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.widget.ImageView;
import android.widget.TextView;


public class Main2Activity extends Activity {


private ImageView img;
private TextView textView;


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
initview();
textView.setText(MainActivity.qqName);
img.setImageBitmap(MainActivity.qqLogo);
}


private void initview() {
img = (ImageView)findViewById(R.id.imageView1);
textView = (TextView)findViewById(R.id.textView1);
}
}


***********************************************************************************************************

<string name="qq_login">登录</string>
    <string name="qq_logout">退出当前账号</string>

**************************************************************************************************************************


package com.example.qqlogintest;


import java.io.Serializable;




import android.graphics.Bitmap;
import android.os.Parcel;
import android.os.Parcelable;


public class QQInfo implements Serializable{
public String qqname;
public Bitmap qqLogo;
public String getQqname() {
return qqname;
}
public void setQqname(String qqname) {
this.qqname = qqname;
}
public Bitmap getQqLogo() {
return qqLogo;
}
public void setQqLogo(Bitmap qqLogo) {
this.qqLogo = qqLogo;
}

 
}

********************************************************************************************************************

package com.example.util;


import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;


import junit.framework.Assert;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;


public class Util {

private static final String TAG = "SDK_Sample.Util";

private static Dialog mProgressDialog;
private static Toast mToast;


    /* Convert byte[] to hex string.这里我们可以将byte转换成int,然后利用Integer.toHexString(int)来转换成16进制字符串。
            * @param src byte[] data
    * @return hex string
    */
    public static String bytesToHexString(byte[] src){
        StringBuilder stringBuilder = new StringBuilder("");
        if (src == null || src.length <= 0) {
            return null;
        }
        for (int i = 0; i < src.length; i++) {
            int v = src[i] & 0xFF;
            String hv = Integer.toHexString(v);
            if (hv.length() < 2) {
                stringBuilder.append(0);
            }
            stringBuilder.append(hv);
        }
        return stringBuilder.toString();
    }
    /**
     * Convert hex string to byte[]
     * @param hexString the hex string
     * @return byte[]
     */
    public static byte[] hexStringToBytes(String hexString) {
        if (hexString == null || hexString.equals("")) {
            return null;
        }
        hexString = hexString.toUpperCase();
        int length = hexString.length() / 2;
        char[] hexChars = hexString.toCharArray();
        byte[] d = new byte[length];
        for (int i = 0; i < length; i++) {
            int pos = i * 2;
            d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
        }
        return d;
    }
    /**
     * Convert char to byte
     * @param c char
     * @return byte
     */
    private static byte charToByte(char c) {
        return (byte) "0123456789ABCDEF".indexOf(c);
    }


    /*
     * 16进制数字字符集
     */
    private static String hexString="0123456789ABCDEF";
    /*
     * 将字符串编码成16进制数字,适用于所有字符(包括中文)
     */
    public static String toHexString(String str)
    {
//根据默认编码获取字节数组
        byte[] bytes=str.getBytes();
        StringBuilder sb=new StringBuilder(bytes.length*2);
//将字节数组中每个字节拆解成2位16进制整数
        for(int i=0;i<bytes.length;i++)
        {
            sb.append(hexString.charAt((bytes[i]&0xf0)>>4));
            sb.append(hexString.charAt((bytes[i]&0x0f)>>0));
        }
        return sb.toString();
    }


    //转换十六进制编码为字符串
    public static String hexToString(String s)
    {
        if("0x".equals(s.substring(0, 2)))
        {
            s =s.substring(2);
        }
        byte[] baKeyword = new byte[s.length()/2];
        for(int i = 0; i < baKeyword.length; i++)
        {
            try
            {
                baKeyword[i] = (byte)(0xff & Integer.parseInt(s.substring(i*2, i*2+2),16));
            }
            catch(Exception e)
            {
                e.printStackTrace();
            }
        }


        try
        {
            s = new String(baKeyword, "utf-8");//UTF-16le:Not
        }
        catch (Exception e1)
        {
            e1.printStackTrace();
        }
        return s;
    }


    public static byte[] bmpToByteArray(final Bitmap bmp, final boolean needRecycle) {
ByteArrayOutputStream output = new ByteArrayOutputStream();
bmp.compress(CompressFormat.PNG, 100, output);
if (needRecycle) {
bmp.recycle();
}

byte[] result = output.toByteArray();
try {
output.close();
} catch (Exception e) {
e.printStackTrace();
}

return result;
}

public static byte[] getHtmlByteArray(final String url) {
URL htmlUrl = null;     
InputStream inStream = null;     
try {         
htmlUrl = new URL(url);         
URLConnection connection = htmlUrl.openConnection();         
HttpURLConnection httpConnection = (HttpURLConnection)connection;         
int responseCode = httpConnection.getResponseCode();         
if(responseCode == HttpURLConnection.HTTP_OK){             
inStream = httpConnection.getInputStream();         
 }     
} catch (MalformedURLException e) {               
e.printStackTrace();     
} catch (IOException e) {              
e.printStackTrace();    
 } 
byte[] data = inputStreamToByte(inStream);


return data;
}

public static byte[] inputStreamToByte(InputStream is) {
try{
ByteArrayOutputStream bytestream = new ByteArrayOutputStream();
int ch;
while ((ch = is.read()) != -1) {
bytestream.write(ch);
}
byte imgdata[] = bytestream.toByteArray();
bytestream.close();
return imgdata;
}catch(Exception e){
e.printStackTrace();
}

return null;
}

public static byte[] readFromFile(String fileName, int offset, int len) {
if (fileName == null) {
return null;
}


File file = new File(fileName);
if (!file.exists()) {
Log.i(TAG, "readFromFile: file not found");
return null;
}


if (len == -1) {
len = (int) file.length();
}


Log.d(TAG, "readFromFile : offset = " + offset + " len = " + len + " offset + len = " + (offset + len));


if(offset <0){
Log.e(TAG, "readFromFile invalid offset:" + offset);
return null;
}
if(len <=0 ){
Log.e(TAG, "readFromFile invalid len:" + len);
return null;
}
if(offset + len > (int) file.length()){
Log.e(TAG, "readFromFile invalid file len:" + file.length());
return null;
}


byte[] b = null;
try {
RandomAccessFile in = new RandomAccessFile(fileName, "r");
b = new byte[len];
in.seek(offset);
in.readFully(b);
in.close();


} catch (Exception e) {
Log.e(TAG, "readFromFile : errMsg = " + e.getMessage());
e.printStackTrace();
}
return b;
}


    public static int computeSampleSize(BitmapFactory.Options options,


                                        int minSideLength, int maxNumOfPixels) {


        int initialSize = computeInitialSampleSize(options, minSideLength,


                maxNumOfPixels);


        int roundedSize;


        if (initialSize <= 8) {


            roundedSize = 1;


            while (roundedSize < initialSize) {


                roundedSize <<= 1;


            }


        } else {


            roundedSize = (initialSize + 7) / 8 * 8;


        }


        return roundedSize;
    }


    private static int computeInitialSampleSize(BitmapFactory.Options options,


                                                int minSideLength, int maxNumOfPixels) {


        double w = options.outWidth;


        double h = options.outHeight;


        int lowerBound = (maxNumOfPixels == -1) ? 1 :


                (int) Math.ceil(Math.sqrt(w * h / maxNumOfPixels));


        int upperBound = (minSideLength == -1) ? 128 :


                (int) Math.min(Math.floor(w / minSideLength),


                        Math.floor(h / minSideLength));


        if (upperBound < lowerBound) {


            // return the larger one when there is no overlapping zone.


            return lowerBound;


        }


        if ((maxNumOfPixels == -1) &&


                (minSideLength == -1)) {


            return 1;


        } else if (minSideLength == -1) {


            return lowerBound;


        } else {


            return upperBound;


        }
    }


    /**
     * 以最省内存的方式读取图片
     */
    public static Bitmap readBitmap(final String path){
        try{
            FileInputStream stream = new FileInputStream(new File(path+"test.jpg"));
            BitmapFactory.Options opts = new BitmapFactory.Options();
            opts.inSampleSize = 8;
            opts.inPurgeable=true;
            opts.inInputShareable=true;
            Bitmap bitmap = BitmapFactory.decodeStream(stream , null, opts);
            return bitmap;
        }
        catch (Exception e){
            return null;
        }
    }


    private static final int MAX_DECODE_PICTURE_SIZE = 1920 * 1440;
public static Bitmap extractThumbNail(final String path, final int height, final int width, final boolean crop) {
Assert.assertTrue(path != null && !path.equals("") && height > 0 && width > 0);


BitmapFactory.Options options = new BitmapFactory.Options();


try {
options.inJustDecodeBounds = true;
Bitmap tmp = BitmapFactory.decodeFile(path, options);
if (tmp != null) {
tmp.recycle();
tmp = null;
}


Log.d(TAG, "extractThumbNail: round=" + width + "x" + height + ", crop=" + crop);
final double beY = options.outHeight * 1.0 / height;
final double beX = options.outWidth * 1.0 / width;
Log.d(TAG, "extractThumbNail: extract beX = " + beX + ", beY = " + beY);
options.inSampleSize = (int) (crop ? (beY > beX ? beX : beY) : (beY < beX ? beX : beY));
if (options.inSampleSize <= 1) {
options.inSampleSize = 1;
}


// NOTE: out of memory error
while (options.outHeight * options.outWidth / options.inSampleSize > MAX_DECODE_PICTURE_SIZE) {
options.inSampleSize++;
}


int newHeight = height;
int newWidth = width;
if (crop) {
if (beY > beX) {
newHeight = (int) (newWidth * 1.0 * options.outHeight / options.outWidth);
} else {
newWidth = (int) (newHeight * 1.0 * options.outWidth / options.outHeight);
}
} else {
if (beY < beX) {
newHeight = (int) (newWidth * 1.0 * options.outHeight / options.outWidth);
} else {
newWidth = (int) (newHeight * 1.0 * options.outWidth / options.outHeight);
}
}


options.inJustDecodeBounds = false;


Log.i(TAG, "bitmap required size=" + newWidth + "x" + newHeight + ", orig=" + options.outWidth + "x" + options.outHeight + ", sample=" + options.inSampleSize);
Bitmap bm = BitmapFactory.decodeFile(path, options);
if (bm == null) {
Log.e(TAG, "bitmap decode failed");
return null;
}


Log.i(TAG, "bitmap decoded size=" + bm.getWidth() + "x" + bm.getHeight());
final Bitmap scale = Bitmap.createScaledBitmap(bm, newWidth, newHeight, true);
if (scale != null) {
bm.recycle();
bm = scale;
}


if (crop) {
final Bitmap cropped = Bitmap.createBitmap(bm, (bm.getWidth() - width) >> 1, (bm.getHeight() - height) >> 1, width, height);
if (cropped == null) {
return bm;
}


bm.recycle();
bm = cropped;
Log.i(TAG, "bitmap croped size=" + bm.getWidth() + "x" + bm.getHeight());
}
return bm;


} catch (final OutOfMemoryError e) {
Log.e(TAG, "decode bitmap failed: " + e.getMessage());
options = null;
}


return null;
}

public static final void showResultDialog(Context context, String msg,
String title) {
if(msg == null) return;
String rmsg = msg.replace(",", "\n");
Log.d("Util", rmsg);
new AlertDialog.Builder(context).setTitle(title).setMessage(rmsg)
.setNegativeButton("知道了", null).create().show();
}


public static final void showProgressDialog(Context context, String title,
String message) {
dismissDialog();
if (TextUtils.isEmpty(title)) {
title = "请稍候";
}
if (TextUtils.isEmpty(message)) {
message = "正在加载...";
}
mProgressDialog = ProgressDialog.show(context, title, message);
}


public static final void dismissDialog() {
if (mProgressDialog != null) {
mProgressDialog.dismiss();
mProgressDialog = null;
}
}


/**
* 打印消息并且用Toast显示消息

* @param activity
* @param message
* @param logLevel
*            填d, w, e分别代表debug, warn, error; 默认是debug
*/
public static final void toastMessage(final Activity activity,
final String message, String logLevel) {
if ("w".equals(logLevel)) {
Log.w("sdkDemo", message);
} else if ("e".equals(logLevel)) {
Log.e("sdkDemo", message);
} else {
Log.d("sdkDemo", message);
}
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
if (mToast != null) {
mToast.cancel();
mToast = null;
}
mToast = Toast.makeText(activity, message, Toast.LENGTH_SHORT);
mToast.show();
}
});
}


/**
* 打印消息并且用Toast显示消息

* @param activity
* @param message
* @param logLevel
*            填d, w, e分别代表debug, warn, error; 默认是debug
*/
public static final void toastMessage(final Activity activity,
final String message) {
toastMessage(activity, message, null);
}


/**
* 根据一个网络连接(String)获取bitmap图像

* @param imageUri
* @return
* @throws MalformedURLException
*/
public static Bitmap getbitmap(String imageUri) {
Log.v(TAG, "getbitmap:" + imageUri);
// 显示网络上的图片
Bitmap bitmap = null;
try {
URL myFileUrl = new URL(imageUri);
HttpURLConnection conn = (HttpURLConnection) myFileUrl
.openConnection();
conn.setDoInput(true);
conn.connect();
InputStream is = conn.getInputStream();
bitmap = BitmapFactory.decodeStream(is);
is.close();


Log.v(TAG, "image download finished." + imageUri);
} catch (IOException e) {
e.printStackTrace();
Log.v(TAG, "getbitmap bmp fail---");
return null;
}
return bitmap;
}
}

**************************************************************************************************************************************************

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"
    android:paddingBottom="25dp"
    android:paddingLeft="10dp"
    android:paddingRight="10dp"
    android:paddingTop="25dp" >


    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent" >


        <LinearLayout
            android:id="@+id/main_container"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical" >


            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:orientation="horizontal" >


                <ImageView
                    android:id="@+id/user_logo"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:visibility="gone" />


                <TextView
                    android:id="@+id/user_nickname"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:textColor="#80505050"
                    android:textSize="18sp"
                    android:visibility="gone" />
            </LinearLayout>


            <Button
                android:id="@+id/new_login_btn"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />
        </LinearLayout>
    </ScrollView>


</LinearLayout>


*************************************************************************************************************************************************

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.qqlogintest"
    android:versionCode="1"
    android:versionName="1.0" >


    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="17" />


    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.qqlogintest.MainActivity"
            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.tencent.connect.common.AssistActivity"
            android:configChanges="orientation|keyboardHidden"
            android:screenOrientation="portrait"
            android:theme="@android:style/Theme.Translucent.NoTitleBar" />
        <activity android:name="com.example.qqlogintest.ReturnActivity" >
        </activity>
        <activity
            android:name="com.tencent.tauth.AuthActivity"
            android:launchMode="singleTask"
            android:noHistory="true" >
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />


                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />


                <data android:scheme="tencent222222" />
                <!-- 100380359 100381104 222222 -->
            </intent-filter>
        </activity>
        <activity
            android:name="com.example.qqlogintest.SecondActivity"
            android:label="@string/title_activity_second" >
        </activity>
    </application>


    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <!-- SDK2.1新增获取用户位置信息 -->
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />


</manifest>




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值