精华内容
下载资源
问答
  • iptables在维基百科上的解释是:ptables是一个配置...我这里介绍的是在linux平台实现网络数据的转发和网络数据共享的功能。  整体结构和测试环境如下图所示。 电脑/终端:  win7 系统,一个网卡eth0,通过...

        iptables在维基百科上的解释是:ptables是一个配置Linux内核防火墙的命令行工具,是netfilter项目的一部分,可以检测、修改、转发、重定向和丢弃IPv4数据包。ip6tables用于ipv6。我这里介绍的是在linux平台实现网络数据的转发和网络数据共享的功能。

        整体结构和测试环境如下图所示。

    电脑/终端
        win7 系统,一个网卡eth0,通过有线连接到linux 终端设备的eth0网口
    Linux 终端设备:
        linux系统,三个网口:eth0有线连接网口,IP:192.168.20.168;eht1为3G/4G拨号上网网口;wlan0 WIFI热点使用网口。
    移动设备:
        手机,平板,手提电脑等,通过WIFI连接到linux终端设备的wlan0网口
        所有的设备经过iptable处理过后,都可以共享linux终端设备的3g/4g网络,实现数据共享上网的功能。


    (一)有线数据共享

        电脑通过有线连接到linux终端的eth0网口,实现共享linux终端4G数据。

    (1)电脑端

        设置电脑自动获取IP。

    (2)linux终端设备

        (a)启动eht1网口

          启动linux设备的3G/4G模块,使设备能够正常的拨号上网,并且域名等参数设置正常,可以解析域名地址。

        (b)启动eth0 动态分配IP功能:

          该功能是为有线连接的设备自动分配IP使用

        #创建udhcpd.leases 文件
        touch /var/lib/misc/udhcpd.leases
        #启动eth0自动分配IP功能
        udhcpd -fS /usr/share/wifi/dhcp_eth0.conf &

        dhcp_eth0.conf 配置文件内容为:

    start 192.168.20.2                                                                                             
    end 192.168.20.25
    interface eth0
    opt dns 202.96.128.86
    opt dns 120.80.88.88
    opt dns 223.5.5.5
    opt dns 8.8.8.8
    opt subnet 255.255.255.0
    opt router 192.168.20.168
    opt lease 864000

        注意,这里需要设置网关, opt router 192.168.20.168。这里设置的是电脑通过有线连接的linux终端后的网关,这个网关也就是所连接linux设备eth0网口的IP 192.168.20.168。如果这里网关设置不正确,电脑端的数据将发送不出去。

        (c)启动网络转发功能

        #使能转发功能
        echo '1' >> /proc/sys/net/ipv4/ip_forward
        #将有线连接192.168.20.2/25 之间的数据转发到eth1网卡,通过3G/4G 收发数据 
        iptables -t nat -A POSTROUTING -s 192.168.20.2/25  -o eth1 -j MASQUERADE

    (二)无线数据共享

        移动设备端的手机平板等设备,通过WIFI连接到linux 终端设备,实现共享3G/4G网络上网。

         (a)linux设备的WIFI网卡设置:

        #启动网卡
        ifconfig wlan0 up
        #设置IP
        ifconfig wlan0 192.168.0.1
        #wifi配置
        hostapd /usr/share/wifi/rtl_hostapd_2G.conf -B

        rtl_hostapd_2G.conf 的内容为 :

    ##### hostapd configuration file ##############################################
    
    interface=wlan0
    ctrl_interface=/var/run/hostapd
    ssid=LiCaibiao_Debug
    channel=6
    wpa=2
    wpa_passphrase=87654321
    bridge=br0
    
    ##### Wi-Fi Protected Setup (WPS) #############################################
    
    eap_server=1
    
    # WPS state
    # 0 = WPS disabled (default)
    # 1 = WPS enabled, not configured
    # 2 = WPS enabled, configured
    wps_state=2
    
    uuid=12345678-9abc-def0-1234-56789abcdef0
    
    # Device Name
    # User-friendly description of device; up to 32 octets encoded in UTF-8
    device_name=RTL8192CU
    
    # Manufacturer
    # The manufacturer of the device (up to 64 ASCII characters)
    manufacturer=Realtek
    
    # Model Name
    # Model of the device (up to 32 ASCII characters)
    model_name=RTW_SOFTAP
    
    # Model Number
    # Additional device description (up to 32 ASCII characters)
    model_number=WLAN_CU
    
    # Serial Number
    # Serial number of the device (up to 32 characters)
    serial_number=12345
    
    # Primary Device Type
    # Used format: <categ>-<OUI>-<subcateg>
    # categ = Category as an integer value
    # OUI = OUI and type octet as a 4-octet hex-encoded value; 0050F204 for
    #       default WPS OUI
    # subcateg = OUI-specific Sub Category as an integer value
    # Examples:
    #   1-0050F204-1 (Computer / PC)
    #   1-0050F204-2 (Computer / Server)
    #   5-0050F204-1 (Storage / NAS)
    #   6-0050F204-1 (Network Infrastructure / AP)
    device_type=6-0050F204-1
    
    # OS Version
    # 4-octet operating system version number (hex string)
    os_version=01020300
    
    # Config Methods
    # List of the supported configuration methods
    config_methods=label display push_button keypad
    
    
    ##### default configuration #######################################
    
    driver=rtl871xdrv
    beacon_int=100
    hw_mode=g
    ieee80211n=1
    wme_enabled=1
    ht_capab=[SHORT-GI-20][SHORT-GI-40][HT40+]
    wpa_key_mgmt=WPA-PSK
    wpa_pairwise=CCMP
    max_num_sta=8
    wpa_group_rekey=86400

    (b)启动wlan0网口的自动分配IP功能

        udhcpd -fS /usr/share/wifi/dhcp.conf &

    start 192.168.0.20                                                                                                             
    end 192.168.0.254
    interface wlan0
    opt dns 202.96.128.86
    opt dns 120.80.88.88
    opt dns 223.5.5.5
    opt dns 8.8.8.8
    opt subnet 255.255.255.0
    opt router 192.168.0.1
    opt lease 864000

        同样这里也需要注意网关的设置,opt router 192.168.0.1 要与ifconfig wlan0 192.168.0.1 的地址对应。 

        在linux设备中可以启动多个udhcpd 对不同网口的设备进行IP的自动分配,只是㤇设置不同的配置文件就可以了。比如上面启动了的两个网口:

    udhcpd -fS /usr/share/wifi/dhcp.conf &

    udhcpd -fS /usr/share/wifi/dhcp_eth0.conf &

    (c)设置wlan0网口的数据转发:

        将wlan0网口192.168.0.20~254之间的IP数据通过eth1网口也就是3G/4G网卡转发出去。 

    iptables -t nat -A POSTROUTING -s 192.168.0.20/254  -o eth1 -j MASQUERADE

        到这里所有的网络共享和数据转发都已实现。在我设备上测试可行,记录在这里以备将来查询。有需要的可根据自己实际需求更改设置。 这里设置的linuxWIFI功能,实际也就相当于一个路由器的功能。

     

     

    展开全文
  • Java实现数据共享的三种方式

    千次阅读 2020-06-16 22:02:27
    Java实现数据共享的三种方式 目录 文章目录1、类的静态变量2、类内声明共享数据类型的引用3、内部类***后记*** : 内容 1、类的静态变量 示例:老师和学生共用一间教室 Classroom类代码1-1:教室类 ...

    Java实现数据共享的三种方式


    目录




    内容

    1、类的静态变量

    • 示例:老师和学生共用一间教室

    • Classroom类代码1-1:教室类

        package innerclass;
      
        public class Classroom {
        	private String no;
      
        	public Classroom(String no) {
        		super();
        		this.no = no;
        	}
      
        	public String getNo() {
        		return no;
        	}
      
        	public void setNo(String no) {
        		this.no = no;
        	}
      
        	@Override
        	public String toString() {
        		return this.no + "号教室";
        	}
        }
      
    • Teacher类代码1-2:老师类

        package innerclass;
      
        public class Teacher {
        	private String name;
        	private Student stu;
        	public Teacher(String name) {
        		super();
        		this.name = name;
        	}
        	public String getName() {
        		return name;
        	}
        	public void setName(String name) {
        		this.name = name;
        	}
        }
      
    • Student类代码1-3:学生类

        package innerclass;
      
        public class Student {
        	private String name;
        	private Teacher teacher;
      
        	public Student(String name) {
        		super();
        		this.name = name;
        	}
      
      
        	public String getName() {
        		return name;
        	}
      
      
        	public void setName(String name) {
        		this.name = name;
        	}
        }
      
    • Test2类代码1-4:测试类

        package innerclass;
      
        public class Test2 {
      
        	static Classroom room = new Classroom("002");
      
        	public static void main(String[] args) {
        		Teacher t = new Teacher("高老师");
        		Student s = new Student("小飞");
      
        		System.out.println(t.getName() + "在" + Test2.room + "教课");
        		System.out.println(s.getName() + "在" + Test2.room + "上课");
        	}
        }
      
    • 测试结果:

        高老师在002号教室教课
        小飞在002号教室上课
      
    • 解析:类的静态成员在内存中只有1个

    2、类内声明共享数据类型的引用

    • 示例:一名老师负责指导一名学生

    • Teacher类代码2-1:老师类

        package innerclass;
      
        public class Teacher {
        	private String name;
        	private Student stu;
        	public Teacher(String name) {
        		super();
        		this.name = name;
        	}
        	public String getName() {
        		return name;
        	}
        	public void setName(String name) {
        		this.name = name;
        	}
      
        	public void setStu(Student stu) {
        		this.stu = stu;
        	}
        	@Override
        	public String toString() {
        		return this.name;
        	}
      
        	public void teacher() {
        		System.out.println(this.name + "指导" + this.stu.getName() + "同学");
        	}
        }
      
    • Student类代码2-2:学生类

        package innerclass;
      
        public class Student {
        	private String name;
        	private Teacher teacher;
      
        	public Student(String name) {
        		super();
        		this.name = name;
        	}
      
      
        	public String getName() {
        		return name;
        	}
      
      
        	public void setName(String name) {
        		this.name = name;
        	}
      
      
        	public void setTeacher(Teacher teacher) {
        		this.teacher = teacher;
        	}
      
      
        	@Override
        	public String toString() {
        		return this.name;
        	}
      
        	public void study() {
        		System.out.println(this.name + "同学"+ "由" + this.teacher.getName() + "指导");
        	}
        }
      
    • Test1类代码2-3:测试类

        package innerclass;
      
        public class Test1 {
        	public static void main(String[] args) {
        		Teacher t = new Teacher("王老师");
        		Student stu = new Student("小明");
      
        		t.setStu(stu);
        		stu.setTeacher(t);
      
        		t.teacher();
        		stu.study();
        	}
        }
      
    • 测试结果:

        王老师指导小明同学
        小明同学由王老师指导
      

    3、内部类

    • 示例:同上

    • 代码3-1:

        package innerclass;
      
        public class Test3 {
        	public static void main(String[] args) {
        		Classroom1 room = new Classroom1("003");
        		Classroom1.Teacher t = room.new Teacher("李老师");
        		Classroom1.Student s = room.new Student("小田");
      
        		t.display();
        		s.display();
        	}
        }
      
        class Classroom1 {
        	private String no;
      
        	class Teacher {
        		private String name;
        		public Teacher(String name) {
        			super();
        			this.name = name;
        		}
        		public String getName() {
        			return name;
        		}
        		public void setName(String name) {
        			this.name = name;
        		}
      
        		public void display() {
        			System.out.println(this.name + "在" + no + "号教室" + "教课");
        		}
        	}
      
        	class Student {
        		private String name;
      
        		public Student(String name) {
        			super();
        			this.name = name;
        		}
      
      
        		public String getName() {
        			return name;
        		}
      
      
        		public void setName(String name) {
        			this.name = name;
        		}
      
        		public void display() {
        			System.out.println(this.name + "在" + no + "号教室" + "上课");
        		}
        	}
        	public Classroom1(String no) {
        		super();
        		this.no = no;
        	}
      
        	public String getNo() {
        		return no;
        	}
      
        	public void setNo(String no) {
        		this.no = no;
        	}
        }
      

    后记

    本项目为参考某马视频开发,相关视频及配套资料可自行度娘或者联系本人。上面为自己编写的开发文档,持续更新。欢迎交流,本人QQ:806797785

    前端项目源代码地址:https://gitee.com/gaogzhen/vue-leyou
        后端JAVA源代码地址:https://gitee.com/gaogzhen/JAVA

    展开全文
  • C++实现线程间数据共享

    千次阅读 2019-05-07 22:12:06
      本博客介绍一个简单的工作:C++实现线程间数据共享。   在某些程序开发中,例如ORB-SLAM2中就是一个4线程的工程,这四个线程之间的工作不同,但需要数据的联系,也就是四个线程中某个线程进行的工作是为了准备...

    一、前言
      本博客介绍一个简单的工作:C++实现线程间数据共享。
      在某些程序开发中,例如ORB-SLAM2中就是一个4线程的工程,这四个线程之间的工作不同,但需要数据的联系,也就是四个线程中某个线程进行的工作是为了准备另一个线程所需要的数据。这里不多说ORB-SLAM2的细节了,在这方面SLAM有研究的朋友可私聊一下,一起交流学习一下。下面开始介绍本博客的内容。
    二、介绍
      这里设计两个线程,两个线程执行的函数分别是两个类的run()函数。第一个线程主要做类成员变量的显示,第二个线程主要做的工作是改变第一个线程run()函数所在的类的成员变量的值。这样就实现了第二个线程为第一个线程做数据准备的一个简单的案例。具体看代码。
    三、代码

    #include <iostream>
    #include<thread>
    #include<unistd.h>
    #include<mutex>
    using namespace std;
    
    using namespace std;
    class MyClass1{
    public:
        int a;
        std::mutex mymutex;
    
        void Display(){
            cout<<"a="<<a<<endl;
        }
        void Change_a(int x1){
            unique_lock<mutex> lock(mymutex);
            a=x1;
        }
        void run1();
    };
    
    class MyClass2{
    public:
        MyClass1* cp;
        int b;
        
        void set_c1(MyClass1* class1);
        void run2();
    };
    void MyClass1::run1(){
        a=2;
        while (1){
            Display();
            cout<<"----------run1-----------"<<endl;
            a=2;
            Display();
            sleep(1);
        }
    }
    void MyClass2::set_c1(MyClass1* class1){
        cp=class1;
    }
    void MyClass2::run2(){
        b=2;
        while (1){
            b++;
            if(b>10){
                b=3;
            }
            cp->Change_a(b);
            cout<<endl<<"-----------run2----------"<<endl;
            sleep(2);
        }
    }
    int main(){
        MyClass1* c1=new MyClass1();
        MyClass2* c2=new MyClass2();
        c2->set_c1(c1);
        thread thread_c1(&MyClass1::run1,c1);
        thread thread_c2(&MyClass2::run2,c2);
        thread_c1.join();
        thread_c2.join();
        return 0;
    }
    

    四、CMakeLists.txt
      该代码是在ubuntu下运行的,CMakeLists.txt的内容如下。

    cmake_minimum_required(VERSION 2.8)
    project(opencv_test)
    set( CMAKE_CXX_FLAGS "-std=c++11")
    #find_package(OpenCV REQUIRED)
    find_package(Threads REQUIRED)
    
    include_directories(
        include
    )
    
    add_executable(test src/test.cpp)
    target_link_libraries(test  Threads::Threads)
    

    五、代码解析
      实现数据共享的关键在于在MyClass2中声明了类指针——MyClass1* cp,并且通过成员函数void set_c1(MyClass1* class1)对该类指针进行赋值。在main函数里分别实例化了两个类指针,并且词c2通过void set_c1(MyClass1* class1);将词c2里的cp设置成了c1,于是这样在run2()中就可以通过c2的成员变量cp来进行c1的成员变量的操作了(具体是通过改变c2的b,将b值传递给a)。可能解释的不是很好,可以参考代码理解一下。还有问题在留言取讨论吧。下面来看一下结果。
    六、运行结果
      运行结果如下:
    在这里插入图片描述
    可以看到每一次run2()执行后a值都发生了改变,证明我们的功能实现了。

    展开全文
  • 目录: 7.1 内容提供器简介 7.2 运行时权限 7.2.1 Android 权限机制详解 7.2.2 在程序运行时中申请权限 7.3 访问其他程序中的数据 ...7.4.2 实现跨程序数据共享 7.5 Git 时间——版本控制工具进阶...

    目录:

    7.1 内容提供器简介

    7.2 运行时权限

    7.2.1 Android 权限机制详解

    7.2.2 在程序运行时中申请权限

    7.3 访问其他程序中的数据

    7.3.1 ContentResolver的基本用法

    7.3.2 读取系统联系人

    7.4 创建自己的内容提供器

    7.4.1 创建内容提供器的步骤

    7.4.2 实现跨程序数据共享

    7.5 Git 时间——版本控制工具进阶

    7.5.1 忽略文件

    7.5.2 查看修改内容

    7.5.3 撤销未提交的修改

    7.5.4 查看提交记录

    7.6 小结与点评


    知识点:

    7.1 内容提供器简介

    内容提供器(Content Provider)主要用于在不同的应用程序之间实现数据共享的功能,它提供了一套完整的机制,允许一个程序访问到另一个程序中的数据,同时还能保证被访问数据的安全性。目前,使用内容提供器是 Android 实现跨程序共享数据的标准方式。

    不同于文件存储和 SharedPreferences 存储中的两种全局可读写操作模式,内容提供器可以选择只对哪一部分数据进行共享,从而保证程序中的隐私数据不会有泄露的风险。

    7.2 运行时权限

    运行时权限并不是什么新鲜事物,从系统的第一个版本开始就已经存在了。但其实之前Android的权限机制在保护用户安全和隐私等方面起到的作用比较有限,尤其是一些大家都离不开的常用软件,非常容易“店大欺客”。为此,Android开发团队在Android6.0 系统中引用了运行时权限这个功能,从而更好地保护了用户的安全和隐私。

    7.2.1 Android 权限机制详解

    Android 把所有的权限归成两类:普通权限和危险权限。

    • 普通权限
        不会直接威胁到用户的安全和隐私的权限,对于这部分的权限申请,系统会自动帮我们进行授权。

    • 危险权限
        可能触及用户隐私,或对设备安全性造成影响的权限,如获取联系人信息、地理位置等,对于这部分的权限申请,必须由用户手动点击授权才可以,否则程序无法使用相应的功能。

    7.2.2 在程序运行时中申请权限

    首先我们需要在AndroidManifest.xml中添加 如下 用于拨打电话

    <uses-permission android:name="android.permission.CALL_PHONE" />

    然后新建Activity 在onCreate中 直接申请权限

    之后在回调中进行处理

    package com.dak.administrator.firstcode.permission;
    
    import android.Manifest;
    import android.annotation.SuppressLint;
    import android.content.Intent;
    import android.content.pm.PackageManager;
    import android.net.Uri;
    import android.support.annotation.NonNull;
    import android.support.v4.app.ActivityCompat;
    import android.support.v4.content.ContextCompat;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.view.ViewConfiguration;
    import android.widget.Toast;
    
    import com.dak.administrator.firstcode.R;
    
    public class PermissionActivity extends AppCompatActivity {
    
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_permission);
    
            if (ContextCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
    
                ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CALL_PHONE}, 1);
            } else {
                call();
            }
    
    
        }
    
        @SuppressLint("MissingPermission")
        private void call() {
            Intent intent = new Intent(Intent.ACTION_CALL);
            intent.setData(Uri.parse("tel:10085"));
            startActivity(intent);
        }
    
        @Override
        public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
            switch (requestCode) {
                case 1:
                    if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                        call();
                    }else{
                        Toast.makeText(this, "YYou denied the permiss", Toast.LENGTH_SHORT).show();
                    }
                    break;
            }
    
    
        }
    
        private void setObject(Object object) {
    //        (() object)  object.cast
    	// 用户滑动的最小距离
    //        ViewConfiguration.get(this).getScaledTouchSlop();
        }
    }
    

    7.3 访问其他程序中的数据

    内容提供器的用法有两种:

    • 使用现有的内容提供器来读取和操作相应程序中的数据
    • 创建自己的内容提供器给我们程序的数据提供外部访问接口

    7.3.1 ContentResolver的基本用法

    对于每一个应用程序来说,如果想要访问内容提供器中共享的数据,就一定要借助ContentResolver类,可以通过Context中的getContentResolver方法获取到该类的实例,从而对数据记性CRUD操作。

    要点:

    内容 URI 给内容提供器中的数据建立了唯一标识符,它由 authority(区分不同的应用程序)和 path(区分不同的表)组成,具体的可以到百度了解一下。

    content://com.example.app.provider/table1

    对于CRUD操作:

    查询:

    Curson curson = getContentResolver().query(uri,projection,selection,selectionArgs,sortOrder);

    添加操作:

    // 将待添加的数据组装到 ContentValues 中
    ContentValues values = new ContentValues();
    values.put("column1","text");
    values.put("column2",1);
    // 调用 insert() 方法添加数据
    getContentResolver().insert(uri, values);
    

    更新操作:

    ContentValues values = new ContentValues();
    // 清空
    values.put("column1","");
    // 调用 update() 方法更新数据
    getContentResolver().update(uri, values, "column1 = ? and column2 = ?",new String[]{"text","1"});
    

    删除操作:

    getContentResolver().delete(uri,  "column2 = ?", new String[]{"1"});
    

    7.3.2 读取系统联系人

    话不多说,直接上代码:

    package com.dak.administrator.firstcode.content_resolver;
    
    import android.Manifest;
    import android.content.Context;
    import android.content.pm.PackageManager;
    import android.database.Cursor;
    import android.provider.ContactsContract;
    import android.support.annotation.NonNull;
    import android.support.v4.app.ActivityCompat;
    import android.support.v4.content.ContextCompat;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.widget.ArrayAdapter;
    import android.widget.ListView;
    import android.widget.Toast;
    
    import com.dak.administrator.firstcode.R;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import static android.content.pm.PackageManager.PERMISSION_GRANTED;
    
    public class ResolverActivity extends AppCompatActivity {
    
        ArrayAdapter<String> adapter;
        List<String> contactsList = new ArrayList<>();
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_resolver);
    
            ListView contactsView = findViewById(R.id.contacts_view);
            adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, contactsList);
            contactsView.setAdapter(adapter);
    
            if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS) != PERMISSION_GRANTED) {
                ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_CONTACTS}, 1);
            }else{
                readContacts();
            }
        }
    
        private void readContacts() {
            Cursor cursor = null;
    
            try {
                cursor = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null);
                if (cursor != null) {
                    while (cursor.moveToNext()) {
                        String displayName = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
                        String number = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
                        contactsList.add(displayName + "\n" + number);
                    }
                    adapter.notifyDataSetChanged();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                if (cursor != null) {
                    cursor.close();
                }
            }
        }
    
        @Override
        public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    
            switch (requestCode) {
                case 1:
                    if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                        readContacts();
                    } else {
                        Toast.makeText(this, "You denied the permission", Toast.LENGTH_SHORT).show();
                    }
                    break;
    
    
    
            }
        }
    }
    

    Xml文件 显示我们查询到的内容

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context="com.dak.administrator.firstcode.content_resolver.ResolverActivity">
    
        <ListView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/contacts_view"
            >
    
    
    
    
        </ListView>
    
    
    </LinearLayout>
    

    7.4 创建自己的内容提供器

    7.4.1 创建内容提供器的步骤

    相关方法已经注释

    package com.dak.administrator.firstcode.content_resolver;
    
    import android.content.ContentProvider;
    import android.content.ContentValues;
    import android.content.UriMatcher;
    import android.database.Cursor;
    import android.net.Uri;
    import android.support.annotation.NonNull;
    import android.support.annotation.Nullable;
    
    import java.io.BufferedReader;
    
    /**
     * Created by Administrator on 2018/10/18.
     */
    
    public class MyProvider extends ContentProvider {
        public static final int TABLE1_DIR = 0;
        public static final int TABLE1_TIME = 1;
        public static final int TABLE2_DIR = 2;
        public static final int TABLE2_TIME = 3;
    
        private static UriMatcher uriMatcher;
    
        static {
            uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
            uriMatcher.addURI("com.dak.administrator.firstcode","table1",TABLE1_DIR);
            uriMatcher.addURI("com.dak.administrator.firstcode","table1/#",TABLE1_TIME);
            uriMatcher.addURI("com.dak.administrator.firstcode","table2",TABLE2_DIR);
            uriMatcher.addURI("com.dak.administrator.firstcode","table2/#",TABLE2_TIME);
        }
    
        // 初始化内容提供器的时候调用,返回true表示成功,false失败
        @Override
        public boolean onCreate() {
            return false;
        }
    
        // 从内容提供器中查询数据
        @Nullable
        @Override
        public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder) {
            switch (uriMatcher.match(uri)) {
                case TABLE1_DIR:
                    //查询table1表中的所有数据
                    break;
                case TABLE1_TIME:
                    //查询table1表中的单条数据
                    break;
                case TABLE2_DIR:
                    //查询table2表中的所有数据
                    break;
                case TABLE2_TIME:
                    //查询table2表中的单条数据
                    break;
            }
    
            return null;
        }
        // 根据传入的内容 URI 来返回 MIME 类型
        @Nullable
        @Override
        public String getType(@NonNull Uri uri) {
            //MIME类型  规定:
            // 1. 必须以vnd 开头
            // 2. 如果内容URI以路径结尾,则后接android.cursor.dir/
            //    如果内容URI以id结尾,则后接android.cursor.item/
            // 3. 最后接上vnd.<authority>.<path>
            switch (uriMatcher.match(uri)) {
                case TABLE1_DIR:
                    return "vnd.android.cursor.dir/vnd.com.dak.administrator.firstcode.table1";
                case TABLE1_TIME:
    
                    return "vnd.android.cursor.item/vnd.com.dak.administrator.firstcode.table1";
                case TABLE2_DIR:
    
                    return "vnd.android.cursor.dir/vnd.com.dak.administrator.firstcode.table2";
                case TABLE2_TIME:
    
                    return "vnd.android.cursor.item/vnd.com.dak.administrator.firstcode.table2";
            }
    
            return null;
        }
    
        // 向内容提供器中添加一条数据
        @Nullable
        @Override
        public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) {
            return null;
        }
    
        // 从内容提供器中删除数据
        @Override
        public int delete(@NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) {
            return 0;
        }
        // 更新内容提供器中已有的数据
        @Override
        public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection, @Nullable String[] selectionArgs) {
            return 0;
        }
    }
    

    7.4.2 实现跨程序数据共享

    在这里主要是通过SQLite 的增删改查方式,来操作。

    提供一个主要Resolver,关乎数据库方面的这块就不写了。

    public class DataBaseProvider extends ContentProvider {
    
        public static final int BOOK_DIR = 0; //访问 book 表中的所有数据
        public static final int BOOK_ITEM = 1;//访问 book 表中的单条数据
        public static final int CATEGORY_DIR = 3;
        public static final int CATEGORY_ITEM = 4;
    
        public static final String AUTHORITY = "com.wonderful.myfirstcode.chapter7.provider";
    
        private static UriMatcher uriMatcher;
        
        private MyDatabaseHelper dbHelper;
    
        static {
            // 创建 UriMatcher 实例
            uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
            // 调用 addURI() 方法,此方法接收3个参数:authority、path、自定义代码
            uriMatcher.addURI(AUTHORITY,"book",BOOK_DIR);
            uriMatcher.addURI(AUTHORITY,"book/#",BOOK_ITEM);
            uriMatcher.addURI(AUTHORITY,"category",CATEGORY_DIR);
            uriMatcher.addURI(AUTHORITY,"category/#",CATEGORY_ITEM);
        }
    
        /**
         * 初始化内容提供器
         */
        @Override
        public boolean onCreate() {
            // 创建 MyDatabaseHelper 实例
            dbHelper = new MyDatabaseHelper(getContext(),"BookStore.db",null,2);
            // 返回true表示完成了创建或升级数据库
            return true;
        }
    
        /**
         * 查询数据
         */
        @Override
        public Cursor query(Uri uri, String[] projection, String selection,
                            String[] selectionArgs, String sortOrder) {
            SQLiteDatabase db = dbHelper.getReadableDatabase();
            Cursor cursor = null;
            switch (uriMatcher.match(uri)){
                case BOOK_DIR:
                    // 查询 book 表中的所有数据
                    cursor = db.query("book",projection,selection,selectionArgs,
                            null,null,sortOrder);
                    break;
                
                case BOOK_ITEM:
                    // 查询 book 表中的单条数据
                    String bookId = uri.getPathSegments().get(1);
                    cursor = db.query("book",projection,"id = ?",new String[]{bookId},
                            null,null,sortOrder);
                    break;
                
                case CATEGORY_DIR:
                    cursor = db.query("category",projection,selection,selectionArgs,
                            null,null,sortOrder);
                    break;
                
                case CATEGORY_ITEM:
                    String categoryId = uri.getPathSegments().get(1);
                    cursor = db.query("category",projection,"id = ?",new String[]
                            {categoryId}, null,null,sortOrder);
                    break;
                
                default:
                    break;
            }
            return cursor;
        }
    
        /**
         * 添加数据
         */
        @Override
        public Uri insert(Uri uri, ContentValues values) {
            SQLiteDatabase db = dbHelper.getWritableDatabase();
            Uri uriReturn = null;
            switch (uriMatcher.match(uri)){
                case BOOK_DIR:
                case BOOK_ITEM:
                    long newBookId = db.insert("book",null,values);
                    uriReturn = Uri.parse("content://" + AUTHORITY + "/book" + newBookId);
                    break;
    
                case CATEGORY_DIR:
                case CATEGORY_ITEM:
                    long newCategoryId = db.insert("category",null,values);
                    uriReturn = Uri.parse("content://" + AUTHORITY + "/category" +
                            newCategoryId);
                    break;
    
                default:
                    break;
            }
            return uriReturn;
        }
    
        /**
         * 更新数据
         */
        @Override
        public int update(Uri uri, ContentValues values, String selection,
                          String[] selectionArgs) {
            SQLiteDatabase db = dbHelper.getReadableDatabase();
            int updatedRows = 0;
            switch (uriMatcher.match(uri)){
                case BOOK_DIR:
                    updatedRows = db.update("book",values,selection,selectionArgs);
                    break;
    
                case BOOK_ITEM:
                    String bookId = uri.getPathSegments().get(1);
                    updatedRows = db.update("book",values,"id = ?",new String[]{bookId});
                    break;
    
                case CATEGORY_DIR:
                    updatedRows = db.update("category",values,selection,selectionArgs);
                    break;
    
                case CATEGORY_ITEM:
                    String categoryId = uri.getPathSegments().get(1);
                    updatedRows = db.update("category",values,"id = ?",new String[]
                            {categoryId});
                    break;
    
                default:
                    break;
            }
            return updatedRows;
        }
    
        /**
         * 删除数据
         */
        @Override
        public int delete(Uri uri, String selection, String[] selectionArgs) {
            SQLiteDatabase db = dbHelper.getReadableDatabase();
            int deletedRows = 0;
            switch (uriMatcher.match(uri)){
                case BOOK_DIR:
                    deletedRows = db.delete("book",selection,selectionArgs);
                    break;
    
                case BOOK_ITEM:
                    String bookId = uri.getPathSegments().get(1);
                    deletedRows = db.delete("book","id = ?",new String[]{bookId});
                    break;
    
                case CATEGORY_DIR:
                    deletedRows = db.delete("category",selection,selectionArgs);
                    break;
    
                case CATEGORY_ITEM:
                    String categoryId = uri.getPathSegments().get(1);
                    deletedRows = db.delete("category","id = ?",new String[]
                            {categoryId});
                    break;
    
                default:
                    break;
            }
            return deletedRows;
        }
    
        /**
         * 获取 Uri 对象所对应的 MIME 类型
         */
        @Override
        public String getType(Uri uri) {
            switch (uriMatcher.match(uri)){
                case BOOK_DIR:
                    return "vnd.android.cursor.dir/vnd.com.wonderful.myfirstcode." +
                            "chapter7.provider.book";
    
                case BOOK_ITEM:
                    return "vnd.android.cursor.item/vnd.com.wonderful.myfirstcode." +
                            "chapter7.provider.book";
    
                case CATEGORY_DIR:
                    return "vnd.android.cursor.dir/vnd.com.wonderful.myfirstcode." +
                            "chapter7.provider.category";
    
                case CATEGORY_ITEM:
                    return "vnd.android.cursor.item/vnd.com.wonderful.myfirstcode." +
                            "chapter7.provider.category";
            }
            return null;
        }
        
    }
    

     

    7.5 Git 时间——版本控制工具进阶

    7.5.1 忽略文件

    7.5.2 查看修改内容

    7.5.3 撤销未提交的修改

    7.5.4 查看提交记录

    关于Git 相关的内容请移驾:

    https://blog.csdn.net/lhk147852369/article/details/84307580

    7.6 小结与点评

    郭霖总结:

    本章的内容不算多,而且很多时候都是在使用上一章中学习的数据库只是,所以理解这部分内容对你来说是比较轻松地吧。在本章中,我们一开始先了解了Android的权限机制,并且学会了如何在6.0以上的系统中使用运行时权限,然然后又重点学习了内容提供器的相关内容,以实现跨进程数据共享的功能。现在你不仅知道了如何去访问其他程序中的数据,还学会了怎样创建自己的内容提供器来共享数据,收获还是挺大的吧。

    不过每次在创建内容提供器的时候,你都需要提醒下自己, 我是不是应该这么做?因为只有真正需要将数据共享出去的时候我们才应该创建内容提供器,仅仅是用于程序内部访问的数据就没有必要这么做,所以千万别对它进行滥用。

    在连续学了几章系统机制方面的内容之后是不是感觉有些枯燥?那么下一- 章中我们就来换换口味,学习一下Android多媒体方面的知识吧。

    我的总结:

    之前在进行工作的过程中,并没有用到这方面的知识,现在学习了一番,收获还是非常大的。

     

    展开全文
  • ContendProvider是不同应用程序之间进行数据交换的标准API,ContentProvider以某种Uri的形式对外提供数据,允许其他应用访问或修改数据;其他应用程序使用ContentReslover根据Uri去访问操作指定数据因为...
  • python 、mmap 实现内存数据共享

    千次阅读 2017-05-04 10:09:52
    如果内容较多,可以调大一点 mmap_file = mmap.mmap(-1, 1024, access = mmap.ACCESS_WRITE, tagname = ' share_mmap ' ) # #读取有效比特数,不包括空比特 cnt=mmap_file.read_byte() if cnt==0: print...
  • 方法一:Python+OpenCv实现树莓派数据采集,树莓派搭建服务器,PC机作为客户端实现数据传输,结果发现传输画质太差。 网址:https://blog.csdn.net/m0_38106923/article/details/81974373 方法二:使...
  • 内容提供者简介 访问其他应用中的数据 ContentResolver 的基本用法 实例读取系统联系人 创建自己的内容提供器 ...实现跨程序数据共享 内容提供者 访问自己创建的内容提供者数据 遇到的问题内容提供者简介 使用场景:
  • 实现数据开放共享的方法

    万次阅读 2017-01-23 11:59:27
    当前之所以存在严重的信息孤岛问题、数据难以...本文的方法是在系统的设计阶段实现数据的开放共享,从根本上避免信息孤岛问题的产生。火车是以标准的钢轨为基础避免了铁路交通孤岛而实现了互联互通,本文借鉴了此方法。
  • Servlet实现共享数据JavaWeb组件

    千次阅读 2020-10-27 10:34:35
    Servlet JavaWeb三大组件包括,Servlet组件(接受请求,响应数据),Filter组件(过滤,拦截请求),Listener组件(监听),这三大组件构成了javaWeb核心内容,也是作为后端来说,JavaWeb最重要的内容。...
  • Zabbix的功能虽然很强大,能将数据以图表形式展现在Web中,但是,一个监控系统的使用者如果不了解Zabbix,或者其非维护人员需要通过监控了解各个服务器大致运行状况时,Zabbix所提供的界面就不是很友好了。...
  • ... ...2.从react-redux导入...这样我们就利用react-redux模块完成了react各个组件之间数据共享。跟上篇文章一样,实现了在一个组件Input中通过actions更新数据到store,然后在另一个组件Show中展示store中的数据
  • 数据卷flocker插件实现容器集群(或者Docker Swarm)的数据共享3.数据卷容器作为其他容器的数据卷.降低磁盘开销.4.数据的备份,恢复和迁移.5.Docker hub的常用操作.1.0.数据卷(Data volumes)Data volumes是一个或者多个...
  • 例如,你可以:从 Power BI Desktop 向 Power BI 服务发布报表 使用 Power BI Mobile 应用查看共享报表和仪表板并与其交互 创建打包仪表板、报表和数据集的*内容包*,并将之发送给同事。 他们可以将其作为起点并...
  • redis实现session共享

    万次阅读 2018-10-10 15:41:57
    session共享 什么是session? 由于 HTTP 协议是无状态的协议,所以服务端需要记录用户的状态时,就需要用某种机制来识具体的用户。Session 是另一种记录客户状态的机制,不同的是 Cookie 保存在客户端浏览器中,而...
  • 本文通过实例介绍怎样在Rancher中配置Rancher NFS,实现Rancher中“服务”内的“容器”实例共享一台外置NFS Server服务器上的数据目录。
  • 【面试题】Linux如何实现共享内存

    千次阅读 2019-06-25 10:09:17
    为什么实现共享内存? 采用共享内存通信的一个显而易见的好处是效率高,因为进程可以直接读写内存,而不需要任何数据的拷贝。对于像管道和消息队列等通信方式,则需要在内核和用户空间进行四次的数据拷贝,而共享...
  • 基于区块链的医疗数据共享系统

    千次阅读 2020-04-06 22:52:07
    基于区块链的医疗数据共享系统 I. Abstract 随着大数据时代的到来,数据已经成为重要的资源,发挥数据价值的关键在于数据流通。但是,由于隐私泄漏等问题,各行业的数据共享发展缓慢,可以说,解决数据流通面临的...
  • 【python实战】python一行代码,实现文件共享服务器

    千次阅读 多人点赞 2021-04-17 21:04:25
    一行代码实现文件共享 就是这么简单 1、需要共享内容 2、python一键共享 3、共享效果 4、通过http直接访问 参数详解 推荐越多 pygame系列 一行代码实现文件共享 在一个局域网内,需要共享一个文件夹里...
  • 本篇介绍Spring-Session的整个实现的原理。以及对核心的源码进行简单的介绍! 实现原理介绍 实现原理这里简单说明描述: 就是当Web服务器接收到http请求后,当请求进入对应的Filter进行过滤,将原本...
  • 数据共享与整合技术-总结01

    千次阅读 2019-05-28 08:46:43
    大数据(big data),指无法在一定时间范围内用常规软件工具进行捕捉、管理和处理的数据集合,是需要新处理模式才能具有更强的决策力、洞察发现力和流程优化能力的海量、高增长率和多样化的信息资产。 大数据可以...
  • 专题:区块链与数据共享

    千次阅读 2018-04-24 09:44:25
    专题:区块链与数据共享Blockchain and Data Sharing导读:区块链的概念来源于2008年中本聪发表的论文《比特币:一种点对点的电子现金系统》。在区块...
  • 导读:本文将介绍一个智能项目,我们将使用回归建模方式来模拟Capital Bikeshare系统中的自行车共享数据集,并了解温度、风和时间等变量是如何影响自行车租赁需求的...
  • 如何实现 Excel 多人共享与协作

    千次阅读 2018-04-12 10:44:05
    因此,如何实现多人操作同一份 Excel,从而实现信息共享与协作,就变得很有意义。 本 Chat 讲述 4 种 Excel 共享方案,能让您较全面了解简易型的信息共享方法。 主要内容如下: Excel 共享必要性 共享方案概述 方案...
  • 本文主讲了AngularJs中的Controller中基础使用、数据共享、继承、通信的详细使用. AngularJS中的controller中文名就是控制,它是一个Javascript函数(类型/类),用来向视图的作用域($scope)添加额外的功能。...
  • 共享内存实现原理

    千次阅读 2018-09-28 18:02:39
    共享内存的使用实现原理(必考必问,然后共享内存段被映射进进程空间之后,存在于进程空间的什么位置?共享内存段最大限制是多少?) nmap函数要求内核创建一个新额虚拟存储器区域,最好是从地质start开始的一个...
  • 简单点来说Container是在Image基础上进行创建的,Image(只读)不能写数据而Container可以写数据,虽然Container能够写数据,但是数据只限于这个Container(当容器删除后,那么之前在容器中写入的数据或文件就全部...
  • laravel视图模板数据共享view()->share()

    千次阅读 2018-08-15 20:54:27
    我们可以使用视图模板的数据共享实现。 与所有视图共享数据 如果需要共享一段数据给应用程序的所有视图,你可以在服务提供器的 boot 方法中调用视图 Facade 的 share 方法。例如,可以将它们添加到 ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 643,028
精华内容 257,211
关键字:

内容提供器怎么实现数据共享