当前位置:  编程技术>移动开发
本页文章导读:
    ▪getLastknownLocation()在 nexus 回到null值        getLastknownLocation()在 nexus 返回null值原问题来自于CSDN问答频道,更多见:http://ask.csdn.net/questions/1730 问题描述: 我使用下面的代码来开发一个基于位置定位的项目,这个项目我是用的是google api.........
    ▪ 浅谈su暂时切换用户的实现方法        浅谈su临时切换用户的实现方法最近开发Android app需要用到root权限去调用一些shell程序,接触过Linux的同学知道用su这个命令,su的意思是switch user,切换用户。然而在我调用su的时候,授权管理.........
    ▪ Unable to build: the file dx.jar was not loaded from the SDK folder 异常       Unable to build: the file dx.jar was not loaded from the SDK folder 错误platform-tools\lib folder was missing after upgrade (my eclipse was open). close eclipse, using sdk manager uninstall and install "Android SDK platform-tools". 即先关闭ecli.........

[1]getLastknownLocation()在 nexus 回到null值
    来源: 互联网  发布时间: 2014-02-18
getLastknownLocation()在 nexus 返回null值

原问题来自于CSDN问答频道,更多见:http://ask.csdn.net/questions/1730

问题描述:

我使用下面的代码来开发一个基于位置定位的项目,这个项目我是用的是google api 8。

lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
    currloc = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
    TextView t = (TextView)findViewById(R.id.textView1);
    try{
        t.setText("Your current location is - "+currloc.getLatitude()+","+currloc.getLongitude());
    }catch (Exception e) {
        // TODO: handle exception
        t.setText("cant find current location ");
    }


这段代码在galaxy tab上能正常运行,htc上也可以。
但是当我使用nexus的时候,location得到的是null。对于galaxy nexus来说,我是不是得改变api版本,或者说还有其他一些特殊需求吗?

仿照下面的代码:

Step1: into your oncreate

LocationListener locationListener = new LocalLocationListener();
    locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);

Step2: into class body

/**Listener on location change*/
private class LocalLocationListener implements LocationListener
{

    public void onLocationChanged(Location location)
    {
        String text = "My current Location is: "+location.getLatitude()+", "+location.getLongitude();
        GeoPoint geoPoint = new GeoPoint((int)(location.getLatitude()* 1E6), (int)(location.getLatitude() * 1E6));
        mapController_.animateTo(geoPoint);
        Toast.makeText(LocalMap.this, text, Toast.LENGTH_SHORT).show();
        Log.i("onLocationChanged", text);

    }

    public void onProviderDisabled(String provider)
    {
        // TODO Auto-generated method stub
        Toast.makeText(LocalMap.this, "GPS Disable", Toast.LENGTH_SHORT).show();
        Log.i("onProviderDisabled", "GPS Disable");
    }

    public void onProviderEnabled(String provider)
    {
        // TODO Auto-generated method stub
        Toast.makeText(LocalMap.this, "GPS Enable", Toast.LENGTH_SHORT).show();
        Log.i("onProviderEnabled", "GPS Enable");
    }

    public void onStatusChanged(String provider, int status, Bundle extras)
    {
        // TODO Auto-generated method stub

    }


 


    
[2] 浅谈su暂时切换用户的实现方法
    来源: 互联网  发布时间: 2014-02-18
浅谈su临时切换用户的实现方法

最近开发Android app需要用到root权限去调用一些shell程序,接触过Linux的同学知道用su这个命令,su的意思是switch user,切换用户。然而在我调用su的时候,授权管理器总会弹出确认提示,更操蛋的是我手机安装的授权管理器即使设置了自动授权所有请求都不起作用!火了!干脆自己找su源码去改写个来用。

搜索了一下,发现superuser的su源码:

/*
** 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.
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <dirent.h>
#include <errno.h>
#include <sys/stat.h>

#include <unistd.h>
#include <time.h>

#include <pwd.h>

#include <sqlite3.h>

#define DBPATH "/data/data/com.koushikdutta.superuser/databases/superuser.sqlite"

static int g_puid;

static void printRow(int argc, char** argv, char** azColName)
{
        int i;
        for (i = 0; i < argc; i++)
        {
                printf("%s: %s\n", azColName[i], argv[i]);
        }
}

typedef struct whitelistCallInfo whitelistCallInfo;
struct whitelistCallInfo
{
        sqlite3* db;
        int count;
};

static int whitelistCallback(void *data, int argc, char **argv, char **azColName)
{       
        whitelistCallInfo* callInfo = (whitelistCallInfo*)data;
        // note the count
        int count = atoi(argv[2]);
        callInfo->count = count;
        // remove whitelist entries that are expired
        if (count - 1 <= 0)
        {
                char remove[1024];
                sprintf(remove, "delete from whitelist where _id='%s';", argv[0]);
                sqlite3_exec(callInfo->db, remove, NULL, NULL, NULL);
                return 0;
        }

        char update[1024];
        sprintf(update, "update whitelist set count=%d where _id='%s';", count, argv[0]);
        sqlite3_exec(callInfo->db, update, NULL, NULL, NULL);
        return 0;
}

static int checkWhitelist()
{
        sqlite3 *db;
        int rc = sqlite3_open_v2(DBPATH, &db, SQLITE_OPEN_READWRITE, NULL);
        if (!rc)
        {
                char *errorMessage;
                char query[1024];
                sprintf(query, "select * from whitelist where _id=%d limit 1;", g_puid);
                struct whitelistCallInfo callInfo;
                callInfo.count = 0;
                callInfo.db = db;
                rc = sqlite3_exec(db, query, whitelistCallback, &callInfo, &errorMessage);
                if (rc != SQLITE_OK)
                {
                        sqlite3_close(db);
                        return 0;
                }
                sqlite3_close(db);
                return callInfo.count;
        }
        sqlite3_close(db);
        return 0;
}

static int executionFailure(char *context)
{
        fprintf(stderr, "su: %s. Error:%s\n", context, strerror(errno));
        return -errno;
}

static int permissionDenied()
{
        // the superuser activity couldn't be started
        printf("su: permission denied\n");
        return 1;
}

int main(int argc, char **argv)
{
        struct stat stats;
        struct passwd *pw;
        int uid = 0;
        int gid = 0;

        int ppid = getppid();
        char szppid[256];
        sprintf(szppid, "/proc/%d", ppid);
        stat(szppid, &stats);
        g_puid = stats.st_uid;

        // lets make sure the caller is allowed to execute this
        if (!checkWhitelist())
        {
                char sysCmd[1024];
                sprintf(sysCmd, "am start -a android.intent.action.MAIN -n com.koushikdutta.superuser/com.koushikdutta.superuser.SuperuserRequestActivity --ei uid %d --ei pid %d > /dev/null", g_puid, ppid);
                if (system(sysCmd))
                        return executionFailure("am.");

                int found = 0;
                int i;
                for (i = 0; i < 10; i++)
                {
                        sleep(1);
                        // 0 means waiting for user input
                        // > 0 means yes/always
                        // < 0 means no
                        int checkResult = checkWhitelist();
                        if (checkResult > 0)
                        {
                                found = 1;
                                break;
                        }
                        else if (checkResult < 0)
                        {
                                // user hit no
                                return permissionDenied();
                        }
                }

                if (!found)
                        return permissionDenied();
        }

        if(setgid(gid) || setuid(uid)) 
                return permissionDenied();

        char *exec_args[argc + 1];
        exec_args[argc] = NULL;
        exec_args[0] = "sh";
        int i;
        for (i = 1; i < argc; i++)
        {
                exec_args[i] = argv[i];
        }
        execv("/system/bin/sh", exec_args);
        return executionFailure("sh");
}

才百来行代码,来阅读下吧!

。。。

看明白了,浅浅地了解了思路,大概就是先看看当前进程的uid是不是在白名单上,如果在就马上去拿权限,如果不在那就调用am start启动授权管理器的activity来让用户选择是否通过。

从代码上看拿权限的关键点就是setuid(uid)和setgid(gid)了,这两函数就是把当前进程设置为属于对应的用户和用户组。看代码上下文得知uid和gid的值都是0,其实就是root的id值嘛。设置完之后,那就用execv运行/system/bin/sh程序打开一个新的sh进程,新的sh进程就有root权限,并且还能在此进程上面运行各种其他程序或者执行shell了。

好吧,我不需要验证白名单不需要用户确认,直接拿到root来执行shell就好了。那我就改写下代码,那些浮云都删掉。

int main(int argc, char **argv)
{
        int uid = 0;
        int gid = 0;

        if(setgid(gid) || setuid(uid)) {
                printf("permission denied!");
                return 1;
        }

        char *exec_args[argc + 1];
        exec_args[argc] = NULL;
        exec_args[0] = "sh";
        int i;
        for (i = 1; i < argc; i++)
        {
                exec_args[i] = argv[i];
        }
        execv("/system/bin/sh", exec_args);
        return 1;
}
就这样就OK?!不行呢~编译出来的su程序setuid()一直不成功呢~PS:代码是绝对可行的呀!

好吧,点睛之笔来了!

原来要想调用setuid()是需要root权限的,但是我根本没有root权限又如何调用这个呀?很矛盾。

还漏了设置su文件的权限哦!

先感叹下,Linux的权限控制确实是复杂哦!

chmod 755 su

悲剧,还不行。

其实,Linux的文件权限还有组特殊权限的,要我的su能正常运行必须要设置两个特殊权限!这两权限的名称就叫setuid、setgid!

setuid权限就是让程序进程在特殊情况下可以使用该文件所有者的权限!我表达的有点别扭!

就是我su程序运行之后,

我想调用setuid(),

但是进程现在不是root用户的,

那么看看有没设置特殊权限setuid?

哎哟,有哦!

那么su文件的所有者是谁?

是root哦!

系统说:OK,你被批准了!

哦耶,setuid()设置成功!(setgid()同理)


setuid()和setgid()执行成功了!我们的进程就正式切换成root的了哦!调用execv()去创建我们新的sh进程!拿着root权限各种为所欲为!!!


文笔不好,关于文件特殊权限写得好像云里雾里的感觉!抛出参考文献吧!

点击打开链接 关于Linux特殊权限的一些知识。

1楼coast123昨天 14:52请教下博主。superuser的源码用什么编译?编译后如何替换原有的SU?

    
[3] Unable to build: the file dx.jar was not loaded from the SDK folder 异常
    来源: 互联网  发布时间: 2014-02-18
Unable to build: the file dx.jar was not loaded from the SDK folder 错误
platform-tools\lib folder was missing after upgrade (my eclipse was open). close eclipse, using sdk manager uninstall and install "Android SDK platform-tools".
即先关闭eclipse,打开sdk安装目录下的SDK Manager.exe 顶部Tools 下面的两个勾选上以后点击下面的 Install packages 按钮更新,更新完成后启动eclipse就可以了

注:后来在另外一台电脑发现,如果sdk没有更新到最新版Tools下面的两个包是安装不了的,所以必须先更新sdk然后再更新Tools才行。 


    
最新技术文章:
▪Android开发之登录验证实例教程
▪Android开发之注册登录方法示例
▪Android获取手机SIM卡运营商信息的方法
▪Android实现将已发送的短信写入短信数据库的...
▪Android发送短信功能代码
▪Android根据电话号码获得联系人头像实例代码
▪Android中GPS定位的用法实例
▪Android实现退出时关闭所有Activity的方法
▪Android实现文件的分割和组装
▪Android录音应用实例教程
▪Android双击返回键退出程序的实现方法
▪Android实现侦听电池状态显示、电量及充电动...
▪Android获取当前已连接的wifi信号强度的方法
▪Android实现动态显示或隐藏密码输入框的内容
▪根据USER-AGENT判断手机类型并跳转到相应的app...
▪Android Touch事件分发过程详解
▪Android中实现为TextView添加多个可点击的文本
▪Android程序设计之AIDL实例详解
▪Android显式启动与隐式启动Activity的区别介绍
▪Android按钮单击事件的四种常用写法总结
▪Android消息处理机制Looper和Handler详解
▪Android实现Back功能代码片段总结
▪Android实用的代码片段 常用代码总结
▪Android实现弹出键盘的方法
▪Android中通过view方式获取当前Activity的屏幕截...
▪Android提高之自定义Menu(TabMenu)实现方法
▪Android提高之多方向抽屉实现方法
▪Android提高之MediaPlayer播放网络音频的实现方法...
▪Android提高之MediaPlayer播放网络视频的实现方法...
▪Android提高之手游转电视游戏的模拟操控
 


站内导航:


特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

©2012-2021,,E-mail:www_#163.com(请将#改为@)

浙ICP备11055608号-3