接上android来去电显示并增添自定义数据库(类似360通话)

安卓apk360加固 一、配置AS 官网: https://jiagu.360.cn/#/global/index 1:下载后,把这个jiagu文件放到项目根目录下 2:然后在创建 360protect.gradle文件 /** -login 首次使用必须先登录 <360用户名> <password> <登录密码> -importsign <k 阅读详情


好了,电话来去电的显示功能完成了,接下来就是对本地通讯录的数据抓取与同步的功能,在同步的方面我只做到了一半就是自定义数据库与本地数据库的同步,反向的则有些麻烦,还需要一段时间的研究。


开始吧。在上文中有一个自定义类是UserInfo,把他当做我们自定义数据库的单个数据:


<span style="white-space:pre">	</span>// id
	private int _id;

	// 名字
	private String name;
	
	// 号码
	private String phoneNum;
	
	// 部门
	private String department;
	
	// 具体职位
	private String job;

这是里面的所需要的数据库的列。根据这个是用SQLiteOpenHelper来继承并创建数据库,在创建一个DBUtils类来对该自定义联系人数据库进行增,删, 改,查。这是对自定义数据库的创建与操作的两个类。

SQLiteOpenHelper------->create table booklist(_id integer primary key autoincrement,name,phonenum,department,job)


还有一个是对本地联系人数据库的增,删,改的操作的类(DBPhoneUtils)。


另外在该程序第一次进入的时候需要导入本地联系人数据库。于是代码如下:


<span style="white-space:pre">		</span>public static void getSystemContacts(Context context, DBUtils dbUtils) {
			
			UserInfo userInfo = null;
			
			String contactsID;
			Cursor cursor = context.getContentResolver().query(phoneUris[0], null, null, null,
					null);
			while (cursor.moveToNext()) {
				userInfo = new UserInfo();
				contactsID = cursor.getString(cursor
						.getColumnIndex(ContactsContract.Contacts._ID));
				String userName = cursor.getString(cursor
						.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
				userInfo.setName(userName);
				Cursor cursor2 = context.getContentResolver().query(
						phoneUris[1],
						null,
						ContactsContract.CommonDataKinds.Phone.CONTACT_ID + "="
								+ contactsID, null, null);
				while (cursor2.moveToNext()) {
					String userPhone = cursor2
							.getString(cursor2
									.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
					userInfo.setPhoneNum(userPhone);

				}
				cursor2.close();
				
				// 添加到自己的数据库中
				dbUtils.insertData(userInfo.getName(), userInfo.getPhoneNum(),
						null, null);

			}
		}

在第一次没有发现自定义数据库的时候导入本地联系人数据库。


结束后需要把自定义联系人数据库的内容使用listview来展示:


<span style="white-space:pre">		</span>listView = (ListView) findViewById(R.id.listview);


		// 游标适配器初始化
		cursorAdapter = new SimpleCursorAdapter(this, R.layout.activity_item,
				dbUtils.getCursor(), new String[] { "name", "phonenum" },
				new int[] { R.id.userName, R.id.userPhone },
				CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);

		listView.setAdapter(cursorAdapter)

使用游标适配器很好的与数据库结合使用,速度更快。而DBUtils是一个对自定义联系人数据库的帮助类,但是数据量太大,我们一点点来讲:

<span style="white-space:pre">	</span>// 得到数据库的起始游标
	public Cursor getCursor() {
		Cursor cursor = bookListDB.getReadableDatabase().query("booklist",
				null, null, null, null, null, null);
		
		return cursor;
	}

这是得到自定义联系人数据库的起始游标,然后使用SimpleCursorAdapter来展示。


我的整个实现代码思想是这样的,现对自定义数据库进行处理(增删改查),然后同时对本地数据库进行处理(增删改)。所达成同步效果,所以整体是以 主函数 --> 嵌套 --> 自定义数据库 --> 嵌套 --> 本地数据库 来进行处理。


在对自定义数据库帮助类的创建与处理上使用了单例(DBUtils代码如下):


public class DBUtils {

	private BookListDB bookListDB;
	private Context context;

	private static DBUtils dbUtils;
	private DBPhoneUtils dbPhoneUtils;

	public DBUtils(Context context) {
		bookListDB = new BookListDB(context);
		dbPhoneUtils = new DBPhoneUtils(context);
		this.context = context;
	}

	public static DBUtils getInstance(Context context) {
		if (dbUtils == null) {
			dbUtils = new DBUtils(context);
		}
		return dbUtils;
	}

	// 添加数据
	public void insertData(String name, String phonenum,
			String department, String job) {
		SQLiteDatabase dbDatabase = bookListDB.getReadableDatabase();

		// 添加自定义数据库信息
		if (!TextUtils.isEmpty(department) && !TextUtils.isEmpty(job)) {
			dbDatabase
					.execSQL(
							"insert into booklist(name,phonenum,department,job) values(?,?,?,?)",
							new Object[] { name, phonenum, department, job });
		} else {
			dbDatabase
					.execSQL(
							"insert into booklist(name,phonenum,department,job) values(?,?,?,?)",
							new Object[] { name, phonenum, "未填写", "未填写" });
		}
		
		// 添加手机数据库信息
		dbPhoneUtils.insertPhone(name, phonenum);

		dbDatabase.close();
	}

	// 修改数据
	public void updateData(String oldName, int _id, String name, String phonenum,
			String department, String job) {
		SQLiteDatabase dbDatabase = bookListDB.getReadableDatabase();
		ContentValues values = new ContentValues();
		values.put("name", name);
		values.put("phonenum", phonenum);
		values.put("department", department);
		values.put("job", job);
		
		// 修改自定义数据库信息
		dbDatabase.update("booklist", values, "_id=?", new String[]{_id+""});
		
		// 修改手机数据库信息
		dbPhoneUtils.updatePhone(oldName, name, phonenum);
		
		dbDatabase.close();
	}

	// 删除数据
	public void delData(int _id, String name) {
		SQLiteDatabase dbDatabase = bookListDB.getReadableDatabase();
		
		// 删除自定义数据库信息
		dbDatabase.delete("booklist", "_id=?", new String[]{_id+""});
		
		// 删除手机数据库信息
		dbPhoneUtils.deletePhone(name);
		
		dbDatabase.close();
	}

	// 查询数据
	public UserInfo selectInfo(String phoneNum) {
		UserInfo userInfo = null;

		SQLiteDatabase dbDatabase = bookListDB.getReadableDatabase();

		Cursor cursor = dbDatabase.query("booklist", null, "phonenum = ?",
				new String[] { phoneNum }, null, null, null);

		if (cursor == null) {
		} else {

			if (cursor.moveToFirst()) {

				userInfo = new UserInfo();

				userInfo.set_id(cursor.getInt(cursor.getColumnIndex("_id")));
				userInfo.setName(cursor.getString(cursor.getColumnIndex("name")));
				userInfo.setPhoneNum(cursor.getString(cursor
						.getColumnIndex("phonenum")));
				userInfo.setDepartment(cursor.getString(cursor
						.getColumnIndex("department")));
				userInfo.setJob(cursor.getString(cursor.getColumnIndex("job")));

			} else {
				Toast.makeText(context, "数据不存在", Toast.LENGTH_SHORT).show();
			}
		}
		cursor.close();
		dbDatabase.close();
		
		return userInfo;
	}
	
	// 得到数据库的起始游标
	public Cursor getCursor() {
		Cursor cursor = bookListDB.getReadableDatabase().query("booklist",
				null, null, null, null, null, null);
		
		return cursor;
	}

	// 得到通讯录总人数
	public int getCount() {
		Cursor cursor = bookListDB.getReadableDatabase().query("booklist",
				null, null, null, null, null, null);

		int count = cursor.getCount();
		cursor.close();

		return count;

	}
}

其中在一些判断上只是为了保证用户输入的完整性,所以没什么太大用处。最后是在打开游标,数据库的时候要及时关闭以保证内存及时释放减少消耗。另外在几条代码中会有添加手机数据库等等注释就是为了同步本地数据库的方法:


public class DBPhoneUtils {

	private Context context;

	public DBPhoneUtils(Context context) {
		this.context = context;
	}

	// 增
	public void insertPhone(String name, String phoneNum) {
		try {
			ContentValues values = new ContentValues();

			// 下面的操作会根据RawContacts表中已有的rawContactId使用情况自动生成新联系人的rawContactId
			Uri rawContactUri = context.getContentResolver().insert(
					RawContacts.CONTENT_URI, values);
			long rawContactId = ContentUris.parseId(rawContactUri);

			// 向data表插入姓名数据
			if (name != "") {
				values.clear();
				values.put(Data.RAW_CONTACT_ID, rawContactId);
				values.put(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);
				values.put(StructuredName.GIVEN_NAME, name);
				context.getContentResolver().insert(
						ContactsContract.Data.CONTENT_URI, values);
			}

			// 向data表插入电话数据
			if (phoneNum != "") {
				values.clear();
				values.put(Data.RAW_CONTACT_ID, rawContactId);
				values.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
				values.put(Phone.NUMBER, phoneNum);
				values.put(Phone.TYPE, Phone.TYPE_MOBILE);
				context.getContentResolver().insert(
						ContactsContract.Data.CONTENT_URI, values);
			}

			// 向data表插入Email数据
			// if (work_email != "") {
			// values.clear();
			// values.put(Data.RAW_CONTACT_ID, rawContactId);
			// values.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
			// values.put(Email.DATA, work_email);
			// values.put(Email.TYPE, Email.TYPE_WORK);
			// context.getContentResolver().insert(ContactsContract.Data.CONTENT_URI,
			// values);
			// }

			// 向data表插入QQ数据
			// if (im_qq != "") {
			// values.clear();
			// values.put(Data.RAW_CONTACT_ID, rawContactId);
			// values.put(Data.MIMETYPE, Im.CONTENT_ITEM_TYPE);
			// values.put(Im.DATA, im_qq);
			// values.put(Im.PROTOCOL, Im.PROTOCOL_QQ);
			// context.getContentResolver().insert(ContactsContract.Data.CONTENT_URI,
			// values);
			// }

			// 向data表插入头像数据
			// Bitmap sourceBitmap =
			// BitmapFactory.decodeResource(context.getResources(),
			// R.drawable.icon);
			// final ByteArrayOutputStream os = new ByteArrayOutputStream();
			// // 将Bitmap压缩成PNG编码,质量为100%存储
			// sourceBitmap.compress(Bitmap.CompressFormat.PNG, 100, os);
			// byte[] avatar = os.toByteArray();
			// values.put(Data.RAW_CONTACT_ID, rawContactId);
			// values.put(Data.MIMETYPE, Photo.CONTENT_ITEM_TYPE);
			// values.put(Photo.PHOTO, avatar);
			// context.getContentResolver().insert(ContactsContract.Data.CONTENT_URI,
			// values);
		}

		catch (Exception e) {

		}
	}

	// 删
	public void deletePhone(String name) {
		// 根据姓名求id
		Uri uri = Uri.parse("content://com.android.contacts/raw_contacts");
		ContentResolver resolver = context.getContentResolver();
		Cursor cursor = resolver.query(uri, new String[] { Data._ID },
				"display_name=?", new String[] { name }, null);
		if (cursor.moveToFirst()) {
			int id = cursor.getInt(0);
			// 根据id删除data中的相应数据
			resolver.delete(uri, "display_name=?", new String[] { name });
			uri = Uri.parse("content://com.android.contacts/data");
			resolver.delete(uri, "raw_contact_id=?", new String[] { id + "" });
		}
	}

	// 改
	public void updatePhone(String oldName, String newName, String newPhoneNum) {
		// 根据姓名求id
		Uri uri = Uri.parse("content://com.android.contacts/raw_contacts");
		ContentResolver resolver = context.getContentResolver();
		Cursor cursor = resolver.query(uri, new String[] { Data._ID },
				"display_name=?", new String[] { oldName }, null);

		if (cursor.moveToFirst()) {

			int id = cursor.getInt(0);

			Uri uri2 = Uri.parse("content://com.android.contacts/data");// 对data表的所有数据操作

			// 修改电话
			ContentValues values = new ContentValues();
			values.put("data1", newPhoneNum);
			context.getContentResolver()
					.update(uri2,
							values,
							"mimetype=? and raw_contact_id=?",
							new String[] { "vnd.android.cursor.item/phone_v2",
									id + "" });

			// 修改姓名
			values.clear();
			values = new ContentValues();
			values.put("data1", newName);
			context.getContentResolver().update(uri2, values,
					"mimetype=? and raw_contact_id=?",
					new String[] { "vnd.android.cursor.item/name", id + "" });
		}
	}

	// 查
	public void selectPhone() {

	}

}

这是对本地数据库的增删改的帮助类。


而作为这个程序的其实位置MainActivity我使用上下文的方法按住跳出dialog框来对数据库的增删改查以及打电话。这个代码量就太大了(Dialog):

// 列表中点击的id及该界面
	private View views;

	// 上下文菜单
	@Override
	public void onCreateContextMenu(ContextMenu menu, View v,
			ContextMenuInfo menuInfo) {
		super.onCreateContextMenu(menu, v, menuInfo);

		getMenuInflater().inflate(R.menu.menu_context_item, menu);

		AdapterContextMenuInfo acmi = (AdapterContextMenuInfo) menuInfo;

		views = acmi.targetView;

	}

	// 数据增删改处理
	@Override
	public boolean onContextItemSelected(MenuItem item) {

		// 得到位置id
		int id = item.getItemId();

		// 图片所有内容初始化
		View view = View.inflate(this, R.layout.window_add, null);
		final EditText nameEditText = (EditText) view
				.findViewById(R.id.add_name);
		final EditText phonenumEditText = (EditText) view
				.findViewById(R.id.add_phonenum);
		final EditText departmentEditText = (EditText) view
				.findViewById(R.id.add_department);
		final EditText jobEditText = (EditText) view.findViewById(R.id.add_job);

		// 上下文点击位置
		TextView textView = (TextView) views.findViewById(R.id.userPhone);

		// 修改前将原有数据放置上去, 并通过其_Id来修改用户数据
		userInfo = dbUtils.selectInfo(textView.getText().toString() + "");

		switch (id) {
		case R.id.insert:

			// 弹出增添联系人框
			AlertDialog alertDialog = new AlertDialog.Builder(this)
					.setTitle("增加联系人").setView(view)
					.setPositiveButton("增加", new OnClickListener() {

						@Override
						public void onClick(DialogInterface dialog, int which) {
							String nameString = nameEditText.getText()
									.toString();
							String phonenumString = phonenumEditText.getText()
									.toString();
							String departmentString = departmentEditText
									.getText().toString();
							String jobString = jobEditText.getText().toString();
							if (!TextUtils.isEmpty(nameString)
									&& !TextUtils.isEmpty(phonenumString)
									&& !TextUtils.isEmpty(departmentString)
									&& !TextUtils.isEmpty(jobString)) {

								// 数据库添加
								dbUtils.insertData(nameString, phonenumString,
										departmentString, jobString);

							} else if (TextUtils.isEmpty(departmentString)
									|| TextUtils.isEmpty(jobString)) {

								// 数据库添加
								dbUtils.insertData(nameString, phonenumString,
										null, null);

							} else {

								// 数据未填写完整提示
								Toast.makeText(MainActivity.this, "请填写完整",
										Toast.LENGTH_SHORT).show();
							}

							// 刷新列表
							cursorAdapter.changeCursor(dbUtils.getCursor());

						}
					}).setNegativeButton("取消", new OnClickListener() {

						@Override
						public void onClick(DialogInterface dialog, int which) {
							dialog.dismiss();
						}
					}).create();
			alertDialog.show();

			break;

		case R.id.update:

			nameEditText.setText(userInfo.getName());
			phonenumEditText.setText(userInfo.getPhoneNum());
			departmentEditText.setText(userInfo.getDepartment());
			jobEditText.setText(userInfo.getJob());

			// 弹出修改联系人框
			AlertDialog alertDialog2 = new AlertDialog.Builder(this)
					.setTitle("修改联系人").setView(view)
					.setPositiveButton("修改", new OnClickListener() {

						@Override
						public void onClick(DialogInterface dialog, int which) {

							// 用户输入数据
							String nameString = nameEditText.getText()
									.toString();
							String phonenumString = phonenumEditText.getText()
									.toString();
							String departmentString = departmentEditText
									.getText().toString();
							String jobString = jobEditText.getText().toString();

							if (!TextUtils.isEmpty(nameString)
									&& !TextUtils.isEmpty(phonenumString)
									&& !TextUtils.isEmpty(departmentString)
									&& !TextUtils.isEmpty(jobString)) {

								// 数据库修改
								dbUtils.updateData(userInfo.getName(), userInfo.get_id(),
										nameString, phonenumString,
										departmentString, jobString);

							} else {

								// 数据未填写完整提示
								Toast.makeText(MainActivity.this, "请填写完整",
										Toast.LENGTH_SHORT).show();
							}

							// 刷新列表
							cursorAdapter.changeCursor(dbUtils.getCursor());

						}
					}).setNegativeButton("取消", new OnClickListener() {

						@Override
						public void onClick(DialogInterface dialog, int which) {
							dialog.dismiss();
						}
					}).create();
			alertDialog2.show();

			break;

		case R.id.delet:

			AlertDialog alertDialog3 = new AlertDialog.Builder(this)
					.setTitle("删除联系人")
					.setMessage("是否删除联系人:\n\n\t" + userInfo.getName())
					.setPositiveButton("删除", new OnClickListener() {

						@Override
						public void onClick(DialogInterface dialog, int which) {

							// 数据库删除
							dbUtils.delData(userInfo.get_id(), userInfo.getName());

							// 刷新列表
							cursorAdapter.changeCursor(dbUtils.getCursor());
						}
					}).setNegativeButton("取消", new OnClickListener() {

						@Override
						public void onClick(DialogInterface dialog, int which) {
							dialog.dismiss();
						}
					}).create();
			alertDialog3.show();

			break;

		case R.id.select:

			AlertDialog alertDialog4 = new AlertDialog.Builder(this)
					.setTitle("联系人:" + userInfo.getName())
					.setMessage(
							"姓名:" + userInfo.getName() + "\n电话:"
									+ userInfo.getPhoneNum() + "\n部门:"
									+ userInfo.getDepartment() + "\n职位:"
									+ userInfo.getJob())
					.setPositiveButton("拨打电话", new OnClickListener() {

						@Override
						public void onClick(DialogInterface dialog, int which) {
							Intent intent = new Intent();
							intent.setAction(Intent.ACTION_CALL);
							intent.setData(Uri.parse("tel:"
									+ userInfo.getPhoneNum()));
							startActivity(intent);
						}
					}).setNegativeButton("关闭", new OnClickListener() {

						@Override
						public void onClick(DialogInterface dialog, int which) {
							dialog.dismiss();
						}
					}).create();
			alertDialog4.show();

			break;

		}

		return super.onContextItemSelected(item);
	}

在结束整个程序后发现有很多不好的方法,比如可以使用本地数据库的ID导入到自定义数据库,这样可以在后续的处理中可以调用这个ID来直接处理本地数据库而不需要通过名字来找到ID在对该ID来处理本地数据库了。还有就是SIM卡和手机本地的区分,要往里面走的话就很多很多要学习的了,技术不佳..............


有任何建议,意见,及帮助请留言,相互学习!!!





安卓开发360扫描出现病毒“盗号木马” 安装开发项目,之前的版本没有问题。 debug调试的时候,也没有发现问题。 签名打包的时候, 360扫描apk出现病毒“盗号木马” 提示:使用与软件本身属性不符的风险权限 如下图所示: 发生的原因: 经过各种情况的测验,有如下发现: 1. 签名:用原始keystore签名,360报木马。怀疑是原始keystore感染木马,于是创建了一 阅读详情

相关推荐

android系统定制三:Dialer禁止系统拉起来去电页面(InCallActivity);

Dialer禁止系统拉起来去电页面

qq_20395637的博客 815

android 向系统插入一条通话记录

/** * 插入一条通话记录 * @param number 通话号码 * @param duration 通话时长(响铃时长)以秒为单位 1分30秒则输入90 * @param type 通话类型 1呼入 2呼出 3未接 * @param isNew 是否已查看 0已看1未看 */ private void inse

JohnLiu的博客 7850

实现安卓360波浪效果进度条的设计与实践

进度条是一种常见的用户界面元素,用于显示操作进度的完成情况,它在应用和系统中扮演着至关重要的角色。本质上,进度条的主要功能是通过视觉反馈减少用户的等待焦虑,增强体验感。具体作用可以细分为以下几点:提供进度反馈:当用户发起一个可能需要较长时间才能完成的操作(如文件下载、数据加载等),进度条能够显示从0%到100%的完成进度,让用户知道何时可以使用或继续下一步。心理暗示:进度条能够通过不断更新的进度视觉效果,暗示用户系统仍在工作,减少用户因长时间等待而产生的焦虑感。引导注意力。

weixin_32098457的博客 1255

android自定义数据,在Android上录制时添加自定义数据

通过Recording&Playback API,您可以记录会话并使用它来代替实时摄像机供稿。但是,这些记录仅包含视频和传感器数据。您还可以将自定义数据添加到会话记录中,并在回放过程中将数据返回给您,就好像它是相机图像的一部分一样。ARCore不会在录音中自动包括任何自定义数据。相反,它允许您在记录过程中将自定义数据添加到ARCore框架,并在回放过程中从框架中检索相同的数据。取决于您对应用程序进...

weixin_30025473的博客 321

创建来电归属地数据库专用,个人私用!

创建来电归属地数据库专用,个人私用!

android替换来电页面

Android替换系统来电页面,支持自定义图片,视频,屏幕锁定时可自动唤醒

关于android电话监听显示(类似360通话)

自己琢磨了很久,也查了很多资料。 首先我没有使用BroadcastReceiver,因为在使用广播监听来去点的时候手机会发送多次广播,所以接受并处理会非常麻烦与危险。虽然可以解决来电,但是去电的时候发现并没有相关api,因为android将其隐藏了,CallManager应该是这个类,虽然没有试过。但是在去电结束后又会被来电的监听器接受到挂断的信息,于是又是一个问题。所以我抛弃了Broa

羊羊的学习旅程 1076

从CCD数据上报看wxHOOK的封号风险与规避

本文深入分析了微信CCD数据上报机制对wxHOOK的检测逻辑与封号风险,揭示了调试器路径暴露、非白名单DLL加载和内存校验失败等关键风险点。通过实战案例和规避方案,帮助开发者理解如何安全使用wxHOOK技术,避免封号风险,包括内存镜像欺骗、内核级隐蔽和硬件辅助方案等高级技巧。

weixin_27875131的博客 635

android删除通话记录,安卓手机通话记录删除了怎么恢复

安卓手机通话记录删除了怎么恢复第1步,首先,请将安卓手机连接到电脑上,使用360一键Root软件(下载地址:http://root.360.cn/)对该手机进行Root。第2步,接着请在手机上安装“RE管理器rootexplorer”软件,您可以首先在手机上安装“360手机助手”,然后到360手机助手上搜索下载“RE管理器rootexplorer”,您也可以直接用手机打开本网页,然后点击此处下载该...

weixin_34693167的博客 1127

网络工程系统CAD图:从设计到落地的关键技能与实战指南

网络工程并不只是配置路由器和交换机,真正的核心在于将设计方案转化为可施工的物理图纸。网络工程系统CAD图正是连接逻辑设计与物理世界的桥梁,它涵盖综合布线、信息点布置、桥架路由、弱电间规划等关键内容。理解并掌握这套图纸体系,是网络工程师从基础设备调试走向项目主导者、弱电总工乃至网络架构师的重要分水岭。在园区网、数据中心、智能楼宇等真实场景中,一套规范的系统CAD图直接决定了施工质量、验收效率与后期运维的可靠性。本文从基础概念出发,拆解图纸的组成层次、绘制流程和软件工作流,并结合学习路线与就业方向,帮助初学者建

weixin_33860553的博客 391

从ADS到HFSS:耦合线带通滤波器的设计与模型转换实战

本文详细介绍了耦合线带通滤波器的完整设计流程,重点阐述了从ADS电路级快速优化到HFSS三维电磁场精确验证的模型转换实战方法。通过对比ADS理想模型仿真与HFSS全波仿真结果,指导读者进行参数校准与迭代优化,并分享了关键的板材选择、加工误差及端口设置等避坑指南,确保设计性能与实物测试高度一致。

weixin_29290863的博客 347

Android 自定义控件 轻松实现360软件详情页

1、概述最近有不少朋友私聊问应用宝、360软件助手之类的软件详情页怎么做,刚好,最近有时间就模仿360软件助手详情页给大家做个Demo,供大家参考。嗯,关于实现呢,我写了两种方式:1、ScrollView内嵌软件介绍+ViewPager+ViewPager中是ScrollView,这种方式呢,纯原生,没有涉及到自定义控件,但是这样嵌套呢,涉及到测量以及事件的冲突处理,大家可以自己尝试去做一下,想像

Hongyang 8万+

光学设计必看:如何用泽尼克系数优化镜头像差?从Zemax到实际案例解析

本文深入解析了如何利用泽尼克系数优化镜头像差,从理解其工程价值、解码软件报告,到在Zemax中主动设置优化目标。通过高倍显微物镜等实际案例,详细展示了如何通过分析泽尼克系数诊断问题,并实施针对性优化策略,从而实现对球差、彗差等像差的精准控制,提升光学设计的精细度和系统稳健性。

gg901的博客 1035

android 通话背景音,360 Vizza设置通话背景音的方法

360 Vizza如何添加通话背景音?相信很多用户都遇到过不想接的电话,比如说朋友打来喊约牌的,闺蜜打来秀恩爱的,以及好久不联系的朋友打来找你帮忙的。有时候是真的没有时间接或者是心情不好的时候也不想接,但是这些电话却又是不得不接的,你说这应该怎么办?这个时候我们可以找通话背景音来帮忙,只要设置通话背景音以后,接电话的时候对方听见你这边的情况可能就自己挂电话了,甚至都不用自己动手。这样又不会伤朋友间...

weixin_29706315的博客 6570

CODESYS V3.5 SP17编程环境全攻略:从安装到多语言编程实战

本文全面解析CODESYS V3.5 SP17编程环境,从安装配置到多语言编程实战技巧。详细介绍了运行时环境设置、六种IEC 61131-3语言的特性对比与混合编程策略,以及高级功能开发如自定义算法模块和实时通信配置。适合工业自动化工程师快速掌握这一强大工具。

weixin_30632089的博客 493

别再手动改文献了!手把手教你定制Mendeley的GB/T 7714-2005引用格式(附常见问题修复)

本文详细指导如何定制Mendeley的GB/T 7714-2005引用格式,解决科研文献管理中的常见问题。通过深度解析Mendeley样式编辑器,精准控制作者显示规则、出版社信息精简及期刊页码处理,实现参考文献一键合规。附常见问题修复和实战调试方法,大幅提升学术写作效率。

weixin_26833503的博客 375

继续接上添加动画效果(类似360通话)

在360通话程序上还有一个功能就是来去点跳出来的windowmanager会以动画的效果显示。 在网上寻找并看了很多帖子都没有,于是只有找源码发现有一个android自带资源android.R.style.Animation_Translucent可以基本满足以上要求,但是这是自带的,只能进行窗口平移,不能自由组合动画。在sdk里翻了半天找到了文件所在: SDK ---> platforms

羊羊的学习旅程 1128

QT C++ AI棉花智能变量灌溉工上位机(信创完整版)

北斗履带灌溉机器人/田间分区电磁阀基站 → 多层土壤温湿度/盐分EC传感器实时采集墒情 → 双目AI视觉扫描棉田长势、病苗分布 → AI融合**生育期+土壤墒情+盐分+棉株长势**计算变量灌溉定额、水肥配比、灌溉时长 → 分区电磁阀/变频水泵变量供水,病弱苗地块减量、干旱地块增量;墒情、盐分、长势多因子闭环修正灌水量;多层土壤含水率(0–10/20–40/40–80cm)、土壤EC盐分、土壤温度、空气温湿度、蒸发量、北斗地块坐标、管道水压、水肥罐液位、分区流量计、水泵电机负载、滴灌带压力反馈。

寒寒豆豆软件公司的博客 188

【安卓逆向】360加固-脱壳修复

最近花了一些时间学习逆向脱壳,这方面一直投入的时间比较少。样本经过某加固宝进行加固,这里简单记录一下脱壳过程和思路,感谢某数字公司对安全加固的无私贡献,让我有机会小小的提高一下这方面的技能。 DUMP classes.dex 打开APK包中的classes.dex看一下: 已经变成了壳代{过}{滤}理,没有一点原APK的代码。在assets中,有两个壳相关的SO: 尝试从内存中DUMP原cla...

YJJYXM的博客 2万+

Android AMS——AMS初始化(二)

Android AMS 也是一个系统服务,属于系统服务中的引导服务,在 startBootstrapServices() 方法中启动。这里我们就来看一下 ActivityManagerService 的启动流程。

小旭的专栏 779

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

苹果手机计算机怎么看之前的记录,苹果怎么查之前的通话记录吗(苹果手机怎么查通话录音内容)...

苹果怎么查之前的通话记录吗(苹果手机怎么查通话录音内容)如何查询6个月以前的通话记录是网上常见的问题,因为不管是移动,联通,还是电信,都只可以查询最近6个月内的通话记录,那六个月以前的通话祥单是否有办法查询呢?答案是可以的,因为不管是苹果手机,还是安卓手机,所有通话记录均保存在手机上的一个数据库文件中,我们可以通过将这个数据库文件导出到电脑上来直接打开查看。苹果手机如何查询6个月以前的通话记录(含...

weixin_34313315的博客 4349

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

android 仿360浮动,Android仿360悬浮小球自定义view实现示例

Android仿360悬浮小球自定义view实现示例效果图如下:实现当前这种类似的效果 和360小球 悬浮桌面差不错类似。这种效果是如何实现的呢。废话不多说 ,直接上代码。1.新建工程,添加悬浮窗权限。2.自定义一个FloatMessagerMainWindowimport android.content.Context;import android.graphics.PixelFormat;im...

weixin_31887861的博客 352

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

电话计算机怎么看记录,移动怎么查通话记录详单(中国移动通话查询明细)

移动怎么查通话记录详单(中国移动通话查询明细)如果我们知道自己手机号的服务密码的话,是可以去营业厅查询最近6个月的通话记录的,但如果我们忘记了自己的密码该怎么办呢?是否还有办法进行查询呢?其实方法还是有的,并且今天小编介绍的方法具有如下优势:1,无需知道密码,即使忘记了服务密码也可以进行查询。2,没有时间限制。去营业厅查询的话只可以查到最近6个月的通话清单,但今天要介绍的方法可百思特网以查询自手机...

weixin_32573931的博客 4052

[Android Wear]安卓穿戴设备Moto 360测评与开发分析

前言: 昨天刚买到了Moto 360,这是楼主目前为止见到的最好的安卓可穿戴设备,一个圆形的手表: BesBuy和官网都卖光了。。这是楼主听说补货了去bestbuy买到的。 外形上这就是一块普通的电子表,但其实包含的功能确实不少。最令人心动的就是它圆形的表盘,这比市面上方形的安卓手表更具有吸引力。 唯一的遗憾就是。。不是完整的圆形(处女座的。。) 这个其实是可以理解的:做成完整的圆形也是可

jhbxlx的专栏 2142

电脑会显示android,怎么在电脑上显示、操作安卓手机

想要在电脑上显示、操作安卓手机,该怎么办,那么怎么在电脑上显示、操作安卓手机的呢?下面是学习啦小编收集整理的怎么在电脑上显示、操作安卓手机,希望对大家有帮助~~在电脑上显示、操作安卓手机的方法工具/原料windows操作系统安卓手机电脑版和手机版的360助手otg数据线,鼠标方法/步骤首先对手机进行设置。在桌面上点击设置。找到手机里的 开发者选项或者是“开发人员工具”,一般在如图所示的 辅助功能 ...

weixin_33765959的博客 1715

Android自定义类似ProgressDialog效果的Dialog

Android自定义类似ProgressDialog效果的Dialog. 方法如下: 1.首先准备两张自己要定义成哪样子的效果的图片和背景图片(也可以不要背景)。 如我要的效果: 2.定义loading_dialog.xml布局文件(这里你也可以按自己的布局效果定义,关键是要有个imageView): <LinearLayout xmlns:android="htt

钱进的专栏 13万+
上一篇: 关于android电话监听显示(类似360通话)
下一篇: 继续接上添加动画效果(类似360通话)
羊羊爱代码
博客等级 码龄11年 8粉丝 28原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值