Intent&Context&Manager&Listener

Intent&Context&Listener&Manager

  1. Intent数据类型
  2. Context区别
  3. Listener
  4. Manager
01.Intent携带的数据类型
  1. 8种基本数据类型以及数组形式以及String
  2. 实现了序列化接口的对象
    1. Serializable(Sun),声明为transient 的变量不会被序列化
    2. Parcelable(Google)

public class User implements Parcelable {
  private String name;
  private int age;
  public String getName() {
    return name;
  }
  public void setName(String name) {
    this.name = name;
  }
  public int getAge() {
    return age;
  }
  public void setAge(int age) {
    this.age = age;
  }
  /*
   * 必须声明:public static final Parcelable.Creator<User> CREATOR反序列化的
   */
  public static final Parcelable.Creator<User> CREATOR = new Parcelable.Creator<User>() {
    /*
     * 用于反序列,给你一个数据包,你把数据包中的数据拿出来,封装成一个对象,并返回
     */
    public User createFromParcel(Parcel in) {
      User user = new User();
      /*
       * 注意:一定按照序列化时的顺序读取
       */
      String name = in.readString();
      int age = in.readInt();
      user.setAge(age);
      user.setName(name);
      return user;
    }
    /*
     * 如果一个对象可以被序列化,那么这个对象的数组也能被序列化
     */
    public User[] newArray(int size) {
      return new User[size];
    }
  };
  // 用于序列化对象的,将需要序列化出去的属性写到数据包中即可
  @Override
  public void writeToParcel(Parcel dest, int flags) {
    dest.writeString(name);
    dest.writeInt(age);
  }
  @Override
  public int describeContents() {
    return 0;
  }
}

3. 前者序列化对象时会产生大量的临时文件,效率比较低后者效率高
02.Context的区别
  1. Activity 一个Activity对应一个Context
  2. Service 一个Service对应一个Context
  3. BroadCastReceiver中的onReceive(Context)方法执行完了了,这里的Context就完了
  4. 在内容提供者中获得上下文getContext()
  5. getApplicationContext()全局上下文
  6. 在fragment中可以通过getActivity()获得

Context

03.Listener
1. setOnItemClickListener()
2. button.setOnClickListener(OnClickListener);
3. button.setOnLongClickListener(OnClickListener);
4. checkBox.setOnCheckedChangeListener(listener);
5. listview.setOnItemClickListener(OnItemClickListener);
6. listview.setOnScrollListener(OnScrollListener);
7. imageView.setOnTouchListener()
8. fragment public void onHiddenChanged(boolean hidden) {}
9. setOnSeekBarChangeListener
10.OntouchListener
11.SeekBar.setOnSeekBarChangeListener(Listener)
04. Manager

01. smsManager

实现:发送短信


SmsManager smsManager = SmsManager.getDefault();
//发送短信是通过API 提供的短信管理器实现的
//通过SmsManager 的静态方法获取对象
SmsManager smsManager = SmsManager.getDefault();
//短信长度超过一定的限制后需要切割成多条分批发送
//一定要使用SmsManager 对象提供的divideMessage(String)方法切割
ArrayList<String> parts = smsManager.divideMessage(sms);
smsManager.sendMultipartTextMessage(num, null, parts, null, null);

02. TelephoneManager

实现:监听电话状态


TelephonyManager tm = (TelephonyManager) context.getSystemServer(Context.TELEPHONY_SERVICE);
//电话状态的监听
tm.listen(listener, PhoneStateListener.LISTEN_CALL_STATE);
//SIM卡的绑定:权限:android.permission.READ_PHONE_STATE
String simSerialNumber = tm.getSimSerialNumber();

03. connectivityManager
实现:获取网络状态


ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);

04. WindowManager

实现:获取屏幕的宽高


// 方式1:获取屏幕的宽高
DisplayMetrics metrics = context.getResources().getDisplayMetrics();
int widthPixels = metrics.widthPixels;
int heightPixels = metrics.heightPixels;
//方式2: Activity中获取屏幕的宽高,
Display display = getWindowManager().getDefaultDisplay();
int width = display.getWidth();
int height = display.getHeight();
//方式3:推荐该方式.
DisplayMetrics metrics =getWindowManager().getDefaultDisplay().getDisplayMetrics();
int widthPixels = metrics.widthPixels;
int heightPixels = metrics.heightPixels;

05. FragmentManager


FragmentManager fragmentManager = getSupportFragmentManager();

06. LocationManager GPS
实现:获取GPS位置服务


LocationManager lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
String provider = LocationManager.GPS_PROVIDER;

long minTime = 0;
float minDistance = 0;
lm.requestLocationUpdates(provider, minTime, minDistance, this);
public void onLocationChanged(Location location) {
    // 经度
    double longitude = location.getLongitude();
    // 纬度
    double latitude = location.getLatitude();
    System.out.println(
            "onLocationChanged:" + ",longitude:" + longitude + ",latitude:" + latitude);
}

protected void onPause() {
    super.onPause();
    // 取消监听, 节约资源
    lm.removeUpdates(this);
}

07. DevicePolicyManager

实现:获取设备管理员权限,锁屏,擦除数据


DevicePolicyManager dpm = (DevicePolicyManager) getSystemService(DEVICE_POLICY_SERVICE);

如用模拟器,请使用5.0以下版本测试一键锁屏

  • 实现 : 参考/docs/guide/topics/admin/device-admin.html页面

1. 创建一个DeviceAdminReceiver 的子类, 例如LockDeviceAdminReceiver

2. 在manifest文件中注册这个新创建的广播接收者,模板代码
    <receiver
        android:name="com.itheima.lockapp.LockDeviceAdminReceiver"
        android:description="@string/device_admin_description" // 本功能的描述, 需自己创建
        android:label="@string/app_name" // 软件名称
        android:permission="android.permission.BIND_DEVICE_ADMIN" >
        <meta-data
            android:name="android.app.device_admin"
            android:resource="@xml/device_admin" /> // 该文件用来声明本软件所要使用的安全策略, 需自己创建文件
        <intent-filter>
            <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
        </intent-filter>
    </receiver>

>
3. 在res目录下, 新建一个目录,名为xml, 在xml目录下新建一个xml文件, 文件名必须和manifest文件中声明的receiver的android:resource节点值一致. 文件内容如下, 需根据实际业务需要进行增删




















>
4. 实现功能, 监听状态
public class MainActivity extends Activity {
private static final int REQUEST_CODE_ENABLE_ADMIN = 100;
private DevicePolicyManager dpm;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 获取设备策略管理器
dpm = (DevicePolicyManager) getSystemService(DEVICE_POLICY_SERVICE);
// 创建自定义Receiver的唯一标识
ComponentName admin = new ComponentName(this, LockDeviceAdminReceiver.class);
// 判断自定义的Receiver是否已经被激活
boolean isAdaminActive = dpm.isAdminActive(admin);
// 如果已经被激活,直接锁屏并关闭当前页面
if (isAdaminActive) {
dpm.lockNow();
finish();
} else {
// 如果没有被激活,弹窗提示用户去激活系统管理员
Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, admin);
intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION,
getString(R.string.device_admin_description));
startActivityForResult(intent, REQUEST_CODE_ENABLE_ADMIN);
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_CODE_ENABLE_ADMIN) {
// 激活成功, 锁屏并关闭当前页面
if (resultCode == Activity.RESULT_OK) {
dpm.lockNow();
finish();
// 激活失败, 直接退出
} else if (resultCode == Activity.RESULT_CANCELED) {
finish();
}
}
}
}

* 需求 : 激活系统管理员以后直接卸载程序, 不弹出警告窗口
* 实现 : 判断当前软件是否已经激活系统管理员, 如果激活了, 先取消. 之后调用隐式意图卸载程序
* 代码 : 

public class UninstallActivity extends Activity {
    private DevicePolicyManager dpm;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_uninstall);
        // 获取设备策略管理器
        dpm = (DevicePolicyManager) getSystemService(DEVICE_POLICY_SERVICE);
        // 创建自定义Receiver的唯一标识
        ComponentName admin = new ComponentName(this, LockDeviceAdminReceiver.class);
        // 判断自定义的Receiver是否已经被激活
        boolean isAdaminActive = dpm.isAdminActive(admin);
        // 如果激活了, 先取消设备管理器
        if (isAdaminActive) {
            dpm.removeActiveAdmin(admin);
        }
        // 发送隐式意图,卸载当前应用
        Intent intent = new Intent();
        intent.setAction(Intent.ACTION_DELETE);
        intent.addCategory(Intent.CATEGORY_DEFAULT);
        intent.setData(Uri.parse("package:" + getPackageName()));
        startActivity(intent);
        finish();
    }
}
// manifest文件
<activity
    android:name=".UninstallActivity"
    android:label="一键卸载"
    android:launchMode="singleInstance" >
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />

        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

* 需求 : 实现远程擦除数据和锁屏的功能
* 实现 : 通过DevicePolicyManager的wipeData()方法和lockNow()实现
* 代码 :

DevicePolicyManager dpm = (DevicePolicyManager) context
        .getSystemService(Context.DEVICE_POLICY_SERVICE);
dpm.wipeData(DevicePolicyManager.WIPE_EXTERNAL_STORAGE);
abortBroadcast();
DevicePolicyManager dpm = (DevicePolicyManager) context
        .getSystemService(Context.DEVICE_POLICY_SERVICE);
//设置密码.
dpm.resetPassword("123", DevicePolicyManager.RESET_PASSWORD_REQUIRE_ENTRY);

08. ActivityManager

实现:查询当前运行的服务,正在运行的进程,内存使用情况,杀死进程


ActivityManager am = (ActivityManager) context .getSystemService(Context.ACTIVITY_SERVICE);
//获取服务的状态
public static boolean isServiceRunning(Context context,
        Class<? extends Service> clazz) {
    boolean flag = false;
    // 获取ActivityManager
    ActivityManager am = (ActivityManager) context
            .getSystemService(Context.ACTIVITY_SERVICE);
    // 获取正在运行的服务
    List<RunningServiceInfo> lis = am.getRunningServices(Integer.MAX_VALUE);
    // 遍历集合
    for (RunningServiceInfo info : lis) {
        // 获取服务的名字
        String className = info.service.getClassName();
        // 如果有服务和我们的服务名字一致, 说明正在运行
        if (className.equals(clazz.getName())) {
            flag = true;
        }
    }
    return flag;
}


**不能在Android5.0以上机器使用以下代码**
* 正在运行的进程可以通过ActivityManager.getRunningAppProcesses()方法获得

* 内存使用情况可以通过ActivityManager.getMemoryInfo()方法获取

ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
List<RunningAppProcessInfo> runningAppProcesses = am.getRunningAppProcesses();
// 获取总共可运行内存个数
PackageManager pm = getPackageManager();

## 0902_版本适配获得内存信息
* 需求 :  判断当前系统的版本, 对于低版本系统使用读取系统文件的方式获取总内存大小
* 实现 : * 读取系统的/proc/meminfo文件获取内存信息
private void initRam() {
    // 获取内存信息
    MemoryInfo outInfo = new MemoryInfo();
    am.getMemoryInfo(outInfo);
    //可用内存
    long availMem = outInfo.availMem;
    long totalMem = 0;
    int sdkInt = Build.VERSION.SDK_INT;
    // 高版本系统,直接读取
    if (sdkInt >= Build.VERSION_CODES.JELLY_BEAN) {
        totalMem = outInfo.totalMem;
    } else {
        // 低版本系统读取系统文件
        File file = new File("/proc/meminfo");
        BufferedReader br = null;
        try {
            br = new BufferedReader(new FileReader(file));
            String readLine = br.readLine();
            readLine = readLine.replace("MemTotal:", "");
            readLine = readLine.replace("kB", "");
            readLine = readLine.trim();
            totalMem = Long.valueOf(readLine) * 1024;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            close(br);
        }

    }
//已用内存
long usedMem = totalMem - availMem;
//
private void initAdapter() {
    ArrayList<AppRAMBean> list = new ArrayList<AppRAMBean>();
    // 遍历所有正在运行的进程
    for (RunningAppProcessInfo info : runningAppProcesses) {
        AppRAMBean bean = new AppRAMBean();
        // 获取包名
        String pkgName = info.processName;
        // 获取应用图标.如果有就用应用自己的,没有就用默认的
        try {
            Drawable icon = packageManager.getApplicationIcon(pkgName);
            bean.icon = icon;
        } catch (NameNotFoundException e) {
            bean.icon = getResources().getDrawable(R.drawable.ic_launcher);
            e.printStackTrace();
        }

        try {
            ApplicationInfo applicationInfo = packageManager.getApplicationInfo(pkgName, 0);
            // 获取应用的名称
            CharSequence applicationLabel = packageManager.getApplicationLabel(applicationInfo);
            bean.name = applicationLabel.toString();
            // 获取是否是系统应用
            int flag = applicationInfo.flags;
            if ((flag & ApplicationInfo.FLAG_SYSTEM) == ApplicationInfo.FLAG_SYSTEM) {
                bean.isSystem = true;
            } else {
                bean.isSystem = false;
            }
        } catch (NameNotFoundException e) {
            e.printStackTrace();
        }
        // 获取当前进程所占用的内存信息
        int pid = info.pid;
        android.os.Debug.MemoryInfo processMemoryInfo =
                activityManager.getProcessMemoryInfo(new int[] {pid})[0];
        int totalPss = processMemoryInfo.getTotalPss();
        bean.usedRam = totalPss*1024
    }
}

* 实现 : 清理进程的方法 ActivityManager.killBackgroundProcesses(String pkgName). 
* 杀死后台进程要添加权限 android.permission.KILL_BACKGROUND_PROCESSES

09. AssetsManager 获取资产目录路径


getAssets

10. PackageManager

实现:版本信息,应用信息,包名,总进程数

  • 1.获取版本信息,应用的信息:名称,图标,安装路径,包名,UID(获取流量).2.判断安装位置.判断系统应用,
  • 3.通过包名,打开程序,卸载程序,打开应用详情页面.4.通过文件的路径,可以跳转安装程序页面.

PackageManager pm = context.getPackageManager();

// 获取当前包的版本号,可用于升级.
PackageInfo packageInfo = pm.getPackageInfo(context.getPackageName(), 0);
String versionName = packageInfo.versionName;

// 获取当前手机安装的所有应用信息
List<ApplicationInfo> list = pm.getInstalledApplications(0);
for (ApplicationInfo info : list) {
    // 获取应用的名称
    CharSequence applicationLabel = pm.getApplicationLabel(info);

    // 获取应用的图标
    Drawable icon = pm.getApplicationIcon(info);

    // 获取应用的安装路径
    String sourceDir = info.sourceDir;
    File file = new File(sourceDir);
    // 获取包名
    bean.pkgName = info.packageName;

    // 获去应用的uid,可用于统计流量
    int uid = info.uid;

    // 获取应用的大小
    long totalSpace = file.length();
    bean.size = Formatter.formatFileSize(this, totalSpace);

    // 判断应用的安装位置
    if (sourceDir.startsWith("/mnt/asec")) {
        bean.isOnSD = true;
    } else {
        bean.isOnSD = false;
    }
}

//判断出程序是否是系统程序
// 方法一 : 判断ApplicationInfo.sourceDir 是否以"/system" 开头
if (sourceDir.startsWith("/system")) {
    bean.isSystemApp = true;
} else {
    bean.isSystemApp = false;
}

//方法二 : 判断ApplicationInfo.FLAG_SYSTEM与运算的结果
int flags = info.flags;

if ((flags & ApplicationInfo.FLAG_SYSTEM) == ApplicationInfo.FLAG_SYSTEM) {
    bean.isSystemApp = true;
} else {
    bean.isSystemApp = false;
}

// 跳转应用信息详情界面,包名
 Intent intent = new Intent();
 intent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS");
 intent.addCategory("android.intent.category.DEFAULT");
 intent.setData(Uri.parse("package:" + itemBean.pkgName));
 startActivity(intent);

//打开程序,包名
intent = getPackageManager().getLaunchIntentForPackage(itemBean.pkgName);
startActivity(intent); 

//安装程序,文件的目录
Intent intent = new Intent();
intent.setAction("android.intent.action.VIEW");
intent.addCategory("android.intent.category.DEFAULT");
intent.setDataAndType(Uri.parse("file:" + file.getAbsolutePath()),
        "application/vnd.android.package-archive");
startActivityForResult(intent, REQ_CODE_INSTALL_APP);

// 卸载应用,包名
Uri packageURI = Uri.parse("package:" + itemBean.pkgName);
Intent uninstallIntent = new Intent(Intent.ACTION_DELETE, packageURI);
startActivity(uninstallIntent);

// 注册广播,拿到卸载应用的包名
receiver = new UninstallReceiver();
IntentFilter filter = new IntentFilter();
filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
filter.addDataScheme("package");
registerReceiver(receiver, filter);
// 广播类
class UninstallReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        //获得广播的内容,package:+ 包名
        String dataString = intent.getDataString();
        //拿到包名
        dataString = dataString.replace("package:", "");
    }
}
  • 需求 : 获取流量使用的详细数据. 此功能只能在低版本手机上测试,不能使用模拟器
  • 实现 :
    • 默认情况下,每一个应用的流量使用情况都会储存在”/proc/uid_stat/uid/”目录下的两个文件中,tcp_rcv文件记录收到的流量,tcp_snd文件记录发送的流量.此方法获取的数据比较准确,但是在高版本手机上无法读取到这两个文件.在改版的手机上因为目录可能被更改,也会导致无法使用
    • 通过TrafficStats.getUidRxBytes获取收到的流量,通过TrafficStats.getUidTxBytes获取发送的流量,但是这种方法获取的数据并不准确

PackageManager pm = getPackageManager();
List<ApplicationInfo> lists = pm.getInstalledApplications(0);
for (ApplicationInfo info : lists) {
    //获取应用的标识符uid
    int uid = info.uid;
    // 此方法获取的数据并不准确
    long uidRxBytes = TrafficStats.getUidRxBytes(uid);
    long uidTxBytes = TrafficStats.getUidTxBytes(uid);

// 此方法比较准确,但是在高版本手机上无法使用.
// 在改版的手机上因为目录可能被更改,也会导致无法使用
private long getReceive(int uid) {
    //收到的流量
    File file = new File("/proc/uid_stat/" + uid + "/tcp_rcv");
    //发送的流量
    //File file = new File("/proc/uid_stat/" + uid + "/tcp_snd");
    BufferedReader br = null;
    try {
        br = new BufferedReader(new FileReader(file));
        String readLine = br.readLine();
        return Long.valueOf(readLine);
    } catch (Exception e) {
        e.printStackTrace();
        return 0;
    } finally {
        if (br != null) {
            try {
                br.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            br = null;
        }
    }


**不能在Android5.0以上机器使用以下代码**
* 总进程数可以通过PackageManager.getInstalledPackages(0)方法的返回值获取
// 获取手机上所有已安装的应用
List<PackageInfo> installedPackages = pm.getInstalledPackages(0);
// 创建集合
Set<String> set = new HashSet<String>();
for (PackageInfo packageInfo : installedPackages) {
    // 获取所有Application节点的processName
    String processName = packageInfo.applicationInfo.processName;
    set.add(processName);
    // 获取所有Activity节点的processName
    ActivityInfo[] activities = packageInfo.activities;
    if (activities != null) {
        for (ActivityInfo activityInfo : activities) {
            String processName2 = activityInfo.processName;
            set.add(processName2);
        }
    }
    // 获取所有Service节点的processName
    ServiceInfo[] services = packageInfo.services;
    if (services != null) {
        for (ServiceInfo serviceInfo : services) {
            set.add(serviceInfo.processName);
        }
    }
    // 获取所有receiver节点的processName
    ActivityInfo[] receivers = packageInfo.receivers;
    if (receivers != null) {
        for (ActivityInfo activityInfo : receivers) {
            set.add(activityInfo.processName);
        }
    }
    // 获取所有Provider节点的processName
    ProviderInfo[] providers = packageInfo.providers;
    if (providers != null) {
        for (ProviderInfo providerInfo : providers) {
            set.add(providerInfo.processName);
        }
    }
    ssv_num.setFreeText("可运行" + set.size() + "个");
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值