آموزش برنامه نویسی اندروید با اندروید استودیو (بخش پنجاه و نهم: نوشتن در فایل در دایرکتوری معین )

استاندارد

در بخش قبلی در مورد نحوه خواندن از یک فایل Text در دایرکتوری مشخص صحبت کردیم.

دیدیم که می توان با استفاده از کلاس Environment به فایل تکست دسترسی داشت، سپس با استفاده از کلاس File ، آن فایل را به برنامه معرفی کردیم و در آخر محتویات فایل تکست را به رشته String تبدیل نمودیم.

در این بخش می خواهیم برعکس این کار را انجام دهیم.

یعنی عمل نوشتن در فایل Text با استفاده از یک رشته را انجام بدهیم.

در بخش قبلی از کلاس FileInputStream برای وارد نمودن اطلاعات از فایل به اپلیکیشن استفاده کردیم.

از آنجایی که این کلاس جریان بایت های یک فایل را می پذیرد، می تواند با انواع مختلف فایل کار کند.

در این بخش می خواهیم از کلاس FileOutputStream برای وارد نمودن اطلاعات از پروژه (اپلیکیشن) به فایل خروجی استفاده نماییم. ( نوشتن در فایل یا عمل Write )

در این بخش نیز از کلاس FileOuputStream که رفتاری مشابه دارد و اطلاعات را به جریانی از بایت ها برای ارسال به فایل، تبدیل می کند، استفاده می شود.

 از این کلاس می توان برای فایل های مختلف استفاده نمود.

اگر فرض کنیم فایل را به صورت زیر، از دایرکتوری مشخص مثلا (/android/) با نام “1” که پسوند txt. دارد ، به کد جاوای برنامه معرفی کرده باشیم…

String fileName = "1.txt";
String baseDir = Environment.getExternalStorageDirectory().getAbsolutePath();
String pathDir = baseDir + "/Android/";

File myfile = new File(pathDir + File.separator + fileName);

برای نوشتن بر روی فایل از این کد استفاده خواهیم نمود.

FileOutputStream stream = new FileOutputStream(myfile); // نام فایل است myfile
        try {
            stream.write("Gsm Developers".getBytes()); //به جریانی از بایت ها تبدیل شده و بر روی فایل نوشته می شود "Gsm Developers" در قسمت اول، رشته ی
        } finally {
            stream.close();
        }

شرح کد:

 

فرض می کنیم فایلی به صورتی که در تصویر مشاهده می کنید وجود دارد.

مشخصات این فایل بدین صورت است:

Name: 1.txt

Directory: /Android/

نام و دایرکتوری فایل را به صورت زیر در کدجاوای پروژه مشخص می کنیم:

String fileName = "1.txt";
String baseDir = Environment.getExternalStorageDirectory().getAbsolutePath();
String pathDir = baseDir + "/Android/";

در مرحله ی بعدی یک شی به نام myfile از کلاس File می سازیم و با استفاده از مسیر دایرکتوری که به برنامه گفتیم و نام فایلی که می خواهیم آن را تعریف می کنیم.

File myfile = new File(pathDir + File.separator + fileName);

در قسمت اول، pathDir یعنی مسیر دایرکتوری و در قسمت سوم، fileName یعنی همان نام فایل از ورودی های سازنده برای این شی می باشند.

برای نوشتن بر روی فایل بدین ترتیب عمل می کنیم.

ابتدا یک شی به نام stream از کلاس FileOutputStream ، می سازیم و فایل را به عنوان ورودی سازنده ی آن شی ، قرار می دهیم.

FileOutputStream stream = new FileOutputStream(myfile);

در قسمت بعد، از آنجایی که می خواهیم یک متن را به فایل تکست، اضافه نماییم، کد زیر را می نویسیم.

stream.write("Gsm Developers".getBytes());

این کد، رشته ی “Gsm Developers” را به جریانی از بایت ها تبدیل نموده و در فایل write می کند.

نکته:

در بعضی کامپایلرها مثلا Android Studio ، به دلیل آن که فایل ممکن است در حافظه موجود نباشد یا به هر دلیلی قابل نوشتن نباشد، کدی که مربوط به کلاس FileOutputStream است را در ساختار try-catch می نویسیم.

FileOutputStream stream = null;
        try {
            stream = new FileOutputStream(myfile);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        try {
            stream.write("Gsm Developers".getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                stream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

برای دادن دسترسی ها و مجوزهای لازم، باید به قسمت AndroidManifest.xml رفته و کد زیر را برای نوشتن در حافظه ی خارجی بنویسیم.

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

پروژه را Run می کنیم.

اگر به فایل رجوع کنید ، می بینید که محتوای آن به رشته ای که شما در کد نوشتید، تبدیل شده است.

کد کامل MainActivity.java

import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        String fileName = "1.txt";
        String baseDir = Environment.getExternalStorageDirectory().getAbsolutePath();
        String pathDir = baseDir + "/Android/";

        File myfile = new File(pathDir + File.separator + fileName);

        FileOutputStream stream = null;
        try {
            stream = new FileOutputStream(myfile);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        try {
            stream.write("Gsm Developers".getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                stream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

آموزش برنامه نویسی اندروید با اندروید استودیو (بخش پنجاه و پنجم: بررسی امکان دسترسی خواندن و نوشتن در حافظه )

استاندارد

دسترسی خواندن و نوشتن در حافظه موضوع مورد بحث این بخش است.

در این بخش از آموزش برنامه نویسی اندروید، می خواهیم بررسی کنیم که آیا می توانیم فایلی را در حافظه ی خارجی توسط اپلیکیشن بنویسیم؟

به عبارتی آیا اپلیکیشن ما اجازه ی این کار را دارد؟

این بخش، پیش نیاز کار با فایل ها در برنامه نویسی اندروید است.

پس بررسی موضوع دسترسی خواندن و نوشتن در حافظه ی خارجی ، می تواند به ما در کار با فایل ها کمک نماید.

قبل از هر چیز دقت نمایید که حافظه ی گوشی و یا تبلت اندرویدی به دو قسمت حافظه ی داخلی و حافظه ی خارجی تقسیم می شود.

که نام انگلیسی آن ها به ترتیب Internal Memory و External Memory می باشد.

کاربر به Internal Memory دسترسی ندارد. بلکه به External Memory دسترسی دارد.

هدف ما در این بخش نیز بررسی دسترسی اپلیکیشن به این حافظه می باشد.

دقت کنید که External Memory را با Sd Card که یعنی کارت حافظه ی Sd ، با قابلیت جداشدن است، اشتباه نگیرید.

برنامه نویسی جاوای این پروژه

به قسمت کد جاوای برنامه یعنی MainActivity.java می رویم.

در ابتدا در متد ()onCreate دو متیر از نوع Boolean معرفی می کنیم.

boolean memoryExternalStorageAvailable = false;
boolean memoryExternalStorageWrite = false;

متغیر اولی، یعنی memoryExternalStorageAvailable بررسی می کند که آیا می توان به حافظه دسترسی پیدا کرد؟ به عبارتی آیا حافظه ی خارجی برای اپلیکیشن حاضر (Available) است؟ (Read)

متغیر دومی، یعنی memoryExternalStorageWrite بررسی می کند که آیا امکان نوشتن در حافظه وجود دارد؟ (Write)

کاری که می خواهیم انجام دهیم اینست که با بررسی با استفاده از کدهایی در قسمت بعدی، در صورت مثبت بودن جواب این سوالات، مقدار True و در صورت منفی بودن جواب این سوالات، مقدار false را به متغیر مربوطه بدهیم.

با استفاده از کلاس Environment می توان به حافظه ی خارجی دسترسی داشت.

پس یک متغیر رشته ای از یکی از متدهای این کلاس می سازم. و نامش را state به معنی وضعیت می گذارم.

String state = Environment.getExternalStorageState();

مشاهده می کنید که این متغیر یک نوع رشته از متد getExternalStorageState می باشد. که در واقع متد getExternalStorageState وضعیت حافظه ی خارجی را به ما اطلاع می دهد.

در قسمت بعدی با استفاده از یک ساختار کنترلی if-else به بررسی این موضوع می پردازم که آیا حافظه ی خارجی بر روی دستگاه، سوار (mount) شده است یا خیر؟

if (Environment.MEDIA_MOUNTED.equals(state)) {
            memoryExternalStorageAvailable = memoryExternalStorageWrite = true;
        } else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
            memoryExternalStorageAvailable = true;
            memoryExternalStorageWrite = false;
        } else {
            memoryExternalStorageAvailable = memoryExternalStorageWrite = false;
        }

در همین ساختار کنترلی است که مقدارهای دو متغیر Boolean ی که در ابتدا تعریف نمودیم، مشخص می شود.

در if دوم، با استفاده از MEDIA_MOUNTED_READ_ONLY به معنی آنست که اگر ، حافظه ی خارجی به صورت Read Only است، فقط متغیر memoryExternalStorageAvailable مقدار True را داشته باشد. که به معنی فقط خواندنی است.

برای این که این موضوع را به اطلاع کاربر برسانیم بهتر است از یک پیغام Toast استفاده کنیم.

پس دو رشته به نام های Readable و Writeable می سازم.

مقدار اولیه ی این دو رشته به ترتیب برابر Not Readable و Not Writable است. ولی اگر از دستور if با موفقیت عبور نمایند، مقدار Can Read Data From External Memory و Can Write Data into External Memory به آن ها داده می شود که این پیغام در آخر با استفاده از یک Toast به کاربر نمایش داده می شود.

String Readable = "Not Readable";
if(memoryExternalStorageAvailable)
    Readable="Can Read Data From External Memory";
String Writeable = "\nNot Writeable";
if(memoryExternalStorageWrite)
     Writeable="\nCan Write Data into External Memory";
Toast.makeText(getApplicationContext(), Readable+Writeable, Toast.LENGTH_SHORT).show();

کد کامل MainActivity.java

import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        boolean memoryExternalStorageAvailable = false;
        boolean memoryExternalStorageWrite = false;
        String state = Environment.getExternalStorageState();

        if (Environment.MEDIA_MOUNTED.equals(state)) {
            memoryExternalStorageAvailable = memoryExternalStorageWrite = true;
        } else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
            memoryExternalStorageAvailable = true;
            memoryExternalStorageWrite = false;
        } else {
            memoryExternalStorageAvailable = memoryExternalStorageWrite = false;
        }
        String Readable = "Not Readable";
        if(memoryExternalStorageAvailable)
            Readable="Can Read Data From External Memory";
        String Writeable = "\nNot Writeable";
        if(memoryExternalStorageWrite)
            Writeable="\nCan Write Data into External Memory";
        Toast.makeText(getApplicationContext(), Readable+Writeable, Toast.LENGTH_SHORT).show();

    }
}

در برخی منابع، ذکر شده که برای دادن دسترسی ها به اپلیکیشن در صورت نیاز باید کدهای زیر برای دسترسی به حافظه ی خارجی در AndroidManifest.xml نوشته شوند.

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

پروژه را Run می کنیم.

آموزش برنامه نویسی اندروید با اندروید استودیو (بخش پنجاه و چهارم: انتقال اپلیکیشن به حافظه SD )

استاندارد

بیشتر دستگاه های اندرویدی با حافظه داخلی 16 یا 32 گیگابایت عرضه می شوند. که پس از آن که سیستم عامل و اپلیکیشن هامقداری از آن را به خود اختصاص دهند، مقدار باقی مانده کمتر خواهد بود.

اگر چه این مقدار نیز می تواند در ابتدا کافی باشد ولی به مرور زمان ممکن است حافظه داخلی بعد از مدتی دچار کمبود حافظه شود.

امروزه بیشتر گوشی ها و تبلت های اندرویدی ، امکان اضافه کردن Sd Card را دارند. که می توان با استفاده از آن بعضی از اپلیکیشن ها را به کارت حافظه انتقال داد.

در این قسمت از برنامه نویسی اندروید، می خواهیم به شما آموزش دهیم که چگونه با استفاده از کدنویسی ، این امکان را برای اپلیکیشن خود به وجود آورید.

به عبارتی اگر پروژه هایی که تا به حال نوشته اید، قابلیت Move to Sd card آن ها، غیرفعال بوده است، به دلیل آن است که این امکان را برای پروژه ی خود به وجود نیاورده بودید.

می توان با دسترسی دادن به این پروژه، طبق چیزی که در زیر گفته شده است، این کار را انجام داد.

ولی ما این آموزش را به صورت پروژه محور انجام داده و با استفاده از Intent ، می خواهیم به سراغ تنظیمات این اپلیکیشن رفته تا این بخش را به صورت مستقیم مشاهده کنیم.

همچنین برای کسانی که می خواهند از درون یک اپلیکیشن به صورت مستقیم، به قسمت تنظیمات آن بروند، آموزش خوبی است.

تعیین دسترسی ها

برای آن که بتوانیم به Sd Card منتقل نماییم و در واقع انتقال این اپلیکیشن به حافظه Sd ، باید دسترسی های آن را پیکربندی نماییم.

به سراغ manifests->AndoirdManifest.xml می رویم. سپس کد زیر را در تگ manifest> اضافه می کنیم.

android:installLocation="auto"

دقت نمایید که همین کار برای فعال شدن Move to Sd Card کافی ست.

طراحی Layout اپلیکیشن

ما در اینجا سعی می کنیم این آموزش را به صورتی پروژه محور انجام داده تا با ارائه مثالی عملی این کار را انجام دهیم.

من یک پروژه در اندروید استودیو ایجاد می کنم و نامش را Sd-Card-Gsm می گذارم.

به سراغ Layout اپلیکیشن (activity_main.xml) می رویم و یک دکمه Button ایجاد می کنیم.

<Button
        android:text="Move to Sd Card"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:layout_centerHorizontal="true"
        android:id="@+id/button"
        android:onClick="AppManager"/>

دقت نمایید که به دکمه Button بالا یک خاصیت onClick اضافه نمودیم که مقدار آن AppManager می گذاریم تا متد آن را بعدا در قسمت جاوای برنامه بنویسیم.

android:onClick="AppManager"/>

کاری که این دکمه Button انجام می دهد اینست که با کلیک بر روی آن، برنامه به اکتیویتی تنظیمات این اپلیکیشن رفته تا عملیات Move to Sd Card را برای آن انجام دهیم.

MainActivity.java

به سراغ برنامه نویسی این پروژه (MainActivity.java) می رویم تا کدهای جاوای آن را بنویسیم.

در این قسمت ، در کلاسMainActivity ، یک متد به نام AppManager ایجاد می کنیم.

کاری که این متد برای ما انجام می دهد اینست که با استفاده از این Intent ، وقتی به روی دکمه Button کلیک نماییم، به قسمت تنظیمات (Settings) این اپلیکیشن می رویم.

این متد به شکل زیر است:

public void AppManager(View view) {
        String packageName = "com.gsm_developers.sd_card_gsm";

        try {
            Intent intent = new  Intent(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
            intent.setData(Uri.parse("package:" + packageName));
            startActivity(intent);
        }
        catch (ActivityNotFoundException e) {
            Intent intent = new  Intent(android.provider.Settings.ACTION_MANAGE_APPLICATIONS_SETTINGS);
            startActivity(intent);
        }
    }

 

کدهای بالا را شرح می دهیم:

در قسمت try این متد، یک Intent به نام intent می سازیم که به application details این برنامه دسترسی داشته و وارد آن شویم.

Intent intent = new  Intent(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS);

ولی در ابتدای این متد، یک متغیر به نام packageName از نوع رشته می سازیم که مقدار آن را برابر نام پکیج این پروژه قرار می دهیم.

String packageName = "com.gsm_developers.sd_card_gsm";

باید نام پکیج این اپلیکیشن وقتی به Sd Card منتقل شود، را به این Intent تخصیص دهیم.

intent.setData(Uri.parse("package:" + packageName));

در قسمت بعدی باید این Intent را با استفاده از کد startActivity شروع (Start) نماییم.

startActivity(intent);

کد کامل MainActivity

package com.gsm_developers.sd_card_gsm;

import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.net.Uri;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    public void AppManager(View view) {
        String packageName = "com.gsm_developers.sd_card_gsm";

        try {
            Intent intent = new  Intent(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
            intent.setData(Uri.parse("package:" + packageName));
            startActivity(intent);
        }
        catch (ActivityNotFoundException e) {
            Intent intent = new  Intent(android.provider.Settings.ACTION_MANAGE_APPLICATIONS_SETTINGS);
            startActivity(intent);
        }
    }
}

یادتان باشد که دسترسی این اپلیکیشن را نیز تغییر دهید.

یعنی به سراغ manifests->AndoirdManifest.xml رفته و سپس کد زیر را در تگ manifest> اضافه می کنیم.

android:installLocation="auto"

 کد کامل manifest این اپلیکیشن را در زیر مشاهده می کنید.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.gsm_developers.sd_card_gsm"
    android:installLocation="auto">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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

</manifest>

کار به اتمام رسیده است، پروژه را Run می کنیم.

با زدن دکمه ی Move To Sd Card به بخش Settings این اپلیکیشن می رویم.

مشاهده می کنید که این قسمت برای این اپلیکیشن فعال شده است.

آموزش برنامه نویسی اندروید با اندروید استودیو (بخش پنجاه و دوم: برنامه نویسی کلیپ بورد (ClipBoard) در اندروید )

استاندارد

در این بخش از برنامه نویسی اندروید، می خواهیم نحوه ساخت کلیپ بورد (ClipBoard) های ساده را به شما آموزش دهیم.

کلیپ بورد (clipboard) یک حافظه ی موقت است که تصاویر،متن و ..در این محیط به طور موقت ذخیره می شوند تا بعدا مورد استفاده قرار بگیرد و یا حذف شود.

این بخش را به صورت پروژه محور، انجام می دهیم.

من یک پروژه به نام Gsm-ClipBoard در اندروید استودیو ایجاد می کنم. به سراغ فایل Layout برنامه یعنی activity_main.xml می روم.

این فایل همان طور که می دانید در مسیر res->Layout می باشد.

کاری که می خواهیم انجام دهیم اینست که در یک EditText یا همان PlainText ، متنی را بنویسیم سپس با استفاده از ابزار دکمه button کپی کنیم. و در EditText دیگر، آن را با دکمه ی Button دیگر، Paste نماییم. پس به چهار ابزار نیاز داریم.

پس دو ابزار PlainText از جعبه ابزار (Palette) انتخاب کرده و به لایه اپلیکیشن می کشم.

سپس دو ابزار دکمه Button نیز به داخل این لایه می کشم. و اسم یکی از آن ها را Copy نام دیگری را Paste می گذارم.

من برای دو دکمه ی Button که ایجاد کردم خاصیت دیگری به اسم onClick اضافه می کنم.

این خاصیت شبیه Listener عمل می کند و باعث می شود که وقتی بر روی دکمه Button کلیک کردیم، دکمه تابعی که به آن در این قسمت معرفی می شود را اجرا نماید.

به عنوان مثال :

android:onClick="copy"

در قسمت جاوای برنامه باید متدی به نام copy وجود داشته باشد تا وقتی بر روی این دکمه کلیک شد، عملیات مربوط به آن اجرا شوند.

پس کد دکمه های ما به این صورت است:

<Button
        android:text="Copy"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/editText"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="50dp"
        android:onClick="copy"
        android:id="@+id/button" />

    <Button
        android:text="Paste"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignTop="@+id/editText2"
        android:layout_alignLeft="@+id/button"
        android:layout_alignStart="@+id/button"
        android:layout_marginTop="80dp"
        android:onClick="paste"
        android:id="@+id/button2" />

کد Layout اپلیکیشن

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.gsm_developers.clipboard_gsm.MainActivity">

    <EditText
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:inputType="textPersonName"
        android:text="Copy this text"
        android:ems="10"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="83dp"
        android:id="@+id/editText" />

    <EditText
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:inputType="textPersonName"
        android:text="Paste The text here"
        android:ems="10"
        android:layout_alignParentBottom="true"
        android:layout_alignRight="@+id/editText"
        android:layout_alignEnd="@+id/editText"
        android:layout_marginBottom="154dp"
        android:id="@+id/editText2" />

    <Button
        android:text="Copy"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/editText"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="50dp"
        android:onClick="copy"
        android:id="@+id/button" />

    <Button
        android:text="Paste"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignTop="@+id/editText2"
        android:layout_alignLeft="@+id/button"
        android:layout_alignStart="@+id/button"
        android:layout_marginTop="80dp"
        android:onClick="paste"
        android:id="@+id/button2" />
</RelativeLayout>

به سراغ فایل MainActivity.java می رویم تا کدهای جاوای برنامه را بنویسیم.

در کلاس MainActivity ، ابتدا یک شی به نام Clipboard از کلاس ClipboardManager ، می سازیم. تا عملیات مربوط به Copy & Paste را بتوانیم با آن مدیریت نماییم.

private ClipboardManager Clipboard;

سپس یک شی به نام Clipdata از کلاس ClipData می سازیم تا مقدار رشته ای که می خواهیم از EditText اول، کپی کنیم را در خود نگه دارد.

private ClipData Clipdata;

همچنین دو شی نیز از کلاس EditText می سازیم تا بتوانیم ابزارهای CopyText و PasteText را به کد جاوای برنامه معرفی کنیم.

private EditText CopyText,PasteText;

در متد ()onCreate این اشیایی که ساختیم را مقدار دهی می کنیم. تا در هنگام اجرای برنامه دارای مقدار باشند.

Clipboard = (ClipboardManager)getSystemService(CLIPBOARD_SERVICE);
CopyText = (EditText)findViewById(R.id.editText);
PasteText = (EditText)findViewById(R.id.editText2);

البته Clipdata که شی از کلاس ClipData بود را در توابعی که می خواهیم بنویسیم، مقدار دهی می کنیم.

در خارج از متد ()onCreate یک تابع برای عملیات کپی مینویسیم. اسم این تابع را copy می گذاریم.

public void copy(View view){
        String text = CopyText.getText().toString();
        Clipdata = ClipData.newPlainText("text", text);
        Clipboard.setPrimaryClip(Clipdata);
        Toast.makeText(getApplicationContext(), "Text Copied",
                Toast.LENGTH_SHORT).show();
    }

کد بالا ابتدا متغیری به نام text را از نوع رشته معرفی کرده و مقدار آن را برابر با متنی که در ابزار EditText اول وجود دارد می گذارد.

سپس در خط دوم، مقدار آن را به عنوان ورودی متد newPlainText برای ذخیره ی نوشته ، در آبجکت Clipdata می ریزیم.

دستور getPrimaryClip که یکی از اجزای آبجکت Clipboard است، کلیپ بورد را برای عملیات کپی و پیس فراخوانی می کند.

مقدار آرگومان ورودی این متد (getPrimaryClip) برای کپی کردن، آبجکت Clipdata که شی از کلاس ClipData می باشد، است که در بالا آن را مقدار دهی کردیم.

در خط آخر نیز، عملیات کپی کردن متن، به کاربر با استفاده از یک Toast اطلاع داده می شود.

در قسمت بعدی یک متد برای Paste کردن به نام paste می نویسیم.

public void paste(View view){
        ClipData neveshte = Clipboard.getPrimaryClip();
        ClipData.Item item = neveshte.getItemAt(0);
        String text = item.getText().toString();
        PasteText.setText(text);
        Toast.makeText(getApplicationContext(), "Text Pasted",
                Toast.LENGTH_SHORT).show();
    }

در کد بالا و اولین خط با استفاده از متد getPrimaryClip ، آبجکت Clipdata که مقدار آن را در کد بالا از ورودی EditText اول گرفته بودیم، فراخوانی کرده و در یک آبجکت جدید به نام neveshte که نوعی از کلاس ClipData می باشد می ریزیم.

در دو خط بعدی مقدار نوشته ای که درون این آبجکت است، گرفته شده و به رشته تبدیل می شود.

در خط چهارم، مقدار این رشته را به عنوان ورودی متن در ابزار EditText دوم ( که با آیدی PasteText آن را می شناسیم)، می ریزیم.

در خط آخر نیز با استفاده از پیغام Toast موفق بودن عملیات به کاربر نشان داده می شود.

کدهای MainActivity.java

package com.gsm_developers.clipboard_gsm;

import android.content.ClipData;
import android.content.ClipboardManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    private ClipboardManager Clipboard;
    private ClipData Clipdata;
    private EditText CopyText,PasteText;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Clipboard = (ClipboardManager)getSystemService(CLIPBOARD_SERVICE);
        CopyText = (EditText)findViewById(R.id.editText);
        PasteText = (EditText)findViewById(R.id.editText2);
    }

    public void copy(View view){
        String text = CopyText.getText().toString();
        Clipdata = ClipData.newPlainText("text", text);
        Clipboard.setPrimaryClip(Clipdata);
        Toast.makeText(getApplicationContext(), "Text Copied",
                Toast.LENGTH_SHORT).show();
    }

    public void paste(View view){
        ClipData neveshte = Clipboard.getPrimaryClip();
        ClipData.Item item = neveshte.getItemAt(0);
        String text = item.getText().toString();
        PasteText.setText(text);
        Toast.makeText(getApplicationContext(), "Text Pasted",
                Toast.LENGTH_SHORT).show();
    }
}

پروژه را Run می کنیم.

بر روی دکمه ی Copy کلیک می کنیم تا نوشته ی درون EditText ، کپی شود.

مشاهده می کنید که با استفاده از یک Toast این موضوع به اطلاع می رسد.

حال بر روی دکمه Paste کلیک می کنیم. مشاهده می کنید که نوشته ی بالا در ابزار EditText دوم، Paste شد.

آموزش برنامه نویسی اندروید با اندروید استودیو (بخش پنجاه و یکم: ارسال پیامک Sms با استفاده از خود اپلیکیشن )

استاندارد

در بخش قبلی در مورد نحوه ارسال sms در اپلیکیشن با استفاده از Intent صحبت کردیم.

پیام و شماره مخاطبی که می خواستیم پیام بفرستیم با استفاده از Intent به اکیتیویتی جدید و در واقع برنامه SMS که در سیستم عامل اندروید وجود دارد، محول می شد.

ولی سوالی که در اینجا پیش می آید اینست که چگونه می توان در خود اپلیکیشن و به صورت مستقیم اقدام به ارسال پیامک نمود؟

در این بخش با ما همراه باشید تا این شیوه را هم آموزش دهیم.

برای این کار دیگر نیازی به Intent ها نخواهیم داشت.

ولی این بخش حتی می تواند ساده تر از بخش قبلی باشد.

کاری که باید انجام بدهیم استفاده از کلاس SmsManager است.

کلاس SmsManager ، خود  عملیات ارسال پیامک را برای ما انجام می دهد و دیگر نیازی به Intent نمی باشد.

ولی باید دسترسی و مجوز ارسال پیامک به اپلیکیشن اندرویدیمان داده شود.

تمام مراحل طراحی Layout اپلیکیشن مثل جلسه قبل می باشد ولی ما بار دیگر برای جلوگیری از ابهام این مرحله را شرح می دهیم.

طراحی Layout اپلیکیشن

همانن بخش قبلی باید دو  EditText ایجاد نماییم.

یکی از آن ها که یک نوع PlainText است، کاربر پیام خود را وارد می کند.

و دومی مربوط به اینست که کاربر شماره ای که می خواهد به آن پیام ارسال کند را در EditText که یک ابزار Phone است، وارد نماید.

من یک پروژه در اندروید استودیو به نام Sms-Gsm ایجاد می کنم.

به قسمت لایه اپلیکیشن می روم و سپس از قسمت Text Fields ها در Palette ، یک ابزار Plain Text و یک ابزار Phone به Layout برنامه اضافه می کنم.

از قسمت Widget ها هم یک دکمه Button را برای ارسال اضافه میکنم.

کدهای Layout اپلیکیشن

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.gsm_developers.sms_gsm.MainActivity">

    <EditText
        android:layout_width="300dp"
        android:layout_height="200dp"
        android:inputType="textPersonName"
        android:text="write your text"
        android:ems="10"
        android:layout_marginTop="23dp"
        android:id="@+id/editText"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true" />

    <EditText
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:inputType="phone"
        android:ems="10"
        android:layout_below="@+id/editText"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="37dp"
        android:id="@+id/editText2" />

    <Button
        android:text="Send"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/editText2"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="53dp"
        android:id="@+id/button" />
</RelativeLayout>

کدنویسی جاوای پروژه

به سراغ قسمت کدنویسی جاوای پروژه می رویم. (این قسمت نیز همانند بخش قبلی می باشد)

ابتدا باید سه ابزار PlainText که برای Message به کار می رود و Phone که یک EditText است و دکمه Button را به قسمت جاوای برنامه معرفی کنم.

پس دو شی EditText و یک شی Button خارج از متد ()onCreate به صورت سراسری ایجاد می کنم.

EditText Message;
EditText PhoneNumber;
Button SendButton;

حال در متد ()onCreate این سه شی را با استفاده از آیدی هایی که در لایه اپلیکیشن به سه ابزارمان دادیم، مقدار دهی میکنم.

Message =(EditText)findViewById(R.id.editText);
PhoneNumber =(EditText)findViewById(R.id.editText2);
SendButton =(Button)findViewById(R.id.button);

در مرحله ی بعدی یک رویداد Listener برای دکمه ایجاد می کنم تا وقتی بر روی دکمه Button کلیک شد، عملیاتی که می خواهیم را برای ما انجام دهد.

از این قسمت به بعد مراحل جدیدی را می خواهیم انچام بدهیم.

ابتدا باید پیام و شماره تماس مخاطب را از ابزارهایی که در قسمت لایه اپلیکیشن تعریف کرده بودیم، به رشته string تبدیل نماییم.

String Msg = Message.getText().toString();
String nmbr = PhoneNumber.getText().toString();

در قسمت بعدی، یک شی به نام MySms از کلاس SmsManager تعریف می کنیم.

SmsManager MySms = SmsManager.getDefault();

یکی از متدهای این کلاس یعنی sendTextMessage  برای ارسال پیامک به کار می رود.

پس با استفاده از شی MySms به این متد دسترسی پیدا می کنیم و پیام و شماره تماس که دو نوع رشته هستند را در قسمت آرگومان ورودی این متد، می نویسیم.

MySms.sendTextMessage(nmbr, null, Msg, null, null);

ورودی اول، مربوط به آدرس مقصد ( شماره مخاطب ) ، ورودی دوم مربوط به آدرس مبدا (شماره فرستنده ) ، ورودی سوم، مربوط به پیام متنی و دو ورودی بعدی مربوط به مورد های ارسال و تحویل می باشند.

کد دکمه Button :

SendButton.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View arg0) {

                String Msg = Message.getText().toString();
                String nmbr = PhoneNumber.getText().toString();

                SmsManager MySms = SmsManager.getDefault();
                MySms.sendTextMessage(nmbr, null, Msg, null, null);
            }

        });

کد کامل MainActivity

package com.gsm_developers.sms_gsm;

import android.content.Intent;
import android.net.Uri;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.telephony.SmsManager;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

public class MainActivity extends AppCompatActivity {

    EditText Message;
    EditText PhoneNumber;
    Button SendButton;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Message =(EditText)findViewById(R.id.editText);
        PhoneNumber =(EditText)findViewById(R.id.editText2);
        SendButton =(Button)findViewById(R.id.button);

        SendButton.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View arg0) {

                String Msg = Message.getText().toString();
                String nmbr = PhoneNumber.getText().toString();

                SmsManager MySms = SmsManager.getDefault();
                MySms.sendTextMessage(nmbr, null, Msg, null, null);
            }

        });
    }
}

نوبت به قسمت مجوزهای اپلیکیشن می رسد. برای ارسال پیامک Sms ، این اپلیکیشن باید دسترسی ارسال آن را داشته باشد.

پس به قسمت دسترسی ها یعنی AndroidManifest.xml می رویم.

و دسترسی زیر را قبل از تگ application> تعریف می کنیم.

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

پروژه را Run می کنیم.

پیام و شماره مورد نظر خود را وارد می کنیم.

دکمه Send را می زنیم تا پیام ارسال شود.

آموزش برنامه نویسی اندروید با اندروید استودیو (بخش پنجاه: ارسال پیامک Sms با استفاده از پیام رسان پیش فرض اندروید )

استاندارد

در بخش قبلی به قابلیت PhoneCall در برنامه نویسی اندروید، پرداختیم.

با استفاده از PhoneCall می توانستیم با دادن یک شماره ، و زدن یک دکمه Button که بر روی آن “تماس” نوشته شود، به آن شماره زنگ بزنیم.

در این بخش ، قابلیت دیگر ارتباطی یعنی ارسال پیامک را در برنامه نویسی اندروید آموزش می دهیم.

این آموزش، بسیار شبیه به بخش قبلی می باشد.

این بار با استفاده از دو مورد شماره و پیام، پیام را به شماره ای که می خواهیم می فرستیم.

برای این پروژه ما از Intent که در بخش قبلی آن را آموزش دادیم ، استفاده می کنیم. زیرا Intent قادر است داده ای را به صورت پیام به activity دیگری بفرستد.

ما برای ارسال پیام نیز به اکتیویتی تماس احتیاج داریم. پس شماره و پیام را به این اکتیویتی با استفاده از اینتنت می فرستیم.

دو  EditText ایجاد می کنیم.

یکی از آن ها که یک نوع PlainText است، کاربر پیام خود را وارد می کند.

کاربر می تواند شماره ای که می خواهد به آن پیام ارسال کند را در EditText که یک ابزار Phone است، وارد نماید.

شماره و پیام  داخل این دو ابزار را به ACTION_VIEW می فرستیم. ACTION_VIEW وظیفه ی عملیات ارسال پیامک را دارد.

من یک پروژه در اندروید استودیو به نام Sms-Gsm ایجاد می کنم.

به قسمت لایه اپلیکیشن می روم و سپس از قسمت Text Fields ها در Palette ، یک ابزار Plain Text و یک ابزار Phone به Layout برنامه اضافه می کنم.

از قسمت Widget ها هم یک دکمه Button را برای ارسال اضافه میکنم.

کدهای Layout اپلیکیشن

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.gsm_developers.sms_gsm.MainActivity">

    <EditText
        android:layout_width="300dp"
        android:layout_height="200dp"
        android:inputType="textPersonName"
        android:text="write your text"
        android:ems="10"
        android:layout_marginTop="23dp"
        android:id="@+id/editText"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true" />

    <EditText
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:inputType="phone"
        android:ems="10"
        android:layout_below="@+id/editText"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="37dp"
        android:id="@+id/editText2" />

    <Button
        android:text="Send"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/editText2"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="53dp"
        android:id="@+id/button" />
</RelativeLayout>

به سراغ قسمت کدنویسی جاوای پروژه می رویم.

ابتدا باید سه ابزار PlainText که برای Message به کار می رود و Phone که یک EditText است و دکمه Button را به قسمت جاوای برنامه معرفی کنم.

پس دو شی EditText و یک شی Button خارج از متد ()onCreate به صورت سراسری ایجاد می کنم.

EditText Message;
EditText PhoneNumber;
Button SendButton;

حال در متد ()onCreate این سه شی را با استفاده از آیدی هایی که در لایه اپلیکیشن به سه ابزارمان دادیم، مقدار دهی میکنم.

Message =(EditText)findViewById(R.id.editText);
PhoneNumber =(EditText)findViewById(R.id.editText2);
SendButton =(Button)findViewById(R.id.button);

در مرحله ی بعدی یک رویداد Listener برای دکمه ایجاد می کنم تا وقتی بر روی دکمه Button کلیک شد، عملیاتی که می خواهیم را برای ما انجام دهد.

SendButton.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View arg0) {

                String Msg = Message.getText().toString();
                String nmbr = PhoneNumber.getText().toString();

                Intent intent = new Intent( Intent.ACTION_VIEW, Uri.parse( "sms:" + nmbr));
                intent.putExtra( "sms_body", Msg );
                startActivity(intent);
            }

        });

در کد بالا ابتدا با استفاده از متد ()getText().toString ، پیام و شماره ای که در ابزار Plain Text و phone وجود دارد، به رشته تبدیل شده و به متغیرهای Msg و nmbr که یک نوع رشته هستند، داده می شود.

این کار لازم است زیرا ما می خواهیم پیام را در Intent به صورت رشته ارسال نماییم.

سپس یک شی به نام intent از نوع Intent می سازیم و Intent.ACTION_VIEW را به آن نسبت می دهیم.

در قسمت بعدی با استفاده از متد putExtra که در کلاس Intent وجود دارد، شی intent را مقداردهی می کنیم.

(در این قسمت پیامی که داده ایم ، به عنوان یکی از پارامترهای شی intent مورد استفاده قرار می گیرد)

در آخر با استفاده از متد startActivity این اکتیویتی را شروع می کنیم.

کد کامل MainActivity

package com.gsm_developers.sms_gsm;

import android.content.Intent;
import android.net.Uri;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

public class MainActivity extends AppCompatActivity {

    EditText Message;
    EditText PhoneNumber;
    Button SendButton;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Message =(EditText)findViewById(R.id.editText);
        PhoneNumber =(EditText)findViewById(R.id.editText2);
        SendButton =(Button)findViewById(R.id.button);

        SendButton.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View arg0) {

                String Msg = Message.getText().toString();
                String nmbr = PhoneNumber.getText().toString();

                Intent intent = new Intent( Intent.ACTION_VIEW, Uri.parse( "sms:" + nmbr));
                intent.putExtra( "sms_body", Msg );
                startActivity(intent);
            }

        });
    }
}

پروژه را Run می کنیم.

پیام و شماره مورد نظر خود را وارد می کنیم.

Send را میزنیم و مشاهده می کنیم که صفحه ارسال پیامک sms فراخوانی می شود. (اکتیویتی ارسال پیامک)

آموزش برنامه نویسی اندروید با اندروید استودیو (بخش چهل و هشتم: ساخت اکتیویتی جدید و رفتن به آن با استفاده از Intent )

استاندارد

در این بخش از آموزش برنامه نویسی اندروید می خواهیم کار با اینتنت ها (Intent) و گذر بین اکتیویتی ها را آموزش بدهیم.

این بخش را با استفاده از رفتن از یک اکتیویتی به اکتیویتی دیگر با استفاده از Intent ، آموزش خواهیم داد.

اینتنت ها بسیار مفید و کاربردی هستند و آموزش های آینده از اینتنت ها استفاده های بسیاری خواهیم نمود.

اینتنت ها وظیفه دارند اطلاعاتی را از مبدا گرفته و به مقصد ارسال نمایند. این اطلاعات می توانند در قالب پیام و یا یک رویداد باشند.

در این مراحل با Intent های بسیار پرکاربرد آشنا خواهیم شد.

پس از معرفی توضیحاتی در رابطه با Intentها کار را شروع می کنیم.

من یک پروژه به نام Intent-Gsm در اندروید استودیو ایجاد می کنم. سپس به قسمت لایه اپلیکیشن برنامه می روم و یک دکمه Button را به لایه می کشم.

این دکمه وظیفه ی این را خواهد داشت که با کلیک به اکتیویتی دوم برود.

کدهای Layout

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.gsm_developers.intent_gsm.MainActivity">

    <Button
        android:text="Button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="181dp"
        android:id="@+id/button"
        android:elevation="0dp" />
</RelativeLayout>

پس از اضافه کردن دکمه ، باید یک Activity جدید به پروژه اضافه نماییم.

برای این کار از منوی فایل New را زده و به قسمت Activity می رویم. سپس Empty Activity را انتخاب می کنیم.

در پنجره باز شده، نام اکتیویتی جدید را از شما می خواهد.

ما نام هایی که خود اندورید استودیو به صورت پیش فرض انتخاب کرده است را به همان صورت می گذاریم.

ولی این نام ها چیست؟

در قسمت اول (Activity Name) نام همان فایلی را می خواهد که در مسیر Java وجود دارد. یعنی همان قسمتی که برای برنامه نویسی جاوا به کار می رود.

در قسمت دوم (Layout Name) نام لایه اپلیکیشن ما را می خواهد.

زیرا یک اکتیویتی جدا باید همراه با کدجاوای جداگانه و رابط کاربری جداگانه برای آن کد باشد.

پس شما می توانید نامی دلخواه برای این دو انتخاب نمایید به شرطی که نام اکتیویتی جدید، با اکتیویتی های موجود، یکسان نباشد.

ولی در قسمت آخر، نام پکیج پروژه را بدهید.

بر روی Finish کلیک کرده سپس مشاهده می کنید که فایل جاوای اکتیویتی جدید ما اضافه شده است.

همچنین لایه ای برای طراحی این اکتیویتی نیز در قسمت layout اضافه شده است.

به قسمت لایه طراحی (layout) اکتیویتی جدید (در اینجا فایل activity_main2.xml) می رویم.

یک TextView به این لایه اضافه می کنیم. من نام این TextView را Activity 2 قرار می دهم.

Layout اکتیویتی دوم

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main2"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.gsm_developers.intent_gsm.Main2Activity">

    <TextView
        android:text="Activity 2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="218dp"
        android:id="@+id/textView" />
</RelativeLayout>

در اکتیویتی اول، یک دکمه ی Button اضافه کردیم. حال باید به قسمت جاوای اکتیویتی اول برویم تا کدهایی را برای آن دکمه بنویسیم که با کلیک به اکتیویتی دوم از این پروژه منتقل شویم.

پس فایل MainActivity.java را باز می کنیم.

در متد ()onCreate دکمه ی Button را به قسمت جاوای برنامه معرفی می کنیم.

Button Btn = (Button) findViewById(R.id.button);

یک رویداد onClickListener به دکمه Button اضافه می کنیم.

پس باید در این رویداد، کدی تعریف نماییم که با کلیک بر روی Button ، به اکتیویتی دوم منتقل شویم.

Btn.setOnClickListener(new View.OnClickListener() {

            public void onClick(View v) {

                startActivity(new Intent(MainActivity.this , Main2Activity.class));
            }
});

همان طور که مشاهده می کنید با استفاده از متدی به نام startActivity این کار صورت می پذیرد.

در این متد، یک Intent جدید با استفاده از دستور New Intent به عنوان ورودی برای startActivity می نویسیم.

این Intent دو آرگومان ورودی می پذیرد.

یکی اکتیویتی که در آن هستیم که در کد بالا به صورت MainActivity.this مشخص شده است.

دومین آرگومان ، اکتیویتی که می خواهیم به آن برویم، که این کار نیز به صورت کد Main2Activity.class نوشته شده است.

MainActivity.java

package com.gsm_developers.intent_gsm;

import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button Btn = (Button) findViewById(R.id.button);
        Btn.setOnClickListener(new View.OnClickListener() {

            public void onClick(View v) {

                startActivity(new Intent(MainActivity.this , Main2Activity.class));
            }
        });
    }
}

پروژه را اجرا می کنیم.

وقتی اپلیکیشن اجرا می شود، مشاهده می کنید که Layout مربوط به اکتیویتی اول به شما نشان داده می شود.

پس از کلیک بر روی Button ، اکتیویتی دوم برای شما ظاهر خواهد شد.

آموزش برنامه نویسی جاوا (بخش بیستم: سازنده و مخرب در جاوا)

استاندارد

سازنده یا Constructor

در هنگام ساخت یک شی از یک نمونه کلاس، می توان متغیر های یک شی را مقداردهی اولیه کرد.

تابع سازنده (Constructor) تابعی است که در حین نمونه گرفتن از یک کلاس یک مرتبه اجرا می شود. زیرا بسیار ساده تر و دقیق تر آن است که کلیه تنظیمات در زمان ایجاد اولیه شی انجام شود.

از این تابع بیشتر برای مقداردهی کردن متغییر ها و فیلدهای یک کلاس در هنگام ساخت یک شی، استفاده می شود.

معمولا بعضی از اعضای کلاس قبل از استفاده نیاز به مقداردهی دارندکه همان طور که گفته شد، اين عمل توسط سازنده (constractor) انجام می گیرد که به شیء اين امکان را می دهد که هنگام ايجاد مقداردهی شود.

سازنده تابعی است هم اسم کلاس که وقتی یک نمونه از کلاس گرفته می شود اتوماتیک فراخوانی می شود.

سازنده نام همان کلاسی را که در آن قرار گرفته اختیار نموده و از نظر صرف و نحو مشابه یک روش است.

وقتی یکبار سازنده ای را تعریف نمایید، بطور خودکار بلافاصله پس از ایجاد یک شی و قبل از اینکه عملگر new تکمیل شود، فراخوانی خواهد شد.

سازندگان کمی بنظر عجیب می آیند زیرا فاقد نوع برگشتی و حتی فاقد void هستند.

در زبان های شی گرا مثل سی شارپ و جاوا چون همه چیز بر پایه شی گرایی و کلاس هست شما وقتی یک کلاس می سازید میتونید با استفاده از سازنده ها متغیر ها رو مقدار دهی کنید.

وقتی شما یکی شی از کلاس مورد نظرتون می سازین(new می کنید!) کامپایلر به سراغ سازنده ی شما می رود که اگه نباشه سازنده ی پیش فرض فراخونی میشه که بدون پارامتره و شما میتونید از سازنده استفاده کرده و اونطوری که دلتون می خواد متغیر هاتون رو مقدار دهی کنید و از همون اول برای شی ساخته شدتون بفرستید .

تابع سازنده می تواند دارای پارامتر باشد بنابراين زمان ايجاد شیء می توان به متغيرهای عضو مقادير اوليه داد. برای ارسال آرگومان به تابع سازنده بايد هنگام تعريف شیء مقدار آرگومان بعد از نام شیء درون پرانتز قرار گيرد.

یک کلاس می تواند دارای چند سازنده با پارامترهای مختلف باشد. بهتر است همیشه حداقل یک سازنده حتی اگر خالی باشد ساخته شود.

برای تابع سازنده مقدار برگشتی ذکر نمی شود (حتی Void).

برای درک بیشتر به مثال زیر توجه نمایید:

public class JavaApplication1 {

static class myClass{
    private int a;
    private char b;
// تابع سازنده
    myClass(){
    this.a=1; // مقدار دهی به متغیر در تابع سازنده
    this.b='a'; // مقدار دهی به متغیر در تابع سازنده
    }
}    
    public static void main(String[] args) {
        myClass newObject = new myClass(); // ایجاد شی
        System.out.print(newObject.a);
        System.out.print(newObject.b);
    } 
}

خروجی کد بالا، 1a می باشد. زیرا شی به هنگام ساخت توسط سازنده ی خودش مقدار دهی می شود.

همچنین سازنده می تواند مقادیری را نیز به صورت پارامتر ورودی در هنگام ساخت شی ، از شی بگیرد.

برای این کار کافیست، در تابع سازنده، پارامتر ورودی در داخل پرانتز، بنویسیم. سپس در هنگام ساخت شی، مقادیر ورودی به آن پارامتر ها را بدهیم تا سازنده بتواند مقدار دهی متغیرهای شی را انجام دهد.

مثال زیر، چگونگی ساخت سازنده با استفاده از پارامتر ورودی را به شما نشان می دهد:

public class JavaApplication1 {

static class myClass{
    int a;
    char b;
// ساخت تابع سازنده
    myClass(int m, char n){
        a = m;
        b = n;
    }
}    
    public static void main(String[] args) {
        myClass newObject = new myClass(5,'m'); // مقدار دهی اولیه فیلدهای شی با استفاده از سازنده
        System.out.print(newObject.a); // خروجی مقدار 5 را نشان می دهد
        System.out.print(newObject.b); را نشان می دهد m خروجی مقدار

    } 
}

constructor مشخص می کند که هنگام ایجاد شیئی از نوع کلاس ، چه اتفاقی رخ می دهد . constructor های خاص خودشان را در تعریف کلاس مشخص می کنند. اما ، اگر constructor به طور صریح مشخص نشود ، در آن صورت جاوا آن را به طور خودکار تامین می کند. در خصوص کلاس ذکر شده در بخش قبل نیز، همین طور است.

مخرب یا Destructor

تابع مخرب کلاس (destructor) کم و بیش عکس سازنده عمل می کند. یک مخرب وقتی فراخوانی می شود که یک شی از بین می رود.

در ++C یک مخرب مشابه سازنده ساخته می شود فقط قبل از اسم آن علامت مد (~)قرار می گیرد.

تابع مخرب اتوماتیک وقتی متغیر شیء از حوزه دسترسی خارج می شود (برای متغیرهای سراسری وقتی از تابع اصلی خارج می شود و برای متغیر محلی هنگام خروج از بلاک تابع) فراخوانی می شود.

مشابه سازنده ها تابع مخرب نيز نوع برگشتی ندارد.

توابع مخرب یا destructor کاربرد زیادی در مدیریت حافظه برنامه های نوشته شده در ++C دارند.

عموما در مورد کلاسهای طراحی شده، با استفاده از این متد به آزاد سازی حافظه پرداخته میشود.

اما در زبانی مانند جاوا که مدیریت حافظه در اختیار ماشین مجازی میباشد، استفاده از این تابع چندان منطقی نیست، با این حال امکان پیاده سازی آن با استفاده از تابع finalize فراهم شده است.

برای انجام این کار در کلاس مربوطه یک تابع به نام finalize پیاده سازی گشته و سیستم Garbage Collector در زمان اتمام استفاده از کلاس و آزاد سازی تمام ارجاعات آن، تابه finalize را فراخوانی مینماید.

از آنجا که زمان عملکرد Grabage Collector نا مشخص است، با استفاده از دستورات gc و runFinalization میتوان ماشین مجازی را ملزم به آزاد سازی حافظه (جمع آوری زباله ها از حافظه) نمود.

مثال زیر نحوه انجام این کار را نشان میدهد:

import java.util.ArrayList;
 
public class Samples  {
    public static void main(String[] args){
        long mem = Runtime.getRuntime().freeMemory();
 
        SampleClass c1 = new SampleClass();
        SampleClass c2 = new SampleClass();
        SampleClass c3 = new SampleClass();
 
        System.out.println(String.format("Used memory: %d KB", (mem - Runtime.getRuntime().freeMemory())/1024));
        mem = Runtime.getRuntime().freeMemory();
 
        c1 = c2 = c3 = null;
 
        System.gc();
        System.runFinalization();
 
        System.out.println(String.format("Released memory: %d KB", (Runtime.getRuntime().freeMemory() - mem)/1024));
    }
}
 
class SampleClass {
    private ArrayList<Double> _obj;
 
    public SampleClass() {
        _obj = new ArrayList<Double>();
        for (int i=0; i<1000000; i++)
            _obj.add(Math.random());
 
        System.out.println("Created");
    }
 
    public void finalize() {
        _obj.clear();
        _obj = null;
        System.out.println("Finalized");
    }
 
}

آموزش برنامه نویسی جاوا (بخش هجدهم: کار با متدها در جاوا – قسمت دوم)

استاندارد

در بخش قبلی، کار با متدها توضیح داده شد. تقریبا بیشتر برنامه های سطح متوسطی که در ادامه خواهیم نوشت، با همان معلومات کافی خواهند بود. ولی بعضی اوقات حتی در یک برنامه ی ساده نیز ممکن است کمی کار پیچیده شود.

در این بخش به ادامه ی مباحثی در مورد کار با متدها می پردازیم. تا کار با متدها را تقریبا تمام کنیم.

این که می گوییم “تقریبا” ، بدان معنی ست که مباحثی تکمیلی در مورد متدها لازم است در آینده مطرح شود که احتیاج است مطالبی دیگر را ابتدا بلد باشید.

آرگومان های متغیر(Variable Arguments)

در بخش قبلی توضیح دادیم که اگر بخواهیم تعداد ورودی های مختلفی به تابع بدهیم باید از مفهوم Overload برای توابع استفاده نماییم.

از JDK 1.5 به بعد می توانیم توسط مفهوم Variable Arguments ، هر تعداد پارامتر ورودی از یک نوع که می خواهیم به تابع بدهیم.

این نوع ورودی ها آرگومان های متغیر نام دارد که به شکل زیر تعریف می شود.

typeName... parameterName

برای تعریف این گونه پارامترها در تابع، باید نوع متغیر را ابتدا مشخص کنید سپس از سه نقطه (…) بدون فاصله از نوع متغیر استفاده نمایید.

در مرحله ی بعد، نامی دلخواه برای پارامتر دریافتی در مقصد نیز مشخص کنید.

مثال:

public class JavaApplication1 {

    public static void main(String[] args) {

        int a = 1;
        int b = 2;
        int c = 3;
        int d = 4;
        VAMethod(a,b,c,d);

    }
    public static void VAMethod(int... numbers){
       System.out.print(numbers.length); // numbers نمایش طول متغیر آرایه ای 
       System.out.print(numbers[2]); // numbers نمایش خانه ای از آرایه ی
    }   
}

همان طور که در بالا مشاهده می نمایید، numbers یک متغیر آرایه است. و با آن به همان صورتی که با آرایه برخورد می کنیم.

متد finalize

بعضی اوقات در جاوا این امکان وجود دارد که در هنگام از بین رفتن یک شی، عمل خاصی انجام شود.

از بین رفتن شی یعنی این که آن شی از داخل حافظه پاک شود.

عمل خاص می تواند، این گونه باشد که قبل از ، از بین رفتن شی ، عملیاتی همچون بستن فایل ها و یا ارتباطات دیتابیس انجام شود.

این عمل در جاوا توسط متد finalize انجام می شود.

همه ی عملیاتی که می خواهیم در هنگام بسته شدن شی انجام شود باید در متد finalize تعریف شود.

finalize به شکل کلی زیر است:

protected void finalize( )
{
   //  finalize کدهای 
}

اگر دقت کنید متوجه می شوید که modifier این متد، از نوع protected تعریف شده است.

دلیل این کار این است که کسی نتواند از خارج از شئ به این متد دسترسی داشته باشد و نتواند آن را صدا بزند.

آموزش برنامه نویسی جاوا (بخش هفدهم: کار با متدها در جاوا)

استاندارد

در بخش قبل با متدها در زبان برنامه نویسی جاوا ، آشنا شدیم. همچنین در مورد اجزای متدها و کمی در مورد نحوه عملکرد آن ها توضیح داده شد.

در این بخش با فراخوانی متدها در توابع مختلف آشنا خواهیم شد.

فراخوانی متدها

برای فراخوانی یک متد باید آن را در جای دیگری صدا بزنیم. زمانی که یک متد صدا زده می شود، کامپایلر، به سراغ اجرای کدهای تعریف شده برای آن متد می رود.

برای فراخوانی یک متد، دو راه وجود دارد:

1- زمانی که متد هیچ مقداری را بر نمی گرداند: در این نوع صدا زدن کافی ست، اسم متد را در تابع اصلی یا هر تابع دیگری که می خواهیم، بنویسیم. سپس در داخل پرانتز لیست آرگومان های ورودی آن متد را در صورت وجود بنویسیم. سپس در آخر از علامت “;” استفاده می کنیم.

وقتی کامپایلر به این خط از برنامه می رسد، کدهای داخل بدنه ی متد فراخوانی شده را اجرا می کند. سپس به ادامه ی کدهای تابعی که در آن بوده است، می پردازد.

به عنوان مثالی از این نوع فراخوانی، کد زیر را مشاهده نمایید:

public class JavaApplication1 {

    public static void main(String[] args) {
        ShowMessage(); // فرخوانی متد
    }
    // تعریف متد
    static void ShowMessage(){
        System.out.print(("Gsm Developers")); // چاپ خروجی
    } 
}

در کد بالا وقتی تابع main اجرا می شود، به سراغ متد و کدهای بدنه ی ShowMessage می رود. در بدنه ی متد ShowMessage نیز، رشته ی “Gsm Developers” چاپ می شود. پس خروجی کد بالا نیز Gsm Developers است.

2- زمانی که متد، مقداری را بر می گرداند: در این نوع صدا زدن، نمی توان فقط با نوشتن اسم متد، آن را صدا زد. زیرا متد مقداری را بر می گرداند و از آن مقدار باید در جایی استفاده شود. مثلا ذخیره شود و یا به عنوان خروجی چاپ شود و …

به عنوان مثال، کد زیر متدی را صدا می زند که مقدار برگشتی دارد:

public class JavaApplication1 {

    public static void main(String[] args) {
        float m = divide(5,6); // m فراخوانی تابع و ریختن مقدار برگشتی آن در متغیر
        System.out.print(m); // m چاپ متغیر 
    }
    //تابع تقسیم
    static float divide(float num1 , float num2){
        float z = num1 / num2;
        return z; // مقدار برگشتی
    }
}

در کد بالا ، بعد از آن که تابع main اجرا شد، به سراغ متد divide می رود. سپس بعد از اجرای کدهای متد divide ، مقدار خروجی متد divide به متغیر m ریخته می شود.

دقت کنید، از آنجایی که در کد بالا تابع main خود به صورت static تعریف شده است، پس هر تابعی که در داخل آن فراخوانی می کنیم باید به صورت static تعریف شود.

همچنین می توانید در داخل متودی، متود دیگری نیز فرخوانی نمایید که به همین شیوه انجام می شود. و فقط کافیست کدهای آن متد در کلاس مربوطه، تعریف شده باشند.

overload کردن متدها

در جاوا همان طور که دیدید، با استفاده از اسم یک متد می توان آن را فراخوانی نمود. اسم متد، همان اسمی است که در هنگام ساخت برای آن تعریف کردیم.

ولی آیا نمی توان با همین اسم، متدی با بدنه و ساختاری دیگر تعریف کرد؟

در جاوا پیش می آید که بخواهیم از این روش استفاده کنیم. زیرا گاهی پیش می آید که بخواهیم متدها را با پارامترهای مختلفی فراخوانی کنیم.

مثلا بخواهیم متد مورد نظر ما، یک بار بدون پارامتر فراخوانی شود و یک بار با پارامتر String و یک بار با پارامتر int. ولی ما فقط یک پارامتر می خواهیم به آن متد ارسال نماییم ، نه بیشتر.

تعریف دو متد با نام یکسان و نوع خروجی و متغیر های یکسان باعث خطا می شود.

به این گونه تعریف متد ها با نام یکسان ولی پارامترهای متفاوت overload کردن متدها یا method overloading گفته می شود.

به عنوان مثال، به کد زیر خوب دقت کنید:

public class JavaApplication1 {

    public static void main(String[] args) {
        ShowMessage(); // تابع اول
        ShowMessage("Gsm Developers 2"); // تابع دوم

    }
    // تابع اول
    static void ShowMessage(){
        System.out.print(("Gsm Developers 1\n"));
    }
    // تابع دوم
    static void ShowMessage(String message){
        System.out.print(message);
    }
}

خروجی کد بالا به صورت زیر است:

Gsm Developers 1

Gsm Developers 2

اولین ShowMessage ی که در کد بالا در تابع اصلی main فراخوانی شد، بدون پارامتر است. پس تابع اولی که مشاهده می کنید، فراخوانی می شود.

ولی تابع دومی که در main فراخوانی می کنیم، بدنه ی تابع دومی که متغیر message به عنوان پارامتر ارسالی، تعریف شده است، فراخوانی می شود.